Index: src/wasm/wasm-js.cc |
diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc |
index d3d8d4d02828caf9a46769c3ef887c9a9dca6769..6529810918bcac9ffecd17a57737cd70c349e026 100644 |
--- a/src/wasm/wasm-js.cc |
+++ b/src/wasm/wasm-js.cc |
@@ -195,8 +195,9 @@ i::MaybeHandle<i::JSObject> InstantiateModuleCommon( |
} |
i::MaybeHandle<i::FixedArray> compiled_module = |
- result.val->CompileFunctions(isolate); |
- if (!compiled_module.is_null()) { |
+ result.val->CompileFunctions(isolate, thrower); |
+ if (!thrower->error()) { |
+ DCHECK(!compiled_module.is_null()); |
object = i::wasm::WasmModule::Instantiate( |
isolate, compiled_module.ToHandleChecked(), ffi, memory); |
if (!object.is_null()) { |
@@ -296,22 +297,33 @@ void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
InstantiateModuleCommon(args, buffer.start, buffer.end, &thrower); |
} |
- |
static i::MaybeHandle<i::JSObject> CreateModuleObject( |
v8::Isolate* isolate, const v8::Local<v8::Value> source, |
ErrorThrower* thrower) { |
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
+ i::MaybeHandle<i::JSObject> nothing; |
RawBuffer buffer = GetRawBufferSource(source, thrower); |
if (buffer.start == nullptr) return i::MaybeHandle<i::JSObject>(); |
- // TODO(rossberg): Once we can, do compilation here. |
DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); |
+ i::Zone zone(i_isolate->allocator()); |
+ i::wasm::ModuleResult result = i::wasm::DecodeWasmModule( |
+ i_isolate, &zone, buffer.start, buffer.end, false, i::wasm::kWasmOrigin); |
+ std::unique_ptr<const i::wasm::WasmModule> decoded_module(result.val); |
+ if (result.failed()) { |
+ thrower->Failed("", result); |
+ return nothing; |
+ } |
+ i::MaybeHandle<i::FixedArray> compiled_module = |
+ decoded_module->CompileFunctions(i_isolate, thrower); |
+ if (compiled_module.is_null()) return nothing; |
Local<Context> context = isolate->GetCurrentContext(); |
i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
i::Handle<i::JSFunction> module_cons(i_context->wasm_module_constructor()); |
i::Handle<i::JSObject> module_obj = |
i_isolate->factory()->NewJSObject(module_cons); |
+ module_obj->SetInternalField(0, *compiled_module.ToHandleChecked()); |
i::Handle<i::Object> module_ref = Utils::OpenHandle(*source); |
i::Handle<i::Symbol> module_sym(i_context->wasm_module_sym()); |
i::Object::SetProperty(module_obj, module_sym, module_ref, i::STRICT).Check(); |
@@ -331,13 +343,15 @@ void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) { |
} |
i::MaybeHandle<i::JSObject> module_obj = |
CreateModuleObject(isolate, args[0], &thrower); |
- if (module_obj.is_null()) return; |
Local<Context> context = isolate->GetCurrentContext(); |
v8::Local<v8::Promise::Resolver> resolver; |
if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; |
- resolver->Resolve(context, Utils::ToLocal(module_obj.ToHandleChecked())); |
- |
+ if (thrower.error()) { |
+ resolver->Reject(context, Utils::ToLocal(thrower.Reify())); |
+ } else { |
+ resolver->Resolve(context, Utils::ToLocal(module_obj.ToHandleChecked())); |
+ } |
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
return_value.Set(resolver->GetPromise()); |
} |
@@ -363,25 +377,59 @@ void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { |
HandleScope scope(args.GetIsolate()); |
v8::Isolate* isolate = args.GetIsolate(); |
- ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), |
- "WebAssembly.Instance()"); |
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
+ |
+ ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); |
if (args.Length() < 1) { |
- thrower.Error("Argument 0 must be a WebAssembly.Module"); |
+ thrower.Error( |
+ "Argument 0 must be provided, and must be a WebAssembly.Module object"); |
return; |
} |
+ |
Local<Context> context = isolate->GetCurrentContext(); |
i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
i::Handle<i::Symbol> module_sym(i_context->wasm_module_sym()); |
i::MaybeHandle<i::Object> source = |
i::Object::GetProperty(Utils::OpenHandle(*args[0]), module_sym); |
- if (source.is_null()) return; |
+ if (source.is_null() || source.ToHandleChecked()->IsUndefined(i_isolate)) { |
+ thrower.Error("Argument 0 must be a WebAssembly.Module"); |
+ return; |
+ } |
- RawBuffer buffer = |
- GetRawBufferSource(Utils::ToLocal(source.ToHandleChecked()), &thrower); |
- if (buffer.start == nullptr) return; |
+ Local<Object> obj = Local<Object>::Cast(args[0]); |
- InstantiateModuleCommon(args, buffer.start, buffer.end, &thrower); |
+ i::Handle<i::JSObject> module_obj = |
+ i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj)); |
+ if (module_obj->GetInternalFieldCount() < 1 || |
+ !module_obj->GetInternalField(0)->IsFixedArray()) { |
+ thrower.Error("Argument 0 is an invalid WebAssembly.Module"); |
+ return; |
+ } |
+ |
+ i::Handle<i::FixedArray> compiled_code = i::Handle<i::FixedArray>( |
+ i::FixedArray::cast(module_obj->GetInternalField(0))); |
+ |
+ i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); |
+ if (args.Length() > 1 && args[1]->IsObject()) { |
+ Local<Object> obj = Local<Object>::Cast(args[1]); |
+ ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); |
+ } |
+ |
+ i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); |
+ if (args.Length() > 2 && args[2]->IsArrayBuffer()) { |
+ Local<Object> obj = Local<Object>::Cast(args[2]); |
+ i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); |
+ memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); |
+ } |
+ i::MaybeHandle<i::JSObject> instance = |
+ i::wasm::WasmModule::Instantiate(i_isolate, compiled_code, ffi, memory); |
+ if (instance.is_null()) { |
+ thrower.Error("Could not instantiate module"); |
+ return; |
+ } |
+ v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
+ return_value.Set(Utils::ToLocal(instance.ToHandleChecked())); |
} |
} // namespace |
@@ -478,6 +526,11 @@ void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
InstallFunc(isolate, wasm_object, "Module", WebAssemblyModule); |
Handle<JSFunction> instance_constructor = |
InstallFunc(isolate, wasm_object, "Instance", WebAssemblyInstance); |
+ i::Handle<i::Map> map = isolate->factory()->NewMap( |
+ i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + i::kPointerSize); |
+ module_constructor->set_prototype_or_initial_map(*map); |
+ map->SetConstructor(*module_constructor); |
+ |
context->set_wasm_module_constructor(*module_constructor); |
context->set_wasm_instance_constructor(*instance_constructor); |
} |