js-api.js (4662B)
1 // |jit-test| test-also=--no-threads; skip-if: !wasmSimdEnabled() 2 3 // SIMD JS API 4 // 5 // As of 31 March 2020 the SIMD spec is very light on information about the JS 6 // API, and what it has is ridden with misspellings, grammatical errors, and 7 // apparent redundancies. The rules below represent my best effort at 8 // understanding the intent of the spec. As far as I can tell, the rules for 9 // v128 are intended to match the rules for i64 in the Wasm MVP. 10 11 // Hopefully, these are enough to test that various JIT stubs are generated and 12 // used if we run the tests in a loop. 13 14 setJitCompilerOption("baseline.warmup.trigger", 2); 15 setJitCompilerOption("ion.warmup.trigger", 4); 16 17 // RULE: v128 cannot cross the JS/wasm boundary as a function parameter. 18 // 19 // A wasm function that: 20 // - takes or returns v128 21 // - was imported into wasm 22 // - is ultimately a JS function 23 // should always throw TypeError when called from wasm. 24 // 25 // Note, JIT exit stubs should be generated here because settings above should 26 // cause the JIT to tier up. 27 28 var ins = wasmEvalText(` 29 (module 30 (import "m" "v128_param" (func $f (param v128))) 31 (import "m" "v128_return" (func $g (result v128))) 32 (func (export "v128_param") 33 (call $f (v128.const i32x4 0 0 0 0))) 34 (func (export "v128_result") 35 (drop (call $g))))`, 36 {m:{v128_param: (x) => 0, 37 v128_return: () => 0}}); 38 39 function call_v128_param() { ins.exports.v128_param(); } 40 function call_v128_result() { ins.exports.v128_result(); } 41 42 for ( let i = 0 ; i < 100; i++ ) { 43 assertErrorMessage(call_v128_param, 44 TypeError, 45 /cannot pass.*value.*to or from JS/); 46 assertErrorMessage(call_v128_result, 47 TypeError, 48 /cannot pass.*value.*to or from JS/); 49 } 50 51 // RULE: v128 cannot cross the JS/wasm boundary as a function parameter. 52 // 53 // A wasm function that: 54 // - takes or returns v128 55 // - is exported from wasm 56 // - is ultimately a true wasm function 57 // should always throw TypeError when called from JS. 58 // 59 // Note, JIT entry stubs should be generated here because settings above should 60 // cause the JIT to tier up. 61 62 var ins2 = wasmEvalText(` 63 (module 64 (func (export "v128_param") (param v128) (result i32) 65 (i32.const 0)) 66 (func (export "v128_result") (result v128) 67 (v128.const i32x4 0 0 0 0)))`); 68 69 function call_v128_param2() { ins2.exports.v128_param(); } 70 function call_v128_result2() { ins2.exports.v128_result(); } 71 72 for ( let i = 0 ; i < 100; i++ ) { 73 assertErrorMessage(call_v128_param2, 74 TypeError, 75 /cannot pass.*value.*to or from JS/); 76 assertErrorMessage(call_v128_result2, 77 TypeError, 78 /cannot pass.*value.*to or from JS/); 79 } 80 81 // RULE: The rules about v128 passing into or out of a function apply even when 82 // an imported JS function is re-exported and is then called. 83 84 var newfn = (x) => x; 85 var ins = wasmEvalText(` 86 (module 87 (import "m" "fn" (func $f (param v128) (result v128))) 88 (export "newfn" (func $f)))`, 89 {m:{fn: newfn}}); 90 assertErrorMessage(() => ins.exports.newfn(3), 91 TypeError, 92 /cannot pass.*value.*to or from JS/); 93 94 // RULE: WebAssembly.Global of type v128 is constructable from JS with a default 95 // value. 96 97 98 // RULE: WebAssembly.Global constructor for type v128 is not constructable with 99 // or without a default value. 100 101 assertErrorMessage(() => new WebAssembly.Global({value: "v128"}, 37), 102 TypeError, 103 /cannot pass.*value.*to or from JS/); 104 assertErrorMessage(() => new WebAssembly.Global({value: "v128"}), 105 TypeError, 106 /cannot pass.*value.*to or from JS/); 107 assertErrorMessage(() => new WebAssembly.Global({value: "v128", mutable: true}), 108 TypeError, 109 /cannot pass.*value.*to or from JS/); 110 111 // RULE: WebAssembly.Global of type v128 have getters and setters that throw 112 // TypeError when called from JS. 113 114 let {gi, gm} = wasmEvalText(` 115 (module 116 (global (export "gi") v128 v128.const i64x2 0 0) 117 (global (export "gm") (mut v128) v128.const i64x2 0 0) 118 )`).exports; 119 120 assertErrorMessage(() => gi.value, 121 TypeError, 122 /cannot pass.*value.*to or from JS/); 123 assertErrorMessage(() => gi.valueOf(), 124 TypeError, 125 /cannot pass.*value.*to or from JS/); 126 assertErrorMessage(() => gm.value = 0, 127 TypeError, 128 /cannot pass.*value.*to or from JS/);