Commit 7f7545cf authored by Ben L. Titzer's avatar Ben L. Titzer Committed by Commit Bot

[wasm] Introduce WasmImportCallKind enum

The WASM engine compiles per-import wrappers for callables imported
into a WASM instance that have one of a number of different shapes,
depending on the type of the imported function and whether there is
a signature match. This CL introduces an enum with a value for each
case in preparation for introducing a per-kind cache.

R=mstarzinger@chromium.org
CC=clemensh@chromium.org

Change-Id: If9b7355ff7c57a329c096f93f3624bc3d6c74e3f
Reviewed-on: https://chromium-review.googlesource.com/1243045
Commit-Queue: Ben Titzer <titzer@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56210}
parent 9f7ec7d4
This diff is collapsed.
......@@ -68,11 +68,27 @@ class TurbofanWasmCompilationUnit {
DISALLOW_COPY_AND_ASSIGN(TurbofanWasmCompilationUnit);
};
// Wraps a JS function, producing a code object that can be called from wasm.
MaybeHandle<Code> CompileWasmToJSWrapper(Isolate*, Handle<JSReceiver> target,
wasm::FunctionSig*, uint32_t index,
wasm::ModuleOrigin,
wasm::UseTrapHandler);
// Calls to WASM imports are handled in several different ways, depending
// on the type of the target function/callable and whether the signature
// matches the argument arity.
enum class WasmImportCallKind {
kLinkError, // static WASM->WASM type error
kRuntimeTypeError, // runtime WASM->JS type error
kWasmToWasm, // fast WASM->WASM call
kJSFunctionArityMatch, // fast WASM->JS call
kJSFunctionArityMatchSloppy, // fast WASM->JS call, sloppy receiver
kJSFunctionArityMismatch, // WASM->JS, needs adapter frame
kJSFunctionArityMismatchSloppy, // WASM->JS, needs adapter frame, sloppy
kUseCallBuiltin // everything else
};
WasmImportCallKind GetWasmImportCallKind(Handle<JSReceiver> callable,
wasm::FunctionSig* sig);
// Compiles an import call wrapper, which allows WASM to call imports.
MaybeHandle<Code> CompileWasmImportCallWrapper(
Isolate*, WasmImportCallKind, Handle<JSReceiver>, wasm::FunctionSig*,
uint32_t index, wasm::ModuleOrigin, wasm::UseTrapHandler);
// Creates a code object calling a wasm function with the given signature,
// callable from JS.
......@@ -366,10 +382,10 @@ class WasmGraphBuilder {
Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
wasm::WasmCodePosition position, Node* instance_node,
UseRetpoline use_retpoline);
Node* BuildImportWasmCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
wasm::WasmCodePosition position, int func_index);
Node* BuildImportWasmCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
wasm::WasmCodePosition position, Node* func_index);
Node* BuildImportCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
wasm::WasmCodePosition position, int func_index);
Node* BuildImportCall(wasm::FunctionSig* sig, Node** args, Node*** rets,
wasm::WasmCodePosition position, Node* func_index);
Node* BuildF32CopySign(Node* left, Node* right);
Node* BuildF64CopySign(Node* left, Node* right);
......
......@@ -1494,41 +1494,41 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) {
}
uint32_t func_index = import.index;
DCHECK_EQ(num_imported_functions, func_index);
auto js_receiver = Handle<JSReceiver>::cast(value);
FunctionSig* expected_sig = module_->functions[func_index].sig;
if (WasmExportedFunction::IsWasmExportedFunction(*value)) {
// The imported function is a WASM function from another instance.
Handle<WasmExportedFunction> imported_function(
WasmExportedFunction::cast(*value), isolate_);
Handle<WasmInstanceObject> imported_instance(
imported_function->instance(), isolate_);
FunctionSig* imported_sig =
imported_instance->module()
->functions[imported_function->function_index()]
.sig;
if (*imported_sig != *expected_sig) {
auto kind = compiler::GetWasmImportCallKind(js_receiver, expected_sig);
switch (kind) {
case compiler::WasmImportCallKind::kLinkError:
ReportLinkError(
"imported function does not match the expected type", index,
module_name, import_name);
return -1;
case compiler::WasmImportCallKind::kWasmToWasm: {
// The imported function is a WASM function from another instance.
auto imported_function = Handle<WasmExportedFunction>::cast(value);
Handle<WasmInstanceObject> imported_instance(
imported_function->instance(), isolate_);
// The import reference is the instance object itself.
Address imported_target = imported_function->GetWasmCallTarget();
ImportedFunctionEntry entry(instance, func_index);
entry.set_wasm_to_wasm(*imported_instance, imported_target);
break;
}
default: {
// The imported function is a callable.
Handle<Code> wrapper_code =
compiler::CompileWasmImportCallWrapper(
isolate_, kind, js_receiver, expected_sig, func_index,
module_->origin, use_trap_handler())
.ToHandleChecked();
RecordStats(*wrapper_code, isolate_->counters());
WasmCode* wasm_code =
native_module->AddImportWrapper(wrapper_code, func_index);
ImportedFunctionEntry entry(instance, func_index);
entry.set_wasm_to_js(*js_receiver, wasm_code);
break;
}
// The import reference is the instance object itself.
Address imported_target = imported_function->GetWasmCallTarget();
ImportedFunctionEntry entry(instance, func_index);
entry.set_wasm_to_wasm(*imported_instance, imported_target);
} else {
// The imported function is a callable.
Handle<JSReceiver> js_receiver(JSReceiver::cast(*value), isolate_);
Handle<Code> wrapper_code =
compiler::CompileWasmToJSWrapper(
isolate_, js_receiver, expected_sig, func_index,
module_->origin, use_trap_handler())
.ToHandleChecked();
RecordStats(*wrapper_code, isolate_->counters());
WasmCode* wasm_code =
native_module->AddImportWrapper(wrapper_code, func_index);
ImportedFunctionEntry entry(instance, func_index);
entry.set_wasm_to_js(*js_receiver, wasm_code);
}
num_imported_functions++;
break;
......
......@@ -41,8 +41,10 @@ TestingModuleBuilder::TestingModuleBuilder(
if (maybe_import) {
// Manually compile a wasm to JS wrapper and insert it into the instance.
CodeSpaceMemoryModificationScope modification_scope(isolate_->heap());
MaybeHandle<Code> code = compiler::CompileWasmToJSWrapper(
isolate_, maybe_import->js_function, maybe_import->sig,
auto kind = compiler::GetWasmImportCallKind(maybe_import->js_function,
maybe_import->sig);
MaybeHandle<Code> code = compiler::CompileWasmImportCallWrapper(
isolate_, kind, maybe_import->js_function, maybe_import->sig,
maybe_import_index, test_module_->origin,
trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler
: kNoTrapHandler);
......
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