[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 */ \
|
/* ES #sec-promise-resolve-functions */ \
|
||||||
/* Starting at step 6 of "Promise Resolve Functions" */ \
|
/* Starting at step 6 of "Promise Resolve Functions" */ \
|
||||||
TFS(ResolvePromise, kPromise, kResolution) \
|
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(PromiseGetCapabilitiesExecutor, 2, kReceiver, kResolve, kReject) \
|
||||||
TFJ(PromiseConstructorLazyDeoptContinuation, 4, kReceiver, kPromise, \
|
TFJ(PromiseConstructorLazyDeoptContinuation, 4, kReceiver, kPromise, \
|
||||||
kReject, kException, kResult) \
|
kReject, kException, kResult) \
|
||||||
|
@ -630,72 +630,6 @@ void PromiseBuiltinsAssembler::SetPromiseHandledByIfTrue(
|
|||||||
BIND(&done);
|
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) {
|
TF_BUILTIN(PromiseConstructorLazyDeoptContinuation, PromiseBuiltinsAssembler) {
|
||||||
Node* promise = Parameter(Descriptor::kPromise);
|
Node* promise = Parameter(Descriptor::kPromise);
|
||||||
Node* reject = Parameter(Descriptor::kReject);
|
Node* reject = Parameter(Descriptor::kReject);
|
||||||
|
@ -7,7 +7,15 @@
|
|||||||
|
|
||||||
namespace runtime {
|
namespace runtime {
|
||||||
extern transitioning 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
|
// https://tc39.es/ecma262/#sec-promise-abstract-operations
|
||||||
@ -36,6 +44,8 @@ namespace promise {
|
|||||||
extern macro PromiseReactionMapConstant(): Map;
|
extern macro PromiseReactionMapConstant(): Map;
|
||||||
extern macro PromiseFulfillReactionJobTaskMapConstant(): Map;
|
extern macro PromiseFulfillReactionJobTaskMapConstant(): Map;
|
||||||
extern macro PromiseRejectReactionJobTaskMapConstant(): Map;
|
extern macro PromiseRejectReactionJobTaskMapConstant(): Map;
|
||||||
|
extern transitioning builtin
|
||||||
|
ResolvePromise(Context, JSPromise, JSAny): JSAny;
|
||||||
|
|
||||||
extern transitioning builtin
|
extern transitioning builtin
|
||||||
EnqueueMicrotask(Context, PromiseReactionJobTask): Undefined;
|
EnqueueMicrotask(Context, PromiseReactionJobTask): Undefined;
|
||||||
@ -196,7 +206,7 @@ namespace promise {
|
|||||||
// https://tc39.es/ecma262/#sec-rejectpromise
|
// https://tc39.es/ecma262/#sec-rejectpromise
|
||||||
transitioning builtin
|
transitioning builtin
|
||||||
RejectPromise(implicit context: Context)(
|
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
|
// If promise hook is enabled or the debugger is active, let
|
||||||
// the runtime handle this operation, which greatly reduces
|
// the runtime handle this operation, which greatly reduces
|
||||||
// the complexity here and also avoids a couple of back and
|
// the complexity here and also avoids a couple of back and
|
||||||
@ -233,6 +243,12 @@ namespace promise {
|
|||||||
generates 'PromiseBuiltins::kCapabilitiesContextLength';
|
generates 'PromiseBuiltins::kCapabilitiesContextLength';
|
||||||
const kPromiseBuiltinsCapabilitySlot: constexpr ContextSlot
|
const kPromiseBuiltinsCapabilitySlot: constexpr ContextSlot
|
||||||
generates 'PromiseBuiltins::kCapabilitySlot';
|
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
|
extern macro
|
||||||
PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Context): JSPromise;
|
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