globals.js (9537B)
1 // Globals have identity now 2 { 3 const { g, same } = wasmEvalText(`(module 4 (type (struct)) 5 (global (export "g") eqref (struct.new 0)) 6 (func $same (export "same") (param eqref) (result i32) 7 (ref.eq (local.get 0) (global.get 0)) 8 ) 9 (func $sanity 10 (if (call $same (global.get 0)) (then return)) 11 unreachable 12 ) 13 (start $sanity) 14 )`).exports; 15 16 assertEq(same(g.value), 1, "global had different identity when exported"); 17 } 18 19 // Subtypes with func refs 20 { 21 wasmEvalText(`(module 22 (type $s1 (struct)) 23 (type $t1 (sub (func (param (ref $s1))))) 24 (type $t2 (sub $t1 (func (param (ref null $s1))))) 25 (func $a (type $t1)) 26 (func $b (type $t2)) 27 28 (global (ref $t1) ref.func $a) 29 (global (ref null $t1) ref.func $a) 30 (global (ref func) ref.func $a) 31 (global (ref null func) ref.func $a) 32 33 (global (ref $t2) ref.func $b) 34 (global (ref null $t2) ref.func $b) 35 (global (ref $t1) ref.func $b) 36 (global (ref null $t1) ref.func $b) 37 (global (ref func) ref.func $b) 38 (global (ref null func) ref.func $b) 39 )`); 40 41 assertErrorMessage(() => wasmEvalText(`(module 42 (type $s1 (struct)) 43 (type $t1 (func (param (ref $s1)))) 44 (type $t2 (func (param (ref null $s1)))) ;; not a subtype of t1 45 (func $a (type $t2)) 46 (global (ref $t1) ref.func $a) 47 )`), WebAssembly.CompileError, /type mismatch/); 48 } 49 50 // Subtypes with struct refs 51 { 52 wasmEvalText(`(module 53 (type $t1 (sub (struct))) 54 (type $t2 (sub $t1 (struct (field i32)))) 55 56 (global (ref $t1) struct.new_default $t1) 57 (global (ref null $t1) struct.new_default $t1) 58 (global (ref struct) struct.new_default $t1) 59 (global (ref null struct) struct.new_default $t1) 60 (global (ref eq) struct.new_default $t1) 61 (global (ref null eq) struct.new_default $t1) 62 (global (ref any) struct.new_default $t1) 63 (global (ref null any) struct.new_default $t1) 64 65 (global (ref $t2) struct.new_default $t2) 66 (global (ref null $t2) struct.new_default $t2) 67 (global (ref $t1) struct.new_default $t2) 68 (global (ref null $t1) struct.new_default $t2) 69 (global (ref struct) struct.new_default $t2) 70 (global (ref null struct) struct.new_default $t2) 71 (global (ref eq) struct.new_default $t2) 72 (global (ref null eq) struct.new_default $t2) 73 (global (ref any) struct.new_default $t2) 74 (global (ref null any) struct.new_default $t2) 75 )`); 76 77 assertErrorMessage(() => wasmEvalText(`(module 78 (type $t1 (struct)) 79 (type $t2 (struct (field i32))) ;; not a subtype of t1 80 (global (ref $t1) struct.new_default $t2) 81 )`), WebAssembly.CompileError, /type mismatch/); 82 } 83 84 // Subtypes with array refs 85 { 86 wasmEvalText(`(module 87 (type $s (struct)) 88 (type $t1 (sub (array (ref null $s)))) 89 (type $t2 (sub $t1 (array (ref $s)))) 90 91 (global (ref $t1) array.new_fixed $t1 0) 92 (global (ref null $t1) array.new_fixed $t1 0) 93 (global (ref array) array.new_fixed $t1 0) 94 (global (ref null array) array.new_fixed $t1 0) 95 (global (ref eq) array.new_fixed $t1 0) 96 (global (ref null eq) array.new_fixed $t1 0) 97 (global (ref any) array.new_fixed $t1 0) 98 (global (ref null any) array.new_fixed $t1 0) 99 100 (global (ref $t2) array.new_fixed $t2 0) 101 (global (ref null $t2) array.new_fixed $t2 0) 102 (global (ref $t1) array.new_fixed $t2 0) 103 (global (ref null $t1) array.new_fixed $t2 0) 104 (global (ref array) array.new_fixed $t2 0) 105 (global (ref null array) array.new_fixed $t2 0) 106 (global (ref eq) array.new_fixed $t2 0) 107 (global (ref null eq) array.new_fixed $t2 0) 108 (global (ref any) array.new_fixed $t2 0) 109 (global (ref null any) array.new_fixed $t2 0) 110 )`); 111 112 assertErrorMessage(() => wasmEvalText(`(module 113 (type $s (struct)) 114 (type $t1 (array (ref null $s))) 115 (type $t2 (array (ref $s))) ;; not a subtype of t1 116 (global (ref $t1) array.new_fixed $t2 0) 117 )`), WebAssembly.CompileError, /type mismatch/); 118 } 119 120 // Subtypes should be respected on imports and exports 121 { 122 const { struct, mut_struct, eq, mut_eq, any, mut_any } = wasmEvalText(`(module 123 (type (struct)) 124 (global (export "struct") structref (struct.new 0)) 125 (global (export "mut_struct") (mut structref) (struct.new 0)) 126 (global (export "eq") eqref (struct.new 0)) 127 (global (export "mut_eq") (mut eqref) (struct.new 0)) 128 (global (export "any") anyref (struct.new 0)) 129 (global (export "mut_any") (mut anyref) (struct.new 0)) 130 )`).exports; 131 132 function importGlobalIntoType(g, t) { 133 wasmEvalText(`(module 134 (global (import "test" "g") ${t}) 135 )`, { "test": { "g": g } }); 136 } 137 138 importGlobalIntoType(struct, `structref`); 139 importGlobalIntoType(struct, `eqref`); 140 importGlobalIntoType(struct, `anyref`); 141 142 importGlobalIntoType(mut_struct, `(mut structref)`); 143 assertErrorMessage(() => importGlobalIntoType(mut_struct, `(mut eqref)`), WebAssembly.LinkError, /global type mismatch/); 144 assertErrorMessage(() => importGlobalIntoType(mut_struct, `(mut anyref)`), WebAssembly.LinkError, /global type mismatch/); 145 146 assertErrorMessage(() => importGlobalIntoType(eq, `structref`), WebAssembly.LinkError, /global type mismatch/); 147 importGlobalIntoType(eq, `eqref`); 148 importGlobalIntoType(eq, `anyref`); 149 150 assertErrorMessage(() => importGlobalIntoType(mut_eq, `(mut structref)`), WebAssembly.LinkError, /global type mismatch/); 151 importGlobalIntoType(mut_eq, `(mut eqref)`); 152 assertErrorMessage(() => importGlobalIntoType(mut_eq, `(mut anyref)`), WebAssembly.LinkError, /global type mismatch/); 153 154 assertErrorMessage(() => importGlobalIntoType(any, `structref`), WebAssembly.LinkError, /global type mismatch/); 155 assertErrorMessage(() => importGlobalIntoType(any, `eqref`), WebAssembly.LinkError, /global type mismatch/); 156 importGlobalIntoType(any, `anyref`); 157 158 assertErrorMessage(() => importGlobalIntoType(mut_any, `(mut structref)`), WebAssembly.LinkError, /global type mismatch/); 159 assertErrorMessage(() => importGlobalIntoType(mut_any, `(mut eqref)`), WebAssembly.LinkError, /global type mismatch/); 160 importGlobalIntoType(mut_any, `(mut anyref)`); 161 } 162 163 // Importing globals with ref types 164 { 165 const { struct, array, func } = wasmEvalText(`(module 166 (type (struct)) 167 (type (array i32)) 168 (func $f) 169 (global (export "struct") structref (struct.new 0)) 170 (global (export "array") arrayref (array.new_fixed 1 0)) 171 (global (export "func") funcref (ref.func $f)) 172 )`).exports; 173 174 function importValueIntoType(v, t) { 175 wasmEvalText(`(module 176 (global (import "test" "v") ${t}) 177 )`, { "test": { "v": v } }); 178 } 179 180 assertErrorMessage(() => importValueIntoType(struct.value, `(mut structref)`), WebAssembly.LinkError, /global mutability mismatch/); 181 182 importValueIntoType(null, `structref`); 183 assertErrorMessage(() => importValueIntoType(null, `(ref struct)`), TypeError, /cannot pass null/); 184 assertErrorMessage(() => importValueIntoType(0, `structref`), TypeError, /can only pass/); 185 importValueIntoType(struct.value, `structref`); 186 assertErrorMessage(() => importValueIntoType(array.value, `structref`), TypeError, /can only pass/); 187 188 importValueIntoType(null, `i31ref`); 189 assertErrorMessage(() => importValueIntoType(null, `(ref i31)`), TypeError, /cannot pass null/); 190 importValueIntoType(0, `i31ref`); 191 assertErrorMessage(() => importValueIntoType(0.1, `i31ref`), TypeError, /can only pass/); 192 assertErrorMessage(() => importValueIntoType("test", `i31ref`), TypeError, /can only pass/); 193 assertErrorMessage(() => importValueIntoType(struct.value, `i31ref`), TypeError, /can only pass/); 194 195 importValueIntoType(null, `eqref`); 196 assertErrorMessage(() => importValueIntoType(null, `(ref eq)`), TypeError, /cannot pass null/); 197 assertErrorMessage(() => importValueIntoType(undefined, `(ref eq)`), TypeError, /can only pass/); 198 importValueIntoType(0, `eqref`); 199 assertErrorMessage(() => importValueIntoType(0.1, `eqref`), TypeError, /can only pass/); 200 assertErrorMessage(() => importValueIntoType((x)=>x, `eqref`), TypeError, /can only pass/); 201 assertErrorMessage(() => importValueIntoType("test", `eqref`), TypeError, /can only pass/); 202 importValueIntoType(struct.value, `eqref`); 203 assertErrorMessage(() => importValueIntoType(func.value, `eqref`), TypeError, /can only pass/); 204 205 importValueIntoType(null, `anyref`); 206 assertErrorMessage(() => importValueIntoType(null, `(ref any)`), TypeError, /cannot pass null/); 207 importValueIntoType(undefined, `(ref any)`); 208 importValueIntoType(0, `anyref`); 209 importValueIntoType(0.1, `anyref`); 210 importValueIntoType((x)=>x, `anyref`) 211 importValueIntoType("test", `anyref`); 212 importValueIntoType(struct.value, `anyref`); 213 importValueIntoType(func.value, `anyref`); 214 215 importValueIntoType(null, `externref`); 216 assertErrorMessage(() => importValueIntoType(null, `(ref extern)`), TypeError, /cannot pass null/); 217 importValueIntoType(undefined, `(ref extern)`); 218 importValueIntoType(0, `externref`); 219 importValueIntoType(0.1, `externref`); 220 importValueIntoType((x)=>x, `externref`) 221 importValueIntoType("test", `externref`); 222 importValueIntoType(struct.value, `externref`); 223 importValueIntoType(func.value, `externref`); 224 225 importValueIntoType(null, `funcref`); 226 assertErrorMessage(() => importValueIntoType(null, `(ref func)`), TypeError, /cannot pass null/); 227 assertErrorMessage(() => importValueIntoType(0, `funcref`), TypeError, /can only pass/); 228 assertErrorMessage(() => importValueIntoType((x)=>x, `funcref`), TypeError, /can only pass/); 229 importValueIntoType(func.value, `funcref`) 230 importValueIntoType(func.value, `(ref func)`) 231 }