[wasm] Fix importing wasm-lazy-compile stubs
If two modules use lazy compilation, and one imports a function of another, we are unwrapping the js-to-wasm wrapper of the export. This was failing so far, because during unwrapping we did not find the wasm code. This CL fixes this by also recognizing WasmCompileLazy stubs as "wasm code". R=ahaas@chromium.org Bug: chromium:779569, v8:5991 Change-Id: If2260c3721e3746a7635b9d0182fd520df2fb773 Reviewed-on: https://chromium-review.googlesource.com/771672 Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/master@{#49405}
This commit is contained in:
parent
f139f17e59
commit
77b0baa649
@ -615,8 +615,10 @@ Handle<Code> CompileLazy(Isolate* isolate) {
|
||||
Handle<WasmInstanceObject> instance;
|
||||
Handle<FixedArray> exp_deopt_data;
|
||||
int func_index = -1;
|
||||
// If the lazy compile stub has deopt data, use that to determine the
|
||||
// instance and function index. Otherwise this must be a wasm->wasm call
|
||||
// within one instance, so extract the information from the caller.
|
||||
if (lazy_compile_code->deoptimization_data()->length() > 0) {
|
||||
// Then it's an indirect call or via JS->wasm wrapper.
|
||||
DCHECK_LE(2, lazy_compile_code->deoptimization_data()->length());
|
||||
exp_deopt_data = handle(lazy_compile_code->deoptimization_data(), isolate);
|
||||
auto* weak_cell = WeakCell::cast(exp_deopt_data->get(0));
|
||||
|
@ -679,20 +679,21 @@ Handle<Code> WasmExportedFunction::GetWasmCode() {
|
||||
Handle<Code> export_wrapper_code = handle(this->code());
|
||||
DCHECK_EQ(export_wrapper_code->kind(), Code::JS_TO_WASM_FUNCTION);
|
||||
int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
|
||||
auto IsWasmFunctionCode = [](Code* code) {
|
||||
return code->kind() == Code::WASM_FUNCTION ||
|
||||
code->kind() == Code::WASM_TO_JS_FUNCTION ||
|
||||
code->kind() == Code::WASM_INTERPRETER_ENTRY ||
|
||||
code->builtin_index() == Builtins::kWasmCompileLazy;
|
||||
};
|
||||
for (RelocIterator it(*export_wrapper_code, mask);; it.next()) {
|
||||
DCHECK(!it.done());
|
||||
Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
|
||||
if (target->kind() != Code::WASM_FUNCTION &&
|
||||
target->kind() != Code::WASM_TO_JS_FUNCTION &&
|
||||
target->kind() != Code::WASM_INTERPRETER_ENTRY)
|
||||
continue;
|
||||
if (!IsWasmFunctionCode(target)) continue;
|
||||
// There should only be this one call to wasm code.
|
||||
#ifdef DEBUG
|
||||
for (it.next(); !it.done(); it.next()) {
|
||||
Code* code = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
|
||||
DCHECK(code->kind() != Code::WASM_FUNCTION &&
|
||||
code->kind() != Code::WASM_TO_JS_FUNCTION &&
|
||||
code->kind() != Code::WASM_INTERPRETER_ENTRY);
|
||||
DCHECK(!IsWasmFunctionCode(code));
|
||||
}
|
||||
#endif
|
||||
return handle(target);
|
||||
|
49
test/mjsunit/wasm/lazy-compilation.js
Normal file
49
test/mjsunit/wasm/lazy-compilation.js
Normal file
@ -0,0 +1,49 @@
|
||||
// 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: --wasm-lazy-compilation
|
||||
|
||||
load('test/mjsunit/wasm/wasm-constants.js');
|
||||
load('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
|
||||
(function importFromOtherInstance() {
|
||||
print(arguments.callee.name);
|
||||
const builder1 = new WasmModuleBuilder();
|
||||
builder1.addFunction('func', kSig_v_v).addBody([]).exportFunc();
|
||||
const instance1 = builder1.instantiate();
|
||||
|
||||
const builder2 = new WasmModuleBuilder();
|
||||
builder2.addImport('mod', 'fn', kSig_v_v);
|
||||
builder2.instantiate({mod: {fn: instance1.exports.func}});
|
||||
})();
|
||||
|
||||
(function testWasmToWasmWithDifferentMemory() {
|
||||
print(arguments.callee.name);
|
||||
const builder1 = new WasmModuleBuilder();
|
||||
builder1.addMemory(1, 1, true);
|
||||
builder1.addFunction('store', kSig_v_i)
|
||||
.addBody([
|
||||
kExprI32Const, 0, // i32.const 1
|
||||
kExprGetLocal, 0, // get_local 0
|
||||
kExprI32StoreMem, 0, 0, // i32.store offset=0 align=0
|
||||
])
|
||||
.exportFunc();
|
||||
const instance1 = builder1.instantiate();
|
||||
const mem1 = new Int32Array(instance1.exports.memory.buffer);
|
||||
|
||||
const builder2 = new WasmModuleBuilder();
|
||||
builder2.addMemory(1, 1, true);
|
||||
builder2.addImport('mod', 'store', kSig_v_i);
|
||||
builder2.addFunction('call_store', kSig_v_i)
|
||||
.addBody([kExprGetLocal, 0, kExprCallFunction, 0])
|
||||
.exportFunc();
|
||||
const instance2 = builder2.instantiate({mod: {store: instance1.exports.store}});
|
||||
const mem2 = new Int32Array(instance2.exports.memory.buffer);
|
||||
|
||||
assertEquals(0, mem1[0]);
|
||||
assertEquals(0, mem2[0]);
|
||||
instance2.exports.call_store(3);
|
||||
assertEquals(3, mem1[0]);
|
||||
assertEquals(0, mem2[0]);
|
||||
})();
|
Loading…
Reference in New Issue
Block a user