Skip to content

Commit 5d92a64

Browse files
authored
Fix undone autorelease in inlined context (#1043)
1 parent dec4790 commit 5d92a64

File tree

3 files changed

+39
-35
lines changed

3 files changed

+39
-35
lines changed

src/compiler.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6652,28 +6652,46 @@ export class Compiler extends DiagnosticEmitter {
66526652
): void {
66536653
// Differs from `performAutoreleases` in that concluding this flow also
66546654
// concludes all its parent flows, for example on a `return`.
6655-
var module = this.module;
66566655
if (flow.is(FlowFlags.INLINE_CONTEXT)) {
66576656
// Traverse to the top-most flow containing the inlined function's
66586657
// locals as scoped locals and release these instead of all the locals.
6658+
let current = flow;
66596659
let parent: Flow | null;
6660-
while (parent = flow.parent) flow = parent;
6661-
this.performAutoreleases(flow, stmts, /* finalize */ false);
6660+
while (parent = current.parent) current = parent;
6661+
let scopedLocals = current.scopedLocals;
6662+
if (scopedLocals) {
6663+
for (let local of scopedLocals.values()) {
6664+
this.maybeFinishAutorelease(local, flow, stmts);
6665+
}
6666+
}
66626667
} else {
66636668
for (let local of flow.parentFunction.localsByIndex) {
6664-
let localIndex = local.index;
6665-
if (flow.isAnyLocalFlag(localIndex, LocalFlags.ANY_RETAINED)) {
6666-
flow.unsetLocalFlag(localIndex, LocalFlags.ANY_RETAINED);
6667-
stmts.push(
6668-
this.makeRelease(
6669-
module.local_get(localIndex, local.type.toNativeType())
6670-
)
6671-
);
6672-
}
6669+
this.maybeFinishAutorelease(local, flow, stmts);
66736670
}
66746671
}
66756672
}
66766673

6674+
/** Finishes a single autorelease of the specified local. */
6675+
private maybeFinishAutorelease(
6676+
/** Local to finish autoreleasing. */
6677+
local: Local,
6678+
/** Flow releasing its queued autoreleases. */
6679+
flow: Flow,
6680+
/** Array of statements to append the releases to. */
6681+
stmts: ExpressionRef[]
6682+
): void {
6683+
var localIndex = local.index;
6684+
var module = this.module;
6685+
if (~localIndex && flow.isAnyLocalFlag(localIndex, LocalFlags.ANY_RETAINED)) {
6686+
flow.unsetLocalFlag(localIndex, LocalFlags.ANY_RETAINED);
6687+
stmts.push(
6688+
this.makeRelease(
6689+
module.local_get(localIndex, local.type.toNativeType())
6690+
)
6691+
);
6692+
}
6693+
}
6694+
66776695
// </reference-counting>
66786696

66796697
/** Creates a direct call to the specified function. */

tests/compiler/std/typedarray.optimized.wat

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3383,20 +3383,16 @@
33833383
block $~lib/typedarray/SORT<~lib/typedarray/Float64Array,f64>|inlined.0
33843384
local.get $0
33853385
call $~lib/rt/pure/__retain
3386-
local.tee $1
3387-
call $~lib/typedarray/Int64Array#get:length
33883386
local.tee $2
3387+
call $~lib/typedarray/Int64Array#get:length
3388+
local.tee $1
33893389
i32.const 1
33903390
i32.le_s
3391-
if
3392-
local.get $1
3393-
call $~lib/rt/pure/__release
3394-
br $~lib/typedarray/SORT<~lib/typedarray/Float64Array,f64>|inlined.0
3395-
end
3396-
local.get $1
3391+
br_if $~lib/typedarray/SORT<~lib/typedarray/Float64Array,f64>|inlined.0
3392+
local.get $2
33973393
i32.load offset=4
33983394
local.set $0
3399-
local.get $2
3395+
local.get $1
34003396
i32.const 2
34013397
i32.eq
34023398
if
@@ -3421,24 +3417,22 @@
34213417
local.get $3
34223418
f64.store
34233419
end
3424-
local.get $1
3425-
call $~lib/rt/pure/__release
34263420
br $~lib/typedarray/SORT<~lib/typedarray/Float64Array,f64>|inlined.0
34273421
end
3428-
local.get $2
3422+
local.get $1
34293423
i32.const 256
34303424
i32.lt_s
34313425
if
34323426
local.get $0
3433-
local.get $2
3427+
local.get $1
34343428
call $~lib/util/sort/insertionSort<f64>
34353429
else
34363430
local.get $0
3437-
local.get $2
3431+
local.get $1
34383432
call $~lib/util/sort/weakHeapSort<f64>
34393433
end
34403434
end
3441-
local.get $1
3435+
local.get $2
34423436
)
34433437
(func $~lib/util/sort/COMPARATOR<f64>~anonymous|0 (; 57 ;) (param $0 f64) (param $1 f64) (result i32)
34443438
(local $2 i64)

tests/compiler/std/typedarray.untouched.wat

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5246,10 +5246,6 @@
52465246
i32.le_s
52475247
if
52485248
local.get $3
5249-
local.set $5
5250-
local.get $3
5251-
call $~lib/rt/pure/__release
5252-
local.get $5
52535249
br $~lib/typedarray/SORT<~lib/typedarray/Float64Array,f64>|inlined.0
52545250
end
52555251
local.get $3
@@ -5282,10 +5278,6 @@
52825278
f64.store
52835279
end
52845280
local.get $3
5285-
local.set $8
5286-
local.get $3
5287-
call $~lib/rt/pure/__release
5288-
local.get $8
52895281
br $~lib/typedarray/SORT<~lib/typedarray/Float64Array,f64>|inlined.0
52905282
end
52915283
local.get $5

0 commit comments

Comments
 (0)