Skip to content

Commit 47a2af0

Browse files
authored
fix: Fix assertion when trying to inline virtual (super) calls (#1346)
1 parent 3163abb commit 47a2af0

File tree

5 files changed

+336
-3
lines changed

5 files changed

+336
-3
lines changed

src/compiler.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -6927,7 +6927,7 @@ export class Compiler extends DiagnosticEmitter {
69276927
if (instance.hasDecorator(DecoratorFlags.UNSAFE)) this.checkUnsafe(reportNode);
69286928

69296929
// Inline if explicitly requested
6930-
if (instance.hasDecorator(DecoratorFlags.INLINE)) {
6930+
if (instance.hasDecorator(DecoratorFlags.INLINE) && (!instance.is(CommonFlags.VIRTUAL) || reportNode.isCallOnSuper)) {
69316931
assert(!instance.is(CommonFlags.STUB)); // doesn't make sense
69326932
let inlineStack = this.inlineStack;
69336933
if (inlineStack.includes(instance)) {
@@ -6999,8 +6999,6 @@ export class Compiler extends DiagnosticEmitter {
69996999
thisArg: ExpressionRef = 0,
70007000
immediatelyDropped: bool = false
70017001
): ExpressionRef {
7002-
assert(!instance.is(CommonFlags.VIRTUAL));
7003-
70047002
var module = this.module;
70057003
var numArguments = operands ? operands.length : 0;
70067004
var signature = instance.signature;

tests/compiler/super-inline.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"asc_flags": [
3+
"--runtime none"
4+
]
5+
}
+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
(module
2+
(type $i32_=>_i32 (func (param i32) (result i32)))
3+
(type $none_=>_none (func))
4+
(memory $0 0)
5+
(global $~lib/rt/stub/offset (mut i32) (i32.const 0))
6+
(global $super-inline/foo (mut i32) (i32.const 0))
7+
(export "memory" (memory $0))
8+
(start $~start)
9+
(func $~lib/rt/stub/__alloc (param $0 i32) (result i32)
10+
(local $1 i32)
11+
(local $2 i32)
12+
(local $3 i32)
13+
(local $4 i32)
14+
global.get $~lib/rt/stub/offset
15+
i32.const 16
16+
i32.add
17+
local.tee $3
18+
i32.const 16
19+
i32.add
20+
local.tee $1
21+
memory.size
22+
local.tee $4
23+
i32.const 16
24+
i32.shl
25+
local.tee $2
26+
i32.gt_u
27+
if
28+
local.get $4
29+
local.get $1
30+
local.get $2
31+
i32.sub
32+
i32.const 65535
33+
i32.add
34+
i32.const -65536
35+
i32.and
36+
i32.const 16
37+
i32.shr_u
38+
local.tee $2
39+
local.get $4
40+
local.get $2
41+
i32.gt_s
42+
select
43+
memory.grow
44+
i32.const 0
45+
i32.lt_s
46+
if
47+
local.get $2
48+
memory.grow
49+
i32.const 0
50+
i32.lt_s
51+
if
52+
unreachable
53+
end
54+
end
55+
end
56+
local.get $1
57+
global.set $~lib/rt/stub/offset
58+
local.get $3
59+
i32.const 16
60+
i32.sub
61+
local.tee $1
62+
i32.const 16
63+
i32.store
64+
local.get $1
65+
i32.const 1
66+
i32.store offset=4
67+
local.get $1
68+
local.get $0
69+
i32.store offset=8
70+
local.get $1
71+
i32.const 0
72+
i32.store offset=12
73+
local.get $3
74+
)
75+
(func $super-inline/Foo#constructor (param $0 i32) (result i32)
76+
local.get $0
77+
if (result i32)
78+
local.get $0
79+
else
80+
i32.const 3
81+
call $~lib/rt/stub/__alloc
82+
end
83+
)
84+
(func $~start
85+
i32.const 1024
86+
global.set $~lib/rt/stub/offset
87+
i32.const 0
88+
call $super-inline/Foo#constructor
89+
global.set $super-inline/foo
90+
block $__inlined_func$super-inline/Foo#a@virtual
91+
global.get $super-inline/foo
92+
i32.const 8
93+
i32.sub
94+
i32.load
95+
i32.const 4
96+
i32.eq
97+
br_if $__inlined_func$super-inline/Foo#a@virtual
98+
end
99+
i32.const 4
100+
call $~lib/rt/stub/__alloc
101+
call $super-inline/Foo#constructor
102+
drop
103+
)
104+
)

tests/compiler/super-inline.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Foo {
2+
@inline
3+
a(): i32 { return 1; }
4+
}
5+
6+
class Bar extends Foo {
7+
a(): i32 { return super.a(); } // no AS228
8+
}
9+
10+
var foo = new Foo();
11+
foo.a(); // AS228
12+
13+
var bar = new Bar();
14+
bar.a();
+212
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
(module
2+
(type $i32_=>_i32 (func (param i32) (result i32)))
3+
(type $none_=>_none (func))
4+
(type $i32_=>_none (func (param i32)))
5+
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
6+
(memory $0 0)
7+
(table $0 1 funcref)
8+
(global $~lib/rt/stub/startOffset (mut i32) (i32.const 0))
9+
(global $~lib/rt/stub/offset (mut i32) (i32.const 0))
10+
(global $super-inline/foo (mut i32) (i32.const 0))
11+
(global $super-inline/bar (mut i32) (i32.const 0))
12+
(global $~lib/heap/__heap_base i32 (i32.const 8))
13+
(export "memory" (memory $0))
14+
(start $~start)
15+
(func $~lib/rt/stub/maybeGrowMemory (param $0 i32)
16+
(local $1 i32)
17+
(local $2 i32)
18+
(local $3 i32)
19+
(local $4 i32)
20+
(local $5 i32)
21+
memory.size
22+
local.set $1
23+
local.get $1
24+
i32.const 16
25+
i32.shl
26+
local.set $2
27+
local.get $0
28+
local.get $2
29+
i32.gt_u
30+
if
31+
local.get $0
32+
local.get $2
33+
i32.sub
34+
i32.const 65535
35+
i32.add
36+
i32.const 65535
37+
i32.const -1
38+
i32.xor
39+
i32.and
40+
i32.const 16
41+
i32.shr_u
42+
local.set $3
43+
local.get $1
44+
local.tee $4
45+
local.get $3
46+
local.tee $5
47+
local.get $4
48+
local.get $5
49+
i32.gt_s
50+
select
51+
local.set $4
52+
local.get $4
53+
memory.grow
54+
i32.const 0
55+
i32.lt_s
56+
if
57+
local.get $3
58+
memory.grow
59+
i32.const 0
60+
i32.lt_s
61+
if
62+
unreachable
63+
end
64+
end
65+
end
66+
local.get $0
67+
global.set $~lib/rt/stub/offset
68+
)
69+
(func $~lib/rt/stub/__alloc (param $0 i32) (param $1 i32) (result i32)
70+
(local $2 i32)
71+
(local $3 i32)
72+
(local $4 i32)
73+
(local $5 i32)
74+
(local $6 i32)
75+
local.get $0
76+
i32.const 1073741808
77+
i32.gt_u
78+
if
79+
unreachable
80+
end
81+
global.get $~lib/rt/stub/offset
82+
i32.const 16
83+
i32.add
84+
local.set $2
85+
local.get $0
86+
i32.const 15
87+
i32.add
88+
i32.const 15
89+
i32.const -1
90+
i32.xor
91+
i32.and
92+
local.tee $3
93+
i32.const 16
94+
local.tee $4
95+
local.get $3
96+
local.get $4
97+
i32.gt_u
98+
select
99+
local.set $5
100+
local.get $2
101+
local.get $5
102+
i32.add
103+
call $~lib/rt/stub/maybeGrowMemory
104+
local.get $2
105+
i32.const 16
106+
i32.sub
107+
local.set $6
108+
local.get $6
109+
local.get $5
110+
i32.store
111+
i32.const 1
112+
drop
113+
local.get $6
114+
i32.const 1
115+
i32.store offset=4
116+
local.get $6
117+
local.get $1
118+
i32.store offset=8
119+
local.get $6
120+
local.get $0
121+
i32.store offset=12
122+
local.get $2
123+
)
124+
(func $~lib/rt/stub/__retain (param $0 i32) (result i32)
125+
local.get $0
126+
)
127+
(func $super-inline/Foo#constructor (param $0 i32) (result i32)
128+
local.get $0
129+
i32.eqz
130+
if
131+
i32.const 0
132+
i32.const 3
133+
call $~lib/rt/stub/__alloc
134+
call $~lib/rt/stub/__retain
135+
local.set $0
136+
end
137+
local.get $0
138+
)
139+
(func $super-inline/Foo#a (param $0 i32) (result i32)
140+
i32.const 1
141+
)
142+
(func $super-inline/Bar#constructor (param $0 i32) (result i32)
143+
local.get $0
144+
i32.eqz
145+
if
146+
i32.const 0
147+
i32.const 4
148+
call $~lib/rt/stub/__alloc
149+
call $~lib/rt/stub/__retain
150+
local.set $0
151+
end
152+
local.get $0
153+
call $super-inline/Foo#constructor
154+
local.set $0
155+
local.get $0
156+
)
157+
(func $super-inline/Bar#a (param $0 i32) (result i32)
158+
(local $1 i32)
159+
local.get $0
160+
local.set $1
161+
i32.const 1
162+
)
163+
(func $start:super-inline
164+
global.get $~lib/heap/__heap_base
165+
i32.const 15
166+
i32.add
167+
i32.const 15
168+
i32.const -1
169+
i32.xor
170+
i32.and
171+
global.set $~lib/rt/stub/startOffset
172+
global.get $~lib/rt/stub/startOffset
173+
global.set $~lib/rt/stub/offset
174+
i32.const 0
175+
call $super-inline/Foo#constructor
176+
global.set $super-inline/foo
177+
global.get $super-inline/foo
178+
call $super-inline/Foo#a@virtual
179+
drop
180+
i32.const 0
181+
call $super-inline/Bar#constructor
182+
global.set $super-inline/bar
183+
global.get $super-inline/bar
184+
call $super-inline/Bar#a
185+
drop
186+
)
187+
(func $~start
188+
call $start:super-inline
189+
)
190+
(func $super-inline/Foo#a@virtual (param $0 i32) (result i32)
191+
(local $1 i32)
192+
block $default
193+
block $case0
194+
local.get $0
195+
i32.const 8
196+
i32.sub
197+
i32.load
198+
local.set $1
199+
local.get $1
200+
i32.const 4
201+
i32.eq
202+
br_if $case0
203+
br $default
204+
end
205+
local.get $0
206+
call $super-inline/Bar#a
207+
return
208+
end
209+
local.get $0
210+
call $super-inline/Foo#a
211+
)
212+
)

0 commit comments

Comments
 (0)