Skip to content

Commit 790babf

Browse files
authoredOct 17, 2023
fix: crash on assignment chain (#2767)
Fixes: #2674
1 parent e0e738c commit 790babf

5 files changed

+182
-3
lines changed
 

‎src/compiler.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -5811,14 +5811,14 @@ export class Compiler extends DiagnosticEmitter {
58115811
assert(getterInstance.signature.thisType == thisType);
58125812
let returnType = getterInstance.signature.returnType;
58135813
let returnTypeRef = returnType.toRef();
5814-
let tempThis = flow.getTempLocal(returnType);
5814+
let tempThis = flow.getTempLocal(thisType);
58155815
let ret = module.block(null, [
58165816
this.makeCallDirect(setterInstance, [
5817-
module.local_tee(tempThis.index, thisExpr, returnType.isManaged),
5817+
module.local_tee(tempThis.index, thisExpr, /* isManaged=*/false, thisType.toRef()), // thisType is managed but here it must be alive
58185818
valueExpr
58195819
], valueExpression),
58205820
this.makeCallDirect(getterInstance, [
5821-
module.local_get(tempThis.index, returnTypeRef)
5821+
module.local_get(tempThis.index, thisType.toRef())
58225822
], valueExpression)
58235823
], returnTypeRef);
58245824
return ret;
+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
(module
2+
(type $i32_i64_=>_none (func (param i32 i64)))
3+
(type $i32_=>_none (func (param i32)))
4+
(type $i32_=>_i64 (func (param i32) (result i64)))
5+
(type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32)))
6+
(type $none_=>_none (func))
7+
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
8+
(global $~lib/memory/__data_end i32 (i32.const 8))
9+
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 32776))
10+
(global $~lib/memory/__heap_base i32 (i32.const 32776))
11+
(memory $0 0)
12+
(table $0 1 1 funcref)
13+
(elem $0 (i32.const 1))
14+
(export "memory" (memory $0))
15+
(export "foo" (func $export:assignment-chain/foo))
16+
(func $assignment-chain/A#set:y (param $this i32) (param $y i64)
17+
local.get $this
18+
local.get $y
19+
i64.store $0 offset=8
20+
)
21+
(func $assignment-chain/A#get:y (param $this i32) (result i64)
22+
local.get $this
23+
i64.load $0 offset=8
24+
)
25+
(func $assignment-chain/A#set:x (param $this i32) (param $x i64)
26+
local.get $this
27+
local.get $x
28+
i64.store $0
29+
)
30+
(func $~stack_check
31+
global.get $~lib/memory/__stack_pointer
32+
global.get $~lib/memory/__data_end
33+
i32.lt_s
34+
if
35+
i32.const 32800
36+
i32.const 32848
37+
i32.const 1
38+
i32.const 1
39+
call $~lib/builtins/abort
40+
unreachable
41+
end
42+
)
43+
(func $assignment-chain/foo (param $a i32)
44+
(local $1 i32)
45+
(local $2 i32)
46+
global.get $~lib/memory/__stack_pointer
47+
i32.const 8
48+
i32.sub
49+
global.set $~lib/memory/__stack_pointer
50+
call $~stack_check
51+
global.get $~lib/memory/__stack_pointer
52+
i64.const 0
53+
i64.store $0
54+
local.get $a
55+
local.set $2
56+
global.get $~lib/memory/__stack_pointer
57+
local.get $2
58+
i32.store $0
59+
local.get $2
60+
local.get $a
61+
local.tee $1
62+
local.set $2
63+
global.get $~lib/memory/__stack_pointer
64+
local.get $2
65+
i32.store $0 offset=4
66+
local.get $2
67+
i64.const 1
68+
call $assignment-chain/A#set:y
69+
local.get $1
70+
local.set $2
71+
global.get $~lib/memory/__stack_pointer
72+
local.get $2
73+
i32.store $0 offset=4
74+
local.get $2
75+
call $assignment-chain/A#get:y
76+
call $assignment-chain/A#set:x
77+
global.get $~lib/memory/__stack_pointer
78+
i32.const 8
79+
i32.add
80+
global.set $~lib/memory/__stack_pointer
81+
)
82+
(func $export:assignment-chain/foo (param $0 i32)
83+
global.get $~lib/memory/__stack_pointer
84+
i32.const 4
85+
i32.sub
86+
global.set $~lib/memory/__stack_pointer
87+
call $~stack_check
88+
global.get $~lib/memory/__stack_pointer
89+
local.get $0
90+
i32.store $0
91+
local.get $0
92+
call $assignment-chain/foo
93+
global.get $~lib/memory/__stack_pointer
94+
i32.const 4
95+
i32.add
96+
global.set $~lib/memory/__stack_pointer
97+
)
98+
)

‎tests/compiler/assignment-chain.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"asc_flags": [
3+
]
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
(module
2+
(type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32)))
3+
(type $i32_=>_none (func (param i32)))
4+
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
5+
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 33792))
6+
(memory $0 0)
7+
(export "memory" (memory $0))
8+
(export "foo" (func $export:assignment-chain/foo))
9+
(func $export:assignment-chain/foo (param $0 i32)
10+
(local $1 i32)
11+
global.get $~lib/memory/__stack_pointer
12+
i32.const 4
13+
i32.sub
14+
global.set $~lib/memory/__stack_pointer
15+
block $folding-inner0
16+
global.get $~lib/memory/__stack_pointer
17+
i32.const 1024
18+
i32.lt_s
19+
br_if $folding-inner0
20+
global.get $~lib/memory/__stack_pointer
21+
local.tee $1
22+
local.get $0
23+
i32.store $0
24+
local.get $1
25+
i32.const 8
26+
i32.sub
27+
global.set $~lib/memory/__stack_pointer
28+
global.get $~lib/memory/__stack_pointer
29+
i32.const 1024
30+
i32.lt_s
31+
br_if $folding-inner0
32+
global.get $~lib/memory/__stack_pointer
33+
local.tee $1
34+
i64.const 0
35+
i64.store $0
36+
local.get $1
37+
local.get $0
38+
i32.store $0
39+
local.get $1
40+
local.get $0
41+
i32.store $0 offset=4
42+
local.get $0
43+
i64.const 1
44+
i64.store $0 offset=8
45+
local.get $1
46+
local.get $0
47+
i32.store $0 offset=4
48+
local.get $0
49+
local.get $0
50+
i64.load $0 offset=8
51+
i64.store $0
52+
local.get $1
53+
i32.const 8
54+
i32.add
55+
global.set $~lib/memory/__stack_pointer
56+
global.get $~lib/memory/__stack_pointer
57+
i32.const 4
58+
i32.add
59+
global.set $~lib/memory/__stack_pointer
60+
return
61+
end
62+
i32.const 33824
63+
i32.const 33872
64+
i32.const 1
65+
i32.const 1
66+
call $~lib/builtins/abort
67+
unreachable
68+
)
69+
)

‎tests/compiler/assignment-chain.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class A {
2+
x: i64 = 0;
3+
y: i64 = 0;
4+
}
5+
6+
export function foo(a: A): void {
7+
a.x = a.y = 1;
8+
}

0 commit comments

Comments
 (0)
Please sign in to comment.