[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:
parent
72b652e8f7
commit
8fe297617f
@ -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) \
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user