v8/test/mjsunit/wasm/test-wasm-module-builder.js
Manos Koukoutos ce8812aceb [wasm-gc][test] Add builtin ref type handling in wasm-module-builder
We currently print reference type indices as unsigned LEB. This will not
work properly for large indices (>=64), as they will be interpreted as
negative indices when read back. They may also alias with builtin types.
In this CL, we fix this by defining builtin types as negative numbers.
We add positive byte constants that can be used in function bodies.
We adapt wasm-module-builder and tests to the above changes.

Bug: v8:7748
Change-Id: I4dfaa65d4cbf77a6731ca2283148bd842ea5c56b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3080569
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76176}
2021-08-09 16:23:22 +00:00

207 lines
6.4 KiB
JavaScript

// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --experimental-wasm-typed-funcref
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
var debug = true;
function instantiate(buffer, ffi) {
return new WebAssembly.Instance(new WebAssembly.Module(buffer), ffi);
}
(function BasicTest() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addMemory(1, 2, false);
builder.addFunction('foo', kSig_i_v)
.addBody([kExprI32Const, 11])
.exportAs('blarg');
var buffer = builder.toBuffer(debug);
var instance = instantiate(buffer);
assertEquals(11, instance.exports.blarg());
})();
(function ImportTest() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
var index = builder.addImport('', 'print', makeSig_v_x(kWasmI32));
builder.addFunction('foo', kSig_v_v)
.addBody([kExprI32Const, 13, kExprCallFunction, index])
.exportAs('main');
var buffer = builder.toBuffer(debug);
var instance = instantiate(buffer, {'': {print: print}});
print('should print 13! ');
instance.exports.main();
})();
(function LocalsTest() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addFunction(undefined, kSig_i_i)
.addLocals(kWasmI32, 1)
.addBody([kExprLocalGet, 0, kExprLocalSet, 1, kExprLocalGet, 1])
.exportAs('main');
var buffer = builder.toBuffer(debug);
var instance = instantiate(buffer);
assertEquals(19, instance.exports.main(19));
assertEquals(27777, instance.exports.main(27777));
})();
(function LocalsTest2() {
print(arguments.callee.name);
// TODO(titzer): i64 only works on 64-bit platforms.
var types = [
{count: 1, type: kWasmI32},
{count: 1, type: kWasmF32},
{count: 1, type: kWasmF64},
];
for (p of types) {
let builder = new WasmModuleBuilder();
builder.addFunction(undefined, makeSig_r_x(p.type, p.type))
.addLocals(p.type, p.count)
.addBody([kExprLocalGet, 0, kExprLocalSet, 1, kExprLocalGet, 1])
.exportAs('main');
var buffer = builder.toBuffer(debug);
var instance = instantiate(buffer);
assertEquals(19, instance.exports.main(19));
assertEquals(27777, instance.exports.main(27777));
}
})();
(function CallTest() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addFunction('add', kSig_i_ii).addBody([
kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add
]);
builder.addFunction('main', kSig_i_ii)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprCallFunction, 0])
.exportAs('main');
var instance = builder.instantiate();
assertEquals(44, instance.exports.main(11, 33));
assertEquals(7777, instance.exports.main(2222, 5555));
})();
(function IndirectCallTest() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addFunction('add', kSig_i_ii).addBody([
kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add
]);
builder.addFunction('main', kSig_i_iii)
.addBody([
kExprLocalGet, 1, kExprLocalGet, 2, kExprLocalGet, 0, kExprCallIndirect,
0, kTableZero
])
.exportAs('main');
builder.appendToTable([0]);
var instance = builder.instantiate();
assertEquals(44, instance.exports.main(0, 11, 33));
assertEquals(7777, instance.exports.main(0, 2222, 5555));
assertThrows(() => instance.exports.main(1, 1, 1));
})();
(function DataSegmentTest() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addMemory(1, 1, false);
builder.addFunction('load', kSig_i_i)
.addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0])
.exportAs('load');
builder.addDataSegment(0, [9, 9, 9, 9]);
var buffer = builder.toBuffer(debug);
var instance = instantiate(buffer);
assertEquals(151587081, instance.exports.load(0));
})();
(function BasicTestWithUint8Array() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addMemory(1, 2, false);
builder.addFunction('foo', kSig_i_v)
.addBody([kExprI32Const, 17])
.exportAs('blarg');
var buffer = builder.toBuffer(debug);
var array = new Uint8Array(buffer);
var instance = instantiate(array);
assertEquals(17, instance.exports.blarg());
var kPad = 5;
var buffer2 = new ArrayBuffer(kPad + buffer.byteLength + kPad);
var whole = new Uint8Array(buffer2);
for (var i = 0; i < whole.byteLength; i++) {
whole[i] = 0xff;
}
var array2 = new Uint8Array(buffer2, kPad, buffer.byteLength);
for (var i = 0; i < array2.byteLength; i++) {
array2[i] = array[i];
}
var instance = instantiate(array2);
assertEquals(17, instance.exports.blarg());
})();
(function ImportTestTwoLevel() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
var index = builder.addImport('mod', 'print', makeSig_v_x(kWasmI32));
builder.addFunction('foo', kSig_v_v)
.addBody([kExprI32Const, 19, kExprCallFunction, index])
.exportAs('main');
var buffer = builder.toBuffer(debug);
var instance = instantiate(buffer, {mod: {print: print}});
print('should print 19! ');
instance.exports.main();
})();
(function TestI32Const() {
print(arguments.callee.name);
let ints = [
// A few negative number of different length.
-3 << 28, -20000, -400, -200, -100, -50, -10, -1,
// And a few positive number of different length.
0, 1, 2, 20, 120, 130, 260, 500, 5000000, 3 << 28
];
for (let i of ints) {
let builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_i_v)
.addBody([...wasmI32Const(i)])
.exportAs('main');
let instance = builder.instantiate();
assertEquals(i, instance.exports.main());
}
})();
(function TestBigTypeIndices() {
print(arguments.callee.name);
// These are all positive type indices (e.g. kI31RefCode and not kWasmI31Ref)
// and should be treated as such.
let indices = [kI31RefCode, kDataRefCode, 200, 400];
let kMaxIndex = 400;
let builder = new WasmModuleBuilder();
for (let i = 0; i <= kMaxIndex; i++) {
builder.addType(kSig_i_i);
builder.addFunction(undefined, i)
.addBody([kExprLocalGet, 0]);
builder.addGlobal(wasmRefType(i), false, WasmInitExpr.RefFunc(i));
}
for (let i of indices) {
builder.addFunction('f_' + i, makeSig([], [wasmRefType(i)]))
.addBody([kExprRefFunc, ...wasmSignedLeb(i, 5)])
.exportFunc();
}
builder.instantiate();
})();