non-nullable-table.js (3243B)
1 // non-null table initialization 2 var { get1, get2, get3, get4 } = wasmEvalText(`(module 3 (type $dummy (func)) 4 (func $dummy) 5 6 (table $t1 10 funcref) 7 (table $t2 10 funcref (ref.func $dummy)) 8 (table $t3 10 (ref $dummy) (ref.func $dummy)) 9 (table $t4 10 (ref func) (ref.func $dummy)) 10 11 (func (export "get1") (result funcref) (table.get $t1 (i32.const 1))) 12 (func (export "get2") (result funcref) (table.get $t2 (i32.const 4))) 13 (func (export "get3") (result funcref) (table.get $t3 (i32.const 7))) 14 (func (export "get4") (result funcref) (table.get $t4 (i32.const 5))) 15 )`).exports; 16 assertEq(get1(), null); 17 assertEq(get2() != null, true); 18 assertEq(get3() != null, true); 19 assertEq(get4() != null, true); 20 21 const sampleWasmFunction = get2(); 22 sampleWasmFunction(); 23 24 // Invalid initializers 25 for (let i of [ 26 `(table $t1 10 (ref $dummy) (ref.func $dummy1))`, 27 `(table $t2 5 10 (ref func))`, 28 `(table $t3 10 10 (ref func) (ref.null $dummy1))`, 29 `(table $t4 10 (ref $dummy))`, 30 '(table $t5 1 (ref $dummy) (ref.null $dummy))', 31 ]) { 32 wasmFailValidateText(`(module 33 (type $dummy (func)) 34 (type $dummy1 (func (param i32))) 35 (func $dummy1 (param i32)) 36 37 ${i} 38 )`, /(type mismatch|table with non-nullable references requires initializer)/); 39 } 40 41 let { t1, t2 } = new wasmEvalText(`(module 42 (func $dummy) 43 (table (export "t1") 10 funcref (ref.func $dummy)) 44 (table (export "t2") 10 (ref func) (ref.func $dummy)) 45 )`).exports; 46 assertEq(t1.get(2) != null, true); 47 48 // Imported tables require strict equality of their reference types. 49 wasmEvalText(`(module 50 (import "" "t1" (table 10 funcref)) 51 (import "" "t2" (table 10 (ref func))) 52 )`, { "": { t1, t2 } }); 53 assertErrorMessage( 54 () => wasmEvalText(`(module (import "" "t1" (table 10 (ref func))))`, { "": { t1 } }), 55 WebAssembly.LinkError, /imported table type mismatch/, 56 ); 57 assertErrorMessage( 58 () => wasmEvalText(`(module (import "" "t2" (table 10 funcref)))`, { "": { t2 } }), 59 WebAssembly.LinkError, /imported table type mismatch/, 60 ); 61 62 // Tables with non-nullable types require init expressions, but only if they 63 // are defined in the module. 64 wasmFailValidateText(`(module 65 (table $t 10 (ref func)) 66 )`, /table with non-nullable references requires initializer/); 67 wasmValidateText(`(module 68 (import "" "t1" (table 10 (ref func))) 69 )`); 70 71 wasmFailValidateText(` 72 (module 73 (func $dummy) 74 (table (export "t") 10 funcref (ref.null none)) 75 )`, /type mismatch/); 76 77 const foo = "bar"; 78 const { t3 } = wasmEvalText(` 79 (module 80 (global (import "" "foo") externref) 81 (table (export "t3") 6 20 externref (global.get 0)) 82 )`, { "": { "foo": foo } }).exports; 83 84 assertEq(t3.get(5), "bar"); 85 assertThrows(() => { t3.get(7) }); 86 assertThrows(() => { t3.grow(30, null) }); 87 t3.grow(8, {t: "test"}); 88 assertEq(t3.get(3), "bar"); 89 assertEq(t3.get(7).t, "test"); 90 91 // Fail because tables come before globals in the binary format, so tables 92 // cannot refer to globals. 93 wasmFailValidateText(`(module 94 (global $g1 externref) 95 (table 10 externref (global.get $g1)) 96 )`, /global.get index out of range/); 97 98 function assertThrows(f) { 99 var ok = false; 100 try { 101 f(); 102 } catch (exc) { 103 ok = true; 104 } 105 if (!ok) 106 throw new TypeError("Assertion failed: " + f + " did not throw as expected"); 107 }