From ed0d02364c13c004b1ff3844af4a70a496da0d20 Mon Sep 17 00:00:00 2001 From: dcode Date: Tue, 22 Oct 2019 10:59:27 +0200 Subject: [PATCH] Minor flow improvements --- src/compiler.ts | 23 ++++++++++------------- src/flow.ts | 40 +++++++++++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 0dd2b2b024..4b470a1f8c 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -1288,7 +1288,7 @@ export class Compiler extends DiagnosticEmitter { ) ) ); - flow.setLocalFlag(index, LocalFlags.RETAINED); + flow.setLocalFlag(index, LocalFlags.RETAINED | LocalFlags.PARAMETER); } } @@ -2252,8 +2252,10 @@ export class Compiler extends DiagnosticEmitter { if (!this.skippedAutoreleases.has(expr)) { if (returnType.isManaged) { if (getExpressionId(expr) == ExpressionId.LocalGet) { - if (flow.isAnyLocalFlag(getLocalGetIndex(expr), LocalFlags.ANY_RETAINED)) { - flow.unsetLocalFlag(getLocalGetIndex(expr), LocalFlags.ANY_RETAINED); + let index = getLocalGetIndex(expr); + if (flow.isAnyLocalFlag(index, LocalFlags.ANY_RETAINED)) { + flow.unsetLocalFlag(index, LocalFlags.ANY_RETAINED); + flow.setLocalFlag(index, LocalFlags.RETURNED); this.skippedAutoreleases.add(expr); } } @@ -6248,23 +6250,18 @@ export class Compiler extends DiagnosticEmitter { let initExpr = this.compileExpression( assert(instance.prototype.functionTypeNode.parameters[i].initializer), initType, - Constraints.CONV_IMPLICIT + Constraints.CONV_IMPLICIT | Constraints.WILL_RETAIN ); let argumentLocal = flow.addScopedLocal(signature.getParameterName(i), initType); if (!flow.canOverflow(initExpr, initType)) flow.setLocalFlag(argumentLocal.index, LocalFlags.WRAPPED); if (flow.isNonnull(initExpr, initType)) flow.setLocalFlag(argumentLocal.index, LocalFlags.NONNULL); if (initType.isManaged) { flow.setLocalFlag(argumentLocal.index, LocalFlags.RETAINED); - body.push( - module.local_set(argumentLocal.index, - this.makeRetain(initExpr) - ) - ); - } else { - body.push( - module.local_set(argumentLocal.index, initExpr) - ); + if (!this.skippedAutoreleases.has(initExpr)) initExpr = this.makeRetain(initExpr); } + body.push( + module.local_set(argumentLocal.index, initExpr) + ); } // Compile the called function's body in the scope of the inlined flow diff --git a/src/flow.ts b/src/flow.ts index 30db86e122..8a7c23b97e 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -144,41 +144,58 @@ export enum LocalFlags { /** Local is constant. */ CONSTANT = 1 << 0, + /** Local is a function parameter. */ + PARAMETER = 1 << 1, /** Local is properly wrapped. Relevant for small integers. */ - WRAPPED = 1 << 1, + WRAPPED = 1 << 2, /** Local is non-null. */ - NONNULL = 1 << 2, + NONNULL = 1 << 3, /** Local is read from. */ - READFROM = 1 << 3, + READFROM = 1 << 4, /** Local is written to. */ - WRITTENTO = 1 << 4, + WRITTENTO = 1 << 5, /** Local is retained. */ - RETAINED = 1 << 5, + RETAINED = 1 << 6, + /** Local is returned. */ + RETURNED = 1 << 7, /** Local is conditionally read from. */ - CONDITIONALLY_READFROM = 1 << 6, + CONDITIONALLY_READFROM = 1 << 8, /** Local is conditionally written to. */ - CONDITIONALLY_WRITTENTO = 1 << 7, + CONDITIONALLY_WRITTENTO = 1 << 9, /** Local must be conditionally retained. */ - CONDITIONALLY_RETAINED = 1 << 8, + CONDITIONALLY_RETAINED = 1 << 10, + /** Local is conditionally returned. */ + CONDITIONALLY_RETURNED = 1 << 11, /** Any categorical flag. */ ANY_CATEGORICAL = CONSTANT + | PARAMETER | WRAPPED | NONNULL | READFROM | WRITTENTO - | RETAINED, + | RETAINED + | RETURNED, /** Any conditional flag. */ ANY_CONDITIONAL = RETAINED | CONDITIONALLY_READFROM | CONDITIONALLY_WRITTENTO - | CONDITIONALLY_RETAINED, + | CONDITIONALLY_RETAINED + | CONDITIONALLY_RETURNED, + + /** Any written to flag. */ + ANY_WRITTENTO = WRITTENTO + | CONDITIONALLY_WRITTENTO, /** Any retained flag. */ ANY_RETAINED = RETAINED - | CONDITIONALLY_RETAINED + | CONDITIONALLY_RETAINED, + + /** Any returned flag. */ + ANY_RETURNED = RETURNED + | CONDITIONALLY_RETURNED } export namespace LocalFlags { export function join(left: LocalFlags, right: LocalFlags): LocalFlags { @@ -565,6 +582,7 @@ export class Flow { if (flags & LocalFlags.RETAINED) this.setLocalFlag(i, LocalFlags.CONDITIONALLY_RETAINED); if (flags & LocalFlags.READFROM) this.setLocalFlag(i, LocalFlags.CONDITIONALLY_READFROM); if (flags & LocalFlags.WRITTENTO) this.setLocalFlag(i, LocalFlags.CONDITIONALLY_WRITTENTO); + if (flags & LocalFlags.RETURNED) this.setLocalFlag(i, LocalFlags.CONDITIONALLY_RETURNED); } }