WebAssembly JS API: check and test in-call / out-call values
[WebKit-https.git] / JSTests / wasm / js-api / export-arity.js
1 import * as assert from '../assert.js';
2 import Builder from '../Builder.js';
3
4 // Generate wasm export functions of arity [0, max), and call each of these
5 // export functions from JS with [0, max) parameters, for each valid WebAssembly
6 // type. Make sure this number is high enough to force non-register calls.
7 const maxArities = 64;
8
9 const paramExporter = (numParams, paramType, imports) => {
10     let builder = (new Builder())
11         .Type().End()
12         .Import()
13             .Function("imp", "check", { params: [paramType] })
14         .End()
15         .Function().End()
16         .Export()
17             .Function("func")
18         .End()
19         .Code()
20           .Function("func", { params: Array(numParams).fill(paramType) });
21     for (let i = 0; i < numParams; ++i)
22         builder = builder.GetLocal(i).Call(0); // Call the import for each received parameter.
23     builder = builder.Return().End().End();
24     const bin = builder.WebAssembly().get();
25     const module = new WebAssembly.Module(bin);
26     return new WebAssembly.Instance(module, { imp: imports });
27 };
28
29 const types = [
30     { type: "i32", value: 42, defaultWhenArityMismatch: 0 },
31     // i64 isn't supported.
32     { type: "f32", value: 32.0, defaultWhenArityMismatch: NaN },
33     { type: "f64", value: 64.0, defaultWhenArityMismatch: NaN },
34 ];
35
36 for (let type of types) {
37     for (let wasmArity = 0; wasmArity < maxArities; ++wasmArity) {
38         let numParamsCallingWith = undefined;
39         let numChecked = 0;
40         const check = value => {
41             assert.isNumber(value);
42             if (numParamsCallingWith <= wasmArity) {
43                 if (numChecked < numParamsCallingWith)
44                     assert.eq(value, type.value);
45                 else
46                     assert.eq(value, type.defaultWhenArityMismatch);
47             }  else {
48                 if (numChecked < wasmArity)
49                     assert.eq(value, type.value);
50                 else
51                     assert.eq(value, type.defaultWhenArityMismatch);
52             }
53             ++numChecked;
54         };
55         const instance = paramExporter(wasmArity, type.type, { check: check });
56         for (let callerArity = 0; callerArity < maxArities; ++callerArity) {
57             numParamsCallingWith = callerArity;
58             const params = Array(callerArity).fill(type.value);
59             const result = instance.exports.func(...params);
60             assert.isUndef(result);
61             assert.eq(numChecked, wasmArity); // check() should be called as many times as the wasm function's arity.
62             numChecked = 0; // Reset the check counter for each arity iteration.
63         }
64     }
65 }