Chromium Code Reviews| Index: src/wasm/wasm-module.cc |
| diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc |
| index ce65b9b729a8b34710b27fd59495f6b49f44036a..6796d5100d9228d18888b052cfc6ebc1da1c56c6 100644 |
| --- a/src/wasm/wasm-module.cc |
| +++ b/src/wasm/wasm-module.cc |
| @@ -116,7 +116,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) { |
| + Handle<ByteArray> signature, Handle<JSObject> module_instance) { |
| Handle<SharedFunctionInfo> shared = |
| isolate->factory()->NewSharedFunctionInfo(name, export_code, false); |
| shared->set_length(arity); |
| @@ -126,6 +126,10 @@ Handle<JSFunction> WrapExportCodeAsJSFunction( |
| function->set_shared(*shared); |
| function->SetInternalField(0, *module_instance); |
| + // add another Internal Field as the shared function |
| + function->SetInternalField(1, *shared); |
| + // add another Internal Field as the signature of the foreign function |
| + function->SetInternalField(2, *signature); |
|
Mircea Trofin
2016/08/01 23:38:32
This might fail, because we only specified a grand
|
| return function; |
| } |
| @@ -183,6 +187,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. |
| }; |
| @@ -671,7 +676,47 @@ bool CompileWrappersToImportedFunctions(Isolate* isolate, |
| *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 = true; |
| + if (export_wrapper_code->kind() == Code::JS_TO_WASM_FUNCTION) { |
| + Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>( |
| + SharedFunctionInfo::cast(func->GetInternalField(1))); |
| + int exported_param_count = shared->length(); |
| + // check whether two functions have same param count |
|
Mircea Trofin
2016/08/01 23:38:32
You should get the parameter count from the wasm f
|
| + if (exported_param_count != param_count) isMatch = false; |
| + Handle<ByteArray> exportedSig = |
| + Handle<ByteArray>(ByteArray::cast(func->GetInternalField(2))); |
|
Mircea Trofin
2016/08/01 23:38:32
why continue computing exportedSig if isMatch=fals
|
| + // check whether two functions have same signature |
| + if (exportedSig->length() == sig_data->length()) { |
| + for (int i = 0; i < exportedSig->length(); i++) { |
| + if (exportedSig->get(i) != sig_data->get(i)) { |
| + isMatch = false; |
| + break; |
| + } |
| + } |
| + } else { |
| + isMatch = false; |
| + } |
| + 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++; |
|
Mircea Trofin
2016/08/01 23:38:32
++wasm_count
|
| + code = handle(target); |
| + } |
| + } |
| + CHECK(wasm_count == 1); |
|
Mircea Trofin
2016/08/01 23:38:32
DCHECK
|
| + } |
| + } |
| + if (export_wrapper_code->kind() != Code::JS_TO_WASM_FUNCTION || |
| + !isMatch) { |
| // Copy the signature to avoid a raw pointer into a heap object when |
| // GC can happen. |
| Zone zone(isolate->allocator()); |
| @@ -681,12 +726,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; |
| @@ -990,8 +1033,10 @@ bool SetupExportsObject(Handle<FixedArray> compiled_module, Isolate* isolate, |
| Handle<String> name = |
| export_metadata->GetValueChecked<String>(kExportName); |
| int arity = Smi::cast(export_metadata->get(kExportArity))->value(); |
| + Handle<ByteArray> signature = |
| + export_metadata->GetValueChecked<ByteArray>(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); |
| @@ -1095,6 +1140,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 = |
| @@ -1331,9 +1385,11 @@ MaybeHandle<JSObject> WasmModule::Instantiate( |
| HandleScope scope(isolate); |
| Handle<Code> startup_code = metadata->GetValueChecked<Code>(kExportCode); |
| int arity = Smi::cast(metadata->get(kExportArity))->value(); |
| + Handle<ByteArray> startup_signature = |
| + metadata->GetValueChecked<ByteArray>(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(); |