Commit 47702c53 authored by Mircea Trofin's avatar Mircea Trofin Committed by Commit Bot

[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: 's avatarBrad Nelson <bradnelson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45411}
parent fc738f1e
......@@ -137,6 +137,34 @@ i::MaybeHandle<i::JSReceiver> GetValueAsImports(Local<Value> arg,
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
void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
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(bytes, imports) ->
// {module: WebAssembly.Module, instance: WebAssembly.Instance}
......@@ -871,8 +926,12 @@ void WasmJs::Install(Isolate* isolate) {
JSObject::AddProperty(webassembly, factory->to_string_tag_symbol(),
v8_str(isolate, "WebAssembly"), ro_attributes);
InstallFunc(isolate, webassembly, "compile", WebAssemblyCompile, 1);
InstallFunc(isolate, webassembly, "compileStreaming",
WebAssemblyCompileStreaming, 1);
InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate, 1);
InstallFunc(isolate, webassembly, "instantiate", WebAssemblyInstantiate, 1);
InstallFunc(isolate, webassembly, "instantiateStreaming",
WebAssemblyInstantiateStreaming, 1);
// Setup Module
Handle<JSFunction> module_constructor =
......
......@@ -20,14 +20,30 @@ var module = new WebAssembly.Module(buffer);
var wrapper = [module];
assertPromiseResult(
WebAssembly.instantiate(wrapper),
WebAssembly.instantiateStreaming(wrapper),
assertUnreachable,
e => assertTrue(e instanceof TypeError));
assertPromiseResult(
WebAssembly.compileStreaming(wrapper),
assertUnreachable,
e => assertTrue(e instanceof TypeError));
assertPromiseResult(
(() => {
%SetWasmCompileFromPromiseOverload();
return WebAssembly.compileStreaming(wrapper);
})(),
module => {
assertTrue(module instanceof WebAssembly.Module);
%ResetWasmOverloads();
},
assertUnreachable);
assertPromiseResult(
(() => {
%SetWasmCompileFromPromiseOverload();
return WebAssembly.instantiate(wrapper);
return WebAssembly.instantiateStreaming(wrapper);
})(),
pair => {
assertTrue(pair.instance instanceof WebAssembly.Instance);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment