Commit 035ba1d8 authored by Andreas Haas's avatar Andreas Haas Committed by V8 LUCI CQ

[wasm] Use the API callback to resolve the wasm result promise

This CL switches resolving and rejecting the wasm result promise from
the V8-internal API to the external API added in
https://chromium-review.googlesource.com/c/v8/v8/+/3695584.

This CL can land once Chrome provided an implementation of the callback.

R=jkummerow@chromium.org

Bug: v8:12953
Change-Id: I3ca395594b4e7b5018fdcdac8c215dd4d6bf8de0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3695589
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81206}
parent 97eff73b
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include <cstring> #include <cstring>
#include "include/v8-function.h" #include "include/v8-function.h"
#include "include/v8-persistent-handle.h"
#include "include/v8-promise.h"
#include "include/v8-wasm.h" #include "include/v8-wasm.h"
#include "src/api/api-inl.h" #include "src/api/api-inl.h"
#include "src/api/api-natives.h" #include "src/api/api-natives.h"
...@@ -264,56 +266,57 @@ i::MaybeHandle<i::JSFunction> GetFirstArgumentAsJSFunction( ...@@ -264,56 +266,57 @@ i::MaybeHandle<i::JSFunction> GetFirstArgumentAsJSFunction(
return i::Handle<i::JSFunction>::cast(arg0); return i::Handle<i::JSFunction>::cast(arg0);
} }
i::MaybeHandle<i::JSReceiver> GetValueAsImports(Local<Value> arg, namespace {
ErrorThrower* thrower) { i::MaybeHandle<i::JSReceiver> ImportsAsMaybeReceiver(Local<Value> ffi) {
if (arg->IsUndefined()) return {}; if (ffi->IsUndefined()) return {};
if (!arg->IsObject()) { Local<Object> obj = Local<Object>::Cast(ffi);
thrower->TypeError("Argument 1 must be an object");
return {};
}
Local<Object> obj = Local<Object>::Cast(arg);
return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
} }
namespace {
// This class resolves the result of WebAssembly.compile. It just places the // This class resolves the result of WebAssembly.compile. It just places the
// compilation result in the supplied {promise}. // compilation result in the supplied {promise}.
class AsyncCompilationResolver : public i::wasm::CompilationResultResolver { class AsyncCompilationResolver : public i::wasm::CompilationResultResolver {
public: public:
AsyncCompilationResolver(i::Isolate* isolate, i::Handle<i::JSPromise> promise) AsyncCompilationResolver(Isolate* isolate, Local<Context> context,
: promise_(isolate->global_handles()->Create(*promise)) { Local<Promise::Resolver> promise_resolver)
i::GlobalHandles::AnnotateStrongRetainer(promise_.location(), : isolate_(isolate),
kGlobalPromiseHandle); context_(isolate, context),
} promise_resolver_(isolate, promise_resolver) {
context_.SetWeak();
~AsyncCompilationResolver() override { promise_resolver_.AnnotateStrongRetainer(kGlobalPromiseHandle);
i::GlobalHandles::Destroy(promise_.location());
} }
void OnCompilationSucceeded(i::Handle<i::WasmModuleObject> result) override { void OnCompilationSucceeded(i::Handle<i::WasmModuleObject> result) override {
if (finished_) return; if (finished_) return;
finished_ = true; finished_ = true;
i::MaybeHandle<i::Object> promise_result = if (context_.IsEmpty()) return;
i::JSPromise::Resolve(promise_, result); auto callback = reinterpret_cast<i::Isolate*>(isolate_)
CHECK_EQ(promise_result.is_null(), ->wasm_async_resolve_promise_callback();
promise_->GetIsolate()->has_pending_exception()); CHECK(callback);
callback(isolate_, context_.Get(isolate_), promise_resolver_.Get(isolate_),
Utils::ToLocal(i::Handle<i::Object>::cast(result)),
WasmAsyncSuccess::kSuccess);
} }
void OnCompilationFailed(i::Handle<i::Object> error_reason) override { void OnCompilationFailed(i::Handle<i::Object> error_reason) override {
if (finished_) return; if (finished_) return;
finished_ = true; finished_ = true;
i::MaybeHandle<i::Object> promise_result = if (context_.IsEmpty()) return;
i::JSPromise::Reject(promise_, error_reason); auto callback = reinterpret_cast<i::Isolate*>(isolate_)
CHECK_EQ(promise_result.is_null(), ->wasm_async_resolve_promise_callback();
promise_->GetIsolate()->has_pending_exception()); CHECK(callback);
callback(isolate_, context_.Get(isolate_), promise_resolver_.Get(isolate_),
Utils::ToLocal(error_reason), WasmAsyncSuccess::kFail);
} }
private: private:
static constexpr char kGlobalPromiseHandle[] = static constexpr char kGlobalPromiseHandle[] =
"AsyncCompilationResolver::promise_"; "AsyncCompilationResolver::promise_";
bool finished_ = false; bool finished_ = false;
i::Handle<i::JSPromise> promise_; Isolate* isolate_;
Global<Context> context_;
Global<Promise::Resolver> promise_resolver_;
}; };
constexpr char AsyncCompilationResolver::kGlobalPromiseHandle[]; constexpr char AsyncCompilationResolver::kGlobalPromiseHandle[];
...@@ -323,36 +326,41 @@ constexpr char AsyncCompilationResolver::kGlobalPromiseHandle[]; ...@@ -323,36 +326,41 @@ constexpr char AsyncCompilationResolver::kGlobalPromiseHandle[];
class InstantiateModuleResultResolver class InstantiateModuleResultResolver
: public i::wasm::InstantiationResultResolver { : public i::wasm::InstantiationResultResolver {
public: public:
InstantiateModuleResultResolver(i::Isolate* isolate, InstantiateModuleResultResolver(Isolate* isolate, Local<Context> context,
i::Handle<i::JSPromise> promise) Local<Promise::Resolver> promise_resolver)
: promise_(isolate->global_handles()->Create(*promise)) { : isolate_(isolate),
i::GlobalHandles::AnnotateStrongRetainer(promise_.location(), context_(isolate, context),
kGlobalPromiseHandle); promise_resolver_(isolate, promise_resolver) {
} context_.SetWeak();
promise_resolver_.AnnotateStrongRetainer(kGlobalPromiseHandle);
~InstantiateModuleResultResolver() override {
i::GlobalHandles::Destroy(promise_.location());
} }
void OnInstantiationSucceeded( void OnInstantiationSucceeded(
i::Handle<i::WasmInstanceObject> instance) override { i::Handle<i::WasmInstanceObject> instance) override {
i::MaybeHandle<i::Object> promise_result = if (context_.IsEmpty()) return;
i::JSPromise::Resolve(promise_, instance); auto callback = reinterpret_cast<i::Isolate*>(isolate_)
CHECK_EQ(promise_result.is_null(), ->wasm_async_resolve_promise_callback();
promise_->GetIsolate()->has_pending_exception()); CHECK(callback);
callback(isolate_, context_.Get(isolate_), promise_resolver_.Get(isolate_),
Utils::ToLocal(i::Handle<i::Object>::cast(instance)),
WasmAsyncSuccess::kSuccess);
} }
void OnInstantiationFailed(i::Handle<i::Object> error_reason) override { void OnInstantiationFailed(i::Handle<i::Object> error_reason) override {
i::MaybeHandle<i::Object> promise_result = if (context_.IsEmpty()) return;
i::JSPromise::Reject(promise_, error_reason); auto callback = reinterpret_cast<i::Isolate*>(isolate_)
CHECK_EQ(promise_result.is_null(), ->wasm_async_resolve_promise_callback();
promise_->GetIsolate()->has_pending_exception()); CHECK(callback);
callback(isolate_, context_.Get(isolate_), promise_resolver_.Get(isolate_),
Utils::ToLocal(error_reason), WasmAsyncSuccess::kFail);
} }
private: private:
static constexpr char kGlobalPromiseHandle[] = static constexpr char kGlobalPromiseHandle[] =
"InstantiateModuleResultResolver::promise_"; "InstantiateModuleResultResolver::promise_";
i::Handle<i::JSPromise> promise_; Isolate* isolate_;
Global<Context> context_;
Global<Promise::Resolver> promise_resolver_;
}; };
constexpr char InstantiateModuleResultResolver::kGlobalPromiseHandle[]; constexpr char InstantiateModuleResultResolver::kGlobalPromiseHandle[];
...@@ -363,49 +371,47 @@ constexpr char InstantiateModuleResultResolver::kGlobalPromiseHandle[]; ...@@ -363,49 +371,47 @@ constexpr char InstantiateModuleResultResolver::kGlobalPromiseHandle[];
class InstantiateBytesResultResolver class InstantiateBytesResultResolver
: public i::wasm::InstantiationResultResolver { : public i::wasm::InstantiationResultResolver {
public: public:
InstantiateBytesResultResolver(i::Isolate* isolate, InstantiateBytesResultResolver(Isolate* isolate, Local<Context> context,
i::Handle<i::JSPromise> promise, Local<Promise::Resolver> promise_resolver,
i::Handle<i::WasmModuleObject> module) Local<Value> module)
: isolate_(isolate), : isolate_(isolate),
promise_(isolate_->global_handles()->Create(*promise)), context_(isolate, context),
module_(isolate_->global_handles()->Create(*module)) { promise_resolver_(isolate, promise_resolver),
i::GlobalHandles::AnnotateStrongRetainer(promise_.location(), module_(isolate, module) {
kGlobalPromiseHandle); context_.SetWeak();
i::GlobalHandles::AnnotateStrongRetainer(module_.location(), promise_resolver_.AnnotateStrongRetainer(kGlobalPromiseHandle);
kGlobalModuleHandle); module_.AnnotateStrongRetainer(kGlobalModuleHandle);
}
~InstantiateBytesResultResolver() override {
i::GlobalHandles::Destroy(promise_.location());
i::GlobalHandles::Destroy(module_.location());
} }
void OnInstantiationSucceeded( void OnInstantiationSucceeded(
i::Handle<i::WasmInstanceObject> instance) override { i::Handle<i::WasmInstanceObject> instance) override {
if (context_.IsEmpty()) return;
Local<Context> context = context_.Get(isolate_);
// The result is a JSObject with 2 fields which contain the // The result is a JSObject with 2 fields which contain the
// WasmInstanceObject and the WasmModuleObject. // WasmInstanceObject and the WasmModuleObject.
i::Handle<i::JSObject> result = Local<Object> result = Object::New(isolate_);
isolate_->factory()->NewJSObject(isolate_->object_function()); result->Set(context, v8_str(isolate_, "module"), module_.Get(isolate_))
.Check();
i::Handle<i::String> instance_name = result
isolate_->factory()->NewStringFromStaticChars("instance"); ->Set(context, v8_str(isolate_, "instance"),
Utils::ToLocal(i::Handle<i::Object>::cast(instance)))
.Check();
i::Handle<i::String> module_name = auto callback = reinterpret_cast<i::Isolate*>(isolate_)
isolate_->factory()->NewStringFromStaticChars("module"); ->wasm_async_resolve_promise_callback();
CHECK(callback);
i::JSObject::AddProperty(isolate_, result, instance_name, instance, callback(isolate_, context, promise_resolver_.Get(isolate_), result,
i::NONE); WasmAsyncSuccess::kSuccess);
i::JSObject::AddProperty(isolate_, result, module_name, module_, i::NONE);
i::MaybeHandle<i::Object> promise_result =
i::JSPromise::Resolve(promise_, result);
CHECK_EQ(promise_result.is_null(), isolate_->has_pending_exception());
} }
void OnInstantiationFailed(i::Handle<i::Object> error_reason) override { void OnInstantiationFailed(i::Handle<i::Object> error_reason) override {
i::MaybeHandle<i::Object> promise_result = if (context_.IsEmpty()) return;
i::JSPromise::Reject(promise_, error_reason); auto callback = reinterpret_cast<i::Isolate*>(isolate_)
CHECK_EQ(promise_result.is_null(), isolate_->has_pending_exception()); ->wasm_async_resolve_promise_callback();
CHECK(callback);
callback(isolate_, context_.Get(isolate_), promise_resolver_.Get(isolate_),
Utils::ToLocal(error_reason), WasmAsyncSuccess::kFail);
} }
private: private:
...@@ -413,9 +419,10 @@ class InstantiateBytesResultResolver ...@@ -413,9 +419,10 @@ class InstantiateBytesResultResolver
"InstantiateBytesResultResolver::promise_"; "InstantiateBytesResultResolver::promise_";
static constexpr char kGlobalModuleHandle[] = static constexpr char kGlobalModuleHandle[] =
"InstantiateBytesResultResolver::module_"; "InstantiateBytesResultResolver::module_";
i::Isolate* isolate_; Isolate* isolate_;
i::Handle<i::JSPromise> promise_; Global<Context> context_;
i::Handle<i::WasmModuleObject> module_; Global<Promise::Resolver> promise_resolver_;
Global<Value> module_;
}; };
constexpr char InstantiateBytesResultResolver::kGlobalPromiseHandle[]; constexpr char InstantiateBytesResultResolver::kGlobalPromiseHandle[];
...@@ -428,45 +435,37 @@ class AsyncInstantiateCompileResultResolver ...@@ -428,45 +435,37 @@ class AsyncInstantiateCompileResultResolver
: public i::wasm::CompilationResultResolver { : public i::wasm::CompilationResultResolver {
public: public:
AsyncInstantiateCompileResultResolver( AsyncInstantiateCompileResultResolver(
i::Isolate* isolate, i::Handle<i::JSPromise> promise, Isolate* isolate, Local<Context> context,
i::MaybeHandle<i::JSReceiver> maybe_imports) Local<Promise::Resolver> promise_resolver, Local<Value> imports)
: isolate_(isolate), : isolate_(isolate),
promise_(isolate_->global_handles()->Create(*promise)), context_(isolate, context),
maybe_imports_(maybe_imports.is_null() promise_resolver_(isolate, promise_resolver),
? maybe_imports imports_(isolate, imports) {
: isolate_->global_handles()->Create( context_.SetWeak();
*maybe_imports.ToHandleChecked())) { promise_resolver_.AnnotateStrongRetainer(kGlobalPromiseHandle);
i::GlobalHandles::AnnotateStrongRetainer(promise_.location(), imports_.AnnotateStrongRetainer(kGlobalImportsHandle);
kGlobalPromiseHandle);
if (!maybe_imports_.is_null()) {
i::GlobalHandles::AnnotateStrongRetainer(
maybe_imports_.ToHandleChecked().location(), kGlobalImportsHandle);
}
}
~AsyncInstantiateCompileResultResolver() override {
i::GlobalHandles::Destroy(promise_.location());
if (!maybe_imports_.is_null()) {
i::GlobalHandles::Destroy(maybe_imports_.ToHandleChecked().location());
}
} }
void OnCompilationSucceeded(i::Handle<i::WasmModuleObject> result) override { void OnCompilationSucceeded(i::Handle<i::WasmModuleObject> result) override {
if (finished_) return; if (finished_) return;
finished_ = true; finished_ = true;
i::wasm::GetWasmEngine()->AsyncInstantiate( i::wasm::GetWasmEngine()->AsyncInstantiate(
isolate_, reinterpret_cast<i::Isolate*>(isolate_),
std::make_unique<InstantiateBytesResultResolver>(isolate_, promise_, std::make_unique<InstantiateBytesResultResolver>(
result), isolate_, context_.Get(isolate_), promise_resolver_.Get(isolate_),
result, maybe_imports_); Utils::ToLocal(i::Handle<i::Object>::cast(result))),
result, ImportsAsMaybeReceiver(imports_.Get(isolate_)));
} }
void OnCompilationFailed(i::Handle<i::Object> error_reason) override { void OnCompilationFailed(i::Handle<i::Object> error_reason) override {
if (finished_) return; if (finished_) return;
finished_ = true; finished_ = true;
i::MaybeHandle<i::Object> promise_result = if (context_.IsEmpty()) return;
i::JSPromise::Reject(promise_, error_reason); auto callback = reinterpret_cast<i::Isolate*>(isolate_)
CHECK_EQ(promise_result.is_null(), isolate_->has_pending_exception()); ->wasm_async_resolve_promise_callback();
CHECK(callback);
callback(isolate_, context_.Get(isolate_), promise_resolver_.Get(isolate_),
Utils::ToLocal(error_reason), WasmAsyncSuccess::kFail);
} }
private: private:
...@@ -475,9 +474,10 @@ class AsyncInstantiateCompileResultResolver ...@@ -475,9 +474,10 @@ class AsyncInstantiateCompileResultResolver
static constexpr char kGlobalImportsHandle[] = static constexpr char kGlobalImportsHandle[] =
"AsyncInstantiateCompileResultResolver::module_"; "AsyncInstantiateCompileResultResolver::module_";
bool finished_ = false; bool finished_ = false;
i::Isolate* isolate_; Isolate* isolate_;
i::Handle<i::JSPromise> promise_; Global<Context> context_;
i::MaybeHandle<i::JSReceiver> maybe_imports_; Global<Promise::Resolver> promise_resolver_;
Global<Value> imports_;
}; };
constexpr char AsyncInstantiateCompileResultResolver::kGlobalPromiseHandle[]; constexpr char AsyncInstantiateCompileResultResolver::kGlobalPromiseHandle[];
...@@ -543,7 +543,7 @@ void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -543,7 +543,7 @@ void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
return_value.Set(promise); return_value.Set(promise);
std::shared_ptr<i::wasm::CompilationResultResolver> resolver( std::shared_ptr<i::wasm::CompilationResultResolver> resolver(
new AsyncCompilationResolver(i_isolate, Utils::OpenHandle(*promise))); new AsyncCompilationResolver(isolate, context, promise_resolver));
bool is_shared = false; bool is_shared = false;
auto bytes = GetFirstArgumentAsBytes(args, &thrower, &is_shared); auto bytes = GetFirstArgumentAsBytes(args, &thrower, &is_shared);
...@@ -600,14 +600,14 @@ void WebAssemblyCompileStreaming( ...@@ -600,14 +600,14 @@ void WebAssemblyCompileStreaming(
Local<Context> context = isolate->GetCurrentContext(); Local<Context> context = isolate->GetCurrentContext();
// Create and assign the return value of this function. // Create and assign the return value of this function.
ASSIGN(Promise::Resolver, result_resolver, Promise::Resolver::New(context)); ASSIGN(Promise::Resolver, promise_resolver, Promise::Resolver::New(context));
Local<Promise> promise = result_resolver->GetPromise(); Local<Promise> promise = promise_resolver->GetPromise();
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
return_value.Set(promise); return_value.Set(promise);
// Prepare the CompilationResultResolver for the compilation. // Prepare the CompilationResultResolver for the compilation.
auto resolver = std::make_shared<AsyncCompilationResolver>( auto resolver = std::make_shared<AsyncCompilationResolver>(isolate, context,
i_isolate, Utils::OpenHandle(*promise)); promise_resolver);
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) { if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
thrower.CompileError("Wasm code generation disallowed by embedder"); thrower.CompileError("Wasm code generation disallowed by embedder");
...@@ -842,12 +842,16 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -842,12 +842,16 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
i::Handle<i::WasmModuleObject> module_obj = maybe_module.ToHandleChecked(); i::Handle<i::WasmModuleObject> module_obj = maybe_module.ToHandleChecked();
i::MaybeHandle<i::JSReceiver> maybe_imports = Local<Value> ffi = args[1];
GetValueAsImports(args[1], &thrower);
if (!ffi->IsUndefined() && !ffi->IsObject()) {
thrower.TypeError("Argument 1 must be an object");
return;
}
if (thrower.error()) return; if (thrower.error()) return;
maybe_instance_obj = i::wasm::GetWasmEngine()->SyncInstantiate( maybe_instance_obj = i::wasm::GetWasmEngine()->SyncInstantiate(
i_isolate, &thrower, module_obj, maybe_imports, i_isolate, &thrower, module_obj, ImportsAsMaybeReceiver(ffi),
i::MaybeHandle<i::JSArrayBuffer>()); i::MaybeHandle<i::JSArrayBuffer>());
} }
...@@ -896,8 +900,7 @@ void WebAssemblyInstantiateStreaming( ...@@ -896,8 +900,7 @@ void WebAssemblyInstantiateStreaming(
// Create an InstantiateResultResolver in case there is an issue with the // Create an InstantiateResultResolver in case there is an issue with the
// passed parameters. // passed parameters.
std::unique_ptr<i::wasm::InstantiationResultResolver> resolver( std::unique_ptr<i::wasm::InstantiationResultResolver> resolver(
new InstantiateModuleResultResolver(i_isolate, new InstantiateModuleResultResolver(isolate, context, result_resolver));
Utils::OpenHandle(*promise)));
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) { if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
thrower.CompileError("Wasm code generation disallowed by embedder"); thrower.CompileError("Wasm code generation disallowed by embedder");
...@@ -907,10 +910,9 @@ void WebAssemblyInstantiateStreaming( ...@@ -907,10 +910,9 @@ void WebAssemblyInstantiateStreaming(
// If args.Length < 2, this will be undefined - see FunctionCallbackInfo. // If args.Length < 2, this will be undefined - see FunctionCallbackInfo.
Local<Value> ffi = args[1]; Local<Value> ffi = args[1];
i::MaybeHandle<i::JSReceiver> maybe_imports =
GetValueAsImports(ffi, &thrower);
if (thrower.error()) { if (!ffi->IsUndefined() && !ffi->IsObject()) {
thrower.TypeError("Argument 1 must be an object");
resolver->OnInstantiationFailed(thrower.Reify()); resolver->OnInstantiationFailed(thrower.Reify());
return; return;
} }
...@@ -920,8 +922,8 @@ void WebAssemblyInstantiateStreaming( ...@@ -920,8 +922,8 @@ void WebAssemblyInstantiateStreaming(
resolver.reset(); resolver.reset();
std::shared_ptr<i::wasm::CompilationResultResolver> compilation_resolver( std::shared_ptr<i::wasm::CompilationResultResolver> compilation_resolver(
new AsyncInstantiateCompileResultResolver( new AsyncInstantiateCompileResultResolver(isolate, context,
i_isolate, Utils::OpenHandle(*promise), maybe_imports)); result_resolver, ffi));
// Allocate the streaming decoder in a Managed so we can pass it to the // Allocate the streaming decoder in a Managed so we can pass it to the
// embedder. // embedder.
...@@ -978,8 +980,7 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -978,8 +980,7 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(promise); args.GetReturnValue().Set(promise);
std::unique_ptr<i::wasm::InstantiationResultResolver> resolver( std::unique_ptr<i::wasm::InstantiationResultResolver> resolver(
new InstantiateModuleResultResolver(i_isolate, new InstantiateModuleResultResolver(isolate, context, promise_resolver));
Utils::OpenHandle(*promise)));
Local<Value> first_arg_value = args[0]; 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(*first_arg_value);
...@@ -992,10 +993,9 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -992,10 +993,9 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
// If args.Length < 2, this will be undefined - see FunctionCallbackInfo. // If args.Length < 2, this will be undefined - see FunctionCallbackInfo.
Local<Value> ffi = args[1]; Local<Value> ffi = args[1];
i::MaybeHandle<i::JSReceiver> maybe_imports =
GetValueAsImports(ffi, &thrower);
if (thrower.error()) { if (!ffi->IsUndefined() && !ffi->IsObject()) {
thrower.TypeError("Argument 1 must be an object");
resolver->OnInstantiationFailed(thrower.Reify()); resolver->OnInstantiationFailed(thrower.Reify());
return; return;
} }
...@@ -1005,7 +1005,8 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -1005,7 +1005,8 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
i::Handle<i::WasmModuleObject>::cast(first_arg); i::Handle<i::WasmModuleObject>::cast(first_arg);
i::wasm::GetWasmEngine()->AsyncInstantiate(i_isolate, std::move(resolver), i::wasm::GetWasmEngine()->AsyncInstantiate(i_isolate, std::move(resolver),
module_obj, maybe_imports); module_obj,
ImportsAsMaybeReceiver(ffi));
return; return;
} }
...@@ -1021,8 +1022,8 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -1021,8 +1022,8 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
resolver.reset(); resolver.reset();
std::shared_ptr<i::wasm::CompilationResultResolver> compilation_resolver( std::shared_ptr<i::wasm::CompilationResultResolver> compilation_resolver(
new AsyncInstantiateCompileResultResolver( new AsyncInstantiateCompileResultResolver(isolate, context,
i_isolate, Utils::OpenHandle(*promise), maybe_imports)); promise_resolver, ffi));
// The first parameter is a buffer source, we have to check if we are allowed // The first parameter is a buffer source, we have to check if we are allowed
// to compile it. // to compile it.
......
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