| Index: src/wasm/wasm-module.cc
|
| diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc
|
| index 3b442881139bebb03c320eda6f36f57942297a75..02d197c547b5ff8362c836b0f6d25c7fadad1ed7 100644
|
| --- a/src/wasm/wasm-module.cc
|
| +++ b/src/wasm/wasm-module.cc
|
| @@ -282,7 +282,8 @@ WasmModule::WasmModule()
|
| signatures(nullptr),
|
| functions(nullptr),
|
| data_segments(nullptr),
|
| - function_table(nullptr) {}
|
| + function_table(nullptr),
|
| + import_table(nullptr) {}
|
|
|
| WasmModule::~WasmModule() {
|
| if (globals) delete globals;
|
| @@ -290,8 +291,33 @@ WasmModule::~WasmModule() {
|
| if (functions) delete functions;
|
| if (data_segments) delete data_segments;
|
| if (function_table) delete function_table;
|
| + if (import_table) delete import_table;
|
| }
|
|
|
| +static MaybeHandle<JSFunction> LookupFunction(ErrorThrower& thrower,
|
| + Handle<JSObject> ffi,
|
| + uint32_t index,
|
| + Handle<String> name,
|
| + const char* cstr) {
|
| + if (!ffi.is_null()) {
|
| + MaybeHandle<Object> result = Object::GetProperty(ffi, name);
|
| + if (!result.is_null()) {
|
| + Handle<Object> obj = result.ToHandleChecked();
|
| + if (obj->IsJSFunction()) {
|
| + return Handle<JSFunction>::cast(obj);
|
| + } else {
|
| + thrower.Error("FFI function #%d:%s is not a JSFunction.", index, cstr);
|
| + return MaybeHandle<JSFunction>();
|
| + }
|
| + } else {
|
| + thrower.Error("FFI function #%d:%s not found.", index, cstr);
|
| + return MaybeHandle<JSFunction>();
|
| + }
|
| + } else {
|
| + thrower.Error("FFI table is not an object.");
|
| + return MaybeHandle<JSFunction>();
|
| + }
|
| +}
|
|
|
| // Instantiates a wasm module as a JSObject.
|
| // * allocates a backing store of {mem_size} bytes.
|
| @@ -312,6 +338,7 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
|
| JS_OBJECT_TYPE,
|
| JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
|
| WasmModuleInstance instance(this);
|
| + std::vector<Handle<Code>> import_code;
|
| instance.context = isolate->native_context();
|
| instance.js_object = factory->NewJSObjectFromMap(map, TENURED);
|
| Handle<FixedArray> code_table =
|
| @@ -351,10 +378,10 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
|
| }
|
|
|
| //-------------------------------------------------------------------------
|
| - // Compile all functions in the module.
|
| + // Compile wrappers to imported functions.
|
| //-------------------------------------------------------------------------
|
| - instance.function_table = BuildFunctionTable(isolate, this);
|
| uint32_t index = 0;
|
| + instance.function_table = BuildFunctionTable(isolate, this);
|
| WasmLinker linker(isolate, functions->size());
|
| ModuleEnv module_env;
|
| module_env.module = this;
|
| @@ -362,7 +389,28 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
|
| module_env.linker = &linker;
|
| module_env.asm_js = false;
|
|
|
| + if (import_table->size() > 0) {
|
| + instance.import_code = &import_code;
|
| + instance.import_code->reserve(import_table->size());
|
| + for (const WasmImport& import : *import_table) {
|
| + const char* cstr = GetName(import.function_name_offset);
|
| + Handle<String> name = factory->InternalizeUtf8String(cstr);
|
| + MaybeHandle<JSFunction> function =
|
| + LookupFunction(thrower, ffi, index, name, cstr);
|
| + if (function.is_null()) return MaybeHandle<JSObject>();
|
| + Handle<Code> code = compiler::CompileWasmToJSWrapper(
|
| + isolate, &module_env, function.ToHandleChecked(), import.sig, cstr);
|
| + instance.import_code->push_back(code);
|
| + index++;
|
| + }
|
| + }
|
| +
|
| + //-------------------------------------------------------------------------
|
| + // Compile all functions in the module.
|
| + //-------------------------------------------------------------------------
|
| +
|
| // First pass: compile each function and initialize the code table.
|
| + index = 0;
|
| for (const WasmFunction& func : *functions) {
|
| if (thrower.error()) break;
|
| DCHECK_EQ(index, func.func_index);
|
| @@ -373,27 +421,11 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
|
| Handle<JSFunction> function = Handle<JSFunction>::null();
|
| if (func.external) {
|
| // Lookup external function in FFI object.
|
| - if (!ffi.is_null()) {
|
| - MaybeHandle<Object> result = Object::GetProperty(ffi, name);
|
| - if (!result.is_null()) {
|
| - Handle<Object> obj = result.ToHandleChecked();
|
| - if (obj->IsJSFunction()) {
|
| - function = Handle<JSFunction>::cast(obj);
|
| - code = compiler::CompileWasmToJSWrapper(isolate, &module_env,
|
| - function, index);
|
| - } else {
|
| - thrower.Error("FFI function #%d:%s is not a JSFunction.", index,
|
| - cstr);
|
| - return MaybeHandle<JSObject>();
|
| - }
|
| - } else {
|
| - thrower.Error("FFI function #%d:%s not found.", index, cstr);
|
| - return MaybeHandle<JSObject>();
|
| - }
|
| - } else {
|
| - thrower.Error("FFI table is not an object.");
|
| - return MaybeHandle<JSObject>();
|
| - }
|
| + MaybeHandle<JSFunction> function =
|
| + LookupFunction(thrower, ffi, index, name, cstr);
|
| + if (function.is_null()) return MaybeHandle<JSObject>();
|
| + code = compiler::CompileWasmToJSWrapper(
|
| + isolate, &module_env, function.ToHandleChecked(), func.sig, cstr);
|
| } else {
|
| // Compile the function.
|
| code = compiler::CompileWasmFunction(thrower, isolate, &module_env, func);
|
| @@ -454,6 +486,13 @@ Handle<Code> ModuleEnv::GetFunctionCode(uint32_t index) {
|
| return Handle<Code>::null();
|
| }
|
|
|
| +Handle<Code> ModuleEnv::GetImportCode(uint32_t index) {
|
| + DCHECK(IsValidImport(index));
|
| + if (instance && instance->import_code) {
|
| + return instance->import_code->at(index);
|
| + }
|
| + return Handle<Code>::null();
|
| +}
|
|
|
| compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone,
|
| uint32_t index) {
|
|
|