| // Copyright 2017 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: --experimental-wasm-mv |
| |
| load("test/mjsunit/wasm/wasm-module-builder.js"); |
| |
| (function MultiBlockResultTest() { |
| print("MultiBlockResultTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_ii = builder.addType(kSig_i_ii); |
| let sig_ii_v = builder.addType(kSig_ii_v); |
| |
| builder.addFunction("main", kSig_i_ii) |
| .addBody([ |
| kExprBlock, sig_ii_v, |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprEnd, |
| kExprI32Add]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(1, 4), 5); |
| })(); |
| |
| (function MultiBlockParamTest() { |
| print("MultiBlockParamTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_ii = builder.addType(kSig_i_ii); |
| |
| builder.addFunction("main", kSig_i_ii) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprBlock, sig_i_ii, |
| kExprI32Add, |
| kExprEnd]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(1, 4), 5); |
| })(); |
| |
| (function MultiBlockBrTest() { |
| print("MultiBlockBrTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_ii = builder.addType(kSig_i_ii); |
| let sig_ii_v = builder.addType(kSig_ii_v); |
| |
| builder.addFunction("main", kSig_i_ii) |
| .addBody([ |
| kExprBlock, sig_ii_v, |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprBr, 0, |
| kExprEnd, |
| kExprI32Add]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(1, 4), 5); |
| })(); |
| |
| (function MultiBlockUnreachableTest() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| let sig_il_v = builder.addType(makeSig([], [kWasmI32, kWasmI64])); |
| |
| builder.addFunction("main", kSig_i_v) |
| .addBody([ |
| kExprBlock, sig_il_v, |
| kExprI32Const, 1, |
| kExprI64Const, 1, |
| kExprBr, 0, |
| kExprI32Const, 1, |
| kExprI64Const, 1, |
| kExprEnd, |
| kExprDrop]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(1, 2), 1); |
| })(); |
| |
| (function MultiBlockUnreachableTypeErrorTest() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| let sig_il_v = builder.addType(makeSig([], [kWasmI32, kWasmI64])); |
| |
| builder.addFunction("main", kSig_i_v) |
| .addBody([ |
| kExprBlock, sig_il_v, |
| kExprI32Const, 1, |
| kExprI64Const, 1, |
| kExprBr, 0, |
| kExprI64Const, 1, |
| kExprI32Const, 1, |
| // Wrong order: expect i32, i64. |
| kExprEnd, |
| kExprDrop]) |
| .exportAs("main"); |
| |
| assertThrows(() => new WebAssembly.Module(builder.toBuffer()), |
| WebAssembly.CompileError, /expected type i64, found i32.const/); |
| })(); |
| |
| (function MultiLoopResultTest() { |
| print("MultiLoopResultTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_ii = builder.addType(kSig_i_ii); |
| let sig_ii_v = builder.addType(kSig_ii_v); |
| |
| builder.addFunction("main", kSig_i_ii) |
| .addBody([ |
| kExprLoop, sig_ii_v, |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprEnd, |
| kExprI32Add]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(1, 4), 5); |
| })(); |
| |
| (function MultiLoopParamTest() { |
| print("MultiLoopParamTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_ii = builder.addType(kSig_i_ii); |
| |
| builder.addFunction("main", kSig_i_ii) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprLoop, sig_i_ii, |
| kExprI32Add, |
| kExprEnd]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(1, 4), 5); |
| })(); |
| |
| (function MultiLoopBrTest() { |
| print("MultiLoopBrTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_ii = builder.addType(kSig_i_ii); |
| let sig_ii_i = builder.addType(kSig_ii_i); |
| let sig_ii_ii = builder.addType(kSig_ii_ii); |
| |
| builder.addFunction("dup", kSig_ii_i) |
| .addBody([kExprLocalGet, 0, kExprLocalGet, 0]); |
| builder.addFunction("swap", kSig_ii_ii) |
| .addBody([kExprLocalGet, 1, kExprLocalGet, 0]); |
| builder.addFunction("main", kSig_i_ii) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprLoop, sig_ii_ii, |
| kExprCallFunction, 1, // swap |
| kExprCallFunction, 0, // dup |
| kExprI32Add, |
| kExprCallFunction, 0, // dup |
| kExprI32Const, 20, |
| kExprI32LeU, |
| kExprBrIf, 0, |
| kExprEnd, |
| kExprDrop]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(0, instance.exports.main(0, 1)); |
| assertEquals(16, instance.exports.main(1, 1)); |
| assertEquals(4, instance.exports.main(3, 1)); |
| assertEquals(4, instance.exports.main(4, 1)); |
| assertEquals(0, instance.exports.main(0, 2)); |
| assertEquals(16, instance.exports.main(1, 2)); |
| assertEquals(8, instance.exports.main(3, 2)); |
| assertEquals(8, instance.exports.main(4, 2)); |
| assertEquals(0, instance.exports.main(0, 3)); |
| assertEquals(8, instance.exports.main(1, 3)); |
| assertEquals(12, instance.exports.main(3, 3)); |
| assertEquals(12, instance.exports.main(4, 3)); |
| assertEquals(0, instance.exports.main(0, 4)); |
| assertEquals(8, instance.exports.main(1, 4)); |
| assertEquals(16, instance.exports.main(3, 4)); |
| assertEquals(16, instance.exports.main(4, 4)); |
| assertEquals(3, instance.exports.main(100, 3)); |
| assertEquals(6, instance.exports.main(3, 100)); |
| })(); |
| |
| |
| (function MultiIfResultTest() { |
| print("MultiIfResultTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_ii = builder.addType(kSig_i_ii); |
| let sig_ii_v = builder.addType(kSig_ii_v); |
| |
| builder.addFunction("main", kSig_i_ii) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprIf, sig_ii_v, |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprElse, |
| kExprLocalGet, 1, |
| kExprLocalGet, 0, |
| kExprEnd, |
| kExprI32Sub]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(8, 3), 5); |
| assertEquals(instance.exports.main(0, 3), 3); |
| })(); |
| |
| (function MultiIfParamTest() { |
| print("MultiIfParamTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_ii = builder.addType(kSig_i_ii); |
| |
| builder.addFunction("main", kSig_i_ii) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprLocalGet, 0, |
| kExprIf, sig_i_ii, |
| kExprI32Add, |
| kExprElse, |
| kExprI32Sub, |
| kExprEnd]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(1, 4), 5); |
| assertEquals(instance.exports.main(0, 4), -4); |
| })(); |
| |
| (function MultiIfBrTest() { |
| print("MultiIfBrTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_ii = builder.addType(kSig_i_ii); |
| let sig_ii_v = builder.addType(kSig_ii_v); |
| |
| builder.addFunction("main", kSig_i_ii) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprIf, sig_ii_v, |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprBr, 0, |
| kExprElse, |
| kExprLocalGet, 1, |
| kExprLocalGet, 0, |
| kExprBr, 0, |
| kExprEnd, |
| kExprI32Sub]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(8, 3), 5); |
| assertEquals(instance.exports.main(0, 3), 3); |
| })(); |
| |
| (function MultiIfParamOneArmedTest() { |
| print("MultiIfParamOneArmedTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_i = builder.addType(kSig_i_i); |
| |
| builder.addFunction("main", kSig_i_i) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprLocalGet, 0, |
| kExprIf, sig_i_i, |
| kExprI32Const, 5, |
| kExprI32Add, |
| kExprEnd]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(0), 0); |
| assertEquals(instance.exports.main(1), 6); |
| })(); |
| |
| (function MultiIfOneArmedNoTypeCheckTest() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_l = builder.addType(kSig_i_l); |
| |
| builder.addFunction("main", kSig_i_v) |
| .addBody([ |
| kExprI64Const, 0, |
| kExprI32Const, 0, |
| kExprIf, sig_i_l, |
| kExprDrop, |
| kExprI32Const, 0, |
| kExprEnd]); |
| |
| assertThrows(() => new WebAssembly.Module(builder.toBuffer()), |
| WebAssembly.CompileError, /expected i32, got i64/); |
| })(); |
| |
| (function MultiResultTest() { |
| print("MultiResultTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_ii = builder.addType(kSig_i_ii); |
| let sig_iii_ii = builder.addType(kSig_iii_ii); |
| |
| builder.addFunction("callee", kSig_iii_ii) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprI32Sub]); |
| builder.addFunction("main", kSig_i_ii) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprCallFunction, 0, |
| kExprI32Mul, |
| kExprI32Add]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(0, 0), 0); |
| assertEquals(instance.exports.main(1, 0), 1); |
| assertEquals(instance.exports.main(2, 0), 2); |
| assertEquals(instance.exports.main(0, 1), -1); |
| assertEquals(instance.exports.main(0, 2), -4); |
| assertEquals(instance.exports.main(3, 4), -1); |
| assertEquals(instance.exports.main(4, 3), 7); |
| })(); |
| |
| (function MultiReturnTest() { |
| print("MultiReturnTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_i = builder.addType(kSig_i_i); |
| let sig_ii_i = builder.addType(kSig_ii_i); |
| |
| builder.addFunction("callee", kSig_ii_i) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprLocalGet, 0, |
| kExprLocalGet, 0, |
| kExprI32Add, |
| kExprReturn]); |
| builder.addFunction("main", kSig_i_i) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprCallFunction, 0, |
| kExprI32Mul]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(0), 0); |
| assertEquals(instance.exports.main(1), 2); |
| assertEquals(instance.exports.main(2), 8); |
| assertEquals(instance.exports.main(10), 200); |
| })(); |
| |
| (function MultiBrReturnTest() { |
| print("MultiBrReturnTest"); |
| let builder = new WasmModuleBuilder(); |
| let sig_i_i = builder.addType(kSig_i_i); |
| let sig_ii_i = builder.addType(kSig_ii_i); |
| |
| builder.addFunction("callee", kSig_ii_i) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprLocalGet, 0, |
| kExprLocalGet, 0, |
| kExprI32Add, |
| kExprBr, 0]); |
| builder.addFunction("main", kSig_i_i) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprCallFunction, 0, |
| kExprI32Mul]) |
| .exportAs("main"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.main(0), 0); |
| assertEquals(instance.exports.main(1), 2); |
| assertEquals(instance.exports.main(2), 8); |
| assertEquals(instance.exports.main(10), 200); |
| })(); |
| |
| (function MultiBrTableTest() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| let sig_ii_v = builder.addType(kSig_v_v); |
| |
| builder.addFunction("main", kSig_ii_v) |
| .addBody([ |
| kExprI32Const, 1, kExprI32Const, 2, |
| kExprI32Const, 0, |
| kExprBrTable, 1, 0, 0, |
| ]) |
| .exportAs("main"); |
| |
| let instance = builder.instantiate(); |
| assertEquals(instance.exports.main(), [1, 2]); |
| })(); |
| |
| (function MultiUnreachablePolymorphicTest() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| let sig_v_i = builder.addType(kSig_v_i); |
| let sig_i_i = builder.addType(kSig_i_i); |
| |
| builder.addFunction("block", kSig_v_v) |
| .addBody([ |
| kExprReturn, |
| kExprBlock, sig_v_i, |
| kExprDrop, |
| kExprEnd |
| ]) |
| .exportAs("block"); |
| builder.addFunction("if_else", kSig_v_v) |
| .addBody([ |
| kExprReturn, |
| kExprIf, sig_v_i, |
| kExprDrop, |
| kExprElse, |
| kExprDrop, |
| kExprEnd |
| ]) |
| .exportAs("if_else"); |
| builder.addFunction("loop", kSig_v_v) |
| .addBody([ |
| kExprReturn, |
| kExprLoop, sig_i_i, |
| kExprEnd, |
| kExprDrop |
| ]) |
| .exportAs("loop"); |
| // TODO(thibaudm): Create eh + mv mjsunit test and add try/catch case. |
| let instance = builder.instantiate(); |
| instance.exports.block(); |
| instance.exports.if_else(); |
| instance.exports.loop(); |
| })(); |
| |
| (function MultiWasmToJSReturnTest() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| let sig_fi_if = makeSig([kWasmI32, kWasmF32], [kWasmF32, kWasmI32]); |
| |
| builder.addFunction("swap", sig_fi_if) |
| .addBody([ |
| kExprLocalGet, 1, |
| kExprLocalGet, 0]) |
| .exportAs("swap"); |
| builder.addFunction("addsubmul", kSig_iii_i) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprLocalGet, 0, |
| kExprI32Add, |
| kExprLocalGet, 0, |
| kExprLocalGet, 0, |
| kExprI32Sub, |
| kExprLocalGet, 0, |
| kExprLocalGet, 0, |
| kExprI32Mul]) |
| .exportAs("addsubmul"); |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| let instance = new WebAssembly.Instance(module); |
| assertEquals(instance.exports.swap(0, 1.5), [1.5, 0]); |
| assertEquals(instance.exports.swap(2, 3.75), [3.75, 2]); |
| assertEquals(instance.exports.addsubmul(4), [8, 0, 16]); |
| assertEquals(instance.exports.addsubmul(5), [10, 0, 25]); |
| })(); |
| |
| (function MultiJSToWasmReturnTest() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| function swap(x, y) { return [y, x]; } |
| function swap_proxy(x, y) { |
| return new Proxy([y, x], { |
| get: function(obj, prop) { return Reflect.get(obj, prop); }, |
| }); |
| } |
| function proxy_throw(x, y) { |
| return new Proxy([y, x], { |
| get: function(obj, prop) { |
| if (prop == 1) { |
| throw new Error("abc"); |
| } |
| return Reflect.get(obj, prop); }, |
| }); |
| } |
| function drop_first(x, y) { |
| return [y]; |
| } |
| function repeat(x, y) { |
| return [x, y, x, y]; |
| } |
| function not_receiver(x, y) { |
| return 0; |
| } |
| function not_iterable(x, y) { |
| a = [x, y]; |
| a[Symbol.iterator] = undefined; |
| return a; |
| } |
| function* generator(x, y) { |
| yield x; |
| yield y; |
| } |
| function* generator_throw(x, y) { |
| yield x; |
| throw new Error("def"); |
| } |
| |
| builder.addImport('imports', 'f', kSig_ii_ii); |
| builder.addFunction("main", kSig_ii_ii) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprLocalGet, 1, |
| kExprCallFunction, 0]) |
| .exportAs("main") |
| |
| let module = new WebAssembly.Module(builder.toBuffer()); |
| |
| var instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : swap } }); |
| assertEquals(instance.exports.main(1, 2), [2, 1]); |
| instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : swap_proxy } }); |
| assertEquals(instance.exports.main(1, 2), [2, 1]); |
| instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : generator } }); |
| assertEquals(instance.exports.main(1, 2), [1, 2]); |
| |
| instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : drop_first } }); |
| assertThrows(() => instance.exports.main(1, 2), TypeError, "multi-return length mismatch"); |
| instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : repeat } }); |
| assertThrows(() => instance.exports.main(1, 2), TypeError, "multi-return length mismatch"); |
| instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : proxy_throw } }); |
| assertThrows(() => instance.exports.main(1, 2), Error, "abc"); |
| instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : not_receiver } }); |
| assertThrows(() => instance.exports.main(1, 2), TypeError, /not iterable/); |
| instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : not_iterable } }); |
| assertThrows(() => instance.exports.main(1, 2), TypeError, /not iterable/); |
| instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : generator_throw } }); |
| assertThrows(() => instance.exports.main(1, 2), Error, "def"); |
| })(); |