diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-08 10:51:43 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-08 11:38:59 +0000 |
commit | 1785e2c1eb5a3b9a9a97ef3125c8f444d9b62afb (patch) | |
tree | 47bf29ba77179ac9b5e60f60ff1b8c50b94f1ab1 | |
parent | 492afe7432c1d2df39983ce8842b80dcf39dee4b (diff) |
[Backport] Merged: [wasm] Call AsyncInstantiate directly when instantiating a module objectv5.11.0-rc2v5.11.0
WebAssembly.instantiate is polymorphic, it can either take a module
object as parameter, or a buffer source which should be compiled first.
To share code between the two implementations, the module object was
first passed to a promise (i.e. which is the result of compilation).
However, passing the module object to a promise has a side effect if
the module object has a then function. To avoid this side effect I
remove this code sharing and call AsyncInstantiate directly in case
the parameter is a module object.
NOTRY=true
NOPRESUBMIT=true
NOTREECHECK=true
R=​mstarzinger@chromium.org
Bug: chromium:836141
Reviewed-on: https://chromium-review.googlesource.com/1025774
Reviewed-on: https://chromium-review.googlesource.com/1027875
Change-Id: I66837c83f01760e6b5e141394e0043d0547c6f69
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r-- | chromium/v8/src/wasm/wasm-js.cc | 71 |
1 files changed, 32 insertions, 39 deletions
diff --git a/chromium/v8/src/wasm/wasm-js.cc b/chromium/v8/src/wasm/wasm-js.cc index ce2bf42455b..aa3f2b3f11f 100644 --- a/chromium/v8/src/wasm/wasm-js.cc +++ b/chromium/v8/src/wasm/wasm-js.cc @@ -322,25 +322,7 @@ MaybeLocal<Value> WebAssemblyInstantiateImpl(Isolate* isolate, return Utils::ToLocal(instance_object.ToHandleChecked()); } -// Entered as internal implementation detail of sync and async instantiate. -// args[0] *must* be a WebAssembly.Module. -void WebAssemblyInstantiateImplCallback( - const v8::FunctionCallbackInfo<v8::Value>& args) { - DCHECK_GE(args.Length(), 1); - v8::Isolate* isolate = args.GetIsolate(); - MicrotasksScope does_not_run_microtasks(isolate, - MicrotasksScope::kDoNotRunMicrotasks); - - HandleScope scope(args.GetIsolate()); - Local<Value> module = args[0]; - Local<Value> ffi = args.Data(); - Local<Value> instance; - if (WebAssemblyInstantiateImpl(isolate, module, ffi).ToLocal(&instance)) { - args.GetReturnValue().Set(instance); - } -} - -void WebAssemblyInstantiateToPairCallback( +void WebAssemblyInstantiateCallback( const v8::FunctionCallbackInfo<v8::Value>& args) { DCHECK_GE(args.Length(), 1); Isolate* isolate = args.GetIsolate(); @@ -429,7 +411,7 @@ void WebAssemblyInstantiateStreaming( DCHECK(!module_promise.IsEmpty()); Local<Value> data = args[1]; ASSIGN(Function, instantiate_impl, - Function::New(context, WebAssemblyInstantiateToPairCallback, data)); + Function::New(context, WebAssemblyInstantiateCallback, data)); ASSIGN(Promise, result, module_promise->Then(context, instantiate_impl)); args.GetReturnValue().Set(result); } @@ -452,10 +434,12 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { Local<Context> context = isolate->GetCurrentContext(); ASSIGN(Promise::Resolver, resolver, Promise::Resolver::New(context)); - Local<Promise> module_promise = resolver->GetPromise(); - args.GetReturnValue().Set(module_promise); + Local<Promise> promise = resolver->GetPromise(); + args.GetReturnValue().Set(promise); Local<Value> first_arg_value = args[0]; + // If args.Length < 2, this will be undefined - see FunctionCallbackInfo. + Local<Value> ffi = args[1]; i::Handle<i::Object> first_arg = Utils::OpenHandle(*first_arg_value); if (!first_arg->IsJSObject()) { thrower.TypeError( @@ -466,26 +450,35 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { return; } - FunctionCallback instantiator = nullptr; if (first_arg->IsWasmModuleObject()) { - module_promise = resolver->GetPromise(); - if (!resolver->Resolve(context, first_arg_value).IsJust()) return; - instantiator = WebAssemblyInstantiateImplCallback; - } else { - ASSIGN(Function, async_compile, Function::New(context, WebAssemblyCompile)); - ASSIGN(Value, async_compile_retval, - async_compile->Call(context, args.Holder(), 1, &first_arg_value)); - module_promise = Local<Promise>::Cast(async_compile_retval); - instantiator = WebAssemblyInstantiateToPairCallback; + i::Handle<i::WasmModuleObject> module_obj = + i::Handle<i::WasmModuleObject>::cast(first_arg); + // If args.Length < 2, this will be undefined - see FunctionCallbackInfo. + i::MaybeHandle<i::JSReceiver> maybe_imports = + GetValueAsImports(ffi, &thrower); + + if (thrower.error()) { + auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify())); + CHECK_IMPLIES(!maybe.FromMaybe(false), + i_isolate->has_scheduled_exception()); + return; + } + + i::wasm::AsyncInstantiate( + i_isolate, Utils::OpenHandle(*promise), module_obj, maybe_imports); + return; } - DCHECK(!module_promise.IsEmpty()); - DCHECK_NOT_NULL(instantiator); - // If args.Length < 2, this will be undefined - see FunctionCallbackInfo. - // We'll check for that in WebAssemblyInstantiateImpl. - Local<Value> data = args[1]; + + // We did not get a WasmModuleObject as input, we first have to compile the + // input. + ASSIGN(Function, async_compile, Function::New(context, WebAssemblyCompile)); + ASSIGN(Value, async_compile_retval, + async_compile->Call(context, args.Holder(), 1, &first_arg_value)); + promise = Local<Promise>::Cast(async_compile_retval); + DCHECK(!promise.IsEmpty()); ASSIGN(Function, instantiate_impl, - Function::New(context, instantiator, data)); - ASSIGN(Promise, result, module_promise->Then(context, instantiate_impl)); + Function::New(context, WebAssemblyInstantiateCallback, ffi)); + ASSIGN(Promise, result, promise->Then(context, instantiate_impl)); args.GetReturnValue().Set(result); } |