[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:
parent
fc738f1e32
commit
47702c53bc
@ -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 =
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user