Chromium Code Reviews| Index: src/wasm/wasm-module.cc |
| diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc |
| index 3b442881139bebb03c320eda6f36f57942297a75..2366bb0c3ec60e3dc1346398c0dd7deef29eb3ae 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); |
|
bradnelson
2016/02/19 06:43:57
This will fix things crashing if a proxy object is
titzer
2016/02/19 11:53:47
It's the same as the code before, just factored in
|
| + 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. |
| @@ -351,10 +377,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 +388,28 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, |
| module_env.linker = &linker; |
| module_env.asm_js = false; |
| + if (import_table->size() > 0) { |
| + instance.import_code = new std::vector<Handle<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 +420,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 +485,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) { |