Commit 79a14688 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by Commit Bot

[wasm][wasm-gc][test] Improve and extend Javascript testing API

Changes:
- Add possibility to define and emit all reference types.
- Simplify function locals definition.
- Change 'type' to 'type_index' where appropiate.

Bug: v8:7748
Change-Id: Ie35a6204369e678298ee2ff2ec7c7793c5315c3e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2390144
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69814}
parent ff0c5cfa
...@@ -12,7 +12,7 @@ var builder = new WasmModuleBuilder(); ...@@ -12,7 +12,7 @@ var builder = new WasmModuleBuilder();
// clang-format off // clang-format off
var func_idx = builder.addFunction('helper', kSig_v_v) var func_idx = builder.addFunction('helper', kSig_v_v)
.addLocals({ i32_count: 1 }) .addLocals(kWasmI32, 1 )
.addBody([ .addBody([
kExprNop, kExprNop,
kExprI32Const, 12, kExprI32Const, 12,
......
...@@ -80,10 +80,9 @@ async function instantiateWasm() { ...@@ -80,10 +80,9 @@ async function instantiateWasm() {
]) ])
.exportAs('main'); .exportAs('main');
builder.addFunction('B (liftoff)', kSig_v_i) builder.addFunction('B (liftoff)', kSig_v_i, ['i32_arg'])
.addLocals( .addLocals(kWasmI32, 1, ['i32_local'])
{i32_count: 1, f32_count: 4}, .addLocals(kWasmF32, 4, ['f32_local', '0', '0'])
['i32_arg', 'i32_local', 'f32_local', '0', '0'])
.addBody([ .addBody([
// Load a parameter and a constant onto the operand stack. // Load a parameter and a constant onto the operand stack.
kExprLocalGet, 0, kExprI32Const, 3, kExprLocalGet, 0, kExprI32Const, 3,
...@@ -96,8 +95,8 @@ async function instantiateWasm() { ...@@ -96,8 +95,8 @@ async function instantiateWasm() {
]); ]);
// A third function which will be stepped through. // A third function which will be stepped through.
let func = builder.addFunction('C (interpreted)', kSig_v_i) let func = builder.addFunction('C (interpreted)', kSig_v_i, ['i32_arg'])
.addLocals({i32_count: 1}, ['i32_arg', 'i32_local']) .addLocals(kWasmI32, 1, ['i32_local'])
.addBody([ .addBody([
// Set global 0 to param 0. // Set global 0 to param 0.
kExprLocalGet, 0, kExprGlobalSet, 0, kExprLocalGet, 0, kExprGlobalSet, 0,
......
...@@ -74,36 +74,37 @@ async function instantiateWasm() { ...@@ -74,36 +74,37 @@ async function instantiateWasm() {
// Add a function without breakpoint, to check that locals are shown // Add a function without breakpoint, to check that locals are shown
// correctly in compiled code. // correctly in compiled code.
const main = builder.addFunction('call_func', kSig_v_i).addLocals({f32_count: 1}).addBody([ const main = builder.addFunction('call_func', kSig_v_i).addLocals(kWasmF32, 1)
// Set local 1 to 7.2. .addBody([
...wasmF32Const(7.2), kExprLocalSet, 1, // Set local 1 to 7.2.
// Call function 'func', forwarding param 0. ...wasmF32Const(7.2), kExprLocalSet, 1,
kExprLocalGet, 0, kExprCallFunction, 1 // Call function 'func', forwarding param 0.
]).exportAs('main'); kExprLocalGet, 0, kExprCallFunction, 1
]).exportAs('main');
// A second function which will be stepped through. // A second function which will be stepped through.
const func = builder.addFunction('func', kSig_v_i) const func = builder.addFunction('func', kSig_v_i, ['i32Arg'])
.addLocals( .addLocals(kWasmI32, 1)
{i32_count: 1, i64_count: 1, f64_count: 3}, .addLocals(kWasmI64, 1, ['i64_local'])
['i32Arg', undefined, 'i64_local', 'unicode☼f64', '0', '0']) .addLocals(kWasmF64, 3, ['unicode☼f64', '0', '0'])
.addBody([ .addBody([
// Set param 0 to 11. // Set param 0 to 11.
kExprI32Const, 11, kExprLocalSet, 0, kExprI32Const, 11, kExprLocalSet, 0,
// Set local 1 to 47. // Set local 1 to 47.
kExprI32Const, 47, kExprLocalSet, 1, kExprI32Const, 47, kExprLocalSet, 1,
// Set local 2 to 0x7FFFFFFFFFFFFFFF (max i64). // Set local 2 to 0x7FFFFFFFFFFFFFFF (max i64).
kExprI64Const, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, kExprI64Const, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0,
kExprLocalSet, 2, kExprLocalSet, 2,
// Set local 2 to 0x8000000000000000 (min i64). // Set local 2 to 0x8000000000000000 (min i64).
kExprI64Const, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, kExprI64Const, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f,
kExprLocalSet, 2, kExprLocalSet, 2,
// Set local 3 to 1/7. // Set local 3 to 1/7.
kExprI32Const, 1, kExprF64UConvertI32, kExprI32Const, 7, kExprI32Const, 1, kExprF64UConvertI32, kExprI32Const, 7,
kExprF64UConvertI32, kExprF64Div, kExprLocalSet, 3, kExprF64UConvertI32, kExprF64Div, kExprLocalSet, 3,
// Set global 0 to 15 // Set global 0 to 15
kExprI32Const, 15, kExprGlobalSet, 0, kExprI32Const, 15, kExprGlobalSet, 0,
]); ]);
// Append function to table to test function table output. // Append function to table to test function table output.
builder.appendToTable([main.index]); builder.appendToTable([main.index]);
...@@ -114,8 +115,10 @@ async function instantiateWasm() { ...@@ -114,8 +115,10 @@ async function instantiateWasm() {
function addWasmJSToTable() { function addWasmJSToTable() {
// Create WasmJS functions to test the function tables output. // Create WasmJS functions to test the function tables output.
const js_func = function js_func() { return 7; }; const js_func = function js_func() { return 7; };
const wasmjs_func = new WebAssembly.Function({parameters:[], results:['i32']}, js_func); const wasmjs_func = new WebAssembly.Function(
const wasmjs_anonymous_func = new WebAssembly.Function({parameters:[], results:['i32']}, _ => 7); {parameters:[], results:['i32']}, js_func);
const wasmjs_anonymous_func = new WebAssembly.Function(
{parameters:[], results:['i32']}, _ => 7);
instance.exports.exported_table.set(0, wasmjs_func); instance.exports.exported_table.set(0, wasmjs_func);
instance.exports.exported_table.set(1, wasmjs_anonymous_func); instance.exports.exported_table.set(1, wasmjs_anonymous_func);
...@@ -123,7 +126,8 @@ async function instantiateWasm() { ...@@ -123,7 +126,8 @@ async function instantiateWasm() {
InspectorTest.log('Calling instantiate function.'); InspectorTest.log('Calling instantiate function.');
await WasmInspectorTest.instantiate(moduleBytes); await WasmInspectorTest.instantiate(moduleBytes);
await WasmInspectorTest.evalWithUrl(`(${addWasmJSToTable})()`, 'populateTable'); await WasmInspectorTest.evalWithUrl(`(${addWasmJSToTable})()`,
'populateTable');
} }
function printIfFailure(message) { function printIfFailure(message) {
......
...@@ -11,7 +11,7 @@ var builder = new WasmModuleBuilder(); ...@@ -11,7 +11,7 @@ var builder = new WasmModuleBuilder();
// clang-format off // clang-format off
var func_idx = builder.addFunction('helper', kSig_v_v) var func_idx = builder.addFunction('helper', kSig_v_v)
.addLocals({ i32_count: 1 }) .addLocals(kWasmI32, 1)
.addBody([ .addBody([
kExprNop, kExprNop,
kExprI32Const, 12, kExprI32Const, 12,
......
...@@ -11,9 +11,8 @@ session.setupScriptMap(); ...@@ -11,9 +11,8 @@ session.setupScriptMap();
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
// Create a function which computes the div of the first two arguments. // Create a function which computes the div of the first two arguments.
builder.addFunction('div', kSig_i_iii) builder.addFunction('div', kSig_i_iii, ['a', 'b', 'unused'])
.addLocals( .addLocals(kWasmI32, 2, ['local_zero', 'local_const_11'])
{i32_count: 2}, ['a', 'b', 'unused', 'local_zero', 'local_const_11'])
.addBody([ .addBody([
kExprI32Const, 11, // const 11 kExprI32Const, 11, // const 11
kExprLocalSet, 4, // set local #4 ('local_const_11') kExprLocalSet, 4, // set local #4 ('local_const_11')
......
...@@ -34,7 +34,7 @@ var func_b = builder.addFunction('wasm_B', kSig_v_i) ...@@ -34,7 +34,7 @@ var func_b = builder.addFunction('wasm_B', kSig_v_i)
.exportAs('main'); .exportAs('main');
let fact = builder.addFunction('fact', kSig_i_i) let fact = builder.addFunction('fact', kSig_i_i)
.addLocals({i32_count: 1}) .addLocals(kWasmI32, 1)
.addBody([ .addBody([
// clang-format off // clang-format off
kExprLocalGet, 0, kExprLocalGet, 0,
......
...@@ -15,7 +15,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -15,7 +15,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
kExprI32Add, kExprI32Add,
]).exportFunc(); ]).exportFunc();
builder.addFunction("main", kSig_i_i) builder.addFunction("main", kSig_i_i)
.addLocals({except_count: 1}) .addLocals(kWasmExnRef, 1)
.addBody([ .addBody([
kExprTry, kWasmStmt, kExprTry, kWasmStmt,
kExprLocalGet, 0, kExprLocalGet, 0,
......
...@@ -6,9 +6,9 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -6,9 +6,9 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_i_iii) builder.addFunction('main', kSig_i_iii)
.addLocals({f32_count: 4}) .addLocals(kWasmF32, 4)
.addLocals({i64_count: 1}) .addLocals(kWasmI64, 1)
.addLocals({f32_count: 2}) .addLocals(kWasmF32, 2)
.addBodyWithEnd([ .addBodyWithEnd([
kExprI64Const, 0, kExprI64Const, 0,
kExprLocalGet, 3, kExprLocalGet, 3,
......
...@@ -19,7 +19,7 @@ kExprEnd, // @5 ...@@ -19,7 +19,7 @@ kExprEnd, // @5
]); ]);
// Generate function 2 (out of 2). // Generate function 2 (out of 2).
builder.addFunction(undefined, 1 /* sig */) builder.addFunction(undefined, 1 /* sig */)
.addLocals({f32_count: 1}).addLocals({i32_count: 13}) .addLocals(kWasmF32, 1).addLocals(kWasmI32, 13)
.addBodyWithEnd([ .addBodyWithEnd([
// signature: v_v // signature: v_v
// body: // body:
......
...@@ -18,7 +18,7 @@ kExprEnd, // @3 ...@@ -18,7 +18,7 @@ kExprEnd, // @3
]); ]);
// Generate function 2 (out of 2). // Generate function 2 (out of 2).
builder.addFunction(undefined, 1 /* sig */) builder.addFunction(undefined, 1 /* sig */)
.addLocals({f64_count: 8}) .addLocals(kWasmF64, 8)
.addBodyWithEnd([ .addBodyWithEnd([
// signature: d_v // signature: d_v
// body: // body:
......
...@@ -10,7 +10,7 @@ const builder = new WasmModuleBuilder(); ...@@ -10,7 +10,7 @@ const builder = new WasmModuleBuilder();
builder.addType(makeSig([kWasmI32, kWasmI32, kWasmI32], [kWasmI32])); builder.addType(makeSig([kWasmI32, kWasmI32, kWasmI32], [kWasmI32]));
// Generate function 1 (out of 1). // Generate function 1 (out of 1).
builder.addFunction(undefined, 0 /* sig */) builder.addFunction(undefined, 0 /* sig */)
.addLocals({i32_count: 2}).addLocals({f32_count: 2}) .addLocals(kWasmI32, 2).addLocals(kWasmF32, 2)
.addBodyWithEnd([ .addBodyWithEnd([
// signature: i_iii // signature: i_iii
// body: // body:
......
...@@ -12,7 +12,7 @@ builder.addGlobal(kWasmI32, 1); ...@@ -12,7 +12,7 @@ builder.addGlobal(kWasmI32, 1);
const sig = builder.addType(makeSig([kWasmI32, kWasmI64, kWasmI64, kWasmI64], [kWasmF32])); const sig = builder.addType(makeSig([kWasmI32, kWasmI64, kWasmI64, kWasmI64], [kWasmF32]));
// Generate function 1 (out of 3). // Generate function 1 (out of 3).
builder.addFunction(undefined, sig) builder.addFunction(undefined, sig)
.addLocals({i32_count: 57}).addLocals({i64_count: 11}) .addLocals(kWasmI32, 57).addLocals(kWasmI64, 11)
.addBodyWithEnd([ .addBodyWithEnd([
// signature: f_illl // signature: f_illl
// body: // body:
......
...@@ -11,7 +11,7 @@ builder.addMemory(1, 1, false, true); ...@@ -11,7 +11,7 @@ builder.addMemory(1, 1, false, true);
const sig = builder.addType(makeSig([], [kWasmI32])); const sig = builder.addType(makeSig([], [kWasmI32]));
builder.addFunction(undefined, sig) builder.addFunction(undefined, sig)
.addLocals({i32_count: 1002}).addLocals({i64_count: 3}) .addLocals(kWasmI32, 1002).addLocals(kWasmI64, 3)
.addBodyWithEnd([ .addBodyWithEnd([
// signature: i_v // signature: i_v
// body: // body:
......
...@@ -16,10 +16,10 @@ const sig = builder.addType(makeSig( ...@@ -16,10 +16,10 @@ const sig = builder.addType(makeSig(
[kWasmI64])); [kWasmI64]));
// Generate function 2 (out of 3). // Generate function 2 (out of 3).
builder.addFunction(undefined, sig) builder.addFunction(undefined, sig)
.addLocals({f32_count: 10}) .addLocals(kWasmF32, 10)
.addLocals({i32_count: 4}) .addLocals(kWasmI32, 4)
.addLocals({f64_count: 1}) .addLocals(kWasmF64, 1)
.addLocals({i32_count: 15}) .addLocals(kWasmI32, 15)
.addBodyWithEnd([ .addBodyWithEnd([
// signature: v_liliiiiiilll // signature: v_liliiiiiilll
// body: // body:
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
load('test/mjsunit/wasm/wasm-module-builder.js'); load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
builder.addFunction(undefined, kSig_v_v).addLocals({i64_count: 1}).addBody([ builder.addFunction(undefined, kSig_v_v).addLocals(kWasmI64, 1).addBody([
kExprI64Const, 0xeb, 0xd7, 0xaf, 0xdf, kExprI64Const, 0xeb, 0xd7, 0xaf, 0xdf,
0xbe, 0xfd, 0xfa, 0xf5, 0x6b, // i64.const 0xbe, 0xfd, 0xfa, 0xf5, 0x6b, // i64.const
kExprI32Const, 0, // i32.const kExprI32Const, 0, // i32.const
......
...@@ -6,7 +6,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -6,7 +6,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
sig0 = makeSig([], [kWasmI32]); sig0 = makeSig([], [kWasmI32]);
builder.addFunction(undefined, sig0).addLocals({i64_count: 1}).addBody([ builder.addFunction(undefined, sig0).addLocals(kWasmI64, 1).addBody([
kExprLoop, kWasmI32, // loop i32 kExprLoop, kWasmI32, // loop i32
kExprF32Const, 0x00, 0x00, 0x00, 0x00, // f32.const 0 --> f32:0 kExprF32Const, 0x00, 0x00, 0x00, 0x00, // f32.const 0 --> f32:0
kExprLocalGet, 0x00, // get_local 0 --> i64:0 kExprLocalGet, 0x00, // get_local 0 --> i64:0
......
...@@ -49,7 +49,7 @@ assertEquals(1, instance.exports.main()); ...@@ -49,7 +49,7 @@ assertEquals(1, instance.exports.main());
const builder2 = new WasmModuleBuilder(); const builder2 = new WasmModuleBuilder();
sig0 = makeSig([], [kWasmI32]); sig0 = makeSig([], [kWasmI32]);
builder2.addFunction(undefined, sig0).addLocals({i64_count: 1}).addBody([ builder2.addFunction(undefined, sig0).addLocals(kWasmI64, 1).addBody([
kExprLoop, kWasmI32, // loop i32 kExprLoop, kWasmI32, // loop i32
kExprLocalGet, 0, // get_local 3 kExprLocalGet, 0, // get_local 3
kExprF32SConvertI64, // f32.sconvert/i64 kExprF32SConvertI64, // f32.sconvert/i64
......
...@@ -9,6 +9,6 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -9,6 +9,6 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
builder.addFunction("main", kSig_i_i) builder.addFunction("main", kSig_i_i)
.addBody([kExprLocalGet, 0]) .addBody([kExprLocalGet, 0])
.addLocals({s128_count: 1}); .addLocals(kWasmS128, 1)
assertFalse(WebAssembly.validate(builder.toBuffer())); assertFalse(WebAssembly.validate(builder.toBuffer()));
...@@ -41,7 +41,7 @@ builder.addImport('mod', 'get', kSig_i_v); ...@@ -41,7 +41,7 @@ builder.addImport('mod', 'get', kSig_i_v);
builder.addImport('mod', 'call', kSig_v_i); builder.addImport('mod', 'call', kSig_v_i);
builder. builder.
addFunction('main', kSig_v_v). addFunction('main', kSig_v_v).
addLocals({i32_count: kNumLocals}). addLocals(kWasmI32, kNumLocals).
addBody(body). addBody(body).
exportAs('main'); exportAs('main');
let m1_bytes = builder.toBuffer(); let m1_bytes = builder.toBuffer();
......
...@@ -6,6 +6,6 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -6,6 +6,6 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
var builder = new WasmModuleBuilder(); var builder = new WasmModuleBuilder();
builder.addFunction(undefined, kSig_i_i) builder.addFunction(undefined, kSig_i_i)
.addLocals({i32_count: 0xffffffff}) .addLocals(kWasmI32, 0xffffffff)
.addBody([]); .addBody([]);
assertThrows(() => builder.instantiate(), WebAssembly.CompileError); assertThrows(() => builder.instantiate(), WebAssembly.CompileError);
...@@ -6,7 +6,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -6,7 +6,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
builder.addFunction(undefined, makeSig([kWasmI32, kWasmF32], [])) builder.addFunction(undefined, makeSig([kWasmI32, kWasmF32], []))
.addLocals({i32_count: 7}) .addLocals(kWasmI32, 7)
.addBody([ .addBody([
kExprLocalGet, 0, // get_local kExprLocalGet, 0, // get_local
kExprI32Const, 0, // i32.const 0 kExprI32Const, 0, // i32.const 0
......
...@@ -32,7 +32,7 @@ const gen_i32_code = [ ...@@ -32,7 +32,7 @@ const gen_i32_code = [
kExprI32Const, 1, // i32.const 1 kExprI32Const, 1, // i32.const 1
kExprI32Add // i32.add --> 2nd param kExprI32Add // i32.add --> 2nd param
]; ];
builder.addFunction(undefined, kSig_v_v).addLocals({i32_count: 1}).addBody([ builder.addFunction(undefined, kSig_v_v).addLocals(kWasmI32, 1).addBody([
// Generate six values on the stack, then six more to force the other six on // Generate six values on the stack, then six more to force the other six on
// the stack. // the stack.
...wasmI32Const(0), // i32.const 0 ...wasmI32Const(0), // i32.const 0
......
...@@ -16,7 +16,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -16,7 +16,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
var builder = new WasmModuleBuilder(); var builder = new WasmModuleBuilder();
var func_idx = builder.addFunction('helper', kSig_i_v) var func_idx = builder.addFunction('helper', kSig_i_v)
.addLocals({i32_count: 1}) .addLocals(kWasmI32, 1)
.addBody([ .addBody([
kExprI32Const, 0x01, kExprI32Const, 0x01,
]).index; ]).index;
......
...@@ -13,7 +13,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -13,7 +13,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
kExprEnd, // @1 kExprEnd, // @1
]); ]);
builder.addFunction(undefined, 1 /* sig */) builder.addFunction(undefined, 1 /* sig */)
.addLocals({i32_count: 65}) .addLocals(kWasmI32, 65)
.addBodyWithEnd([ .addBodyWithEnd([
kExprLoop, kWasmStmt, // @3 kExprLoop, kWasmStmt, // @3
kSimdPrefix, kSimdPrefix,
......
...@@ -9,7 +9,7 @@ builder.addGlobal(kWasmI32, 1); ...@@ -9,7 +9,7 @@ builder.addGlobal(kWasmI32, 1);
builder.addGlobal(kWasmF32, 1); builder.addGlobal(kWasmF32, 1);
builder.addType(makeSig([kWasmI32, kWasmF32, kWasmF32, kWasmF64], [kWasmI32])); builder.addType(makeSig([kWasmI32, kWasmF32, kWasmF32, kWasmF64], [kWasmI32]));
builder.addFunction(undefined, 0 /* sig */) builder.addFunction(undefined, 0 /* sig */)
.addLocals({i32_count: 504}) .addLocals(kWasmI32, 504)
.addBody([ .addBody([
kExprGlobalGet, 0x00, kExprGlobalGet, 0x00,
kExprLocalSet, 0x04, kExprLocalSet, 0x04,
......
...@@ -7,7 +7,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -7,7 +7,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
const sig = builder.addType(makeSig([], [kWasmF64])); const sig = builder.addType(makeSig([], [kWasmF64]));
builder.addFunction(undefined, sig) builder.addFunction(undefined, sig)
.addLocals({f32_count: 5}).addLocals({f64_count: 3}) .addLocals(kWasmF32, 5).addLocals(kWasmF64, 3)
.addBody([ .addBody([
kExprBlock, kWasmF64, kExprBlock, kWasmF64,
kExprF64Const, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, kExprF64Const, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f,
......
...@@ -6,7 +6,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -6,7 +6,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
builder.addFunction(undefined, kSig_i_i) builder.addFunction(undefined, kSig_i_i)
.addLocals({i32_count: 7}) .addLocals(kWasmI32, 7)
.addBody([ .addBody([
kExprI32Const, 0, kExprI32Const, 0,
kExprIf, kWasmI32, // @11 i32 kExprIf, kWasmI32, // @11 i32
......
...@@ -6,7 +6,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -6,7 +6,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
builder.addFunction(undefined, kSig_v_v) builder.addFunction(undefined, kSig_v_v)
.addLocals({i32_count: 1}).addLocals({f32_count: 1}).addLocals({f64_count: 1}) .addLocals(kWasmI32, 1).addLocals(kWasmF32, 1).addLocals(kWasmF64, 1)
.addBody([ .addBody([
kExprLocalGet, 1, kExprLocalGet, 1,
kExprLocalGet, 2, kExprLocalGet, 2,
......
...@@ -6,7 +6,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -6,7 +6,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
builder.addFunction(undefined, kSig_i_i) builder.addFunction(undefined, kSig_i_i)
.addLocals({i32_count: 5}) .addLocals(kWasmI32, 5)
.addBody([ .addBody([
kExprLocalGet, 0, // --> 1 kExprLocalGet, 0, // --> 1
kExprIf, kWasmI32, kExprIf, kWasmI32,
......
...@@ -9,7 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -9,7 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
(function TestTruncatedBrOnExnInLoop() { (function TestTruncatedBrOnExnInLoop() {
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
let fun = builder.addFunction(undefined, kSig_v_v) let fun = builder.addFunction(undefined, kSig_v_v)
.addLocals({except_count: 1}) .addLocals(kWasmExnRef, 1)
.addBody([ .addBody([
kExprLoop, kWasmStmt, kExprLoop, kWasmStmt,
kExprLocalGet, 0, kExprLocalGet, 0,
......
...@@ -7,7 +7,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -7,7 +7,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
const sig = builder.addType(makeSig([kWasmI32], [])); const sig = builder.addType(makeSig([kWasmI32], []));
builder.addFunction(undefined, sig) builder.addFunction(undefined, sig)
.addLocals({i64_count: 1}) .addLocals(kWasmI64, 1)
.addBody([ .addBody([
kExprLoop, kWasmI32, kExprLoop, kWasmI32,
kExprLocalGet, 1, kExprLocalGet, 1,
......
...@@ -7,7 +7,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -7,7 +7,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
const sig = builder.addType(makeSig([kWasmI64], [kWasmI64])); const sig = builder.addType(makeSig([kWasmI64], [kWasmI64]));
builder.addFunction(undefined, sig) builder.addFunction(undefined, sig)
.addLocals({i32_count: 14}).addLocals({i64_count: 17}).addLocals({f32_count: 14}) .addLocals(kWasmI32, 14).addLocals(kWasmI64, 17).addLocals(kWasmF32, 14)
.addBody([ .addBody([
kExprBlock, kWasmStmt, kExprBlock, kWasmStmt,
kExprBr, 0x00, kExprBr, 0x00,
......
...@@ -48,7 +48,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -48,7 +48,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
const gc_index = builder.addImport('q', 'gc', void_sig); const gc_index = builder.addImport('q', 'gc', void_sig);
// First call the gc, then check if the object still exists. // First call the gc, then check if the object still exists.
builder.addFunction('main', ref_sig) builder.addFunction('main', ref_sig)
.addLocals({anyfunc_count: 10}) .addLocals(kWasmAnyFunc, 10)
.addBody([ .addBody([
kExprLocalGet, 0, kExprLocalGet, 0,
kExprLocalSet, 1, // Set local kExprLocalSet, 1, // Set local
...@@ -139,7 +139,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -139,7 +139,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
const sig_index = builder.addType(kSig_a_v); const sig_index = builder.addType(kSig_a_v);
builder.addFunction('main', sig_index) builder.addFunction('main', sig_index)
.addLocals({anyfunc_count: 1}) .addLocals(kWasmAnyFunc, 1)
.addBody([kExprLocalGet, 0]) .addBody([kExprLocalGet, 0])
.exportFunc(); .exportFunc();
......
...@@ -437,7 +437,7 @@ function CmpExchgLoop(opcode, alignment) { ...@@ -437,7 +437,7 @@ function CmpExchgLoop(opcode, alignment) {
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
builder.addImportedMemory("m", "imported_mem", 0, 2, "shared"); builder.addImportedMemory("m", "imported_mem", 0, 2, "shared");
builder.addFunction("main", makeSig([kWasmI32], [])) builder.addFunction("main", makeSig([kWasmI32], []))
.addLocals({i64_count: 2}) .addLocals(kWasmI64, 2)
.addBody([ .addBody([
kExprLoop, kWasmStmt, kExprLoop, kWasmStmt,
kExprLocalGet, 0, kExprLocalGet, 0,
......
...@@ -126,9 +126,7 @@ function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName, ...@@ -126,9 +126,7 @@ function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName,
builder.addFunction(functionName, makeSig([kWasmI32, kWasmI32, kWasmI32, builder.addFunction(functionName, makeSig([kWasmI32, kWasmI32, kWasmI32,
kWasmI32, kWasmI32 kWasmI32, kWasmI32
], [])) ], []))
.addLocals({ .addLocals(kWasmI32, 3)
i32_count: 3
})
.addBody(body) .addBody(body)
.exportAs(functionName); .exportAs(functionName);
} }
...@@ -147,8 +145,8 @@ function spawnWorker(module, memory, address, sequence) { ...@@ -147,8 +145,8 @@ function spawnWorker(module, memory, address, sequence) {
`onmessage = function(msg) { `onmessage = function(msg) {
this.instance = new WebAssembly.Instance(msg.module, this.instance = new WebAssembly.Instance(msg.module,
{m: {imported_mem: msg.memory}}); {m: {imported_mem: msg.memory}});
instance.exports.worker(msg.address, msg.sequence, msg.sequenceLength, msg.workerId, instance.exports.worker(msg.address, msg.sequence,
msg.bitMask); msg.sequenceLength, msg.workerId, msg.bitMask);
postMessage({workerId: msg.workerId}); postMessage({workerId: msg.workerId});
}`, }`,
{type: 'string'} {type: 'string'}
......
...@@ -131,9 +131,7 @@ function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName, ...@@ -131,9 +131,7 @@ function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName,
builder.addFunction(functionName, makeSig([kWasmI32, kWasmI32, kWasmI32, builder.addFunction(functionName, makeSig([kWasmI32, kWasmI32, kWasmI32,
kWasmI32, kWasmI32 kWasmI32, kWasmI32
], [])) ], []))
.addLocals({ .addLocals(kWasmI32, 1).addLocals(kWasmI64, 2)
i32_count: 1, i64_count: 2
})
.addBody(body) .addBody(body)
.exportAs(functionName); .exportAs(functionName);
} }
......
...@@ -105,7 +105,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); ...@@ -105,7 +105,7 @@ load("test/mjsunit/wasm/exceptions-utils.js");
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
let except = builder.addException(kSig_v_a); let except = builder.addException(kSig_v_a);
builder.addFunction("throw_catch_local", kSig_a_v) builder.addFunction("throw_catch_local", kSig_a_v)
.addLocals({anyfunc_count: 1}) .addLocals(kWasmAnyFunc, 1)
.addBody([ .addBody([
kExprTry, kWasmAnyFunc, kExprTry, kWasmAnyFunc,
kExprLocalGet, 0, kExprLocalGet, 0,
......
...@@ -21,7 +21,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); ...@@ -21,7 +21,7 @@ load("test/mjsunit/wasm/exceptions-utils.js");
kExprEnd, kExprEnd,
]).exportFunc(); ]).exportFunc();
builder.addFunction("rethrow1", kSig_i_i) builder.addFunction("rethrow1", kSig_i_i)
.addLocals({except_count: 1}) .addLocals(kWasmExnRef, 1)
.addBody([ .addBody([
kExprTry, kWasmI32, kExprTry, kWasmI32,
kExprThrow, except, kExprThrow, except,
...@@ -51,7 +51,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); ...@@ -51,7 +51,7 @@ load("test/mjsunit/wasm/exceptions-utils.js");
let except1 = builder.addException(kSig_v_v); let except1 = builder.addException(kSig_v_v);
let except2 = builder.addException(kSig_v_v); let except2 = builder.addException(kSig_v_v);
builder.addFunction("rethrow_nested", kSig_i_i) builder.addFunction("rethrow_nested", kSig_i_i)
.addLocals({except_count: 2}) .addLocals(kWasmExnRef, 2)
.addBody([ .addBody([
kExprTry, kWasmI32, kExprTry, kWasmI32,
kExprThrow, except2, kExprThrow, except2,
...@@ -93,7 +93,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); ...@@ -93,7 +93,7 @@ load("test/mjsunit/wasm/exceptions-utils.js");
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
let except = builder.addException(kSig_v_v); let except = builder.addException(kSig_v_v);
builder.addFunction("rethrow_recatch", kSig_i_i) builder.addFunction("rethrow_recatch", kSig_i_i)
.addLocals({except_count: 1}) .addLocals(kWasmExnRef, 1)
.addBody([ .addBody([
kExprTry, kWasmI32, kExprTry, kWasmI32,
kExprThrow, except, kExprThrow, except,
......
...@@ -13,7 +13,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); ...@@ -13,7 +13,7 @@ load("test/mjsunit/wasm/exceptions-utils.js");
var kSig_v_s = makeSig([kWasmS128], []); var kSig_v_s = makeSig([kWasmS128], []);
var except = builder.addException(kSig_v_s); var except = builder.addException(kSig_v_s);
builder.addFunction("throw_simd", kSig_v_v) builder.addFunction("throw_simd", kSig_v_v)
.addLocals({s128_count: 1}) .addLocals(kWasmS128, 1)
.addBody([ .addBody([
kExprLocalGet, 0, kExprLocalGet, 0,
kExprThrow, 0, kExprThrow, 0,
...@@ -31,7 +31,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); ...@@ -31,7 +31,7 @@ load("test/mjsunit/wasm/exceptions-utils.js");
var kSig_v_s = makeSig([kWasmS128], []); var kSig_v_s = makeSig([kWasmS128], []);
var except = builder.addException(kSig_v_s); var except = builder.addException(kSig_v_s);
builder.addFunction("throw_catch_simd", kSig_i_v) builder.addFunction("throw_catch_simd", kSig_i_v)
.addLocals({s128_count: 1}) .addLocals(kWasmS128, 1)
.addBody([ .addBody([
kExprTry, kWasmS128, kExprTry, kWasmS128,
kExprLocalGet, 0, kExprLocalGet, 0,
......
...@@ -12,7 +12,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); ...@@ -12,7 +12,7 @@ load("test/mjsunit/wasm/exceptions-utils.js");
print(arguments.callee.name); print(arguments.callee.name);
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
builder.addFunction("push_and_drop_exnref", kSig_v_v) builder.addFunction("push_and_drop_exnref", kSig_v_v)
.addLocals({except_count: 1}) .addLocals(kWasmExnRef, 1)
.addBody([ .addBody([
kExprLocalGet, 0, kExprLocalGet, 0,
kExprDrop, kExprDrop,
...@@ -343,7 +343,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); ...@@ -343,7 +343,7 @@ load("test/mjsunit/wasm/exceptions-utils.js");
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
let except = builder.addException(kSig_v_v); let except = builder.addException(kSig_v_v);
builder.addFunction("catch_complex", kSig_i_i) builder.addFunction("catch_complex", kSig_i_i)
.addLocals({except_count: 1}) .addLocals(kWasmExnRef, 1)
.addBody([ .addBody([
kExprBlock, kWasmI32, kExprBlock, kWasmI32,
kExprTry, kWasmStmt, kExprTry, kWasmStmt,
...@@ -467,7 +467,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); ...@@ -467,7 +467,7 @@ load("test/mjsunit/wasm/exceptions-utils.js");
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
let except = builder.addException(kSig_v_l); let except = builder.addException(kSig_v_l);
builder.addFunction("throw_catch_param", kSig_i_i) builder.addFunction("throw_catch_param", kSig_i_i)
.addLocals({i64_count: 1}) .addLocals(kWasmI64, 1)
.addBody([ .addBody([
kExprLocalGet, 0, kExprLocalGet, 0,
kExprI64UConvertI32, kExprI64UConvertI32,
...@@ -661,7 +661,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); ...@@ -661,7 +661,7 @@ load("test/mjsunit/wasm/exceptions-utils.js");
.exportFunc(); .exportFunc();
builder.addFunction("same_scope_multiple", kSig_i_i) builder.addFunction("same_scope_multiple", kSig_i_i)
.addLocals({i32_count: 1, except_count: 1}) .addLocals(kWasmI32, 1).addLocals(kWasmExnRef, 1)
// path = 0; // path = 0;
// //
// try { // try {
......
...@@ -53,7 +53,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -53,7 +53,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const gc_index = builder.addImport("q", "gc", void_sig); const gc_index = builder.addImport("q", "gc", void_sig);
// First call the gc, then check if the object still exists. // First call the gc, then check if the object still exists.
builder.addFunction('main', ref_sig) builder.addFunction('main', ref_sig)
.addLocals({externref_count: 10}) .addLocals(kWasmExternRef, 10)
.addBody([ .addBody([
kExprLocalGet, 0, kExprLocalSet, 1, // Set local kExprLocalGet, 0, kExprLocalSet, 1, // Set local
kExprLocalGet, 0, kExprLocalSet, 2, // Set local kExprLocalGet, 0, kExprLocalSet, 2, // Set local
...@@ -209,7 +209,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -209,7 +209,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_r_v) builder.addFunction('main', kSig_r_v)
.addBody([kExprLocalGet, 0]) .addBody([kExprLocalGet, 0])
.addLocals({externref_count: 1}) .addLocals(kWasmExternRef, 1)
.exportFunc(); .exportFunc();
const instance = builder.instantiate(); const instance = builder.instantiate();
......
...@@ -54,7 +54,7 @@ function WasmI64AtomicWait(memory, offset, index, val_low, ...@@ -54,7 +54,7 @@ function WasmI64AtomicWait(memory, offset, index, val_low,
// I64 for the instruction parameter. // I64 for the instruction parameter.
builder.addFunction("main", builder.addFunction("main",
makeSig([kWasmI32, kWasmI32, kWasmI32, kWasmF64], [kWasmI32])) makeSig([kWasmI32, kWasmI32, kWasmI32, kWasmF64], [kWasmI32]))
.addLocals({i64_count: 1}) // local that is passed as value param to wait .addLocals(kWasmI64, 1) // local that is passed as value param to wait
.addBody([ .addBody([
kExprLocalGet, 1, kExprLocalGet, 1,
kExprI64UConvertI32, kExprI64UConvertI32,
......
...@@ -17,7 +17,7 @@ builder.addImportedMemory('m', 'imported_mem', 1, 2); ...@@ -17,7 +17,7 @@ builder.addImportedMemory('m', 'imported_mem', 1, 2);
builder.addType(makeSig(new Array(18).fill(kWasmS128), [])); builder.addType(makeSig(new Array(18).fill(kWasmS128), []));
builder.addFunction(undefined, makeSig([], [])) builder.addFunction(undefined, makeSig([], []))
.addLocals({s128_count: 9}) .addLocals(kWasmS128, 9)
.addBodyWithEnd([ .addBodyWithEnd([
// These will all be args to the callee. // These will all be args to the callee.
// Load first arg from memory, this was written with values from JS. // Load first arg from memory, this was written with values from JS.
......
...@@ -33,7 +33,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -33,7 +33,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
// For each v128 on the stack, we return the first and last lane. This help // For each v128 on the stack, we return the first and last lane. This help
// catch bugs with reading/writing the wrong stack slots. // catch bugs with reading/writing the wrong stack slots.
builder.addFunction("main", sig_iiiiiiiiii_v) builder.addFunction("main", sig_iiiiiiiiii_v)
.addLocals({"i32_count": 10, "s128_count": 1}) .addLocals(kWasmI32, 10).addLocals(kWasmS128, 1)
.addBody([ .addBody([
kExprCallFunction, callee.index, kExprCallFunction, callee.index,
......
...@@ -43,7 +43,7 @@ function instantiate(buffer, ffi) { ...@@ -43,7 +43,7 @@ function instantiate(buffer, ffi) {
print(arguments.callee.name); print(arguments.callee.name);
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
builder.addFunction(undefined, kSig_i_i) builder.addFunction(undefined, kSig_i_i)
.addLocals({i32_count: 1}) .addLocals(kWasmI32, 1)
.addBody([kExprLocalGet, 0, kExprLocalSet, 1, kExprLocalGet, 1]) .addBody([kExprLocalGet, 0, kExprLocalSet, 1, kExprLocalGet, 1])
.exportAs('main'); .exportAs('main');
...@@ -57,16 +57,15 @@ function instantiate(buffer, ffi) { ...@@ -57,16 +57,15 @@ function instantiate(buffer, ffi) {
print(arguments.callee.name); print(arguments.callee.name);
// TODO(titzer): i64 only works on 64-bit platforms. // TODO(titzer): i64 only works on 64-bit platforms.
var types = [ var types = [
{locals: {i32_count: 1}, type: kWasmI32}, {count: 1, type: kWasmI32},
// {locals: {i64_count: 1}, type: kWasmI64}, {count: 1, type: kWasmF32},
{locals: {f32_count: 1}, type: kWasmF32}, {count: 1, type: kWasmF64},
{locals: {f64_count: 1}, type: kWasmF64},
]; ];
for (p of types) { for (p of types) {
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
builder.addFunction(undefined, makeSig_r_x(p.type, p.type)) builder.addFunction(undefined, makeSig_r_x(p.type, p.type))
.addLocals(p.locals) .addLocals(p.type, p.count)
.addBody([kExprLocalGet, 0, kExprLocalSet, 1, kExprLocalGet, 1]) .addBody([kExprLocalGet, 0, kExprLocalSet, 1, kExprLocalGet, 1])
.exportAs('main'); .exportAs('main');
......
...@@ -102,6 +102,9 @@ let kWasmS128 = 0x7b; ...@@ -102,6 +102,9 @@ let kWasmS128 = 0x7b;
let kWasmExternRef = 0x6f; let kWasmExternRef = 0x6f;
let kWasmAnyFunc = 0x70; let kWasmAnyFunc = 0x70;
let kWasmExnRef = 0x68; let kWasmExnRef = 0x68;
function wasmRefType(index) { return {opcode: 0x6b, index: index}; }
function wasmOptRefType(index) { return {opcode: 0x6c, index: index}; }
function wasmRtt(index, depth) { return {opcode: 0x69, index: index, depth: depth}; }
let kExternalFunction = 0; let kExternalFunction = 0;
let kExternalTable = 1; let kExternalTable = 1;
...@@ -781,6 +784,15 @@ class Binary { ...@@ -781,6 +784,15 @@ class Binary {
} }
} }
emit_type(type) {
if ((typeof type) == "number") this.emit_u8(type);
else {
this.emit_u8(type.opcode);
if ('depth' in type) this.emit_u8(type.depth);
this.emit_u32v(type.index);
}
}
emit_header() { emit_header() {
this.emit_bytes([ this.emit_bytes([
kWasmH0, kWasmH1, kWasmH2, kWasmH3, kWasmV0, kWasmV1, kWasmV2, kWasmV3 kWasmH0, kWasmH1, kWasmH2, kWasmH3, kWasmV0, kWasmV1, kWasmV2, kWasmV3
...@@ -802,20 +814,22 @@ class Binary { ...@@ -802,20 +814,22 @@ class Binary {
} }
class WasmFunctionBuilder { class WasmFunctionBuilder {
constructor(module, name, type_index) { // Encoding of local names: a string corresponds to a local name,
// a number n corresponds to n undefined names.
constructor(module, name, type_index, arg_names) {
this.module = module; this.module = module;
this.name = name; this.name = name;
this.type_index = type_index; this.type_index = type_index;
this.body = []; this.body = [];
this.locals = []; this.locals = [];
this.local_names = []; this.local_names = arg_names;
this.body_offset = undefined; // Not valid until module is serialized. this.body_offset = undefined; // Not valid until module is serialized.
} }
numLocalNames() { numLocalNames() {
let num_local_names = 0; let num_local_names = 0;
for (let loc_name of this.local_names) { for (let loc_name of this.local_names) {
if (loc_name !== undefined) ++num_local_names; if (typeof loc_name == "string") ++num_local_names;
} }
return num_local_names; return num_local_names;
} }
...@@ -854,20 +868,17 @@ class WasmFunctionBuilder { ...@@ -854,20 +868,17 @@ class WasmFunctionBuilder {
getNumLocals() { getNumLocals() {
let total_locals = 0; let total_locals = 0;
for (let l of this.locals) { for (let l of this.locals) {
for (let type of ["i32", "i64", "f32", "f64", "s128"]) { total_locals += l.count
total_locals += l[type + "_count"] || 0;
}
} }
return total_locals; return total_locals;
} }
addLocals(locals, names) { addLocals(type, count, names) {
const old_num_locals = this.getNumLocals(); this.locals.push({type: type, count: count});
this.locals.push(locals); names = names || [];
if (names) { if (names.length > count) throw new Error('too many locals names given');
const missing_names = old_num_locals - this.local_names.length; this.local_names.push(...names);
this.local_names.push(...new Array(missing_names), ...names); if (count > names.length) this.local_names.push(count - names.length);
}
return this; return this;
} }
...@@ -972,17 +983,17 @@ class WasmModuleBuilder { ...@@ -972,17 +983,17 @@ class WasmModuleBuilder {
return this.types.length - 1; return this.types.length - 1;
} }
addGlobal(local_type, mutable) { addGlobal(type, mutable) {
let glob = new WasmGlobalBuilder(this, local_type, mutable); let glob = new WasmGlobalBuilder(this, type, mutable);
glob.index = this.globals.length + this.num_imported_globals; glob.index = this.globals.length + this.num_imported_globals;
this.globals.push(glob); this.globals.push(glob);
return glob; return glob;
} }
addTable(type, initial_size, max_size = undefined) { addTable(type, initial_size, max_size = undefined) {
if (type != kWasmExternRef && type != kWasmAnyFunc && type != kWasmExnRef) { if (type == kWasmI32 || type == kWasmI64 || type == kWasmF32 ||
throw new Error( type == kWasmF64 || type == kWasmS128 || type == kWasmStmt) {
'Tables must be of type kWasmExternRef, kWasmAnyFunc or kWasmExnRef'); throw new Error('Tables must be of a reference type');
} }
let table = new WasmTableBuilder(this, type, initial_size, max_size); let table = new WasmTableBuilder(this, type, initial_size, max_size);
table.index = this.tables.length + this.num_imported_tables; table.index = this.tables.length + this.num_imported_tables;
...@@ -997,9 +1008,13 @@ class WasmModuleBuilder { ...@@ -997,9 +1008,13 @@ class WasmModuleBuilder {
return except_index; return except_index;
} }
addFunction(name, type) { addFunction(name, type, arg_names) {
arg_names = arg_names || [];
let type_index = (typeof type) == "number" ? type : this.addType(type); let type_index = (typeof type) == "number" ? type : this.addType(type);
let func = new WasmFunctionBuilder(this, name, type_index); let num_args = this.types[type_index].params.length;
if (num_args < arg_names.length) throw new Error("too many arg names provided");
if (num_args > arg_names.length) arg_names.push(num_args - arg_names.length);
let func = new WasmFunctionBuilder(this, name, type_index, arg_names);
func.index = this.functions.length + this.num_imported_funcs; func.index = this.functions.length + this.num_imported_funcs;
this.functions.push(func); this.functions.push(func);
return func; return func;
...@@ -1011,7 +1026,7 @@ class WasmModuleBuilder { ...@@ -1011,7 +1026,7 @@ class WasmModuleBuilder {
} }
let type_index = (typeof type) == "number" ? type : this.addType(type); let type_index = (typeof type) == "number" ? type : this.addType(type);
this.imports.push({module: module, name: name, kind: kExternalFunction, this.imports.push({module: module, name: name, kind: kExternalFunction,
type: type_index}); type_index: type_index});
return this.num_imported_funcs++; return this.num_imported_funcs++;
} }
...@@ -1047,7 +1062,7 @@ class WasmModuleBuilder { ...@@ -1047,7 +1062,7 @@ class WasmModuleBuilder {
throw new Error('Imported exceptions must be declared before local ones'); throw new Error('Imported exceptions must be declared before local ones');
} }
let type_index = (typeof type) == "number" ? type : this.addType(type); let type_index = (typeof type) == "number" ? type : this.addType(type);
let o = {module: module, name: name, kind: kExternalException, type: type_index}; let o = {module: module, name: name, kind: kExternalException, type_index: type_index};
this.imports.push(o); this.imports.push(o);
return this.num_imported_exceptions++; return this.num_imported_exceptions++;
} }
...@@ -1155,11 +1170,11 @@ class WasmModuleBuilder { ...@@ -1155,11 +1170,11 @@ class WasmModuleBuilder {
section.emit_u8(kWasmFunctionTypeForm); section.emit_u8(kWasmFunctionTypeForm);
section.emit_u32v(type.params.length); section.emit_u32v(type.params.length);
for (let param of type.params) { for (let param of type.params) {
section.emit_u8(param); section.emit_type(param);
} }
section.emit_u32v(type.results.length); section.emit_u32v(type.results.length);
for (let result of type.results) { for (let result of type.results) {
section.emit_u8(result); section.emit_type(result);
} }
} }
}); });
...@@ -1175,9 +1190,9 @@ class WasmModuleBuilder { ...@@ -1175,9 +1190,9 @@ class WasmModuleBuilder {
section.emit_string(imp.name || ''); section.emit_string(imp.name || '');
section.emit_u8(imp.kind); section.emit_u8(imp.kind);
if (imp.kind == kExternalFunction) { if (imp.kind == kExternalFunction) {
section.emit_u32v(imp.type); section.emit_u32v(imp.type_index);
} else if (imp.kind == kExternalGlobal) { } else if (imp.kind == kExternalGlobal) {
section.emit_u32v(imp.type); section.emit_type(imp.type);
section.emit_u8(imp.mutable); section.emit_u8(imp.mutable);
} else if (imp.kind == kExternalMemory) { } else if (imp.kind == kExternalMemory) {
var has_max = (typeof imp.maximum) != "undefined"; var has_max = (typeof imp.maximum) != "undefined";
...@@ -1190,14 +1205,14 @@ class WasmModuleBuilder { ...@@ -1190,14 +1205,14 @@ class WasmModuleBuilder {
section.emit_u32v(imp.initial); // initial section.emit_u32v(imp.initial); // initial
if (has_max) section.emit_u32v(imp.maximum); // maximum if (has_max) section.emit_u32v(imp.maximum); // maximum
} else if (imp.kind == kExternalTable) { } else if (imp.kind == kExternalTable) {
section.emit_u8(imp.type); section.emit_type(imp.type);
var has_max = (typeof imp.maximum) != "undefined"; var has_max = (typeof imp.maximum) != "undefined";
section.emit_u8(has_max ? 1 : 0); // flags section.emit_u8(has_max ? 1 : 0); // flags
section.emit_u32v(imp.initial); // initial section.emit_u32v(imp.initial); // initial
if (has_max) section.emit_u32v(imp.maximum); // maximum if (has_max) section.emit_u32v(imp.maximum); // maximum
} else if (imp.kind == kExternalException) { } else if (imp.kind == kExternalException) {
section.emit_u32v(kExceptionAttribute); section.emit_u32v(kExceptionAttribute);
section.emit_u32v(imp.type); section.emit_u32v(imp.type_index);
} else { } else {
throw new Error("unknown/unsupported import kind " + imp.kind); throw new Error("unknown/unsupported import kind " + imp.kind);
} }
...@@ -1222,7 +1237,7 @@ class WasmModuleBuilder { ...@@ -1222,7 +1237,7 @@ class WasmModuleBuilder {
binary.emit_section(kTableSectionCode, section => { binary.emit_section(kTableSectionCode, section => {
section.emit_u32v(wasm.tables.length); section.emit_u32v(wasm.tables.length);
for (let table of wasm.tables) { for (let table of wasm.tables) {
section.emit_u8(table.type); section.emit_type(table.type);
section.emit_u8(table.has_max); section.emit_u8(table.has_max);
section.emit_u32v(table.initial_size); section.emit_u32v(table.initial_size);
if (table.has_max) section.emit_u32v(table.max_size); if (table.has_max) section.emit_u32v(table.max_size);
...@@ -1253,9 +1268,9 @@ class WasmModuleBuilder { ...@@ -1253,9 +1268,9 @@ class WasmModuleBuilder {
if (debug) print("emitting events @ " + binary.length); if (debug) print("emitting events @ " + binary.length);
binary.emit_section(kExceptionSectionCode, section => { binary.emit_section(kExceptionSectionCode, section => {
section.emit_u32v(wasm.exceptions.length); section.emit_u32v(wasm.exceptions.length);
for (let type of wasm.exceptions) { for (let type_index of wasm.exceptions) {
section.emit_u32v(kExceptionAttribute); section.emit_u32v(kExceptionAttribute);
section.emit_u32v(type); section.emit_u32v(type_index);
} }
}); });
} }
...@@ -1266,7 +1281,7 @@ class WasmModuleBuilder { ...@@ -1266,7 +1281,7 @@ class WasmModuleBuilder {
binary.emit_section(kGlobalSectionCode, section => { binary.emit_section(kGlobalSectionCode, section => {
section.emit_u32v(wasm.globals.length); section.emit_u32v(wasm.globals.length);
for (let global of wasm.globals) { for (let global of wasm.globals) {
section.emit_u8(global.type); section.emit_type(global.type);
section.emit_u8(global.mutable); section.emit_u8(global.mutable);
if ((typeof global.init_index) == "undefined") { if ((typeof global.init_index) == "undefined") {
// Emit a constant initializer. // Emit a constant initializer.
...@@ -1306,6 +1321,15 @@ class WasmModuleBuilder { ...@@ -1306,6 +1321,15 @@ class WasmModuleBuilder {
section.emit_u8(kExprRefNull); section.emit_u8(kExprRefNull);
section.emit_u8(kWasmExnRef); section.emit_u8(kWasmExnRef);
break; break;
default:
if (global.function_index !== undefined) {
section.emit_u8(kExprRefFunc);
section.emit_u32v(global.function_index);
} else {
section.emit_u8(kExprRefNull);
section.emit_u32v(global.type.index);
}
break;
} }
} else { } else {
// Emit a global-index initializer. // Emit a global-index initializer.
...@@ -1459,40 +1483,12 @@ class WasmModuleBuilder { ...@@ -1459,40 +1483,12 @@ class WasmModuleBuilder {
for (let func of wasm.functions) { for (let func of wasm.functions) {
header.reset(); header.reset();
// Function body length will be patched later. // Function body length will be patched later.
let local_decls = []; let local_decls = func.locals || [];
for (let l of func.locals || []) {
if (l.i32_count > 0) {
local_decls.push({count: l.i32_count, type: kWasmI32});
}
if (l.i64_count > 0) {
local_decls.push({count: l.i64_count, type: kWasmI64});
}
if (l.f32_count > 0) {
local_decls.push({count: l.f32_count, type: kWasmF32});
}
if (l.f64_count > 0) {
local_decls.push({count: l.f64_count, type: kWasmF64});
}
if (l.s128_count > 0) {
local_decls.push({count: l.s128_count, type: kWasmS128});
}
if (l.externref_count > 0) {
local_decls.push({count: l.externref_count, type: kWasmExternRef});
}
if (l.anyfunc_count > 0) {
local_decls.push({count: l.anyfunc_count, type: kWasmAnyFunc});
}
if (l.except_count > 0) {
local_decls.push({count: l.except_count, type: kWasmExnRef});
}
}
header.emit_u32v(local_decls.length); header.emit_u32v(local_decls.length);
for (let decl of local_decls) { for (let decl of local_decls) {
header.emit_u32v(decl.count); header.emit_u32v(decl.count);
header.emit_u8(decl.type); header.emit_type(decl.type);
} }
section.emit_u32v(header.length + func.body.length); section.emit_u32v(header.length + func.body.length);
section.emit_bytes(header.trunc_buffer()); section.emit_bytes(header.trunc_buffer());
// Set to section offset for now, will update. // Set to section offset for now, will update.
...@@ -1576,10 +1572,15 @@ class WasmModuleBuilder { ...@@ -1576,10 +1572,15 @@ class WasmModuleBuilder {
if (func.numLocalNames() == 0) continue; if (func.numLocalNames() == 0) continue;
name_section.emit_u32v(func.index); name_section.emit_u32v(func.index);
name_section.emit_u32v(func.numLocalNames()); name_section.emit_u32v(func.numLocalNames());
let name_index = 0;
for (let i = 0; i < func.local_names.length; ++i) { for (let i = 0; i < func.local_names.length; ++i) {
if (func.local_names[i] === undefined) continue; if (typeof func.local_names[i] == "string") {
name_section.emit_u32v(i); name_section.emit_u32v(name_index);
name_section.emit_string(func.local_names[i]); name_section.emit_string(func.local_names[i]);
name_index++;
} else {
name_index += func.local_names[i];
}
} }
} }
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment