Index: src/wasm/wasm-js.cc |
diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc |
index 396f8987a69c9637789b52c0b3303fd04fc6fbee..3b275d19ecccc1444274f0fe60f93fe177d40dbb 100644 |
--- a/src/wasm/wasm-js.cc |
+++ b/src/wasm/wasm-js.cc |
@@ -32,18 +32,6 @@ |
namespace { |
-#define ASSIGN(type, var, expr) \ |
- Local<type> var; \ |
- do { \ |
- if (!expr.ToLocal(&var)) return; \ |
- } while (false) |
- |
-#define DO_BOOL(expr) \ |
- do { \ |
- bool ok; \ |
- if (!expr.To(&ok) || !ok) return; \ |
- } while (false) |
- |
// TODO(wasm): move brand check to the respective types, and don't throw |
// in it, rather, use a provided ErrorThrower, or let caller handle it. |
static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> sym) { |
@@ -129,15 +117,16 @@ |
return i::wasm::ModuleWireBytes(start, start + length); |
} |
-i::MaybeHandle<i::JSReceiver> GetValueAsImports(const Local<Value>& arg, |
- ErrorThrower* thrower) { |
- if (arg->IsUndefined()) return {}; |
- |
- if (!arg->IsObject()) { |
+i::MaybeHandle<i::JSReceiver> GetSecondArgumentAsImports( |
+ const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) { |
+ if (args.Length() < 2) return {}; |
+ if (args[1]->IsUndefined()) return {}; |
+ |
+ if (!args[1]->IsObject()) { |
thrower->TypeError("Argument 1 must be an object"); |
return {}; |
} |
- Local<Object> obj = Local<Object>::Cast(arg); |
+ Local<Object> obj = Local<Object>::Cast(args[1]); |
return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); |
} |
@@ -151,7 +140,8 @@ |
ErrorThrower thrower(i_isolate, "WebAssembly.compile()"); |
Local<Context> context = isolate->GetCurrentContext(); |
- ASSIGN(Promise::Resolver, resolver, Promise::Resolver::New(context)); |
+ v8::Local<v8::Promise::Resolver> resolver; |
+ if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; |
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
return_value.Set(resolver->GetPromise()); |
@@ -263,70 +253,10 @@ |
args.GetReturnValue().Set(Utils::ToLocal(custom_sections)); |
} |
-// Entered as internal implementation detail of sync and async instantiate. |
-// args[0] *must* be a WebAssembly.Module. |
-void WebAssemblyInstantiateImpl( |
- const v8::FunctionCallbackInfo<v8::Value>& args) { |
- DCHECK_GE(args.Length(), 1); |
- Local<Value> module = args[0]; |
- Local<Value> ffi = args.Data(); |
- |
- HandleScope scope(args.GetIsolate()); |
- v8::Isolate* isolate = args.GetIsolate(); |
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
- ErrorThrower thrower(i_isolate, "WebAssembly Instantiation"); |
- i::MaybeHandle<i::JSReceiver> maybe_imports = |
- GetValueAsImports(ffi, &thrower); |
- if (thrower.error()) return; |
- |
- i::Handle<i::WasmModuleObject> module_obj = |
- i::Handle<i::WasmModuleObject>::cast( |
- Utils::OpenHandle(Object::Cast(*module))); |
- i::MaybeHandle<i::Object> instance_object = |
- i::wasm::SyncInstantiate(i_isolate, &thrower, module_obj, maybe_imports, |
- i::MaybeHandle<i::JSArrayBuffer>()); |
- |
- if (instance_object.is_null()) { |
- // TODO(wasm): this *should* mean there's an error to throw, but |
- // we exit sometimes the instantiation pipeline without throwing. |
- // v8:6232. |
- return; |
- } |
- args.GetReturnValue().Set(Utils::ToLocal(instance_object.ToHandleChecked())); |
-} |
- |
-void WebAssemblyInstantiateToPair( |
- const v8::FunctionCallbackInfo<v8::Value>& args) { |
- DCHECK_GE(args.Length(), 1); |
- Local<Value> module = args[0]; |
- Isolate* isolate = args.GetIsolate(); |
- Local<Context> context = isolate->GetCurrentContext(); |
- |
- const uint8_t* instance_str = reinterpret_cast<const uint8_t*>("instance"); |
- const uint8_t* module_str = reinterpret_cast<const uint8_t*>("module"); |
- ASSIGN(Function, vanilla_instantiate, |
- Function::New(context, WebAssemblyInstantiateImpl, args.Data())); |
- |
- ASSIGN(Value, instance, |
- vanilla_instantiate->Call(context, args.Holder(), 1, &module)); |
- Local<Object> ret = Object::New(isolate); |
- ASSIGN(String, instance_name, |
- String::NewFromOneByte(isolate, instance_str, |
- NewStringType::kInternalized)); |
- ASSIGN(String, module_name, |
- String::NewFromOneByte(isolate, module_str, |
- NewStringType::kInternalized)); |
- |
- DO_BOOL(ret->CreateDataProperty(context, instance_name, instance)); |
- DO_BOOL(ret->CreateDataProperty(context, module_name, module)); |
- args.GetReturnValue().Set(ret); |
-} |
- |
// new WebAssembly.Instance(module, imports) -> WebAssembly.Instance |
void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { |
HandleScope scope(args.GetIsolate()); |
- Isolate* isolate = args.GetIsolate(); |
- Local<Context> context = isolate->GetCurrentContext(); |
+ v8::Isolate* isolate = args.GetIsolate(); |
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
if (i_isolate->wasm_instance_callback()(args)) return; |
@@ -335,15 +265,14 @@ |
auto maybe_module = GetFirstArgumentAsModule(args, &thrower); |
if (thrower.error()) return; |
- // If args.Length < 2, this will be undefined - see FunctionCallbackInfo. |
- // We'll check for that in WebAssemblyInstantiateImpl. |
- Local<Value> data = args[1]; |
- |
- ASSIGN(Function, impl, |
- Function::New(context, WebAssemblyInstantiateImpl, data)); |
- Local<Value> first_param = args[0]; |
- ASSIGN(Value, ret, impl->Call(context, args.Holder(), 1, &first_param)); |
- args.GetReturnValue().Set(ret); |
+ auto maybe_imports = GetSecondArgumentAsImports(args, &thrower); |
+ if (thrower.error()) return; |
+ |
+ i::MaybeHandle<i::Object> instance_object = i::wasm::SyncInstantiate( |
+ i_isolate, &thrower, maybe_module.ToHandleChecked(), maybe_imports, |
+ i::MaybeHandle<i::JSArrayBuffer>()); |
+ if (instance_object.is_null()) return; |
+ args.GetReturnValue().Set(Utils::ToLocal(instance_object.ToHandleChecked())); |
} |
// WebAssembly.instantiate(module, imports) -> WebAssembly.Instance |
@@ -361,9 +290,10 @@ |
Local<Context> context = isolate->GetCurrentContext(); |
i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
- ASSIGN(Promise::Resolver, resolver, Promise::Resolver::New(context)); |
- Local<Promise> module_promise = resolver->GetPromise(); |
- args.GetReturnValue().Set(module_promise); |
+ v8::Local<v8::Promise::Resolver> resolver; |
+ if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; |
+ v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
+ return_value.Set(resolver->GetPromise()); |
if (args.Length() < 1) { |
thrower.TypeError( |
@@ -375,8 +305,7 @@ |
return; |
} |
- Local<Value> first_arg_value = args[0]; |
- i::Handle<i::Object> first_arg = Utils::OpenHandle(*first_arg_value); |
+ i::Handle<i::Object> first_arg = Utils::OpenHandle(*args[0]); |
if (!first_arg->IsJSObject()) { |
thrower.TypeError( |
"Argument 0 must be a buffer source or a WebAssembly.Module object"); |
@@ -386,27 +315,31 @@ |
return; |
} |
- FunctionCallback instantiator = nullptr; |
+ auto maybe_imports = GetSecondArgumentAsImports(args, &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::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise()); |
if (HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()))) { |
- module_promise = resolver->GetPromise(); |
- DO_BOOL(resolver->Resolve(context, first_arg_value)); |
- instantiator = WebAssemblyInstantiateImpl; |
+ // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance |
+ auto module_object = GetFirstArgumentAsModule(args, &thrower); |
+ i::wasm::AsyncInstantiate(i_isolate, promise, |
+ module_object.ToHandleChecked(), maybe_imports); |
} 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 = WebAssemblyInstantiateToPair; |
- } |
- 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]; |
- ASSIGN(Function, instantiate_impl, |
- Function::New(context, instantiator, data)); |
- ASSIGN(Promise, result, module_promise->Then(context, instantiate_impl)); |
- args.GetReturnValue().Set(result); |
+ // WebAssembly.instantiate(bytes, imports) -> {module, instance} |
+ auto bytes = GetFirstArgumentAsBytes(args, &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::AsyncCompileAndInstantiate(i_isolate, promise, bytes, |
+ maybe_imports); |
+ } |
} |
bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, |