tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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/);