[promises] Port PromiseCapabilityDefault* to torque.

Bug: v8:9838
Change-Id: I8f1ca56517c4de097cab7e5fbd63ef3fe56d8f8c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1904120
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Reviewed-by: Sathya Gunasekaran  <gsathya@chromium.org>
Commit-Queue: Joshua Litt <joshualitt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64923}
This commit is contained in:
Joshua Litt 2019-11-11 15:57:22 -08:00 committed by Commit Bot
parent 72b652e8f7
commit 8fe297617f
3 changed files with 67 additions and 73 deletions

View File

@ -748,11 +748,6 @@ namespace internal {
/* ES #sec-promise-resolve-functions */ \
/* Starting at step 6 of "Promise Resolve Functions" */ \
TFS(ResolvePromise, kPromise, kResolution) \
/* ES #sec-promise-reject-functions */ \
TFJ(PromiseCapabilityDefaultReject, 1, kReceiver, kReason) \
/* ES #sec-promise-resolve-functions */ \
TFJ(PromiseCapabilityDefaultResolve, 1, kReceiver, kResolution) \
/* ES6 #sec-getcapabilitiesexecutor-functions */ \
TFJ(PromiseGetCapabilitiesExecutor, 2, kReceiver, kResolve, kReject) \
TFJ(PromiseConstructorLazyDeoptContinuation, 4, kReceiver, kPromise, \
kReject, kException, kResult) \

View File

@ -630,72 +630,6 @@ void PromiseBuiltinsAssembler::SetPromiseHandledByIfTrue(
BIND(&done);
}
// ES #sec-promise-reject-functions
TF_BUILTIN(PromiseCapabilityDefaultReject, PromiseBuiltinsAssembler) {
Node* const reason = Parameter(Descriptor::kReason);
Node* const context = Parameter(Descriptor::kContext);
// 2. Let promise be F.[[Promise]].
const TNode<Object> promise =
LoadContextElement(context, PromiseBuiltins::kPromiseSlot);
// 3. Let alreadyResolved be F.[[AlreadyResolved]].
Label if_already_resolved(this, Label::kDeferred);
const TNode<Object> already_resolved =
LoadContextElement(context, PromiseBuiltins::kAlreadyResolvedSlot);
// 4. If alreadyResolved.[[Value]] is true, return undefined.
GotoIf(IsTrue(already_resolved), &if_already_resolved);
// 5. Set alreadyResolved.[[Value]] to true.
StoreContextElementNoWriteBarrier(
context, PromiseBuiltins::kAlreadyResolvedSlot, TrueConstant());
// 6. Return RejectPromise(promise, reason).
const TNode<Object> debug_event =
LoadContextElement(context, PromiseBuiltins::kDebugEventSlot);
Return(CallBuiltin(Builtins::kRejectPromise, context, promise, reason,
debug_event));
BIND(&if_already_resolved);
{
Return(CallRuntime(Runtime::kPromiseRejectAfterResolved, context, promise,
reason));
}
}
// ES #sec-promise-resolve-functions
TF_BUILTIN(PromiseCapabilityDefaultResolve, PromiseBuiltinsAssembler) {
Node* const resolution = Parameter(Descriptor::kResolution);
Node* const context = Parameter(Descriptor::kContext);
// 2. Let promise be F.[[Promise]].
const TNode<Object> promise =
LoadContextElement(context, PromiseBuiltins::kPromiseSlot);
// 3. Let alreadyResolved be F.[[AlreadyResolved]].
Label if_already_resolved(this, Label::kDeferred);
const TNode<Object> already_resolved =
LoadContextElement(context, PromiseBuiltins::kAlreadyResolvedSlot);
// 4. If alreadyResolved.[[Value]] is true, return undefined.
GotoIf(IsTrue(already_resolved), &if_already_resolved);
// 5. Set alreadyResolved.[[Value]] to true.
StoreContextElementNoWriteBarrier(
context, PromiseBuiltins::kAlreadyResolvedSlot, TrueConstant());
// The rest of the logic (and the catch prediction) is
// encapsulated in the dedicated ResolvePromise builtin.
Return(CallBuiltin(Builtins::kResolvePromise, context, promise, resolution));
BIND(&if_already_resolved);
{
Return(CallRuntime(Runtime::kPromiseResolveAfterResolved, context, promise,
resolution));
}
}
TF_BUILTIN(PromiseConstructorLazyDeoptContinuation, PromiseBuiltinsAssembler) {
Node* promise = Parameter(Descriptor::kPromise);
Node* reject = Parameter(Descriptor::kReject);

View File

@ -7,7 +7,15 @@
namespace runtime {
extern transitioning runtime
RejectPromise(implicit context: Context)(JSPromise, JSAny, Boolean): Object;
RejectPromise(implicit context: Context)(JSPromise, JSAny, Boolean): JSAny;
extern transitioning runtime
PromiseRejectAfterResolved(implicit context: Context)(JSPromise, JSAny):
JSAny;
extern transitioning runtime
PromiseResolveAfterResolved(implicit context: Context)(JSPromise, JSAny):
JSAny;
}
// https://tc39.es/ecma262/#sec-promise-abstract-operations
@ -36,6 +44,8 @@ namespace promise {
extern macro PromiseReactionMapConstant(): Map;
extern macro PromiseFulfillReactionJobTaskMapConstant(): Map;
extern macro PromiseRejectReactionJobTaskMapConstant(): Map;
extern transitioning builtin
ResolvePromise(Context, JSPromise, JSAny): JSAny;
extern transitioning builtin
EnqueueMicrotask(Context, PromiseReactionJobTask): Undefined;
@ -196,7 +206,7 @@ namespace promise {
// https://tc39.es/ecma262/#sec-rejectpromise
transitioning builtin
RejectPromise(implicit context: Context)(
promise: JSPromise, reason: JSAny, debugEvent: Boolean): Object {
promise: JSPromise, reason: JSAny, debugEvent: Boolean): JSAny {
// If promise hook is enabled or the debugger is active, let
// the runtime handle this operation, which greatly reduces
// the complexity here and also avoids a couple of back and
@ -233,6 +243,12 @@ namespace promise {
generates 'PromiseBuiltins::kCapabilitiesContextLength';
const kPromiseBuiltinsCapabilitySlot: constexpr ContextSlot
generates 'PromiseBuiltins::kCapabilitySlot';
const kPromiseBuiltinsPromiseSlot: constexpr ContextSlot
generates 'PromiseBuiltins::kPromiseSlot';
const kPromiseBuiltinsAlreadyResolvedSlot: constexpr ContextSlot
generates 'PromiseBuiltins::kAlreadyResolvedSlot';
const kPromiseBuiltinsDebugEventSlot: constexpr ContextSlot
generates 'PromiseBuiltins::kDebugEventSlot';
extern macro
PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Context): JSPromise;
@ -340,4 +356,53 @@ namespace promise {
}
}
}
// https://tc39.es/ecma262/#sec-promise-reject-functions
transitioning javascript builtin
PromiseCapabilityDefaultReject(js-implicit context: Context, receiver: JSAny)(
reason: JSAny): JSAny {
// 2. Let promise be F.[[Promise]].
const promise = UnsafeCast<JSPromise>(context[kPromiseBuiltinsPromiseSlot]);
// 3. Let alreadyResolved be F.[[AlreadyResolved]].
const alreadyResolved =
UnsafeCast<Boolean>(context[kPromiseBuiltinsAlreadyResolvedSlot]);
// 4. If alreadyResolved.[[Value]] is true, return undefined.
if (alreadyResolved == True) {
return runtime::PromiseRejectAfterResolved(promise, reason);
}
// 5. Set alreadyResolved.[[Value]] to true.
context[kPromiseBuiltinsAlreadyResolvedSlot] = True;
// 6. Return RejectPromise(promise, reason).
const debugEvent =
UnsafeCast<Boolean>(context[kPromiseBuiltinsDebugEventSlot]);
return RejectPromise(promise, reason, debugEvent);
}
// https://tc39.es/ecma262/#sec-promise-resolve-functions
transitioning javascript builtin
PromiseCapabilityDefaultResolve(
js-implicit context: Context, receiver: JSAny)(resolution: JSAny): JSAny {
// 2. Let promise be F.[[Promise]].
const promise = UnsafeCast<JSPromise>(context[kPromiseBuiltinsPromiseSlot]);
// 3. Let alreadyResolved be F.[[AlreadyResolved]].
const alreadyResolved =
UnsafeCast<Boolean>(context[kPromiseBuiltinsAlreadyResolvedSlot]);
// 4. If alreadyResolved.[[Value]] is true, return undefined.
if (alreadyResolved == True) {
return runtime::PromiseResolveAfterResolved(promise, resolution);
}
// 5. Set alreadyResolved.[[Value]] to true.
context[kPromiseBuiltinsAlreadyResolvedSlot] = True;
// The rest of the logic (and the catch prediction) is
// encapsulated in the dedicated ResolvePromise builtin.
return ResolvePromise(context, promise, resolution);
}
}