[wasm] {compile|instantiate}Streaming

As per spec, (https://github.com/WebAssembly/design/pull/1068), we
don't have compile/instantiate overloads anymore, instead, we
have explicitly named members.

This change introduces the new APIs, implements instantiateStreaming
based on compileStreaming, and uses the existing embedder mechanism.
It does not yet remove the functionality from compile/instantiate -
we do that after we adopt the new APIs on the blink side.

Also, it temporarily handles exceptions on the v8 side, which is also
something we'll move to the blink side.

Bug: 
Change-Id: I77673b1c0d395dfcf13b2f25464fd5dfd99c8d82
Reviewed-on: https://chromium-review.googlesource.com/508852
Commit-Queue: Brad Nelson <bradnelson@chromium.org>
Reviewed-by: Brad Nelson <bradnelson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45411}
This commit is contained in:
Mircea Trofin 2017-05-18 14:43:54 -07:00 committed by Commit Bot
parent fc738f1e32
commit 47702c53bc
2 changed files with 77 additions and 2 deletions

View File

@ -137,6 +137,34 @@ i::MaybeHandle<i::JSReceiver> GetValueAsImports(Local<Value> arg,
return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
} }
void RejectResponseAPI(const v8::FunctionCallbackInfo<v8::Value>& args,
ErrorThrower* thrower) {
v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate);
Local<Context> context = isolate->GetCurrentContext();
ASSIGN(Promise::Resolver, resolver, Promise::Resolver::New(context));
Local<Promise> module_promise = resolver->GetPromise();
args.GetReturnValue().Set(module_promise);
thrower->TypeError(
"Argument 0 must be provided and must be a Response or Response promise");
auto maybe = resolver->Reject(context, Utils::ToLocal(thrower->Reify()));
CHECK_IMPLIES(!maybe.FromMaybe(false), i_isolate->has_scheduled_exception());
}
void WebAssemblyCompileStreaming(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
MicrotasksScope runs_microtasks(isolate, MicrotasksScope::kRunMicrotasks);
if (!i_isolate->wasm_compile_callback()(args)) {
ErrorThrower thrower(i_isolate, "WebAssembly.compileStreaming()");
RejectResponseAPI(args, &thrower);
}
}
// WebAssembly.compile(bytes) -> Promise // WebAssembly.compile(bytes) -> Promise
void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) { void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
@ -362,6 +390,33 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
} }
} }
void WebAssemblyInstantiateStreaming(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
// we use i_isolate in DCHECKS in the ASSIGN statements.
USE(i_isolate);
MicrotasksScope runs_microtasks(isolate, MicrotasksScope::kRunMicrotasks);
HandleScope scope(isolate);
Local<Context> context = isolate->GetCurrentContext();
ASSIGN(Promise::Resolver, resolver, Promise::Resolver::New(context));
Local<Value> first_arg_value = args[0];
ASSIGN(Function, compileStreaming,
Function::New(context, WebAssemblyCompileStreaming));
ASSIGN(Value, compile_retval,
compileStreaming->Call(context, args.Holder(), 1, &first_arg_value));
Local<Promise> module_promise = Local<Promise>::Cast(compile_retval);
DCHECK(!module_promise.IsEmpty());
Local<Value> data = args[1];
ASSIGN(Function, instantiate_impl,
Function::New(context, WebAssemblyInstantiateToPairCallback, data));
ASSIGN(Promise, result, module_promise->Then(context, instantiate_impl));
args.GetReturnValue().Set(result);
}
// WebAssembly.instantiate(module, imports) -> WebAssembly.Instance // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance
// WebAssembly.instantiate(bytes, imports) -> // WebAssembly.instantiate(bytes, imports) ->
// {module: WebAssembly.Module, instance: WebAssembly.Instance} // {module: WebAssembly.Module, instance: WebAssembly.Instance}
@ -871,8 +926,12 @@ void WasmJs::Install(Isolate* isolate) {
JSObject::AddProperty(webassembly, factory->to_string_tag_symbol(), JSObject::AddProperty(webassembly, factory->to_string_tag_symbol(),
v8_str(isolate, "WebAssembly"), ro_attributes); v8_str(isolate, "WebAssembly"), ro_attributes);
InstallFunc(isolate, webassembly, "compile", WebAssemblyCompile, 1); InstallFunc(isolate, webassembly, "compile", WebAssemblyCompile, 1);
InstallFunc(isolate, webassembly, "compileStreaming",
WebAssemblyCompileStreaming, 1);
InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate, 1); InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate, 1);
InstallFunc(isolate, webassembly, "instantiate", WebAssemblyInstantiate, 1); InstallFunc(isolate, webassembly, "instantiate", WebAssemblyInstantiate, 1);
InstallFunc(isolate, webassembly, "instantiateStreaming",
WebAssemblyInstantiateStreaming, 1);
// Setup Module // Setup Module
Handle<JSFunction> module_constructor = Handle<JSFunction> module_constructor =

View File

@ -20,14 +20,30 @@ var module = new WebAssembly.Module(buffer);
var wrapper = [module]; var wrapper = [module];
assertPromiseResult( assertPromiseResult(
WebAssembly.instantiate(wrapper), WebAssembly.instantiateStreaming(wrapper),
assertUnreachable,
e => assertTrue(e instanceof TypeError));
assertPromiseResult(
WebAssembly.compileStreaming(wrapper),
assertUnreachable, assertUnreachable,
e => assertTrue(e instanceof TypeError)); e => assertTrue(e instanceof TypeError));
assertPromiseResult( assertPromiseResult(
(() => { (() => {
%SetWasmCompileFromPromiseOverload(); %SetWasmCompileFromPromiseOverload();
return WebAssembly.instantiate(wrapper); return WebAssembly.compileStreaming(wrapper);
})(),
module => {
assertTrue(module instanceof WebAssembly.Module);
%ResetWasmOverloads();
},
assertUnreachable);
assertPromiseResult(
(() => {
%SetWasmCompileFromPromiseOverload();
return WebAssembly.instantiateStreaming(wrapper);
})(), })(),
pair => { pair => {
assertTrue(pair.instance instanceof WebAssembly.Instance); assertTrue(pair.instance instanceof WebAssembly.Instance);