Skip to content

Commit 4869f5d

Browse files
authored
Properly compile null in function contexts (#922)
1 parent da65778 commit 4869f5d

File tree

4 files changed

+56
-12
lines changed

4 files changed

+56
-12
lines changed

src/compiler.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7107,12 +7107,20 @@ export class Compiler extends DiagnosticEmitter {
71077107
switch (expression.kind) {
71087108
case NodeKind.NULL: {
71097109
let options = this.options;
7110-
let classReference = contextualType.classReference;
7111-
if (contextualType.is(TypeFlags.REFERENCE) && classReference !== null) {
7112-
this.currentType = classReference.type.asNullable();
7113-
} else {
7114-
this.currentType = options.usizeType; // TODO: anyref context yields <usize>0
7110+
if (contextualType.is(TypeFlags.REFERENCE)) {
7111+
let classReference = contextualType.classReference;
7112+
if (classReference) {
7113+
this.currentType = classReference.type.asNullable();
7114+
return options.isWasm64 ? module.i64(0) : module.i32(0);
7115+
}
7116+
let signatureReference = contextualType.signatureReference;
7117+
if (signatureReference) {
7118+
this.currentType = signatureReference.type.asNullable();
7119+
return module.i32(0);
7120+
}
7121+
// TODO: anyref context yields <usize>0
71157122
}
7123+
this.currentType = options.usizeType;
71167124
return options.isWasm64
71177125
? module.i64(0)
71187126
: module.i32(0);

tests/compiler/function-expression.optimized.wat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
88
(memory $0 1)
99
(data (i32.const 8) ",\00\00\00\01\00\00\00\01\00\00\00,\00\00\00f\00u\00n\00c\00t\00i\00o\00n\00-\00e\00x\00p\00r\00e\00s\00s\00i\00o\00n\00.\00t\00s")
10-
(table $0 11 funcref)
11-
(elem (i32.const 0) $start:function-expression~someName $start:function-expression~anonymous|0 $start:function-expression~anonymous|0 $start:function-expression~someName $start:function-expression~anonymous|2 $start:function-expression~anonymous|3 $start:function-expression~anonymous|4 $start:function-expression~anonymous|5 $start:function-expression~anonymous|3 $start:function-expression~anonymous|4 $start:function-expression~anonymous|5)
10+
(table $0 12 funcref)
11+
(elem (i32.const 0) $start:function-expression~someName $start:function-expression~anonymous|0 $start:function-expression~anonymous|0 $start:function-expression~someName $start:function-expression~anonymous|2 $start:function-expression~anonymous|3 $start:function-expression~anonymous|4 $start:function-expression~anonymous|5 $start:function-expression~anonymous|3 $start:function-expression~anonymous|4 $start:function-expression~anonymous|5 $start:function-expression~anonymous|2)
1212
(global $~lib/argc (mut i32) (i32.const 0))
1313
(export "memory" (memory $0))
1414
(start $start)

tests/compiler/function-expression.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,12 @@ function testOmittedReturn3(): (a: i32, b: i32) => i32 {
3434
assert(testOmittedReturn1()(1, 2) == 3);
3535
assert(testOmittedReturn2()(1, 2) == 1);
3636
assert(testOmittedReturn3()(1, 2) == 42);
37+
38+
function testNullable(b: boolean): (() => i32) | null {
39+
if (b) {
40+
return (): i32 => 1;
41+
} else {
42+
return null;
43+
}
44+
}
45+
assert(testNullable(false) == null);

tests/compiler/function-expression.untouched.wat

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
88
(memory $0 1)
99
(data (i32.const 8) ",\00\00\00\01\00\00\00\01\00\00\00,\00\00\00f\00u\00n\00c\00t\00i\00o\00n\00-\00e\00x\00p\00r\00e\00s\00s\00i\00o\00n\00.\00t\00s\00")
10-
(table $0 11 funcref)
11-
(elem (i32.const 0) $null $start:function-expression~anonymous|0 $start:function-expression~anonymous|1 $start:function-expression~someName $start:function-expression~anonymous|2 $start:function-expression~anonymous|3 $start:function-expression~anonymous|4 $start:function-expression~anonymous|5 $function-expression/testOmittedReturn1~anonymous|0 $function-expression/testOmittedReturn2~anonymous|0 $function-expression/testOmittedReturn3~anonymous|0)
10+
(table $0 12 funcref)
11+
(elem (i32.const 0) $null $start:function-expression~anonymous|0 $start:function-expression~anonymous|1 $start:function-expression~someName $start:function-expression~anonymous|2 $start:function-expression~anonymous|3 $start:function-expression~anonymous|4 $start:function-expression~anonymous|5 $function-expression/testOmittedReturn1~anonymous|0 $function-expression/testOmittedReturn2~anonymous|0 $function-expression/testOmittedReturn3~anonymous|0 $function-expression/testNullable~anonymous|0)
1212
(global $function-expression/f1 (mut i32) (i32.const 1))
1313
(global $~lib/argc (mut i32) (i32.const 0))
1414
(global $function-expression/f2 (mut i32) (i32.const 2))
@@ -67,7 +67,21 @@
6767
(func $function-expression/testOmittedReturn3 (; 14 ;) (type $FUNCSIG$i) (result i32)
6868
i32.const 10
6969
)
70-
(func $start:function-expression (; 15 ;) (type $FUNCSIG$v)
70+
(func $function-expression/testNullable~anonymous|0 (; 15 ;) (type $FUNCSIG$i) (result i32)
71+
i32.const 1
72+
)
73+
(func $function-expression/testNullable (; 16 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
74+
local.get $0
75+
if
76+
i32.const 11
77+
return
78+
else
79+
i32.const 0
80+
return
81+
end
82+
unreachable
83+
)
84+
(func $start:function-expression (; 17 ;) (type $FUNCSIG$v)
7185
i32.const 1
7286
global.set $~lib/argc
7387
i32.const 1
@@ -209,10 +223,23 @@
209223
call $~lib/builtins/abort
210224
unreachable
211225
end
226+
i32.const 0
227+
call $function-expression/testNullable
228+
i32.const 0
229+
i32.eq
230+
i32.eqz
231+
if
232+
i32.const 0
233+
i32.const 24
234+
i32.const 45
235+
i32.const 0
236+
call $~lib/builtins/abort
237+
unreachable
238+
end
212239
)
213-
(func $start (; 16 ;) (type $FUNCSIG$v)
240+
(func $start (; 18 ;) (type $FUNCSIG$v)
214241
call $start:function-expression
215242
)
216-
(func $null (; 17 ;) (type $FUNCSIG$v)
243+
(func $null (; 19 ;) (type $FUNCSIG$v)
217244
)
218245
)

0 commit comments

Comments
 (0)