Commit 4174a68e authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Fix importing exported function in interpreter

When calling an import which is an exported wasm function, the
interpreter needs to look through the jump table to find the
actual code object.
We already had that logic for indirect calls, but it was missing for
imported calls.

R=ahaas@chromium.org

Bug: chromium:860392
Change-Id: I6b5a0192f79c23cb1de55407fe93f6df9a17235a
Reviewed-on: https://chromium-review.googlesource.com/1127671Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54291}
parent b672210f
......@@ -2751,6 +2751,19 @@ class ThreadImpl {
return {ExternalCallResult::EXTERNAL_RETURNED};
}
static WasmCode* GetTargetCode(WasmCodeManager* code_manager,
Address target) {
NativeModule* native_module = code_manager->LookupNativeModule(target);
if (native_module->is_jump_table_slot(target)) {
uint32_t func_index =
native_module->GetFunctionIndexFromJumpTableSlot(target);
return native_module->code(func_index);
}
WasmCode* code = native_module->Lookup(target);
DCHECK_EQ(code->instruction_start(), target);
return code;
}
ExternalCallResult CallImportedFunction(uint32_t function_index) {
// Use a new HandleScope to avoid leaking / accumulating handles in the
// outer scope.
......@@ -2759,13 +2772,10 @@ class ThreadImpl {
DCHECK_GT(module()->num_imported_functions, function_index);
Handle<WasmInstanceObject> instance;
WasmCode* code;
{
ImportedFunctionEntry entry(instance_object_, function_index);
instance = handle(entry.instance(), isolate);
code = isolate->wasm_engine()->code_manager()->GetCodeFromStartAddress(
entry.target());
}
ImportedFunctionEntry entry(instance_object_, function_index);
instance = handle(entry.instance(), isolate);
WasmCode* code =
GetTargetCode(isolate->wasm_engine()->code_manager(), entry.target());
FunctionSig* sig = codemap()->module()->functions[function_index].sig;
return CallExternalWasmFunction(isolate, instance, code, sig);
}
......@@ -2812,17 +2822,8 @@ class ThreadImpl {
}
Handle<WasmInstanceObject> instance = handle(entry.instance(), isolate);
Address target = entry.target();
NativeModule* native_module =
isolate->wasm_engine()->code_manager()->LookupNativeModule(target);
WasmCode* code;
if (native_module->is_jump_table_slot(target)) {
uint32_t func_index =
native_module->GetFunctionIndexFromJumpTableSlot(target);
code = native_module->code(func_index);
} else {
code = native_module->Lookup(target);
}
WasmCode* code =
GetTargetCode(isolate->wasm_engine()->code_manager(), entry.target());
// Call either an internal or external WASM function.
HandleScope scope(isolate);
......
......@@ -318,6 +318,31 @@ function checkStack(stack, expected_lines) {
}
})();
(function testImportExportedFunction() {
// See https://crbug.com/860392.
print(arguments.callee.name);
let instance0 = (() => {
let builder = new WasmModuleBuilder();
builder.addFunction('f11', kSig_i_v).addBody(wasmI32Const(11)).exportFunc();
builder.addFunction('f17', kSig_i_v).addBody(wasmI32Const(17)).exportFunc();
return builder.instantiate();
})();
let builder = new WasmModuleBuilder();
let sig_i_v = builder.addType(kSig_i_v);
let f11_imp = builder.addImport('q', 'f11', sig_i_v);
let f17_imp = builder.addImport('q', 'f17', sig_i_v);
let add = builder.addFunction('add', sig_i_v).addBody([
kExprCallFunction, f11_imp, // call f11
kExprCallFunction, f17_imp, // call f17
kExprI32Add // i32.add
]).exportFunc();
let instance = builder.instantiate(
{q: {f11: instance0.exports.f11, f17: instance0.exports.f17}});
assertEquals(28, instance.exports.add());
})();
(function testInfiniteRecursion() {
print(arguments.callee.name);
var builder = new WasmModuleBuilder();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment