diff --git a/common.gypi b/common.gypi index 0a4ed881a5b925..f68c3e31ce9f92 100644 --- a/common.gypi +++ b/common.gypi @@ -33,7 +33,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.12', + 'v8_embedder_string': '-node.48', # Enable disassembler for `--print-code` v8 options 'v8_enable_disassembler': 1, diff --git a/deps/v8/src/wasm/module-compiler.cc b/deps/v8/src/wasm/module-compiler.cc index 180c025a4965da..2b0eac818aa2fe 100644 --- a/deps/v8/src/wasm/module-compiler.cc +++ b/deps/v8/src/wasm/module-compiler.cc @@ -2653,20 +2653,20 @@ void InstanceBuilder::LoadTableSegments(Handle instance) { // Update the local dispatch table first. uint32_t sig_id = module_->signature_ids[function->sig_index]; - WasmInstanceObject* target_instance = *instance; + Handle target_instance = instance; Address call_target; const bool is_import = func_index < module_->num_imported_functions; if (is_import) { // For imported calls, take target instance and address from the // import table. ImportedFunctionEntry entry(instance, func_index); - target_instance = entry.instance(); + target_instance = handle(entry.instance(), isolate_); call_target = entry.target(); } else { call_target = native_module->GetCallTargetForFunction(func_index); } IndirectFunctionTableEntry(instance, table_index) - .set(sig_id, target_instance, call_target); + .set(sig_id, *target_instance, call_target); if (!table_instance.table_object.is_null()) { // Update the table object's other dispatch tables. @@ -2700,17 +2700,16 @@ void InstanceBuilder::LoadTableSegments(Handle instance) { } table_instance.js_wrappers->set(table_index, *js_wrappers_[func_index]); - // UpdateDispatchTables() should update this instance as well. + // UpdateDispatchTables() updates all other dispatch tables, since + // we have not yet added the dispatch table we are currently building. WasmTableObject::UpdateDispatchTables( isolate_, table_instance.table_object, table_index, function->sig, - instance, call_target); + target_instance, call_target); } } } - // TODO(titzer): we add the new dispatch table at the end to avoid - // redundant work and also because the new instance is not yet fully - // initialized. + // Add the new dispatch table at the end to avoid redundant lookups. if (!table_instance.table_object.is_null()) { // Add the new dispatch table to the WebAssembly.Table object. WasmTableObject::AddDispatchTable(isolate_, table_instance.table_object, diff --git a/deps/v8/test/mjsunit/wasm/import-table.js b/deps/v8/test/mjsunit/wasm/import-table.js new file mode 100644 index 00000000000000..bb8bf7807b5cf5 --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/import-table.js @@ -0,0 +1,244 @@ +// Copyright 2018 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"); + +function addConstFunc(builder, val) { + return builder.addFunction("const" + val, kSig_i_v) + .addBody(wasmI32Const(val)).index; +} + +function addSigs(builder, pad) { + for (let i = 0; i < pad; i++) { + let params = []; + for (let j = 0; j < i; j++) params.push(kWasmF32); + builder.addType(makeSig(params, [])); + } + + return { i_v: builder.addType(kSig_i_v) }; +} + +let kTableSize = 50; + +(function TestAliasedImportedTable() { + print(arguments.callee.name); + + { + let builder = new WasmModuleBuilder(); + let signums = addSigs(builder, 1); + + builder.addImportedTable("m", "table", kTableSize, kTableSize); + let f15 = addConstFunc(builder, 15); + let call = builder.addFunction("call", kSig_i_i) + .addBody([ + kExprGetLocal, 0, + kExprCallIndirect, signums.i_v, kTableZero + ]) + .exportAs("call"); + let f17 = addConstFunc(builder, 17); + builder.addExport("f15", f15); + builder.addExport("f17", f17); + builder.addFunctionTableInit(15, false, [f15], true); + builder.addFunctionTableInit(1, false, [call.index], true); + + var mod1 = builder.toModule(); + } + + { + let builder = new WasmModuleBuilder(); + let signums = addSigs(builder, 5); // ensure different sigids + + builder.addImportedTable("m", "table", kTableSize, kTableSize); + let f15 = builder.addImport("m", "f15", kSig_i_v); + let f17 = builder.addImport("m", "f17", kSig_i_v); + let f21 = addConstFunc(builder, 21); + let call = builder.addFunction("call", kSig_i_i) + .addBody([ + kExprGetLocal, 0, + kExprCallIndirect, signums.i_v, kTableZero + ]) + .exportAs("call"); + let f26 = addConstFunc(builder, 26); + builder.addFunctionTableInit(17, false, [f17], true); + builder.addFunctionTableInit(21, false, [f21], true); + builder.addFunctionTableInit(26, false, [f26], true); + builder.addFunctionTableInit(5, false, [call.index], true); + + var mod2 = builder.toModule(); + } + + var table = new WebAssembly.Table({initial: kTableSize, + maximum: kTableSize, element: "anyfunc"}); + var i1 = new WebAssembly.Instance(mod1, {m: {table: table}}); + + var i2 = new WebAssembly.Instance(mod2, + {m: {table: table, f15: i1.exports.f15, f17: i1.exports.f17}}); + + for (i of [15, 17, 21, 26]) { + print(i); + assertEquals(i, i1.exports.call(i)); + assertEquals(i, i2.exports.call(i)); + } + for (i of [0, 1, 5, 16]) { + assertThrows(() => i1.exports.call(i)); + assertThrows(() => i2.exports.call(i)); + } +})(); + +function addConstFuncUsingGlobal(builder, val) { + let g = builder.addGlobal(kWasmI32, false); + g.init = val; + return builder.addFunction("global" + val, kSig_i_v) + .addBody([kExprGetGlobal, g.index]).index; +} + +(function TestAliasedImportedTableInstanceGlobals() { + print(arguments.callee.name); + + { + let builder = new WasmModuleBuilder(); + let signums = addSigs(builder, 1); + + builder.addImportedTable("m", "table", kTableSize, kTableSize); + let f14 = addConstFuncUsingGlobal(builder, 14); + let call = builder.addFunction("call", kSig_i_i) + .addBody([ + kExprGetLocal, 0, + kExprCallIndirect, signums.i_v, kTableZero + ]) + .exportAs("call"); + let f18 = addConstFuncUsingGlobal(builder, 18); + builder.addExport("f14", f14); + builder.addExport("f18", f18); + builder.addFunctionTableInit(14, false, [f14], true); + builder.addFunctionTableInit(1, false, [call.index], true); + + var mod1 = builder.toModule(); + } + + { + let builder = new WasmModuleBuilder(); + let signums = addSigs(builder, 3); // ensure different sigids + + builder.addImportedTable("m", "table", kTableSize, kTableSize); + let f14 = builder.addImport("m", "f14", kSig_i_v); + let f18 = builder.addImport("m", "f18", kSig_i_v); + let f22 = addConstFuncUsingGlobal(builder, 22); + let call = builder.addFunction("call", kSig_i_i) + .addBody([ + kExprGetLocal, 0, + kExprCallIndirect, signums.i_v, kTableZero + ]) + .exportAs("call"); + let f28 = addConstFuncUsingGlobal(builder, 28); + builder.addFunctionTableInit(18, false, [f18], true); + builder.addFunctionTableInit(22, false, [f22], true); + builder.addFunctionTableInit(28, false, [f28], true); + builder.addFunctionTableInit(5, false, [call.index], true); + + var mod2 = builder.toModule(); + } + + var table = new WebAssembly.Table({initial: kTableSize, + maximum: kTableSize, element: "anyfunc"}); + var i1 = new WebAssembly.Instance(mod1, {m: {table: table}}); + + var i2 = new WebAssembly.Instance(mod2, + {m: {table: table, f14: i1.exports.f14, f18: i1.exports.f18}}); + + for (i of [14, 18, 22, 28]) { + print(i); + assertEquals(i, i1.exports.call(i)); + assertEquals(i, i2.exports.call(i)); + } + for (i of [0, 1, 5, 16]) { + assertThrows(() => i1.exports.call(i)); + assertThrows(() => i2.exports.call(i)); + } +})(); + + +function addConstFuncUsingMemory(builder, val) { + var addr = builder.address; + builder.address += 8; + var bytes = [val & 0xff, (val>>8) & 0xff, (val>>16) & 0xff, (val>>24) & 0xff]; + builder.addDataSegment(addr, bytes); + return builder.addFunction("mem" + val, kSig_i_v) + .addBody([ + ...wasmI32Const(addr), + kExprI32LoadMem, 0, 0 + ]).index; +} + +(function TestAliasedImportedTableInstanceMemories() { + print(arguments.callee.name); + + { + let builder = new WasmModuleBuilder(); + builder.address = 8; + let signums = addSigs(builder, 1); + + builder.addMemory(1, 1, false); + builder.addImportedTable("m", "table", kTableSize, kTableSize); + let f13 = addConstFuncUsingMemory(builder, 13); + let call = builder.addFunction("call", kSig_i_i) + .addBody([ + kExprGetLocal, 0, + kExprCallIndirect, signums.i_v, kTableZero + ]) + .exportAs("call"); + let f19 = addConstFuncUsingMemory(builder, 19); + builder.addExport("f13", f13); + builder.addExport("f19", f19); + builder.addFunctionTableInit(13, false, [f13], true); + builder.addFunctionTableInit(1, false, [call.index], true); + + var mod1 = builder.toModule(); + } + + { + let builder = new WasmModuleBuilder(); + builder.address = 8; + let signums = addSigs(builder, 4); // ensure different sigids + + builder.addMemory(1, 1, false); + builder.addImportedTable("m", "table", kTableSize, kTableSize); + let f13 = builder.addImport("m", "f13", kSig_i_v); + let f19 = builder.addImport("m", "f19", kSig_i_v); + let f23 = addConstFuncUsingMemory(builder, 23); + let call = builder.addFunction("call", kSig_i_i) + .addBody([ + kExprGetLocal, 0, + kExprCallIndirect, signums.i_v, kTableZero + ]) + .exportAs("call"); + let f29 = addConstFuncUsingMemory(builder, 29); + builder.addFunctionTableInit(19, false, [f19], true); + builder.addFunctionTableInit(23, false, [f23], true); + builder.addFunctionTableInit(29, false, [f29], true); + builder.addFunctionTableInit(5, false, [call.index], true); + + var mod2 = builder.toModule(); + } + + var table = new WebAssembly.Table({initial: kTableSize, + maximum: kTableSize, element: "anyfunc"}); + var i1 = new WebAssembly.Instance(mod1, {m: {table: table}}); + + var i2 = new WebAssembly.Instance(mod2, + {m: {table: table, f13: i1.exports.f13, f19: i1.exports.f19}}); + + for (i of [13, 19, 23, 29]) { + print(i); + assertEquals(i, i1.exports.call(i)); + assertEquals(i, i2.exports.call(i)); + } + for (i of [0, 1, 5, 16]) { + assertThrows(() => i1.exports.call(i)); + assertThrows(() => i2.exports.call(i)); + } +})();