From f9718c4c85d785561b1cd887ad4a21685bcc3f83 Mon Sep 17 00:00:00 2001 From: dcode Date: Thu, 2 Jan 2020 21:28:25 +0100 Subject: [PATCH] Fix undone autorelease in inlined context --- src/compiler.ts | 42 +++++++++++++++------ tests/compiler/std/typedarray.optimized.wat | 24 +++++------- tests/compiler/std/typedarray.untouched.wat | 8 ---- 3 files changed, 39 insertions(+), 35 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index ee9be37002..48d3a1088c 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -6652,28 +6652,46 @@ export class Compiler extends DiagnosticEmitter { ): void { // Differs from `performAutoreleases` in that concluding this flow also // concludes all its parent flows, for example on a `return`. - var module = this.module; if (flow.is(FlowFlags.INLINE_CONTEXT)) { // Traverse to the top-most flow containing the inlined function's // locals as scoped locals and release these instead of all the locals. + let current = flow; let parent: Flow | null; - while (parent = flow.parent) flow = parent; - this.performAutoreleases(flow, stmts, /* finalize */ false); + while (parent = current.parent) current = parent; + let scopedLocals = current.scopedLocals; + if (scopedLocals) { + for (let local of scopedLocals.values()) { + this.maybeFinishAutorelease(local, flow, stmts); + } + } } else { for (let local of flow.parentFunction.localsByIndex) { - let localIndex = local.index; - if (flow.isAnyLocalFlag(localIndex, LocalFlags.ANY_RETAINED)) { - flow.unsetLocalFlag(localIndex, LocalFlags.ANY_RETAINED); - stmts.push( - this.makeRelease( - module.local_get(localIndex, local.type.toNativeType()) - ) - ); - } + this.maybeFinishAutorelease(local, flow, stmts); } } } + /** Finishes a single autorelease of the specified local. */ + private maybeFinishAutorelease( + /** Local to finish autoreleasing. */ + local: Local, + /** Flow releasing its queued autoreleases. */ + flow: Flow, + /** Array of statements to append the releases to. */ + stmts: ExpressionRef[] + ): void { + var localIndex = local.index; + var module = this.module; + if (~localIndex && flow.isAnyLocalFlag(localIndex, LocalFlags.ANY_RETAINED)) { + flow.unsetLocalFlag(localIndex, LocalFlags.ANY_RETAINED); + stmts.push( + this.makeRelease( + module.local_get(localIndex, local.type.toNativeType()) + ) + ); + } + } + // /** Creates a direct call to the specified function. */ diff --git a/tests/compiler/std/typedarray.optimized.wat b/tests/compiler/std/typedarray.optimized.wat index d03a156916..a7da285eb3 100644 --- a/tests/compiler/std/typedarray.optimized.wat +++ b/tests/compiler/std/typedarray.optimized.wat @@ -3383,20 +3383,16 @@ block $~lib/typedarray/SORT<~lib/typedarray/Float64Array,f64>|inlined.0 local.get $0 call $~lib/rt/pure/__retain - local.tee $1 - call $~lib/typedarray/Int64Array#get:length local.tee $2 + call $~lib/typedarray/Int64Array#get:length + local.tee $1 i32.const 1 i32.le_s - if - local.get $1 - call $~lib/rt/pure/__release - br $~lib/typedarray/SORT<~lib/typedarray/Float64Array,f64>|inlined.0 - end - local.get $1 + br_if $~lib/typedarray/SORT<~lib/typedarray/Float64Array,f64>|inlined.0 + local.get $2 i32.load offset=4 local.set $0 - local.get $2 + local.get $1 i32.const 2 i32.eq if @@ -3421,24 +3417,22 @@ local.get $3 f64.store end - local.get $1 - call $~lib/rt/pure/__release br $~lib/typedarray/SORT<~lib/typedarray/Float64Array,f64>|inlined.0 end - local.get $2 + local.get $1 i32.const 256 i32.lt_s if local.get $0 - local.get $2 + local.get $1 call $~lib/util/sort/insertionSort else local.get $0 - local.get $2 + local.get $1 call $~lib/util/sort/weakHeapSort end end - local.get $1 + local.get $2 ) (func $~lib/util/sort/COMPARATOR~anonymous|0 (; 57 ;) (param $0 f64) (param $1 f64) (result i32) (local $2 i64) diff --git a/tests/compiler/std/typedarray.untouched.wat b/tests/compiler/std/typedarray.untouched.wat index ecb313497e..e59231ded3 100644 --- a/tests/compiler/std/typedarray.untouched.wat +++ b/tests/compiler/std/typedarray.untouched.wat @@ -5246,10 +5246,6 @@ i32.le_s if local.get $3 - local.set $5 - local.get $3 - call $~lib/rt/pure/__release - local.get $5 br $~lib/typedarray/SORT<~lib/typedarray/Float64Array,f64>|inlined.0 end local.get $3 @@ -5282,10 +5278,6 @@ f64.store end local.get $3 - local.set $8 - local.get $3 - call $~lib/rt/pure/__release - local.get $8 br $~lib/typedarray/SORT<~lib/typedarray/Float64Array,f64>|inlined.0 end local.get $5