js-boundary.js (4162B)
1 // Tests of dynamic type checks 2 test('anyref', WasmAnyrefValues, []); 3 test('eqref', WasmEqrefValues, WasmNonAnyrefValues); 4 test('structref', WasmStructrefValues, WasmNonAnyrefValues); 5 test('arrayref', WasmArrayrefValues, WasmNonAnyrefValues); 6 let { makeStruct } = wasmEvalText(` 7 (module 8 (type $s (struct)) 9 (func (export "makeStruct") (result anyref) 10 struct.new $s) 11 )`).exports; 12 test('(ref null 0)', [makeStruct()], WasmNonAnyrefValues, '(type (struct))'); 13 test('nullref', [null], WasmNonAnyrefValues); 14 15 function test(type, validValues, invalidValues, typeSection = "") { 16 const CheckError = /can only pass|bad type/; 17 18 // 1. Exported function params 19 let {a} = wasmEvalText(`(module 20 ${typeSection} 21 (func (export "a") (param ${type})) 22 )`).exports; 23 for (let val of invalidValues) { 24 assertErrorMessage(() => a(val), TypeError, CheckError); 25 } 26 for (let val of validValues) { 27 a(val); 28 } 29 30 // 2. Imported function results 31 for (let val of invalidValues) { 32 function returnVal() { 33 return val; 34 } 35 let {test} = wasmEvalText(`(module 36 ${typeSection} 37 (func $returnVal (import "" "returnVal") (result ${type})) 38 (func (export "test") 39 call $returnVal 40 drop 41 ) 42 )`, {"": {returnVal}}).exports; 43 assertErrorMessage(() => test(), TypeError, CheckError); 44 } 45 for (let val of validValues) { 46 function returnVal() { 47 return val; 48 } 49 let {test} = wasmEvalText(`(module 50 ${typeSection} 51 (func $returnVal (import "" "returnVal") (result ${type})) 52 (func (export "test") 53 call $returnVal 54 drop 55 ) 56 )`, {"": {returnVal}}).exports; 57 test(val); 58 } 59 60 // TODO: the rest of the tests cannot handle type sections yet. 61 if (typeSection !== "") { 62 return; 63 } 64 65 // 3. Global value setter 66 for (let val of validValues) { 67 // Construct global from JS-API with initial value 68 let a = new WebAssembly.Global({value: type}, val); 69 assertEq(a.value, val, 'roundtrip matches'); 70 71 // Construct global from JS-API with null value, then set 72 let b = new WebAssembly.Global({value: type, mutable: true}, null); 73 b.value = val; 74 assertEq(b.value, val, 'roundtrip matches'); 75 } 76 for (let val of invalidValues) { 77 // Construct global from JS-API with initial value 78 assertErrorMessage(() => new WebAssembly.Global({value: type}, val), 79 TypeError, 80 CheckError); 81 82 // Construct global from JS-API with null value, then set 83 let a = new WebAssembly.Global({value: type, mutable: true}, null); 84 assertErrorMessage(() => a.value = val, 85 TypeError, 86 CheckError); 87 } 88 89 // 4. Table set method 90 for (let val of validValues) { 91 let table = new WebAssembly.Table({element: type, initial: 1, maximum: 1}); 92 table.set(0, val); 93 assertEq(table.get(0), val, 'roundtrip matches'); 94 } 95 for (let val of invalidValues) { 96 let table = new WebAssembly.Table({element: type, initial: 1, maximum: 1}); 97 assertErrorMessage(() => table.set(0, val), 98 TypeError, 99 CheckError); 100 } 101 } 102 103 // Verify that GC objects are opaque 104 for (const val of WasmGcObjectValues) { 105 assertEq(Reflect.getPrototypeOf(val), null); 106 assertEq(Reflect.setPrototypeOf(val, null), true); 107 assertEq(Reflect.setPrototypeOf(val, {}), false); 108 assertEq(Reflect.isExtensible(val), false); 109 assertEq(Reflect.preventExtensions(val), false); 110 assertEq(Reflect.getOwnPropertyDescriptor(val, "anything"), undefined); 111 assertEq(Reflect.defineProperty(val, "anything", { value: 42 }), false); 112 assertEq(Reflect.has(val, "anything"), false); 113 assertEq(Reflect.get(val, "anything"), undefined); 114 assertErrorMessage(() => { Reflect.set(val, "anything", 3); }, TypeError, /can't modify/); 115 assertErrorMessage(() => { Reflect.deleteProperty(val, "anything"); }, TypeError, /can't modify/); 116 assertEq(Reflect.ownKeys(val).length, 0, `gc objects should not have keys, but this one had: ${Reflect.ownKeys(val)}`); 117 for (const i in val) { 118 throw new Error(`GC objects should have no enumerable properties, but had ${i}`); 119 } 120 assertEq(val[Symbol.iterator], undefined, "GC objects should not be iterable"); 121 }