// 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: --expose-wasm load("test/mjsunit/wasm/wasm-constants.js"); load("test/mjsunit/wasm/wasm-module-builder.js"); const kTableSize = 3; var m_i_v; var m_i_i; var m_i_ii; (function BuildExportedMethods() { print("BuildingExportedMethods..."); let builder = new WasmModuleBuilder(); let sig_v_v = builder.addType(kSig_v_v); let sig_i_ii = builder.addType(kSig_i_ii); let sig_i_i = builder.addType(kSig_i_i); let sig_i_v = builder.addType(kSig_i_v); print("exported[i_v] = " + sig_i_v); print("exported[i_i] = " + sig_i_i); print("exported[i_ii] = " + sig_i_ii); builder.addFunction("", sig_i_v) .addBody([ kExprI32Const, 41]) // -- .exportAs("m_i_v"); builder.addFunction("m_i_i", sig_i_i) .addBody([ kExprI32Const, 42]) // -- .exportAs("m_i_i"); builder.addFunction("m_i_ii", sig_i_ii) .addBody([ kExprI32Const, 43]) // -- .exportAs("m_i_ii"); let module = new WebAssembly.Module(builder.toBuffer()); let instance = new WebAssembly.Instance(module); m_i_v = instance.exports.m_i_v; m_i_i = instance.exports.m_i_i; m_i_ii = instance.exports.m_i_ii; m_i_v.sig = kSig_i_v; m_i_i.sig = kSig_i_i; m_i_ii.sig = kSig_i_ii; })(); function caller_module() { let builder = new WasmModuleBuilder(); let sig_i_v = builder.addType(kSig_i_v); let sig_i_ii = builder.addType(kSig_i_ii); let sig_i_i = builder.addType(kSig_i_i); print("imported[i_v] = " + sig_i_v); print("imported[i_i] = " + sig_i_i); print("imported[i_ii] = " + sig_i_ii); builder.addFunction("call1", sig_i_i) .addBody([ kExprGetLocal, 0, // -- kExprCallIndirect, sig_i_v, kTableZero]) // -- .exportAs("call1"); builder.addFunction("call2", sig_i_i) .addBody([ kExprI32Const, 11, // -- kExprGetLocal, 0, kExprCallIndirect, sig_i_i, kTableZero]) // -- .exportAs("call2"); builder.addFunction("call3", sig_i_i) .addBody([ kExprI32Const, 21, kExprI32Const, 22, kExprGetLocal, 0, kExprCallIndirect, sig_i_ii, kTableZero]) // -- .exportAs("call3"); builder.addImportedTable("imp", "table", kTableSize, kTableSize); return builder.toModule(); } function call(func, ...args) { try { return "" + func.apply(undefined, args); } catch (e) { return "!" + e; } } function DoCalls(table, calls) { for (func of calls) { print("func = " + func); for (var i = 0; i < 4; i++) { print(" i = " + i); var expectThrow = true; var exp = null; if (i < table.length) { exported = table.get(i); expectThrow = (exported.sig != func.sig); print(" exp=" + exported); print(" throw=" + expectThrow); } else { print(" exp="); } print(" result=" + call(func, i)); if (expectThrow) { assertThrows(() => func(i), WebAssembly.RuntimeError); } else { assertEquals(exported(0), func(i)); } } } } (function TestExecute() { print("TestExecute"); let module = caller_module(); let table = new WebAssembly.Table({element: "anyfunc", initial: kTableSize, maximum: kTableSize}); let instance = new WebAssembly.Instance(module, {imp: {table: table}}); instance.exports.call1.sig = kSig_i_v; instance.exports.call2.sig = kSig_i_i; instance.exports.call3.sig = kSig_i_ii; let exports = [m_i_v, m_i_i, m_i_ii]; let calls = [instance.exports.call1, instance.exports.call2, instance.exports.call3]; for (f0 of exports) { for (f1 of exports) { for (f2 of exports) { table.set(0, f0); table.set(1, f1); table.set(2, f2); DoCalls(table, calls); } } } })();