Skip to content

Commit 46c06da

Browse files
authored
fix: Fix assertion when a class extends and implements (#1403)
1 parent 87d361b commit 46c06da

File tree

5 files changed

+366
-2
lines changed

5 files changed

+366
-2
lines changed

Diff for: src/program.ts

-2
Original file line numberDiff line numberDiff line change
@@ -1213,11 +1213,9 @@ export class Program extends DiagnosticEmitter {
12131213
let basePrototype = thisPrototype.basePrototype;
12141214
let interfacePrototypes = thisPrototype.interfacePrototypes;
12151215
if (basePrototype) {
1216-
assert(!interfacePrototypes);
12171216
this.markVirtuals(thisPrototype, basePrototype);
12181217
}
12191218
if (interfacePrototypes) {
1220-
assert(!basePrototype);
12211219
for (let j = 0, l = interfacePrototypes.length; j < l; ++j) {
12221220
this.markVirtuals(thisPrototype, interfacePrototypes[j]);
12231221
}

Diff for: tests/compiler/class-implements.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"asc_flags": [
3+
"--runtime none"
4+
]
5+
}

Diff for: tests/compiler/class-implements.optimized.wat

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
(module
2+
(type $i32_=>_i32 (func (param i32) (result i32)))
3+
(type $none_=>_none (func))
4+
(memory $0 1)
5+
(data (i32.const 1024) "&\00\00\00\01\00\00\00\01\00\00\00&\00\00\00c\00l\00a\00s\00s\00-\00i\00m\00p\00l\00e\00m\00e\00n\00t\00s\00.\00t\00s")
6+
(global $~lib/rt/stub/offset (mut i32) (i32.const 0))
7+
(global $class-implements/A i32 (i32.const 3))
8+
(global $class-implements/C i32 (i32.const 5))
9+
(export "memory" (memory $0))
10+
(export "A" (global $class-implements/A))
11+
(export "A#foo" (func $class-implements/A#foo))
12+
(export "A#constructor" (func $class-implements/A#constructor))
13+
(export "C" (global $class-implements/C))
14+
(export "C#foo" (func $class-implements/C#foo))
15+
(start $~start)
16+
(func $~lib/rt/stub/__alloc (param $0 i32) (result i32)
17+
(local $1 i32)
18+
(local $2 i32)
19+
(local $3 i32)
20+
(local $4 i32)
21+
global.get $~lib/rt/stub/offset
22+
i32.const 16
23+
i32.add
24+
local.tee $3
25+
i32.const 16
26+
i32.add
27+
local.tee $1
28+
memory.size
29+
local.tee $4
30+
i32.const 16
31+
i32.shl
32+
local.tee $2
33+
i32.gt_u
34+
if
35+
local.get $4
36+
local.get $1
37+
local.get $2
38+
i32.sub
39+
i32.const 65535
40+
i32.add
41+
i32.const -65536
42+
i32.and
43+
i32.const 16
44+
i32.shr_u
45+
local.tee $2
46+
local.get $4
47+
local.get $2
48+
i32.gt_s
49+
select
50+
memory.grow
51+
i32.const 0
52+
i32.lt_s
53+
if
54+
local.get $2
55+
memory.grow
56+
i32.const 0
57+
i32.lt_s
58+
if
59+
unreachable
60+
end
61+
end
62+
end
63+
local.get $1
64+
global.set $~lib/rt/stub/offset
65+
local.get $3
66+
i32.const 16
67+
i32.sub
68+
local.tee $1
69+
i32.const 16
70+
i32.store
71+
local.get $1
72+
i32.const 1
73+
i32.store offset=4
74+
local.get $1
75+
local.get $0
76+
i32.store offset=8
77+
local.get $1
78+
i32.const 0
79+
i32.store offset=12
80+
local.get $3
81+
)
82+
(func $class-implements/A#constructor (param $0 i32) (result i32)
83+
local.get $0
84+
if (result i32)
85+
local.get $0
86+
else
87+
i32.const 3
88+
call $~lib/rt/stub/__alloc
89+
end
90+
)
91+
(func $class-implements/A#foo (param $0 i32) (result i32)
92+
i32.const 1
93+
)
94+
(func $class-implements/C#foo (param $0 i32) (result i32)
95+
i32.const 2
96+
)
97+
(func $~start
98+
i32.const 1088
99+
global.set $~lib/rt/stub/offset
100+
i32.const 0
101+
call $class-implements/A#constructor
102+
drop
103+
i32.const 5
104+
call $~lib/rt/stub/__alloc
105+
i32.eqz
106+
if
107+
i32.const 6
108+
call $~lib/rt/stub/__alloc
109+
drop
110+
end
111+
)
112+
)

Diff for: tests/compiler/class-implements.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
interface I {
2+
foo(): i32;
3+
}
4+
5+
export class A implements I {
6+
foo(): i32 { return 1; }
7+
}
8+
9+
var a = new A();
10+
assert(a.foo() === 1);
11+
12+
class B {
13+
}
14+
15+
export class C extends B implements I {
16+
foo(): i32 { return 2; }
17+
}
18+
19+
var c = new C();
20+
assert(c.foo() === 2);

Diff for: tests/compiler/class-implements.untouched.wat

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

0 commit comments

Comments
 (0)