Index: src/wasm/wasm-module.cc |
diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc |
index e789982ba8b58b75f469cab1f7d1dd7d11a849d7..7f20dd8b34c6ed42797989717de8b00f3136f103 100644 |
--- a/src/wasm/wasm-module.cc |
+++ b/src/wasm/wasm-module.cc |
@@ -439,10 +439,11 @@ void PatchDirectCalls(Handle<FixedArray> old_functions, |
DCHECK_EQ(new_functions->length(), old_functions->length()); |
DisallowHeapAllocation no_gc; |
- std::map<Code*, Code*> old_to_new_code; |
+ std::map<Code*, HeapObject*> old_to_new_code; |
for (int i = 0; i < new_functions->length(); ++i) { |
- old_to_new_code.insert(std::make_pair(Code::cast(old_functions->get(i)), |
- Code::cast(new_functions->get(i)))); |
+ old_to_new_code.insert( |
+ std::make_pair(Code::cast(old_functions->get(i)), |
+ HeapObject::cast(new_functions->get(i)))); |
} |
int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); |
AllowDeferredHandleDereference embedding_raw_address; |
@@ -455,11 +456,21 @@ void PatchDirectCalls(Handle<FixedArray> old_functions, |
old_code->kind() == Code::WASM_FUNCTION) { |
auto found = old_to_new_code.find(old_code); |
DCHECK(found != old_to_new_code.end()); |
- Code* new_code = found->second; |
+ HeapObject* new_code = found->second; |
if (new_code != old_code) { |
- it.rinfo()->set_target_address(new_code->instruction_start(), |
- UPDATE_WRITE_BARRIER, |
- SKIP_ICACHE_FLUSH); |
+ if (new_code->IsCode()) { |
+ it.rinfo()->set_target_address( |
+ Code::cast(new_code)->instruction_start(), UPDATE_WRITE_BARRIER, |
+ SKIP_ICACHE_FLUSH); |
+ } else { |
+ DCHECK(new_code->IsForeign()); |
+ it.rinfo()->set_target_address( |
+ ExternalReference(Foreign::cast(new_code)->foreign_address(), |
+ it.rinfo()->isolate(), |
+ ExternalReference::BUILTIN_FP_FP_CALL) |
+ .address(), |
+ UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH); |
+ } |
} |
} |
} |
@@ -1383,12 +1394,25 @@ class WasmInstanceBuilder { |
module_name, function_name); |
return -1; |
} |
- |
- Handle<Code> import_wrapper = CompileImportWrapper( |
- index, import, Handle<JSReceiver>::cast(function), module_name, |
- function_name); |
- code_table->set(num_imported_functions, *import_wrapper); |
- RecordStats(isolate_, *import_wrapper); |
+ Handle<JSReceiver> function_as_receiver = |
+ Handle<JSReceiver>::cast(function); |
+ Handle<String> native_variant_key = |
+ isolate_->factory()->InternalizeUtf8String("native_variant"); |
+ MaybeHandle<Object> maybeObj = |
+ JSReceiver::GetProperty(function_as_receiver, native_variant_key); |
+ Handle<Object> native_variant; |
+ if (maybeObj.ToHandle(&native_variant) && |
+ native_variant->IsJSObject()) { |
+ Handle<Foreign> foreign(Foreign::cast( |
+ JSObject::cast(*native_variant)->GetInternalField(0))); |
+ code_table->set(num_imported_functions, *foreign); |
+ } else { |
+ Handle<Code> import_wrapper = |
+ CompileImportWrapper(index, import, function_as_receiver, |
+ module_name, function_name); |
+ code_table->set(num_imported_functions, *import_wrapper); |
+ RecordStats(isolate_, *import_wrapper); |
+ } |
num_imported_functions++; |
break; |
} |