| Index: src/wasm/wasm-module.cc
|
| diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc
|
| index fdec11b33fb572aac5fbc42a3145cef376484fd3..f5db1f00bb9d85be32bd689dd7ef19f245ba0c6f 100644
|
| --- a/src/wasm/wasm-module.cc
|
| +++ b/src/wasm/wasm-module.cc
|
| @@ -25,6 +25,12 @@ namespace v8 {
|
| namespace internal {
|
| namespace wasm {
|
|
|
| +enum JSFunctionExportInternalField {
|
| + kInternalModuleInstance,
|
| + kInternalArity,
|
| + kInternalSignature
|
| +};
|
| +
|
| static const int kPlaceholderMarker = 1000000000;
|
|
|
| static const char* wasmSections[] = {
|
| @@ -116,7 +122,7 @@ std::ostream& operator<<(std::ostream& os, const WasmFunctionName& pair) {
|
|
|
| Handle<JSFunction> WrapExportCodeAsJSFunction(
|
| Isolate* isolate, Handle<Code> export_code, Handle<String> name, int arity,
|
| - Handle<JSObject> module_instance) {
|
| + MaybeHandle<ByteArray> maybe_signature, Handle<JSObject> module_instance) {
|
| Handle<SharedFunctionInfo> shared =
|
| isolate->factory()->NewSharedFunctionInfo(name, export_code, false);
|
| shared->set_length(arity);
|
| @@ -125,7 +131,14 @@ Handle<JSFunction> WrapExportCodeAsJSFunction(
|
| isolate->wasm_function_map(), name, export_code);
|
| function->set_shared(*shared);
|
|
|
| - function->SetInternalField(0, *module_instance);
|
| + function->SetInternalField(kInternalModuleInstance, *module_instance);
|
| + // add another Internal Field as the function arity
|
| + function->SetInternalField(kInternalArity, Smi::FromInt(arity));
|
| + // add another Internal Field as the signature of the foreign function
|
| + Handle<ByteArray> signature;
|
| + if (maybe_signature.ToHandle(&signature)) {
|
| + function->SetInternalField(kInternalSignature, *signature);
|
| + }
|
| return function;
|
| }
|
|
|
| @@ -183,6 +196,7 @@ enum WasmExportMetadata {
|
| kExportName, // String
|
| kExportArity, // Smi, an int
|
| kExportedFunctionIndex, // Smi, an uint32_t
|
| + kExportedSignature, // ByteArray. A copy of the data in FunctionSig
|
| kWasmExportMetadataTableSize // Sentinel value.
|
| };
|
|
|
| @@ -648,8 +662,37 @@ bool CompileWrappersToImportedFunctions(Isolate* isolate,
|
| MaybeHandle<JSFunction> function = LookupFunction(
|
| *thrower, isolate->factory(), ffi, index, module_name, function_name);
|
| if (function.is_null()) return false;
|
| -
|
| - {
|
| + Handle<Code> code;
|
| + Handle<JSFunction> func = function.ToHandleChecked();
|
| + Handle<Code> export_wrapper_code = handle(func->code());
|
| + bool isMatch = false;
|
| + if (export_wrapper_code->kind() == Code::JS_TO_WASM_FUNCTION) {
|
| + int exported_param_count =
|
| + Smi::cast(func->GetInternalField(kInternalArity))->value();
|
| + Handle<ByteArray> exportedSig = Handle<ByteArray>(
|
| + ByteArray::cast(func->GetInternalField(kInternalSignature)));
|
| + if (exported_param_count == param_count &&
|
| + exportedSig->length() == sig_data->length() &&
|
| + memcmp(exportedSig->data(), sig_data->data(),
|
| + exportedSig->length()) == 0) {
|
| + isMatch = true;
|
| + }
|
| + }
|
| + if (isMatch) {
|
| + int wasm_count = 0;
|
| + int const mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
|
| + for (RelocIterator it(*export_wrapper_code, mask); !it.done();
|
| + it.next()) {
|
| + RelocInfo* rinfo = it.rinfo();
|
| + Address target_address = rinfo->target_address();
|
| + Code* target = Code::GetCodeFromTargetAddress(target_address);
|
| + if (target->kind() == Code::WASM_FUNCTION) {
|
| + ++wasm_count;
|
| + code = handle(target);
|
| + }
|
| + }
|
| + DCHECK(wasm_count == 1);
|
| + } else {
|
| // Copy the signature to avoid a raw pointer into a heap object when
|
| // GC can happen.
|
| Zone zone(isolate->allocator());
|
| @@ -659,12 +702,10 @@ bool CompileWrappersToImportedFunctions(Isolate* isolate,
|
| sizeof(MachineRepresentation) * sig_data_size);
|
| FunctionSig sig(ret_count, param_count, reps);
|
|
|
| - Handle<Code> code = compiler::CompileWasmToJSWrapper(
|
| - isolate, function.ToHandleChecked(), &sig, index, module_name,
|
| - function_name);
|
| -
|
| - imports.push_back(code);
|
| + code = compiler::CompileWasmToJSWrapper(isolate, func, &sig, index,
|
| + module_name, function_name);
|
| }
|
| + imports.push_back(code);
|
| }
|
| }
|
| return true;
|
| @@ -969,8 +1010,10 @@ bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate,
|
| Handle<String> name =
|
| export_metadata->GetValueChecked<String>(isolate, kExportName);
|
| int arity = Smi::cast(export_metadata->get(kExportArity))->value();
|
| + MaybeHandle<ByteArray> signature =
|
| + export_metadata->GetValue<ByteArray>(isolate, kExportedSignature);
|
| Handle<JSFunction> function = WrapExportCodeAsJSFunction(
|
| - isolate, export_code, name, arity, instance);
|
| + isolate, export_code, name, arity, signature, instance);
|
| desc.set_value(function);
|
| Maybe<bool> status = JSReceiver::DefineOwnProperty(
|
| isolate, exports_object, name, &desc, Object::THROW_ON_ERROR);
|
| @@ -1081,6 +1124,15 @@ MaybeHandle<FixedArray> WasmModule::CompileFunctions(
|
| Handle<FixedArray> export_metadata =
|
| factory->NewFixedArray(kWasmExportMetadataTableSize, TENURED);
|
| const WasmExport& exp = export_table[i];
|
| + FunctionSig* funcSig = functions[exp.func_index].sig;
|
| + Handle<ByteArray> exportedSig =
|
| + factory->NewByteArray(static_cast<int>(funcSig->parameter_count() +
|
| + funcSig->return_count()),
|
| + TENURED);
|
| + exportedSig->copy_in(0,
|
| + reinterpret_cast<const byte*>(funcSig->raw_data()),
|
| + exportedSig->length());
|
| + export_metadata->set(kExportedSignature, *exportedSig);
|
| WasmName str = GetName(exp.name_offset, exp.name_length);
|
| Handle<String> name = factory->InternalizeUtf8String(str);
|
| Handle<Code> code =
|
| @@ -1333,9 +1385,11 @@ MaybeHandle<JSObject> WasmModule::Instantiate(
|
| Handle<Code> startup_code =
|
| metadata->GetValueChecked<Code>(isolate, kExportCode);
|
| int arity = Smi::cast(metadata->get(kExportArity))->value();
|
| + MaybeHandle<ByteArray> startup_signature =
|
| + metadata->GetValue<ByteArray>(isolate, kExportedSignature);
|
| Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction(
|
| isolate, startup_code, factory->InternalizeUtf8String("start"), arity,
|
| - js_object);
|
| + startup_signature, js_object);
|
| RecordStats(isolate, *startup_code);
|
| // Call the JS function.
|
| Handle<Object> undefined = isolate->factory()->undefined_value();
|
|
|