Skip to content

Commit fa5d4db

Browse files
authored
Fix temp local confusion in field assignment (#1109)
1 parent e0ccf0a commit fa5d4db

10 files changed

+3489
-657
lines changed

src/compiler.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5871,8 +5871,8 @@ export class Compiler extends DiagnosticEmitter {
58715871
let alreadyRetained = this.skippedAutoreleases.has(valueExpr);
58725872
if (flow.isAnyLocalFlag(localIndex, LocalFlags.ANY_RETAINED)) {
58735873
valueExpr = this.makeReplace(
5874-
module.local_get(localIndex, type.toNativeType()),
58755874
valueExpr,
5875+
module.local_get(localIndex, type.toNativeType()),
58765876
alreadyRetained
58775877
);
58785878
if (tee) { // local = REPLACE(local, value)
@@ -5927,8 +5927,8 @@ export class Compiler extends DiagnosticEmitter {
59275927
let alreadyRetained = this.skippedAutoreleases.has(valueExpr);
59285928
valueExpr = module.global_set(global.internalName,
59295929
this.makeReplace(
5930-
module.global_get(global.internalName, nativeType), // oldRef
5931-
valueExpr, // newRef
5930+
valueExpr,
5931+
module.global_get(global.internalName, nativeType),
59325932
alreadyRetained
59335933
)
59345934
);
@@ -5979,7 +5979,8 @@ export class Compiler extends DiagnosticEmitter {
59795979
var nativeThisType = thisType.toNativeType();
59805980

59815981
if (fieldType.isManaged && thisType.isManaged) {
5982-
let tempThis = flow.getTempLocal(thisType);
5982+
let tempThis = flow.getTempLocal(thisType, findUsedLocals(valueExpr));
5983+
// set before and read after valueExpr executes below ^
59835984
let alreadyRetained = this.skippedAutoreleases.has(valueExpr);
59845985
let ret: ExpressionRef;
59855986
if (tee) { // ((t1 = this).field = REPLACE(t1.field, t2 = value)), t2
@@ -5990,11 +5991,11 @@ export class Compiler extends DiagnosticEmitter {
59905991
module.store(fieldType.byteSize,
59915992
module.local_tee(tempThis.index, thisExpr),
59925993
this.makeReplace(
5993-
module.load(fieldType.byteSize, fieldType.is(TypeFlags.SIGNED), // oldRef
5994+
module.local_tee(tempValue.index, valueExpr),
5995+
module.load(fieldType.byteSize, fieldType.is(TypeFlags.SIGNED),
59945996
module.local_get(tempThis.index, nativeThisType),
59955997
nativeFieldType, field.memoryOffset
59965998
),
5997-
module.local_tee(tempValue.index, valueExpr), // newRef
59985999
alreadyRetained
59996000
),
60006001
nativeFieldType, field.memoryOffset
@@ -6007,11 +6008,11 @@ export class Compiler extends DiagnosticEmitter {
60076008
ret = module.store(fieldType.byteSize,
60086009
module.local_tee(tempThis.index, thisExpr),
60096010
this.makeReplace(
6010-
module.load(fieldType.byteSize, fieldType.is(TypeFlags.SIGNED), // oldRef
6011+
valueExpr,
6012+
module.load(fieldType.byteSize, fieldType.is(TypeFlags.SIGNED),
60116013
module.local_get(tempThis.index, nativeThisType),
60126014
nativeFieldType, field.memoryOffset
60136015
),
6014-
valueExpr, // newRef
60156016
alreadyRetained
60166017
),
60176018
nativeFieldType, field.memoryOffset
@@ -6733,10 +6734,10 @@ export class Compiler extends DiagnosticEmitter {
67336734

67346735
/** Makes a replace, retaining the new expression's value and releasing the old expression's value, in this order. */
67356736
makeReplace(
6736-
/** Old value being replaced. */
6737-
oldExpr: ExpressionRef,
67386737
/** New value being assigned. */
67396738
newExpr: ExpressionRef,
6739+
/** Old value being replaced. */
6740+
oldExpr: ExpressionRef,
67406741
/** Whether the new value is already retained. */
67416742
alreadyRetained: bool = false,
67426743
): ExpressionRef {

tests/compiler/issues/1095.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"asc_flags": [
3+
"--runtime half",
4+
"--use ASC_RTRACE=1"
5+
]
6+
}

0 commit comments

Comments
 (0)