summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/simd/js-api.js
blob: b0db13b1280053f36743ce57ff83630df5ffba47 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// |jit-test| test-also=--no-threads; skip-if: !wasmSimdEnabled()

// SIMD JS API
//
// As of 31 March 2020 the SIMD spec is very light on information about the JS
// API, and what it has is ridden with misspellings, grammatical errors, and
// apparent redundancies.  The rules below represent my best effort at
// understanding the intent of the spec.  As far as I can tell, the rules for
// v128 are intended to match the rules for i64 in the Wasm MVP.

// Hopefully, these are enough to test that various JIT stubs are generated and
// used if we run the tests in a loop.

setJitCompilerOption("baseline.warmup.trigger", 2);
setJitCompilerOption("ion.warmup.trigger", 4);

// RULE: v128 cannot cross the JS/wasm boundary as a function parameter.
//
// A wasm function that:
//  - takes or returns v128
//  - was imported into wasm
//  - is ultimately a JS function
// should always throw TypeError when called from wasm.
//
// Note, JIT exit stubs should be generated here because settings above should
// cause the JIT to tier up.

var ins = wasmEvalText(`
  (module
    (import "m" "v128_param" (func $f (param v128)))
    (import "m" "v128_return" (func $g (result v128)))
    (func (export "v128_param")
      (call $f (v128.const i32x4 0 0 0 0)))
    (func (export "v128_result")
      (drop (call $g))))`,
                       {m:{v128_param: (x) => 0,
                           v128_return: () => 0}});

function call_v128_param() { ins.exports.v128_param(); }
function call_v128_result() { ins.exports.v128_result(); }

for ( let i = 0 ; i < 100; i++ ) {
    assertErrorMessage(call_v128_param,
                       TypeError,
                       /cannot pass.*v128.*to or from JS/);
    assertErrorMessage(call_v128_result,
                       TypeError,
                       /cannot pass.*v128.*to or from JS/);
}

// RULE: v128 cannot cross the JS/wasm boundary as a function parameter.
//
// A wasm function that:
//  - takes or returns v128
//  - is exported from wasm
//  - is ultimately a true wasm function
// should always throw TypeError when called from JS.
//
// Note, JIT entry stubs should be generated here because settings above should
// cause the JIT to tier up.

var ins2 = wasmEvalText(`
  (module
    (func (export "v128_param") (param v128) (result i32)
      (i32.const 0))
    (func (export "v128_result") (result v128)
      (v128.const i32x4 0 0 0 0)))`);

function call_v128_param2() { ins2.exports.v128_param(); }
function call_v128_result2() { ins2.exports.v128_result(); }

for ( let i = 0 ; i < 100; i++ ) {
    assertErrorMessage(call_v128_param2,
                       TypeError,
                       /cannot pass.*v128.*to or from JS/);
    assertErrorMessage(call_v128_result2,
                       TypeError,
                       /cannot pass.*v128.*to or from JS/);
}

// RULE: The rules about v128 passing into or out of a function apply even when
// an imported JS function is re-exported and is then called.

var newfn = (x) => x;
var ins = wasmEvalText(`
  (module
    (import "m" "fn" (func $f (param v128) (result v128)))
    (export "newfn" (func $f)))`,
                                   {m:{fn: newfn}});
assertErrorMessage(() => ins.exports.newfn(3),
                   TypeError,
                   /cannot pass.*v128.*to or from JS/);

// RULE: WebAssembly.Global of type v128 is constructable from JS with a default
// value.

var gi = new WebAssembly.Global({value: "v128"});
var gm = new WebAssembly.Global({value: "v128", mutable:true});

// RULE: WebAssembly.Global constructor for type v128 does not accept any value
// but throws TypeError.

assertErrorMessage(() => new WebAssembly.Global({value: "v128"}, 37),
                   TypeError,
                   /cannot pass.*v128.*to or from JS/);

// RULE: WebAssembly.Global of type v128 have getters and setters that throw
// TypeError when called from JS.

assertErrorMessage(() => gi.value,
                   TypeError,
                   /cannot pass.*v128.*to or from JS/);
assertErrorMessage(() => gi.valueOf(),
                   TypeError,
                   /cannot pass.*v128.*to or from JS/);
assertErrorMessage(() => gm.value = 0,
                   TypeError,
                   /cannot pass.*v128.*to or from JS/);