mirror of
https://github.com/nodejs/node.git
synced 2025-05-15 17:51:35 +00:00

PR-URL: https://github.com/nodejs/node/pull/52465 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Michael Dawson <midawson@redhat.com>
675 lines
20 KiB
JavaScript
675 lines
20 KiB
JavaScript
// Copyright 2023 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: --wasm-to-js-generic-wrapper --wasm-staging --experimental-wasm-type-reflection
|
|
// Flags: --wasm-wrapper-tiering-budget=1 --allow-natives-syntax
|
|
|
|
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
|
|
|
|
const kNormal = 0;
|
|
const kGetAndCall = 1;
|
|
|
|
function GetJSFunction(numParams) {
|
|
return () => 15;
|
|
}
|
|
|
|
function GetWasmJSFunction(numParams) {
|
|
return new WebAssembly.Function(
|
|
{parameters: new Array(numParams).fill('i32'), results: []},
|
|
() => 12);
|
|
}
|
|
|
|
function GetReExportedJSFunction(numParams) {
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const impIndex = builder.addImport('m', 'foo', sig);
|
|
builder.addExport("foo", impIndex);
|
|
return builder.instantiate(
|
|
{'m': {'foo': GetJSFunction(numParams)}}).exports.foo;
|
|
}
|
|
|
|
function GetReExportedWasmJSFunction(numParams) {
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const impIndex = builder.addImport('m', 'foo', sig);
|
|
builder.addExport("foo", impIndex);
|
|
return builder.instantiate(
|
|
{'m': {'foo': GetWasmJSFunction(numParams)}}).exports.foo;
|
|
}
|
|
|
|
function AssertWrapperTierup(instance) {
|
|
if (instance.exports.get) {
|
|
assertTrue(%HasUnoptimizedWasmToJSWrapper(instance.exports.get()));
|
|
instance.exports.main();
|
|
assertTrue(!%HasUnoptimizedWasmToJSWrapper(instance.exports.get()));
|
|
instance.exports.main();
|
|
} else {
|
|
const countBefore = %CountUnoptimizedWasmToJSWrapper(instance);
|
|
instance.exports.main();
|
|
const countAfter = %CountUnoptimizedWasmToJSWrapper(instance);
|
|
assertTrue(countBefore > countAfter);
|
|
instance.exports.main();
|
|
}
|
|
}
|
|
|
|
function TestImportedFunction(numParams, jsFunc, mode) {
|
|
if (mode != kNormal) return;
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const impIndex = builder.addImport('m', 'foo', sig);
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
body.push(kExprCallFunction, impIndex);
|
|
|
|
builder.addFunction('main', sig)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate({ 'm': { 'foo': jsFunc } });
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
function TestIndirectElementSection(numParams, jsFunc, mode) {
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const sigId = builder.addType(sig);
|
|
const impIndex = builder.addImport('m', 'foo', sigId);
|
|
|
|
const table = builder.addTable(kWasmAnyFunc, 10).index;
|
|
builder.addActiveElementSegment(table, wasmI32Const(0), [impIndex]);
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
if (mode == kNormal) {
|
|
body.push(kExprI32Const, 0, kExprCallIndirect, sigId, table);
|
|
} else {
|
|
body.push(kExprI32Const, 0, kExprTableGet, table,
|
|
kGCPrefix, kExprRefCast, sigId, kExprCallRef, sigId);
|
|
|
|
builder.addFunction('get', kSig_a_v)
|
|
.addBody([kExprI32Const, 0, kExprTableGet, table])
|
|
.exportFunc();
|
|
}
|
|
|
|
builder.addFunction('main', sigId)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate({ 'm': { 'foo': jsFunc } });
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
function TestIndirectJSTableImport(numParams, jsFunc, mode) {
|
|
if (!(jsFunc instanceof WebAssembly.Function)) {
|
|
return;
|
|
}
|
|
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const sigId = builder.addType(sig);
|
|
const impIndex = builder.addImportedTable('m', 'table', 10, 10, kWasmAnyFunc);
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
if (mode == kNormal) {
|
|
body.push(kExprI32Const, 0, kExprCallIndirect, sigId, impIndex);
|
|
} else {
|
|
body.push(kExprI32Const, 0, kExprTableGet, impIndex,
|
|
kGCPrefix, kExprRefCast, sigId, kExprCallRef, sigId);
|
|
|
|
builder.addFunction('get', kSig_a_v)
|
|
.addBody([kExprI32Const, 0, kExprTableGet, impIndex])
|
|
.exportFunc();
|
|
}
|
|
|
|
builder.addFunction('main', sigId)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
|
|
const table = new WebAssembly.Table({
|
|
element: "anyfunc",
|
|
initial: 10,
|
|
maximum: 10
|
|
});
|
|
|
|
table.set(0, jsFunc);
|
|
|
|
const instance = builder.instantiate({ 'm': { 'table': table } });
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
function TestIndirectWasmTableImport(numParams, jsFunc, mode) {
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const sigId = builder.addType(sig);
|
|
const impIndex = builder.addImportedTable('m', 'table', 10, 10, kWasmAnyFunc);
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
|
|
if (mode == kNormal) {
|
|
body.push(kExprI32Const, 0, kExprCallIndirect, sigId, impIndex);
|
|
} else {
|
|
body.push(kExprI32Const, 0, kExprTableGet, impIndex,
|
|
kGCPrefix, kExprRefCast, sigId, kExprCallRef, sigId);
|
|
|
|
builder.addFunction('get', kSig_a_v)
|
|
.addBody([kExprI32Const, 0, kExprTableGet, impIndex])
|
|
.exportFunc();
|
|
}
|
|
|
|
builder.addFunction('main', sigId)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
|
|
let table;
|
|
{
|
|
const table_module_builder = new WasmModuleBuilder();
|
|
const sigId = table_module_builder.addType(sig);
|
|
const impIndex = table_module_builder.addImport('m', 'foo', sigId);
|
|
|
|
const tableId =
|
|
table_module_builder.addTable(kWasmAnyFunc, 10, 10).exportAs('table').index;
|
|
table_module_builder.addActiveElementSegment(
|
|
tableId, wasmI32Const(0), [impIndex]);
|
|
|
|
table =
|
|
table_module_builder.instantiate({'m': {'foo': jsFunc}}).exports.table;
|
|
}
|
|
|
|
const instance = builder.instantiate({ 'm': { 'table': table } });
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
function TestIndirectTableSetInJS(numParams, jsFunc, mode) {
|
|
if (!(jsFunc instanceof WebAssembly.Function)) {
|
|
return;
|
|
}
|
|
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const sigId = builder.addType(sig);
|
|
|
|
const table = builder.addTable(kWasmAnyFunc, 10).exportAs('table').index;
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
if (mode == kNormal) {
|
|
body.push(kExprI32Const, 0, kExprCallIndirect, sigId, table);
|
|
} else {
|
|
body.push(kExprI32Const, 0, kExprTableGet, table,
|
|
kGCPrefix, kExprRefCast, sigId, kExprCallRef, sigId);
|
|
|
|
builder.addFunction('get', kSig_a_v)
|
|
.addBody([kExprI32Const, 0, kExprTableGet, table])
|
|
.exportFunc();
|
|
}
|
|
|
|
builder.addFunction('main', sigId)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate();
|
|
|
|
instance.exports.table.set(0, jsFunc);
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
function TestIndirectTableSetFromParam(numParams, jsFunc, mode) {
|
|
if (!(jsFunc instanceof WebAssembly.Function)) {
|
|
return;
|
|
}
|
|
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const sigId = builder.addType(sig);
|
|
|
|
const table = builder.addTable(kWasmAnyFunc, 10).index;
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
if (mode == kNormal) {
|
|
body.push(kExprI32Const, 0, kExprCallIndirect, sigId, table);
|
|
} else {
|
|
body.push(kExprI32Const, 0, kExprTableGet, table,
|
|
kGCPrefix, kExprRefCast, sigId, kExprCallRef, sigId);
|
|
|
|
builder.addFunction('get', kSig_a_v)
|
|
.addBody([kExprI32Const, 0, kExprTableGet, table])
|
|
.exportFunc();
|
|
}
|
|
|
|
builder.addFunction('main', sigId)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
builder.addFunction('set', kSig_v_a)
|
|
.addBody([kExprI32Const, 0, kExprLocalGet, 0, kExprTableSet, table])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate();
|
|
|
|
instance.exports.set(jsFunc);
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
function TestIndirectTableSetFromTableGet(numParams, jsFunc, mode) {
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const sigId = builder.addType(sig);
|
|
const impIndex = builder.addImport('m', 'foo', sigId);
|
|
|
|
const table = builder.addTable(kWasmAnyFunc, 10).index;
|
|
builder.addActiveElementSegment(
|
|
table, wasmI32Const(1), [impIndex]);
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
if (mode == kNormal) {
|
|
body.push(kExprI32Const, 0, kExprCallIndirect, sigId, table);
|
|
} else {
|
|
body.push(kExprI32Const, 0, kExprTableGet, table,
|
|
kGCPrefix, kExprRefCast, sigId, kExprCallRef, sigId);
|
|
|
|
builder.addFunction('get', kSig_a_v)
|
|
.addBody([kExprI32Const, 0, kExprTableGet, table])
|
|
.exportFunc();
|
|
}
|
|
|
|
builder.addFunction('main', sigId)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
builder.addFunction('set', kSig_v_v)
|
|
.addBody([
|
|
kExprI32Const, 0, // index of table.set
|
|
...[kExprI32Const, 1, kExprTableGet, table],
|
|
kExprTableSet, table
|
|
])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate({ 'm': { 'foo': jsFunc } });
|
|
|
|
instance.exports.set();
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
function TestIndirectTableSetFromFuncRef(numParams, jsFunc, mode) {
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const sigId = builder.addType(sig);
|
|
const impIndex = builder.addImport('m', 'foo', sigId);
|
|
builder.addDeclarativeElementSegment([impIndex]);
|
|
|
|
const table = builder.addTable(kWasmAnyFunc, 10).index;
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
if (mode == kNormal) {
|
|
body.push(kExprI32Const, 0, kExprCallIndirect, sigId, table);
|
|
} else {
|
|
body.push(kExprI32Const, 0, kExprTableGet, table,
|
|
kGCPrefix, kExprRefCast, sigId, kExprCallRef, sigId);
|
|
|
|
builder.addFunction('get', kSig_a_v)
|
|
.addBody([kExprI32Const, 0, kExprTableGet, table])
|
|
.exportFunc();
|
|
}
|
|
|
|
builder.addFunction('main', sigId)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
builder.addFunction('set', kSig_v_v)
|
|
.addBody([
|
|
kExprI32Const, 0, // index of table.set
|
|
kExprRefFunc, impIndex, kExprTableSet, table
|
|
])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate({ 'm': { 'foo': jsFunc } });
|
|
|
|
instance.exports.set();
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
function TestIndirectTableSetFromParamInOtherInstance(numParams, jsFunc, mode) {
|
|
if (!(jsFunc instanceof WebAssembly.Function)) {
|
|
return;
|
|
}
|
|
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const sigId = builder.addType(sig);
|
|
|
|
let table = builder.addTable(kWasmAnyFunc, 10, 10).exportAs('table').index;
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
if (mode == kNormal) {
|
|
body.push(kExprI32Const, 0, kExprCallIndirect, sigId, table);
|
|
} else {
|
|
body.push(kExprI32Const, 0, kExprTableGet, table,
|
|
kGCPrefix, kExprRefCast, sigId, kExprCallRef, sigId);
|
|
|
|
builder.addFunction('get', kSig_a_v)
|
|
.addBody([kExprI32Const, 0, kExprTableGet, table])
|
|
.exportFunc();
|
|
}
|
|
|
|
builder.addFunction('main', sigId)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
|
|
const setBuilder = new WasmModuleBuilder();
|
|
table = setBuilder.addImportedTable('m', 'table', 10, 10, kWasmAnyFunc);
|
|
setBuilder.addFunction('set', kSig_v_a)
|
|
.addBody([kExprI32Const, 0, kExprLocalGet, 0, kExprTableSet, table])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate();
|
|
|
|
const setInstance =
|
|
setBuilder.instantiate({'m': {'table': instance.exports.table}});
|
|
setInstance.exports.set(jsFunc);
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
function TestIndirectTableSetFromTableGetInOtherInstance(
|
|
numParams, jsFunc, mode) {
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const sigId = builder.addType(sig);
|
|
const impIndex = builder.addImport('m', 'foo', sigId);
|
|
|
|
let table = builder.addTable(kWasmAnyFunc, 10, 10).exportAs('table').index;
|
|
builder.addActiveElementSegment(
|
|
table, wasmI32Const(1), [impIndex]);
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
if (mode == kNormal) {
|
|
body.push(kExprI32Const, 0, kExprCallIndirect, sigId, table);
|
|
} else {
|
|
body.push(kExprI32Const, 0, kExprTableGet, table,
|
|
kGCPrefix, kExprRefCast, sigId, kExprCallRef, sigId);
|
|
|
|
builder.addFunction('get', kSig_a_v)
|
|
.addBody([kExprI32Const, 0, kExprTableGet, table])
|
|
.exportFunc();
|
|
}
|
|
|
|
builder.addFunction('main', sigId)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
|
|
const setBuilder = new WasmModuleBuilder();
|
|
table = setBuilder.addImportedTable('m', 'table', 10, 10, kWasmAnyFunc);
|
|
setBuilder.addFunction('set', kSig_v_v)
|
|
.addBody([
|
|
kExprI32Const, 0, // index of table.set
|
|
...[kExprI32Const, 1, kExprTableGet, table],
|
|
kExprTableSet, table
|
|
])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate({ 'm': { 'foo': jsFunc } });
|
|
|
|
const setInstance =
|
|
setBuilder.instantiate({'m': {'table': instance.exports.table}});
|
|
setInstance.exports.set(jsFunc);
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
function TestIndirectTableSetFromTableGetInOtherInstance2(
|
|
numParams, jsFunc, mode) {
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
let sigId = builder.addType(sig);
|
|
|
|
let table = builder.addTable(kWasmAnyFunc, 10, 10).exportAs('table').index;
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
if (mode == kNormal) {
|
|
body.push(kExprI32Const, 0, kExprCallIndirect, sigId, table);
|
|
} else {
|
|
body.push(kExprI32Const, 0, kExprTableGet, table,
|
|
kGCPrefix, kExprRefCast, sigId, kExprCallRef, sigId);
|
|
|
|
builder.addFunction('get', kSig_a_v)
|
|
.addBody([kExprI32Const, 0, kExprTableGet, table])
|
|
.exportFunc();
|
|
}
|
|
|
|
builder.addFunction('main', sigId)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
|
|
const setBuilder = new WasmModuleBuilder();
|
|
sigId = setBuilder.addType(sig);
|
|
const impIndex = setBuilder.addImport('m', 'foo', sigId);
|
|
table = setBuilder.addImportedTable('m', 'table', 10, 10, kWasmAnyFunc);
|
|
setBuilder.addActiveElementSegment(
|
|
table, wasmI32Const(1), [impIndex]);
|
|
setBuilder.addFunction('set', kSig_v_v)
|
|
.addBody([
|
|
kExprI32Const, 0, // index of table.set
|
|
...[kExprI32Const, 1, kExprTableGet, table],
|
|
kExprTableSet, table
|
|
])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate();
|
|
|
|
const setInstance = setBuilder.instantiate(
|
|
{'m': {'table': instance.exports.table, 'foo': jsFunc}});
|
|
setInstance.exports.set(jsFunc);
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
function TestIndirectTableSetFromFuncRefInOtherInstance(numParams, jsFunc, mode) {
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
let sigId = builder.addType(sig);
|
|
|
|
let table = builder.addTable(kWasmAnyFunc, 10, 10).exportAs('table').index;
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
if (mode == kNormal) {
|
|
body.push(kExprI32Const, 0, kExprCallIndirect, sigId, table);
|
|
} else {
|
|
body.push(kExprI32Const, 0, kExprTableGet, table,
|
|
kGCPrefix, kExprRefCast, sigId, kExprCallRef, sigId);
|
|
|
|
builder.addFunction('get', kSig_a_v)
|
|
.addBody([kExprI32Const, 0, kExprTableGet, table])
|
|
.exportFunc();
|
|
}
|
|
|
|
builder.addFunction('main', sigId)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
|
|
const setBuilder = new WasmModuleBuilder();
|
|
sigId = setBuilder.addType(sig);
|
|
const impIndex = setBuilder.addImport('m', 'foo', sigId);
|
|
setBuilder.addDeclarativeElementSegment([impIndex]);
|
|
table = setBuilder.addImportedTable('m', 'table', 10, 10, kWasmAnyFunc);
|
|
setBuilder.addFunction('set', kSig_v_v)
|
|
.addBody([
|
|
kExprI32Const, 0, // index of table.set
|
|
kExprRefFunc, impIndex, kExprTableSet, table
|
|
])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate();
|
|
const setInstance = setBuilder.instantiate(
|
|
{'m': {'table': instance.exports.table, 'foo': jsFunc}});
|
|
setInstance.exports.set(jsFunc);
|
|
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
function TestCallRefFromParam(numParams, jsFunc, mode) {
|
|
if (mode != kNormal) return;
|
|
if (!(jsFunc instanceof WebAssembly.Function)) {
|
|
return;
|
|
}
|
|
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
let sigId = builder.addType(sig);
|
|
|
|
let body = [];
|
|
for (let i = 1; i <= numParams; ++i) {
|
|
body.push(kExprLocalGet, ...wasmUnsignedLeb(i));
|
|
}
|
|
body.push(kExprLocalGet, 0, kExprCallRef, sigId);
|
|
|
|
const mainParams = [wasmRefNullType(sigId), ...paramsTypes];
|
|
builder.addFunction('main', makeSig(mainParams, retTypes))
|
|
.addBody(body)
|
|
.exportFunc();
|
|
const instance = builder.instantiate();
|
|
|
|
assertTrue(%HasUnoptimizedWasmToJSWrapper(jsFunc));
|
|
instance.exports.main(jsFunc);
|
|
assertTrue(! %HasUnoptimizedWasmToJSWrapper(jsFunc));
|
|
instance.exports.main(jsFunc);
|
|
}
|
|
|
|
function TestCallRefFromFuncRef(numParams, jsFunc, mode) {
|
|
if (mode != kNormal) return;
|
|
const paramsTypes = new Array(numParams).fill(kWasmI32);
|
|
const retTypes = [];
|
|
const sig = makeSig(paramsTypes, retTypes);
|
|
|
|
const builder = new WasmModuleBuilder();
|
|
const sigId = builder.addType(sig);
|
|
const impIndex = builder.addImport('m', 'foo', sigId);
|
|
builder.addDeclarativeElementSegment([impIndex]);
|
|
|
|
let body = [];
|
|
for (let i = 0; i < numParams; ++i) {
|
|
body.push(kExprLocalGet, i);
|
|
}
|
|
body.push(kExprRefFunc, impIndex, kExprCallRef, sigId);
|
|
|
|
builder.addFunction('main', sigId)
|
|
.addBody(body)
|
|
.exportFunc();
|
|
|
|
builder.addFunction('get', kSig_a_v)
|
|
.addBody([kExprRefFunc, impIndex])
|
|
.exportFunc();
|
|
|
|
const instance = builder.instantiate({ 'm': { 'foo': jsFunc } });
|
|
|
|
AssertWrapperTierup(instance);
|
|
}
|
|
|
|
(function Test() {
|
|
const kinds = [
|
|
GetJSFunction, GetWasmJSFunction, GetReExportedJSFunction,
|
|
GetReExportedWasmJSFunction
|
|
];
|
|
|
|
const tests = [
|
|
TestImportedFunction, TestIndirectElementSection, TestIndirectJSTableImport,
|
|
TestIndirectWasmTableImport, TestIndirectTableSetInJS,
|
|
TestIndirectTableSetFromParam, TestIndirectTableSetFromTableGet,
|
|
TestIndirectTableSetFromFuncRef,
|
|
TestIndirectTableSetFromParamInOtherInstance,
|
|
TestIndirectTableSetFromTableGetInOtherInstance,
|
|
TestIndirectTableSetFromTableGetInOtherInstance2,
|
|
TestIndirectTableSetFromFuncRefInOtherInstance, TestCallRefFromParam,
|
|
TestCallRefFromFuncRef
|
|
];
|
|
|
|
const modes = [kNormal, kGetAndCall];
|
|
|
|
let numParams = 0;
|
|
for (const test of tests) {
|
|
console.log('\n', test.name);
|
|
for (const kind of kinds) {
|
|
console.log('>', kind.name);
|
|
for (const mode of modes) {
|
|
console.log(
|
|
mode == kNormal ? ' > CallIndirect' : ' > Table.get + ref.call');
|
|
test(numParams, kind(numParams), mode);
|
|
numParams++;
|
|
}
|
|
}
|
|
}
|
|
})();
|