[wasm] Introduce {JSPromise::Resolve} and {JSPromise::Reject}.

This prevents unnecessary switching back and forth between internal and
public API boundaries. It is also a step towards making all WebAssembly
internals completely independent of "scheduled exception" values.

R=ahaas@chromium.org

Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: I46e8cb4fad3d255d9bd20b9c343901a03a25426c
Reviewed-on: https://chromium-review.googlesource.com/895742
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51002}
This commit is contained in:
Michael Starzinger 2018-01-31 15:58:12 +01:00 committed by Commit Bot
parent ef98172d5d
commit dc08d4f870
5 changed files with 40 additions and 64 deletions

View File

@ -7401,11 +7401,9 @@ Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
ENTER_V8(isolate, context, Promise_Resolver, Resolve, Nothing<bool>(),
i::HandleScope);
auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
has_pending_exception =
i::Execution::Call(isolate, isolate->promise_resolve(),
isolate->factory()->undefined_value(), arraysize(argv),
argv)
i::JSPromise::Resolve(i::Handle<i::JSPromise>::cast(self),
Utils::OpenHandle(*value))
.is_null();
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(true);
@ -7424,14 +7422,9 @@ Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
ENTER_V8(isolate, context, Promise_Resolver, Reject, Nothing<bool>(),
i::HandleScope);
auto self = Utils::OpenHandle(this);
// We pass true to trigger the debugger's on exception handler.
i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value),
isolate->factory()->ToBoolean(true)};
has_pending_exception =
i::Execution::Call(isolate, isolate->promise_internal_reject(),
isolate->factory()->undefined_value(), arraysize(argv),
argv)
i::JSPromise::Reject(i::Handle<i::JSPromise>::cast(self),
Utils::OpenHandle(*value))
.is_null();
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
return Just(true);

View File

@ -15913,6 +15913,29 @@ const char* JSPromise::Status(v8::Promise::PromiseState status) {
UNREACHABLE();
}
// static
MaybeHandle<Object> JSPromise::Resolve(Handle<JSPromise> promise,
Handle<Object> value) {
Isolate* isolate = promise->GetIsolate();
Handle<Object> argv[] = {promise, value};
MaybeHandle<Object> result = Execution::Call(
isolate, isolate->promise_resolve(),
isolate->factory()->undefined_value(), arraysize(argv), argv);
return result;
}
// static
MaybeHandle<Object> JSPromise::Reject(Handle<JSPromise> promise,
Handle<Object> value) {
Isolate* isolate = promise->GetIsolate();
// We pass true to trigger the debugger's on exception handler.
Handle<Object> argv[] = {promise, value, isolate->factory()->ToBoolean(true)};
MaybeHandle<Object> result = Execution::Call(
isolate, isolate->promise_internal_reject(),
isolate->factory()->undefined_value(), arraysize(argv), argv);
return result;
}
namespace {
JSRegExp::Flags RegExpFlagsFromString(Handle<String> flags, bool* success) {

View File

@ -4018,6 +4018,12 @@ class JSPromise : public JSObject {
static const char* Status(v8::Promise::PromiseState status);
v8::Promise::PromiseState status() const;
// Resolve/reject the promise with a given value.
static MaybeHandle<Object> Resolve(Handle<JSPromise> promise,
Handle<Object> value);
static MaybeHandle<Object> Reject(Handle<JSPromise> promise,
Handle<Object> value);
DECL_CAST(JSPromise)
// Dispatched behavior.

View File

@ -448,24 +448,6 @@ MaybeHandle<WasmInstanceObject> InstantiateToInstanceObject(
return builder.Build();
}
void RejectPromise(Isolate* isolate, Handle<Context> context,
ErrorThrower& thrower, Handle<JSPromise> promise) {
Local<Promise::Resolver> resolver =
Utils::PromiseToLocal(promise).As<Promise::Resolver>();
auto maybe = resolver->Reject(Utils::ToLocal(context),
Utils::ToLocal(thrower.Reify()));
CHECK_IMPLIES(!maybe.FromMaybe(false), isolate->has_scheduled_exception());
}
void ResolvePromise(Isolate* isolate, Handle<Context> context,
Handle<JSPromise> promise, Handle<Object> result) {
Local<Promise::Resolver> resolver =
Utils::PromiseToLocal(promise).As<Promise::Resolver>();
auto maybe =
resolver->Resolve(Utils::ToLocal(context), Utils::ToLocal(result));
CHECK_IMPLIES(!maybe.FromMaybe(false), isolate->has_scheduled_exception());
}
Handle<Code> CompileLazyOnGCHeap(Isolate* isolate) {
HistogramTimerScope lazy_time_scope(
isolate->counters()->wasm_lazy_compilation_time());
@ -3477,14 +3459,14 @@ void AsyncCompileJob::AsyncCompileFailed(ErrorThrower& thrower) {
// {job} keeps the {this} pointer alive.
std::shared_ptr<AsyncCompileJob> job =
isolate_->wasm_engine()->compilation_manager()->RemoveJob(this);
RejectPromise(isolate_, context_, thrower, module_promise_);
JSPromise::Reject(module_promise_, thrower.Reify());
}
void AsyncCompileJob::AsyncCompileSucceeded(Handle<Object> result) {
// {job} keeps the {this} pointer alive.
std::shared_ptr<AsyncCompileJob> job =
isolate_->wasm_engine()->compilation_manager()->RemoveJob(this);
ResolvePromise(isolate_, context_, module_promise_, result);
JSPromise::Resolve(module_promise_, result);
}
// A closure to run a compilation step (either as foreground or background

View File

@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "src/wasm/wasm-engine.h"
#include "src/api.h"
#include "src/objects-inl.h"
#include "src/wasm/module-compiler.h"
@ -56,30 +56,6 @@ MaybeHandle<WasmInstanceObject> WasmEngine::SyncInstantiate(
memory);
}
namespace {
// TODO(titzer): these utilities are duplicated in module-compiler.cc
void WasmEngineRejectPromise(Isolate* isolate, Handle<Context> context,
ErrorThrower& thrower, Handle<JSPromise> promise) {
Local<Promise::Resolver> resolver =
Utils::PromiseToLocal(promise).As<Promise::Resolver>();
auto maybe = resolver->Reject(Utils::ToLocal(context),
Utils::ToLocal(thrower.Reify()));
CHECK_IMPLIES(!maybe.FromMaybe(false), isolate->has_scheduled_exception());
}
void WasmEngineResolvePromise(Isolate* isolate, Handle<Context> context,
Handle<JSPromise> promise,
Handle<Object> result) {
Local<Promise::Resolver> resolver =
Utils::PromiseToLocal(promise).As<Promise::Resolver>();
auto maybe =
resolver->Resolve(Utils::ToLocal(context), Utils::ToLocal(result));
CHECK_IMPLIES(!maybe.FromMaybe(false), isolate->has_scheduled_exception());
}
} // namespace
void WasmEngine::AsyncInstantiate(Isolate* isolate, Handle<JSPromise> promise,
Handle<WasmModuleObject> module_object,
MaybeHandle<JSReceiver> imports) {
@ -87,12 +63,10 @@ void WasmEngine::AsyncInstantiate(Isolate* isolate, Handle<JSPromise> promise,
MaybeHandle<WasmInstanceObject> instance_object = SyncInstantiate(
isolate, &thrower, module_object, imports, Handle<JSArrayBuffer>::null());
if (thrower.error()) {
WasmEngineRejectPromise(isolate, handle(isolate->context()), thrower,
promise);
JSPromise::Reject(promise, thrower.Reify());
return;
}
WasmEngineResolvePromise(isolate, handle(isolate->context()), promise,
instance_object.ToHandleChecked());
JSPromise::Resolve(promise, instance_object.ToHandleChecked());
}
void WasmEngine::AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
@ -113,13 +87,11 @@ void WasmEngine::AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
module_object = SyncCompile(isolate, &thrower, bytes);
}
if (thrower.error()) {
WasmEngineRejectPromise(isolate, handle(isolate->context()), thrower,
promise);
JSPromise::Reject(promise, thrower.Reify());
return;
}
Handle<WasmModuleObject> module = module_object.ToHandleChecked();
WasmEngineResolvePromise(isolate, handle(isolate->context()), promise,
module);
JSPromise::Resolve(promise, module);
return;
}