non-nullable.js (4366B)
1 // non-null values are subtype of null values 2 wasmValidateText(`(module 3 (func (param $a (ref extern)) 4 local.get $a 5 (block (param (ref null extern)) 6 drop 7 ) 8 ) 9 )`); 10 11 // null values are not subtype of non-null values 12 wasmFailValidateText(`(module 13 (func (param $a (ref null extern)) 14 local.get $a 15 (block (param (ref extern)) 16 drop 17 ) 18 ) 19 )`, /expression has type externref but expected \(ref extern\)/); 20 21 // can have non-defaultable local, but not use/get if unset. 22 wasmValidateText(`(module 23 (func (local (ref extern))) 24 )`); 25 wasmFailValidateText(`(module 26 (func (local (ref extern)) 27 local.get 0 28 drop 29 ) 30 )`, /local\.get read from unset local/); 31 wasmFailValidateText(`(module 32 (func 33 (local (ref extern)) 34 unreachable 35 block 36 local.get 0 37 drop 38 end 39 ) 40 )`, /local\.get read from unset local/); 41 wasmFailValidateText(`(module 42 (func (param funcref) (result funcref) (local (ref func)) 43 block 44 local.get 0 45 ref.as_non_null 46 local.set 1 47 end 48 local.get 1 49 ) 50 )`, /local\.get read from unset local/); 51 wasmValidateText(`(module 52 (func (param $r (ref extern)) 53 (local $var (ref extern)) 54 local.get $r 55 ref.as_non_null 56 local.set $var 57 block block block 58 local.get $var 59 drop 60 end end end 61 ) 62 (func 63 (param (ref null func) (ref null func) (ref func)) 64 (result funcref) 65 (local (ref func) i32 (ref func) (ref null func)) 66 local.get 0 67 ref.as_non_null 68 local.tee 3 69 block 70 local.get 6 71 ref.as_non_null 72 local.set 5 73 end 74 local.get 2 75 drop 76 local.tee 5 77 ) 78 )`); 79 wasmFailValidateText(`(module 80 (elem declare func 0) 81 (func 82 (local (ref func)) 83 i32.const 0 84 if 85 ref.func 0 86 local.set 0 87 else 88 local.get 0 89 drop 90 end 91 ) 92 )`, /local\.get read from unset local/); 93 wasmValidateText(`(module 94 (elem declare func 0) 95 (func (result funcref) 96 (local (ref func) (ref func)) 97 i32.const 0 98 if (result funcref) 99 ref.func 0 100 local.set 0 101 local.get 0 102 else 103 ref.func 0 104 local.tee 1 105 local.get 1 106 drop 107 end 108 ) 109 )`); 110 111 // exported funcs can't take null in non-nullable params 112 let {a} = wasmEvalText(`(module 113 (func (export "a") (param (ref extern))) 114 )`).exports; 115 assertErrorMessage(() => a(null), TypeError, /cannot pass null to non-nullable/); 116 for (let val of WasmNonNullExternrefValues) { 117 a(val); 118 } 119 120 // imported funcs can't return null in non-nullable results 121 function returnNull() { 122 return null; 123 } 124 function returnMultiNullReg() { 125 return [null, null]; 126 } 127 function returnMultiNullStack() { 128 return [1, 2, 3, 4, 5, 6, 7, 8, null]; 129 } 130 let {runNull, runMultiNullReg, runMultiNullStack} = wasmEvalText(`(module 131 (func $returnNull (import "" "returnNull") (result (ref extern))) 132 (func $returnMultiNullReg (import "" "returnMultiNullReg") (result (ref extern) (ref extern))) 133 (func $returnMultiNullStack (import "" "returnMultiNullStack") (result (ref extern) (ref extern) (ref extern) (ref extern) (ref extern) (ref extern) (ref extern) (ref extern) (ref extern))) 134 (func (export "runNull") 135 call $returnNull 136 unreachable 137 ) 138 (func (export "runMultiNullReg") 139 call $returnMultiNullReg 140 unreachable 141 ) 142 (func (export "runMultiNullStack") 143 call $returnMultiNullStack 144 unreachable 145 ) 146 )`, { "": { returnNull, returnMultiNullReg, returnMultiNullStack } }).exports; 147 assertErrorMessage(() => runNull(), TypeError, /cannot pass null to non-nullable/); 148 assertErrorMessage(() => runMultiNullReg(), TypeError, /cannot pass null to non-nullable/); 149 assertErrorMessage(() => runMultiNullStack(), TypeError, /cannot pass null to non-nullable/); 150 151 { 152 // can have non-nullable globals 153 wasmEvalText(`(module 154 (func $f) 155 (elem declare func $f) 156 (global (ref func) ref.func $f) 157 )`); 158 } 159 160 // cannot have non-nullable tables without initializer 161 wasmFailValidateText(`(module 162 (table (ref extern) (elem)) 163 )`, /table with non-nullable references requires initializer/); 164 165 // Testing internal wasmLosslessInvoke to pass non-nullable as params and arguments. 166 let {t} = wasmEvalText(`(module 167 (func (export "t") (param (ref extern)) (result (ref extern)) 168 (local (ref extern)) 169 (local.set 1 (local.get 0)) 170 (local.get 1) 171 ) 172 )`).exports; 173 const ret = wasmLosslessInvoke(t, {test: 1}); 174 assertEq(ret.value.test, 1);