blob: 40d5aa54814d4bda3274113cc2c53a3fa8a19301 [file] [log] [blame]
// Copyright 2015 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
load('test/mjsunit/wasm/wasm-module-builder.js');
function CreateDefaultBuilder() {
const builder = new WasmModuleBuilder();
const sig_index = kSig_i_dd;
builder.addImport('mod', 'fun', sig_index);
builder.addFunction('main', sig_index)
.addBody([
kExprLocalGet, 0, // --
kExprLocalGet, 1, // --
kExprCallFunction, 0, // --
]) // --
.exportFunc();
return builder;
}
function checkSuccessfulInstantiation(builder, ffi, handler) {
// Test synchronous instantiation.
const instance = builder.instantiate(ffi);
if (handler) handler(instance);
// Test asynchronous instantiation.
assertPromiseResult(builder.asyncInstantiate(ffi), handler);
}
function checkFailingInstantiation(
builder, ffi, error, message, prepend_context = true) {
// Test synchronous instantiation.
assertThrows(
_ => builder.instantiate(ffi), error,
(prepend_context ? 'WebAssembly.Instance(): ' : '') + message);
// Test asynchronous instantiation.
assertThrowsAsync(
builder.asyncInstantiate(ffi), error,
(prepend_context ? 'WebAssembly.instantiate(): ' : '') + message);
}
(function testValidFFI() {
print(arguments.callee.name);
let ffi = {'mod': {fun: print}};
checkSuccessfulInstantiation(CreateDefaultBuilder(), ffi, undefined);
})();
(function testInvalidFFIs() {
print(arguments.callee.name);
checkFailingInstantiation(
CreateDefaultBuilder(), 17, TypeError,
'Argument 1 must be an object');
checkFailingInstantiation(
CreateDefaultBuilder(), {}, TypeError,
'Import #0 module="mod" error: module is not an object or function');
checkFailingInstantiation(
CreateDefaultBuilder(), {mod: {}}, WebAssembly.LinkError,
'Import #0 module="mod" function="fun" error: function import requires a callable');
checkFailingInstantiation(
CreateDefaultBuilder(), {mod: {fun: {}}}, WebAssembly.LinkError,
'Import #0 module="mod" function="fun" error: function import requires a callable');
checkFailingInstantiation(
CreateDefaultBuilder(), {mod: {fun: 0}}, WebAssembly.LinkError,
'Import #0 module="mod" function="fun" error: function import requires a callable');
})();
(function testImportWithInvalidSignature() {
print(arguments.callee.name);
// "fun" should have signature "i_dd"
let builder = new WasmModuleBuilder();
let sig_index = kSig_i_dd;
builder.addFunction('exp', kSig_i_i)
.addBody([
kExprLocalGet,
0,
]) // --
.exportFunc();
let exported = builder.instantiate().exports.exp;
checkFailingInstantiation(
CreateDefaultBuilder(), {mod: {fun: exported}}, WebAssembly.LinkError,
'Import #0 module="mod" function="fun" error: imported function does not match the expected type');
})();
(function regression870646() {
print(arguments.callee.name);
const ffi = {mod: {fun: function() {}}};
Object.defineProperty(ffi, 'mod', {
get: function() {
throw new Error('my_exception');
}
});
checkFailingInstantiation(
CreateDefaultBuilder(), ffi, Error, 'my_exception', false);
})();
// "fun" matches signature "i_dd"
(function testImportWithValidSignature() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addFunction('exp', kSig_i_dd)
.addBody([
kExprI32Const,
33,
]) // --
.exportFunc();
let exported = builder.instantiate().exports.exp;
checkSuccessfulInstantiation(
CreateDefaultBuilder(), {mod: {fun: exported}},
instance => assertEquals(33, instance.exports.main()));
})();
(function I64InSignature() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addMemory(1, 1, true);
builder.addFunction('function_with_invalid_signature', kSig_l_ll)
.addBody([ // --
kExprLocalGet, 0, // --
kExprLocalGet, 1, // --
kExprI64Sub]) // --
.exportFunc()
checkSuccessfulInstantiation(
builder, undefined,
instance => assertEquals(
instance.exports.function_with_invalid_signature(33n, 88n), -55n));
})();
(function I64ParamsInSignature() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addMemory(1, 1, true);
builder.addFunction('function_with_invalid_signature', kSig_i_l)
.addBody([kExprLocalGet, 0, kExprI32ConvertI64])
.exportFunc();
checkSuccessfulInstantiation(
builder, undefined,
instance => assertEquals(12,
instance.exports.function_with_invalid_signature(12n)));
})();
(function I64JSImport() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_index = builder.addType(kSig_i_i);
let sig_i64_index = builder.addType(kSig_i_l);
let index = builder.addImport('', 'func', sig_i64_index);
builder.addFunction('main', sig_index)
.addBody([
kExprLocalGet, 0, kExprI64SConvertI32, kExprCallFunction, index // --
]) // --
.exportFunc();
checkSuccessfulInstantiation(
builder, {'': {func: _ => {}}},
instance => assertEquals(0, instance.exports.main(1)));
})();
(function ImportI64ParamWithF64Return() {
print(arguments.callee.name);
// This tests that we generate correct code by using the correct return
// register. See bug 6096.
let builder = new WasmModuleBuilder();
builder.addImport('', 'f', makeSig([kWasmI64], [kWasmF64]));
builder.addFunction('main', kSig_v_v)
.addBody([kExprI64Const, 0, kExprCallFunction, 0, kExprDrop])
.exportFunc();
checkSuccessfulInstantiation(
builder, {'': {f: i => Number(i)}},
instance => assertDoesNotThrow(instance.exports.main));
})();
(function ImportI64Return() {
print(arguments.callee.name);
// This tests that we generate correct code by using the correct return
// register(s). See bug 6104.
let builder = new WasmModuleBuilder();
builder.addImport('', 'f', makeSig([], [kWasmI64]));
builder.addFunction('main', kSig_v_v)
.addBody([kExprCallFunction, 0, kExprDrop])
.exportFunc();
checkSuccessfulInstantiation(
builder, {'': {f: _ => 1n}},
instance => assertDoesNotThrow(instance.exports.main));
})();
(function ImportSymbolToNumberThrows() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let index = builder.addImport('', 'f', kSig_i_v);
builder.addFunction('main', kSig_i_v)
.addBody([kExprCallFunction, 0])
.exportFunc();
checkSuccessfulInstantiation(
builder, {'': {f: _ => Symbol()}},
instance => assertThrows(
instance.exports.main, TypeError,
'Cannot convert a Symbol value to a number'));
})();