| Index: src/wasm/wasm-js.cc
|
| diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc
|
| index c6f72f67d16486d823c9c9128d512586b386fa22..26431d48343afa083e976a4b9e86e75d979439ed 100644
|
| --- a/src/wasm/wasm-js.cc
|
| +++ b/src/wasm/wasm-js.cc
|
| @@ -177,6 +177,12 @@ void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| thrower.TypeError("Argument 0 must be a buffer source");
|
| return;
|
| }
|
| +
|
| + if (args.Length() > 2) {
|
| + thrower.LinkError(
|
| + "WebAssembly.instantiate accepts no more than 2 parameters");
|
| + return;
|
| + }
|
| i::MaybeHandle<i::JSObject> module_obj =
|
| CreateModuleObject(isolate, args[0], &thrower);
|
| if (module_obj.is_null()) return;
|
| @@ -185,7 +191,48 @@ void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked()));
|
| }
|
|
|
| -void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| +MaybeLocal<Value> InstantiateModuleImpl(
|
| + i::Isolate* i_isolate, i::Handle<i::JSObject> i_module_obj,
|
| + const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
|
| + // It so happens that in both the WebAssembly.instantiate, as well as
|
| + // WebAssembly.Instance ctor, the positions of the ffi object and memory
|
| + // are the same. If that changes later, we refactor the consts into
|
| + // parameters.
|
| + static const int kFfiOffset = 1;
|
| + static const int kMemOffset = 2;
|
| +
|
| + MaybeLocal<Value> nothing;
|
| + i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null();
|
| + if (args.Length() > kFfiOffset && args[kFfiOffset]->IsObject()) {
|
| + Local<Object> obj = Local<Object>::Cast(args[kFfiOffset]);
|
| + ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
|
| + }
|
| +
|
| + i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null();
|
| + if (args.Length() > kMemOffset && args[kMemOffset]->IsObject()) {
|
| + Local<Object> obj = Local<Object>::Cast(args[kMemOffset]);
|
| + i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj);
|
| + if (i::WasmJs::IsWasmMemoryObject(i_isolate, mem_obj)) {
|
| + memory = i::Handle<i::JSArrayBuffer>(
|
| + i::Handle<i::WasmMemoryObject>::cast(mem_obj)->buffer(), i_isolate);
|
| + } else {
|
| + thrower->TypeError("Argument %d must be a WebAssembly.Memory",
|
| + kMemOffset);
|
| + return nothing;
|
| + }
|
| + }
|
| + i::MaybeHandle<i::JSObject> instance = i::wasm::WasmModule::Instantiate(
|
| + i_isolate, thrower, i_module_obj, ffi, memory);
|
| + if (instance.is_null()) {
|
| + if (!thrower->error())
|
| + thrower->RuntimeError("Could not instantiate module");
|
| + return nothing;
|
| + }
|
| + DCHECK(!i_isolate->has_pending_exception());
|
| + return Utils::ToLocal(instance.ToHandleChecked());
|
| +}
|
| +
|
| +void WebAssemblyInstanceCtor(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| HandleScope scope(args.GetIsolate());
|
| v8::Isolate* isolate = args.GetIsolate();
|
| i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| @@ -205,37 +252,51 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| return;
|
| }
|
|
|
| - Local<Object> obj = Local<Object>::Cast(args[0]);
|
| - i::Handle<i::JSObject> i_obj =
|
| - i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj));
|
| + Local<Object> module_obj = Local<Object>::Cast(args[0]);
|
| + i::Handle<i::JSObject> i_module_obj =
|
| + i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*module_obj));
|
|
|
| - 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));
|
| + MaybeLocal<Value> instance =
|
| + InstantiateModuleImpl(i_isolate, i_module_obj, args, &thrower);
|
| + if (instance.IsEmpty()) return;
|
| +
|
| + v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
| + return_value.Set(instance.ToLocalChecked());
|
| +}
|
| +
|
| +void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| + v8::Isolate* isolate = args.GetIsolate();
|
| + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| +
|
| + HandleScope scope(isolate);
|
| + ErrorThrower thrower(i_isolate, "WebAssembly.compile()");
|
| +
|
| + if (args.Length() < 1) {
|
| + thrower.TypeError("Argument 0 must be a buffer source");
|
| + return;
|
| }
|
| + i::MaybeHandle<i::JSObject> module_obj =
|
| + CreateModuleObject(isolate, args[0], &thrower);
|
|
|
| - i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null();
|
| - if (args.Length() > 2 && args[2]->IsObject()) {
|
| - Local<Object> obj = Local<Object>::Cast(args[2]);
|
| - i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj);
|
| - if (i::WasmJs::IsWasmMemoryObject(i_isolate, mem_obj)) {
|
| - memory = i::Handle<i::JSArrayBuffer>(
|
| - i::Handle<i::WasmMemoryObject>::cast(mem_obj)->buffer(), i_isolate);
|
| + Local<Context> context = isolate->GetCurrentContext();
|
| + v8::Local<v8::Promise::Resolver> resolver;
|
| + if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return;
|
| + if (module_obj.is_null()) {
|
| + DCHECK(thrower.error());
|
| + resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
|
| + } else {
|
| + MaybeLocal<Value> instance = InstantiateModuleImpl(
|
| + i_isolate, module_obj.ToHandleChecked(), args, &thrower);
|
| + if (instance.IsEmpty()) {
|
| + DCHECK(thrower.error());
|
| + resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
|
| } else {
|
| - thrower.TypeError("Argument 2 must be a WebAssembly.Memory");
|
| - return;
|
| + DCHECK(!thrower.error());
|
| + resolver->Resolve(context, instance.ToLocalChecked());
|
| }
|
| }
|
| - i::MaybeHandle<i::JSObject> instance =
|
| - i::wasm::WasmModule::Instantiate(i_isolate, &thrower, i_obj, ffi, memory);
|
| - if (instance.is_null()) {
|
| - if (!thrower.error()) thrower.RuntimeError("Could not instantiate module");
|
| - return;
|
| - }
|
| - DCHECK(!i_isolate->has_pending_exception());
|
| v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
| - return_value.Set(Utils::ToLocal(instance.ToHandleChecked()));
|
| + return_value.Set(resolver->GetPromise());
|
| }
|
|
|
| bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
|
| @@ -641,9 +702,12 @@ void WasmJs::InstallWasmConstructors(Isolate* isolate,
|
| // Setup compile
|
| InstallFunc(isolate, webassembly, "compile", WebAssemblyCompile, 1);
|
|
|
| - // Setup compile
|
| + // Setup validate
|
| InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate, 1);
|
|
|
| + // Setup instantiate
|
| + InstallFunc(isolate, webassembly, "instantiate", WebAssemblyInstantiate, 1);
|
| +
|
| // Setup Module
|
| Handle<JSFunction> module_constructor =
|
| InstallFunc(isolate, webassembly, "Module", WebAssemblyModule, 1);
|
| @@ -659,7 +723,7 @@ void WasmJs::InstallWasmConstructors(Isolate* isolate,
|
|
|
| // Setup Instance
|
| Handle<JSFunction> instance_constructor =
|
| - InstallFunc(isolate, webassembly, "Instance", WebAssemblyInstance, 1);
|
| + InstallFunc(isolate, webassembly, "Instance", WebAssemblyInstanceCtor, 1);
|
| context->set_wasm_instance_constructor(*instance_constructor);
|
|
|
| // Setup Table
|
|
|