[promises] Port RejectPromise to torque.
Also ports TriggerPromiseReaction and ExtractHandler to torque. Bug: v8:9838 Change-Id: I35c07dcf4a0cca988dfb4706557cd6ee6bc66efe Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1864583 Commit-Queue: Joshua Litt <joshualitt@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org> Cr-Commit-Position: refs/heads/master@{#64711}
This commit is contained in:
parent
7f4a2ec4d9
commit
aeda4157d4
@ -1151,12 +1151,16 @@ const kPromisePending: constexpr PromiseState
|
|||||||
generates 'Promise::kPending';
|
generates 'Promise::kPending';
|
||||||
const kPromiseFulfilled: constexpr PromiseState
|
const kPromiseFulfilled: constexpr PromiseState
|
||||||
generates 'Promise::kFulfilled';
|
generates 'Promise::kFulfilled';
|
||||||
|
const kPromiseRejected: constexpr PromiseState
|
||||||
|
generates 'Promise::kRejected';
|
||||||
|
|
||||||
// JSPromise constants
|
// JSPromise constants
|
||||||
const kJSPromiseStatusMask: constexpr int31
|
const kJSPromiseStatusMask: constexpr int31
|
||||||
generates 'JSPromise::kStatusMask';
|
generates 'JSPromise::kStatusMask';
|
||||||
const kJSPromiseStatusShift: constexpr int31
|
const kJSPromiseStatusShift: constexpr int31
|
||||||
generates 'JSPromise::kStatusShift';
|
generates 'JSPromise::kStatusShift';
|
||||||
|
const kJSPromiseHasHandlerMask: constexpr int31
|
||||||
|
generates 'JSPromise::kHasHandlerMask';
|
||||||
|
|
||||||
@generateCppClass
|
@generateCppClass
|
||||||
extern class JSPromise extends JSObject {
|
extern class JSPromise extends JSObject {
|
||||||
@ -1174,9 +1178,13 @@ extern class JSPromise extends JSObject {
|
|||||||
this.flags = this.flags | mask;
|
this.flags = this.flags | mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HasHandler(): bool {
|
||||||
|
return (this.flags & kJSPromiseHasHandlerMask) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Smi 0 terminated list of PromiseReaction objects in case the JSPromise was
|
// Smi 0 terminated list of PromiseReaction objects in case the JSPromise was
|
||||||
// not settled yet, otherwise the result.
|
// not settled yet, otherwise the result.
|
||||||
reactions_or_result: Smi|PromiseReaction|JSAny;
|
reactions_or_result: Zero|PromiseReaction|JSAny;
|
||||||
flags: Smi;
|
flags: Smi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1356,6 +1364,10 @@ const kEmptyFixedArrayRootIndex:
|
|||||||
constexpr RootIndex generates 'RootIndex::kEmptyFixedArray';
|
constexpr RootIndex generates 'RootIndex::kEmptyFixedArray';
|
||||||
const kTheHoleValueRootIndex:
|
const kTheHoleValueRootIndex:
|
||||||
constexpr RootIndex generates 'RootIndex::kTheHoleValue';
|
constexpr RootIndex generates 'RootIndex::kTheHoleValue';
|
||||||
|
const kPromiseFulfillReactionJobTaskMapRootIndex: constexpr RootIndex
|
||||||
|
generates 'RootIndex::kPromiseFulfillReactionJobTaskMap';
|
||||||
|
const kPromiseRejectReactionJobTaskMapRootIndex: constexpr RootIndex
|
||||||
|
generates 'RootIndex::kPromiseRejectReactionJobTaskMap';
|
||||||
|
|
||||||
const kInvalidArrayBufferLength: constexpr MessageTemplate
|
const kInvalidArrayBufferLength: constexpr MessageTemplate
|
||||||
generates 'MessageTemplate::kInvalidArrayBufferLength';
|
generates 'MessageTemplate::kInvalidArrayBufferLength';
|
||||||
@ -1490,6 +1502,7 @@ const False: False = FalseConstant();
|
|||||||
const kEmptyString: EmptyString = EmptyStringConstant();
|
const kEmptyString: EmptyString = EmptyStringConstant();
|
||||||
const kLengthString: String = LengthStringConstant();
|
const kLengthString: String = LengthStringConstant();
|
||||||
const kNaN: NaN = NanConstant();
|
const kNaN: NaN = NanConstant();
|
||||||
|
const kZero: Zero = %RawDownCast<Zero>(SmiConstant(0));
|
||||||
|
|
||||||
const true: constexpr bool generates 'true';
|
const true: constexpr bool generates 'true';
|
||||||
const false: constexpr bool generates 'false';
|
const false: constexpr bool generates 'false';
|
||||||
@ -1532,6 +1545,14 @@ extern class PromiseCapability extends Struct {
|
|||||||
type PromiseReactionType extends int31 constexpr 'PromiseReaction::Type';
|
type PromiseReactionType extends int31 constexpr 'PromiseReaction::Type';
|
||||||
const kPromiseReactionFulfill: constexpr PromiseReactionType
|
const kPromiseReactionFulfill: constexpr PromiseReactionType
|
||||||
generates 'PromiseReaction::kFulfill';
|
generates 'PromiseReaction::kFulfill';
|
||||||
|
const kPromiseReactionReject: constexpr PromiseReactionType
|
||||||
|
generates 'PromiseReaction::kReject';
|
||||||
|
const kPromiseReactionSize:
|
||||||
|
constexpr int31 generates 'PromiseReaction::kSize';
|
||||||
|
const kPromiseReactionFulfillHandlerOffset: constexpr int31
|
||||||
|
generates 'PromiseReaction::kFulfillHandlerOffset';
|
||||||
|
const kPromiseReactionPromiseOrCapabilityOffset: constexpr int31
|
||||||
|
generates 'PromiseReaction::kPromiseOrCapabilityOffset';
|
||||||
|
|
||||||
@generateCppClass
|
@generateCppClass
|
||||||
extern class PromiseReaction extends Struct {
|
extern class PromiseReaction extends Struct {
|
||||||
@ -1543,6 +1564,14 @@ extern class PromiseReaction extends Struct {
|
|||||||
promise_or_capability: JSPromise|PromiseCapability|Undefined;
|
promise_or_capability: JSPromise|PromiseCapability|Undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PromiseReactionJobTask constants
|
||||||
|
const kPromiseReactionJobTaskSizeOfAllPromiseReactionJobTasks: constexpr int31
|
||||||
|
generates 'PromiseReactionJobTask::kSizeOfAllPromiseReactionJobTasks';
|
||||||
|
const kPromiseReactionJobTaskHandlerOffset: constexpr int31
|
||||||
|
generates 'PromiseReactionJobTask::kHandlerOffset';
|
||||||
|
const kPromiseReactionJobTaskPromiseOrCapabilityOffset: constexpr int31
|
||||||
|
generates 'PromiseReactionJobTask::kPromiseOrCapabilityOffset';
|
||||||
|
|
||||||
@abstract
|
@abstract
|
||||||
@generateCppClass
|
@generateCppClass
|
||||||
extern class PromiseReactionJobTask extends Microtask {
|
extern class PromiseReactionJobTask extends Microtask {
|
||||||
@ -2275,6 +2304,11 @@ Cast<PositiveSmi>(o: Object): PositiveSmi
|
|||||||
return TaggedToPositiveSmi(o) otherwise CastError;
|
return TaggedToPositiveSmi(o) otherwise CastError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cast<Zero>(o: Object): Zero labels CastError {
|
||||||
|
if (TaggedEqual(o, SmiConstant(0))) return %RawDownCast<Zero>(o);
|
||||||
|
goto CastError;
|
||||||
|
}
|
||||||
|
|
||||||
Cast<Number>(o: Object): Number
|
Cast<Number>(o: Object): Number
|
||||||
labels CastError {
|
labels CastError {
|
||||||
return TaggedToNumber(o) otherwise CastError;
|
return TaggedToNumber(o) otherwise CastError;
|
||||||
@ -2754,6 +2788,22 @@ Cast<JSReceiver|Null>(o: HeapObject): JSReceiver|Null
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cast<PromiseFulfillReactionJobTask>(o: HeapObject):
|
||||||
|
PromiseFulfillReactionJobTask labels CastError {
|
||||||
|
if (IsPromiseFulfillReactionJobTask(o)) {
|
||||||
|
return %RawDownCast<PromiseFulfillReactionJobTask>(o);
|
||||||
|
}
|
||||||
|
goto CastError;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cast<PromiseRejectReactionJobTask>(o: HeapObject):
|
||||||
|
PromiseRejectReactionJobTask labels CastError {
|
||||||
|
if (IsPromiseRejectReactionJobTask(o)) {
|
||||||
|
return %RawDownCast<PromiseRejectReactionJobTask>(o);
|
||||||
|
}
|
||||||
|
goto CastError;
|
||||||
|
}
|
||||||
|
|
||||||
Cast<PromiseReaction>(o: HeapObject): PromiseReaction labels CastError {
|
Cast<PromiseReaction>(o: HeapObject): PromiseReaction labels CastError {
|
||||||
if (IsPromiseReaction(o)) return %RawDownCast<PromiseReaction>(o);
|
if (IsPromiseReaction(o)) return %RawDownCast<PromiseReaction>(o);
|
||||||
goto CastError;
|
goto CastError;
|
||||||
@ -2773,6 +2823,26 @@ Cast<Smi|PromiseReaction>(o: Object): Smi|PromiseReaction labels CastError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cast<Zero|PromiseReaction>(implicit context: Context)(o: Object): Zero|
|
||||||
|
PromiseReaction labels CastError {
|
||||||
|
typeswitch (o) {
|
||||||
|
case (o: Zero): {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
case (o: PromiseReaction): {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
case (Object): {
|
||||||
|
goto CastError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cast<JSBoundFunction>(o: HeapObject): JSBoundFunction labels CastError {
|
||||||
|
if (IsJSBoundFunction(o)) return %RawDownCast<JSBoundFunction>(o);
|
||||||
|
goto CastError;
|
||||||
|
}
|
||||||
|
|
||||||
Cast<PromiseCapability>(o: HeapObject): PromiseCapability labels CastError {
|
Cast<PromiseCapability>(o: HeapObject): PromiseCapability labels CastError {
|
||||||
if (IsPromiseCapability(o)) return %RawDownCast<PromiseCapability>(o);
|
if (IsPromiseCapability(o)) return %RawDownCast<PromiseCapability>(o);
|
||||||
goto CastError;
|
goto CastError;
|
||||||
@ -3566,6 +3636,7 @@ extern macro IsJSRegExp(HeapObject): bool;
|
|||||||
extern macro IsJSRegExpStringIterator(HeapObject): bool;
|
extern macro IsJSRegExpStringIterator(HeapObject): bool;
|
||||||
extern macro IsMap(HeapObject): bool;
|
extern macro IsMap(HeapObject): bool;
|
||||||
extern macro IsJSFunction(HeapObject): bool;
|
extern macro IsJSFunction(HeapObject): bool;
|
||||||
|
extern macro IsJSBoundFunction(HeapObject): bool;
|
||||||
extern macro IsJSObject(HeapObject): bool;
|
extern macro IsJSObject(HeapObject): bool;
|
||||||
extern macro IsJSPromise(HeapObject): bool;
|
extern macro IsJSPromise(HeapObject): bool;
|
||||||
extern macro IsJSTypedArray(HeapObject): bool;
|
extern macro IsJSTypedArray(HeapObject): bool;
|
||||||
@ -3589,6 +3660,8 @@ extern macro IsExtensibleMap(Map): bool;
|
|||||||
extern macro IsJSPrimitiveWrapper(HeapObject): bool;
|
extern macro IsJSPrimitiveWrapper(HeapObject): bool;
|
||||||
extern macro IsPromiseCapability(HeapObject): bool;
|
extern macro IsPromiseCapability(HeapObject): bool;
|
||||||
extern macro IsPromiseReaction(HeapObject): bool;
|
extern macro IsPromiseReaction(HeapObject): bool;
|
||||||
|
extern macro IsPromiseRejectReactionJobTask(HeapObject): bool;
|
||||||
|
extern macro IsPromiseFulfillReactionJobTask(HeapObject): bool;
|
||||||
extern macro IsSharedFunctionInfo(HeapObject): bool;
|
extern macro IsSharedFunctionInfo(HeapObject): bool;
|
||||||
extern macro IsCustomElementsReceiverInstanceType(int32): bool;
|
extern macro IsCustomElementsReceiverInstanceType(int32): bool;
|
||||||
extern macro Typeof(JSAny): String;
|
extern macro Typeof(JSAny): String;
|
||||||
|
@ -747,8 +747,6 @@ namespace internal {
|
|||||||
TFS(ForInFilter, kKey, kObject) \
|
TFS(ForInFilter, kKey, kObject) \
|
||||||
\
|
\
|
||||||
/* Promise */ \
|
/* Promise */ \
|
||||||
/* ES #sec-rejectpromise */ \
|
|
||||||
TFS(RejectPromise, kPromise, kReason, kDebugEvent) \
|
|
||||||
/* 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) \
|
||||||
|
@ -246,19 +246,6 @@ TNode<Word32T> PromiseBuiltinsAssembler::PromiseStatus(Node* promise) {
|
|||||||
return Word32And(SmiToInt32(flags), Int32Constant(JSPromise::kStatusMask));
|
return Word32And(SmiToInt32(flags), Int32Constant(JSPromise::kStatusMask));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PromiseBuiltinsAssembler::PromiseSetStatus(
|
|
||||||
Node* promise, v8::Promise::PromiseState const status) {
|
|
||||||
CSA_ASSERT(this,
|
|
||||||
IsPromiseStatus(PromiseStatus(promise), v8::Promise::kPending));
|
|
||||||
CHECK_NE(status, v8::Promise::kPending);
|
|
||||||
|
|
||||||
TNode<Smi> mask = SmiConstant(status);
|
|
||||||
const TNode<Smi> flags =
|
|
||||||
CAST(LoadObjectField(promise, JSPromise::kFlagsOffset));
|
|
||||||
StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset,
|
|
||||||
SmiOr(flags, mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PromiseBuiltinsAssembler::PromiseSetHandledHint(Node* promise) {
|
void PromiseBuiltinsAssembler::PromiseSetHandledHint(Node* promise) {
|
||||||
const TNode<Smi> flags =
|
const TNode<Smi> flags =
|
||||||
CAST(LoadObjectField(promise, JSPromise::kFlagsOffset));
|
CAST(LoadObjectField(promise, JSPromise::kFlagsOffset));
|
||||||
@ -441,128 +428,6 @@ PromiseBuiltinsAssembler::AllocatePromiseResolveThenableJobTask(
|
|||||||
return CAST(microtask);
|
return CAST(microtask);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ES #sec-triggerpromisereactions
|
|
||||||
void PromiseBuiltinsAssembler::TriggerPromiseReactions(
|
|
||||||
Node* context, Node* reactions, Node* argument,
|
|
||||||
PromiseReaction::Type type) {
|
|
||||||
// We need to reverse the {reactions} here, since we record them on the
|
|
||||||
// JSPromise in the reverse order.
|
|
||||||
{
|
|
||||||
VARIABLE(var_current, MachineRepresentation::kTagged, reactions);
|
|
||||||
VARIABLE(var_reversed, MachineRepresentation::kTagged,
|
|
||||||
SmiConstant(Smi::zero()));
|
|
||||||
|
|
||||||
// As an additional safety net against misuse of the V8 Extras API, we
|
|
||||||
// sanity check the {reactions} to make sure that they are actually
|
|
||||||
// PromiseReaction instances and not actual JavaScript values (which
|
|
||||||
// would indicate that we're rejecting or resolving an already settled
|
|
||||||
// promise), see https://crbug.com/931640 for details on this.
|
|
||||||
TNode<Map> promise_reaction_map = PromiseReactionMapConstant();
|
|
||||||
|
|
||||||
Label loop(this, {&var_current, &var_reversed}), done_loop(this);
|
|
||||||
Goto(&loop);
|
|
||||||
BIND(&loop);
|
|
||||||
{
|
|
||||||
Node* current = var_current.value();
|
|
||||||
GotoIf(TaggedIsSmi(current), &done_loop);
|
|
||||||
CSA_CHECK(this,
|
|
||||||
TaggedEqual(LoadMap(CAST(current)), promise_reaction_map));
|
|
||||||
var_current.Bind(LoadObjectField(current, PromiseReaction::kNextOffset));
|
|
||||||
StoreObjectField(current, PromiseReaction::kNextOffset,
|
|
||||||
var_reversed.value());
|
|
||||||
var_reversed.Bind(current);
|
|
||||||
Goto(&loop);
|
|
||||||
}
|
|
||||||
BIND(&done_loop);
|
|
||||||
reactions = var_reversed.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Morph the {reactions} into PromiseReactionJobTasks and push them
|
|
||||||
// onto the microtask queue.
|
|
||||||
{
|
|
||||||
VARIABLE(var_current, MachineRepresentation::kTagged, reactions);
|
|
||||||
|
|
||||||
Label loop(this, {&var_current}), done_loop(this);
|
|
||||||
Goto(&loop);
|
|
||||||
BIND(&loop);
|
|
||||||
{
|
|
||||||
Node* current = var_current.value();
|
|
||||||
GotoIf(TaggedIsSmi(current), &done_loop);
|
|
||||||
var_current.Bind(LoadObjectField(current, PromiseReaction::kNextOffset));
|
|
||||||
|
|
||||||
VARIABLE(var_context, MachineRepresentation::kTagged,
|
|
||||||
UndefinedConstant());
|
|
||||||
|
|
||||||
Node* primary_handler;
|
|
||||||
Node* secondary_handler;
|
|
||||||
if (type == PromiseReaction::kFulfill) {
|
|
||||||
primary_handler =
|
|
||||||
LoadObjectField(current, PromiseReaction::kFulfillHandlerOffset);
|
|
||||||
secondary_handler =
|
|
||||||
LoadObjectField(current, PromiseReaction::kRejectHandlerOffset);
|
|
||||||
} else {
|
|
||||||
primary_handler =
|
|
||||||
LoadObjectField(current, PromiseReaction::kRejectHandlerOffset);
|
|
||||||
secondary_handler =
|
|
||||||
LoadObjectField(current, PromiseReaction::kFulfillHandlerOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Label use_fallback(this, Label::kDeferred), done(this);
|
|
||||||
ExtractHandlerContext(primary_handler, &var_context);
|
|
||||||
Branch(IsUndefined(var_context.value()), &use_fallback, &done);
|
|
||||||
|
|
||||||
BIND(&use_fallback);
|
|
||||||
var_context.Bind(context);
|
|
||||||
ExtractHandlerContext(secondary_handler, &var_context);
|
|
||||||
CSA_ASSERT(this, IsNotUndefined(var_context.value()));
|
|
||||||
Goto(&done);
|
|
||||||
|
|
||||||
BIND(&done);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Morph {current} from a PromiseReaction into a PromiseReactionJobTask
|
|
||||||
// and schedule that on the microtask queue. We try to minimize the number
|
|
||||||
// of stores here to avoid screwing up the store buffer.
|
|
||||||
STATIC_ASSERT(
|
|
||||||
static_cast<int>(PromiseReaction::kSize) ==
|
|
||||||
static_cast<int>(
|
|
||||||
PromiseReactionJobTask::kSizeOfAllPromiseReactionJobTasks));
|
|
||||||
if (type == PromiseReaction::kFulfill) {
|
|
||||||
StoreMapNoWriteBarrier(current,
|
|
||||||
RootIndex::kPromiseFulfillReactionJobTaskMap);
|
|
||||||
StoreObjectField(current, PromiseReactionJobTask::kArgumentOffset,
|
|
||||||
argument);
|
|
||||||
StoreObjectField(current, PromiseReactionJobTask::kContextOffset,
|
|
||||||
var_context.value());
|
|
||||||
STATIC_ASSERT(
|
|
||||||
static_cast<int>(PromiseReaction::kFulfillHandlerOffset) ==
|
|
||||||
static_cast<int>(PromiseReactionJobTask::kHandlerOffset));
|
|
||||||
STATIC_ASSERT(
|
|
||||||
static_cast<int>(PromiseReaction::kPromiseOrCapabilityOffset) ==
|
|
||||||
static_cast<int>(
|
|
||||||
PromiseReactionJobTask::kPromiseOrCapabilityOffset));
|
|
||||||
} else {
|
|
||||||
StoreMapNoWriteBarrier(current,
|
|
||||||
RootIndex::kPromiseRejectReactionJobTaskMap);
|
|
||||||
StoreObjectField(current, PromiseReactionJobTask::kArgumentOffset,
|
|
||||||
argument);
|
|
||||||
StoreObjectField(current, PromiseReactionJobTask::kContextOffset,
|
|
||||||
var_context.value());
|
|
||||||
StoreObjectField(current, PromiseReactionJobTask::kHandlerOffset,
|
|
||||||
primary_handler);
|
|
||||||
STATIC_ASSERT(
|
|
||||||
static_cast<int>(PromiseReaction::kPromiseOrCapabilityOffset) ==
|
|
||||||
static_cast<int>(
|
|
||||||
PromiseReactionJobTask::kPromiseOrCapabilityOffset));
|
|
||||||
}
|
|
||||||
CallBuiltin(Builtins::kEnqueueMicrotask, var_context.value(), current);
|
|
||||||
Goto(&loop);
|
|
||||||
}
|
|
||||||
BIND(&done_loop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... TArgs>
|
template <typename... TArgs>
|
||||||
Node* PromiseBuiltinsAssembler::InvokeThen(Node* native_context, Node* receiver,
|
Node* PromiseBuiltinsAssembler::InvokeThen(Node* native_context, Node* receiver,
|
||||||
TArgs... args) {
|
TArgs... args) {
|
||||||
@ -1680,52 +1545,6 @@ TF_BUILTIN(PromisePrototypeFinally, PromiseBuiltinsAssembler) {
|
|||||||
var_catch_finally.value()));
|
var_catch_finally.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ES #sec-rejectpromise
|
|
||||||
TF_BUILTIN(RejectPromise, PromiseBuiltinsAssembler) {
|
|
||||||
Node* const promise = Parameter(Descriptor::kPromise);
|
|
||||||
Node* const reason = Parameter(Descriptor::kReason);
|
|
||||||
Node* const debug_event = Parameter(Descriptor::kDebugEvent);
|
|
||||||
Node* const context = Parameter(Descriptor::kContext);
|
|
||||||
|
|
||||||
CSA_ASSERT(this, TaggedIsNotSmi(promise));
|
|
||||||
CSA_ASSERT(this, IsJSPromise(promise));
|
|
||||||
CSA_ASSERT(this, IsBoolean(debug_event));
|
|
||||||
Label if_runtime(this, Label::kDeferred);
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// forth between JavaScript and C++ land.
|
|
||||||
GotoIf(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(),
|
|
||||||
&if_runtime);
|
|
||||||
|
|
||||||
// 7. If promise.[[PromiseIsHandled]] is false, perform
|
|
||||||
// HostPromiseRejectionTracker(promise, "reject").
|
|
||||||
// We don't try to handle rejecting {promise} without handler
|
|
||||||
// here, but we let the C++ code take care of this completely.
|
|
||||||
GotoIfNot(PromiseHasHandler(promise), &if_runtime);
|
|
||||||
|
|
||||||
// 2. Let reactions be promise.[[PromiseRejectReactions]].
|
|
||||||
TNode<Object> reactions =
|
|
||||||
LoadObjectField(promise, JSPromise::kReactionsOrResultOffset);
|
|
||||||
|
|
||||||
// 3. Set promise.[[PromiseResult]] to reason.
|
|
||||||
// 4. Set promise.[[PromiseFulfillReactions]] to undefined.
|
|
||||||
// 5. Set promise.[[PromiseRejectReactions]] to undefined.
|
|
||||||
StoreObjectField(promise, JSPromise::kReactionsOrResultOffset, reason);
|
|
||||||
|
|
||||||
// 6. Set promise.[[PromiseState]] to "rejected".
|
|
||||||
PromiseSetStatus(promise, Promise::kRejected);
|
|
||||||
|
|
||||||
// 7. Return TriggerPromiseReactions(reactions, reason).
|
|
||||||
TriggerPromiseReactions(context, reactions, reason, PromiseReaction::kReject);
|
|
||||||
Return(UndefinedConstant());
|
|
||||||
|
|
||||||
BIND(&if_runtime);
|
|
||||||
TailCallRuntime(Runtime::kRejectPromise, context, promise, reason,
|
|
||||||
debug_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ES #sec-promise-resolve-functions
|
// ES #sec-promise-resolve-functions
|
||||||
TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) {
|
TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) {
|
||||||
const TNode<JSPromise> promise = CAST(Parameter(Descriptor::kPromise));
|
const TNode<JSPromise> promise = CAST(Parameter(Descriptor::kPromise));
|
||||||
|
@ -66,11 +66,6 @@ class V8_EXPORT_PRIVATE PromiseBuiltinsAssembler : public CodeStubAssembler {
|
|||||||
TNode<JSPromise> promise, TNode<Object> debug_event,
|
TNode<JSPromise> promise, TNode<Object> debug_event,
|
||||||
TNode<NativeContext> native_context);
|
TNode<NativeContext> native_context);
|
||||||
|
|
||||||
// The below methods are only temporarily public until they are
|
|
||||||
// migrated to torque.
|
|
||||||
void TriggerPromiseReactions(Node* context, Node* promise, Node* result,
|
|
||||||
PromiseReaction::Type type);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void PromiseInit(Node* promise);
|
void PromiseInit(Node* promise);
|
||||||
|
|
||||||
@ -158,8 +153,6 @@ class V8_EXPORT_PRIVATE PromiseBuiltinsAssembler : public CodeStubAssembler {
|
|||||||
|
|
||||||
TNode<BoolT> IsPromiseStatus(TNode<Word32T> actual,
|
TNode<BoolT> IsPromiseStatus(TNode<Word32T> actual,
|
||||||
v8::Promise::PromiseState expected);
|
v8::Promise::PromiseState expected);
|
||||||
void PromiseSetStatus(Node* promise, v8::Promise::PromiseState status);
|
|
||||||
|
|
||||||
TNode<JSPromise> AllocateJSPromise(TNode<Context> context);
|
TNode<JSPromise> AllocateJSPromise(TNode<Context> context);
|
||||||
|
|
||||||
void ExtractHandlerContext(Node* handler, Variable* var_context);
|
void ExtractHandlerContext(Node* handler, Variable* var_context);
|
||||||
|
@ -5,6 +5,11 @@
|
|||||||
#include 'src/builtins/builtins-promise.h'
|
#include 'src/builtins/builtins-promise.h'
|
||||||
#include 'src/builtins/builtins-promise-gen.h'
|
#include 'src/builtins/builtins-promise-gen.h'
|
||||||
|
|
||||||
|
namespace runtime {
|
||||||
|
extern transitioning runtime
|
||||||
|
RejectPromise(implicit context: Context)(JSPromise, JSAny, Boolean): Object;
|
||||||
|
}
|
||||||
|
|
||||||
// https://tc39.es/ecma262/#sec-promise-abstract-operations
|
// https://tc39.es/ecma262/#sec-promise-abstract-operations
|
||||||
namespace promise {
|
namespace promise {
|
||||||
const PROMISE_FUNCTION_INDEX: constexpr NativeContextSlot
|
const PROMISE_FUNCTION_INDEX: constexpr NativeContextSlot
|
||||||
@ -30,10 +35,138 @@ namespace promise {
|
|||||||
extern macro AllocateFunctionWithMapAndContext(
|
extern macro AllocateFunctionWithMapAndContext(
|
||||||
Map, SharedFunctionInfo, Context): JSFunction;
|
Map, SharedFunctionInfo, Context): JSFunction;
|
||||||
|
|
||||||
extern macro PromiseBuiltinsAssembler::TriggerPromiseReactions(
|
extern macro PromiseReactionMapConstant(): Map;
|
||||||
implicit context:
|
extern macro PromiseFulfillReactionJobTaskMapConstant(): Map;
|
||||||
Context)(Smi|PromiseReaction, JSAny, constexpr PromiseReactionType):
|
extern macro PromiseRejectReactionJobTaskMapConstant(): Map;
|
||||||
void;
|
|
||||||
|
extern transitioning builtin
|
||||||
|
EnqueueMicrotask(Context, PromiseReactionJobTask): Undefined;
|
||||||
|
|
||||||
|
macro
|
||||||
|
ExtractHandlerContext(implicit context: Context)(handler: Callable|Undefined):
|
||||||
|
Context labels NotFound {
|
||||||
|
let iter: JSAny = handler;
|
||||||
|
while (true) {
|
||||||
|
typeswitch (iter) {
|
||||||
|
case (b: JSBoundFunction): {
|
||||||
|
iter = b.bound_target_function;
|
||||||
|
}
|
||||||
|
case (p: JSProxy): {
|
||||||
|
iter = p.target;
|
||||||
|
}
|
||||||
|
case (f: JSFunction): {
|
||||||
|
return f.context;
|
||||||
|
}
|
||||||
|
case (JSAny): {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto NotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
transitioning macro MorpAndEnqueuePromiseReaction(implicit context: Context)(
|
||||||
|
promiseReaction: PromiseReaction, argument: JSAny,
|
||||||
|
reactionType: constexpr PromiseReactionType): void {
|
||||||
|
let primaryHandler: Callable|Undefined;
|
||||||
|
let secondaryHandler: Callable|Undefined;
|
||||||
|
if constexpr (reactionType == kPromiseReactionFulfill) {
|
||||||
|
primaryHandler = promiseReaction.fulfill_handler;
|
||||||
|
secondaryHandler = promiseReaction.reject_handler;
|
||||||
|
} else {
|
||||||
|
StaticAssert(reactionType == kPromiseReactionReject);
|
||||||
|
primaryHandler = promiseReaction.reject_handler;
|
||||||
|
secondaryHandler = promiseReaction.fulfill_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
let handlerContext: Context;
|
||||||
|
try {
|
||||||
|
handlerContext = ExtractHandlerContext(primaryHandler) otherwise NotFound;
|
||||||
|
}
|
||||||
|
label NotFound {
|
||||||
|
handlerContext =
|
||||||
|
ExtractHandlerContext(secondaryHandler) otherwise Default;
|
||||||
|
}
|
||||||
|
label Default {
|
||||||
|
handlerContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Morph {current} from a PromiseReaction into a PromiseReactionJobTask
|
||||||
|
// and schedule that on the microtask queue. We try to minimize the number
|
||||||
|
// of stores here to avoid screwing up the store buffer.
|
||||||
|
StaticAssert(
|
||||||
|
kPromiseReactionSize ==
|
||||||
|
kPromiseReactionJobTaskSizeOfAllPromiseReactionJobTasks);
|
||||||
|
if constexpr (reactionType == kPromiseReactionFulfill) {
|
||||||
|
promiseReaction.map = PromiseFulfillReactionJobTaskMapConstant();
|
||||||
|
const promiseReactionJobTask =
|
||||||
|
UnsafeCast<PromiseFulfillReactionJobTask>(promiseReaction);
|
||||||
|
promiseReactionJobTask.argument = argument;
|
||||||
|
promiseReactionJobTask.context = handlerContext;
|
||||||
|
EnqueueMicrotask(handlerContext, promiseReactionJobTask);
|
||||||
|
StaticAssert(
|
||||||
|
kPromiseReactionFulfillHandlerOffset ==
|
||||||
|
kPromiseReactionJobTaskHandlerOffset);
|
||||||
|
StaticAssert(
|
||||||
|
kPromiseReactionPromiseOrCapabilityOffset ==
|
||||||
|
kPromiseReactionJobTaskPromiseOrCapabilityOffset);
|
||||||
|
} else {
|
||||||
|
StaticAssert(reactionType == kPromiseReactionReject);
|
||||||
|
promiseReaction.map = PromiseRejectReactionJobTaskMapConstant();
|
||||||
|
const promiseReactionJobTask =
|
||||||
|
UnsafeCast<PromiseRejectReactionJobTask>(promiseReaction);
|
||||||
|
promiseReactionJobTask.argument = argument;
|
||||||
|
promiseReactionJobTask.context = handlerContext;
|
||||||
|
promiseReactionJobTask.handler = primaryHandler;
|
||||||
|
EnqueueMicrotask(handlerContext, promiseReactionJobTask);
|
||||||
|
StaticAssert(
|
||||||
|
kPromiseReactionPromiseOrCapabilityOffset ==
|
||||||
|
kPromiseReactionJobTaskPromiseOrCapabilityOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://tc39.es/ecma262/#sec-triggerpromisereactions
|
||||||
|
transitioning macro TriggerPromiseReactions(implicit context: Context)(
|
||||||
|
reactions: Zero|PromiseReaction, argument: JSAny,
|
||||||
|
reactionType: constexpr PromiseReactionType): void {
|
||||||
|
// We need to reverse the {reactions} here, since we record them on the
|
||||||
|
// JSPromise in the reverse order.
|
||||||
|
let current = reactions;
|
||||||
|
let reversed: Zero|PromiseReaction = kZero;
|
||||||
|
|
||||||
|
// As an additional safety net against misuse of the V8 Extras API, we
|
||||||
|
// sanity check the {reactions} to make sure that they are actually
|
||||||
|
// PromiseReaction instances and not actual JavaScript values (which
|
||||||
|
// would indicate that we're rejecting or resolving an already settled
|
||||||
|
// promise), see https://crbug.com/931640 for details on this.
|
||||||
|
while (true) {
|
||||||
|
typeswitch (current) {
|
||||||
|
case (Zero): {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (currentReaction: PromiseReaction): {
|
||||||
|
current = currentReaction.next;
|
||||||
|
currentReaction.next = reversed;
|
||||||
|
reversed = currentReaction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Morph the {reactions} into PromiseReactionJobTasks and push them
|
||||||
|
// onto the microtask queue.
|
||||||
|
current = reversed;
|
||||||
|
while (true) {
|
||||||
|
typeswitch (current) {
|
||||||
|
case (Zero): {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (currentReaction: PromiseReaction): {
|
||||||
|
current = currentReaction.next;
|
||||||
|
MorpAndEnqueuePromiseReaction(
|
||||||
|
currentReaction, argument, reactionType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// https://tc39.es/ecma262/#sec-fulfillpromise
|
// https://tc39.es/ecma262/#sec-fulfillpromise
|
||||||
transitioning builtin
|
transitioning builtin
|
||||||
@ -44,7 +177,7 @@ namespace promise {
|
|||||||
|
|
||||||
// 2. Let reactions be promise.[[PromiseFulfillReactions]].
|
// 2. Let reactions be promise.[[PromiseFulfillReactions]].
|
||||||
const reactions =
|
const reactions =
|
||||||
UnsafeCast<(Smi | PromiseReaction)>(promise.reactions_or_result);
|
UnsafeCast<(Zero | PromiseReaction)>(promise.reactions_or_result);
|
||||||
|
|
||||||
// 3. Set promise.[[PromiseResult]] to value.
|
// 3. Set promise.[[PromiseResult]] to value.
|
||||||
// 4. Set promise.[[PromiseFulfillReactions]] to undefined.
|
// 4. Set promise.[[PromiseFulfillReactions]] to undefined.
|
||||||
@ -59,6 +192,43 @@ namespace promise {
|
|||||||
return Undefined;
|
return Undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern macro PromiseBuiltinsAssembler::
|
||||||
|
IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(): bool;
|
||||||
|
|
||||||
|
// https://tc39.es/ecma262/#sec-rejectpromise
|
||||||
|
transitioning builtin
|
||||||
|
RejectPromise(implicit context: Context)(
|
||||||
|
promise: JSPromise, reason: JSAny, debugEvent: Boolean): Object {
|
||||||
|
// 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
|
||||||
|
// forth between JavaScript and C++ land.
|
||||||
|
if (IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate() ||
|
||||||
|
!promise.HasHandler()) {
|
||||||
|
// 7. If promise.[[PromiseIsHandled]] is false, perform
|
||||||
|
// HostPromiseRejectionTracker(promise, "reject").
|
||||||
|
// We don't try to handle rejecting {promise} without handler
|
||||||
|
// here, but we let the C++ code take care of this completely.
|
||||||
|
return runtime::RejectPromise(promise, reason, debugEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Let reactions be promise.[[PromiseRejectReactions]].
|
||||||
|
const reactions =
|
||||||
|
UnsafeCast<(Zero | PromiseReaction)>(promise.reactions_or_result);
|
||||||
|
|
||||||
|
// 3. Set promise.[[PromiseResult]] to reason.
|
||||||
|
// 4. Set promise.[[PromiseFulfillReactions]] to undefined.
|
||||||
|
// 5. Set promise.[[PromiseRejectReactions]] to undefined.
|
||||||
|
promise.reactions_or_result = reason;
|
||||||
|
|
||||||
|
// 6. Set promise.[[PromiseState]] to "rejected".
|
||||||
|
promise.SetStatus(kPromiseRejected);
|
||||||
|
|
||||||
|
// 8. Return TriggerPromiseReactions(reactions, reason).
|
||||||
|
TriggerPromiseReactions(reactions, reason, kPromiseReactionReject);
|
||||||
|
return Undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const kPromiseCapabilitySize:
|
const kPromiseCapabilitySize:
|
||||||
constexpr int31 generates 'PromiseCapability::kSize';
|
constexpr int31 generates 'PromiseCapability::kSize';
|
||||||
const kPromiseBuiltinsCapabilitiesContextLength: constexpr int31
|
const kPromiseBuiltinsCapabilitiesContextLength: constexpr int31
|
||||||
|
@ -6332,6 +6332,16 @@ TNode<BoolT> CodeStubAssembler::IsPromiseReaction(
|
|||||||
return HasInstanceType(object, PROMISE_REACTION_TYPE);
|
return HasInstanceType(object, PROMISE_REACTION_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TNode<BoolT> CodeStubAssembler::IsPromiseRejectReactionJobTask(
|
||||||
|
SloppyTNode<HeapObject> object) {
|
||||||
|
return HasInstanceType(object, PROMISE_REJECT_REACTION_JOB_TASK_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
TNode<BoolT> CodeStubAssembler::IsPromiseFulfillReactionJobTask(
|
||||||
|
SloppyTNode<HeapObject> object) {
|
||||||
|
return HasInstanceType(object, PROMISE_FULFILL_REACTION_JOB_TASK_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
// This complicated check is due to elements oddities. If a smi array is empty
|
// This complicated check is due to elements oddities. If a smi array is empty
|
||||||
// after Array.p.shift, it is replaced by the empty array constant. If it is
|
// after Array.p.shift, it is replaced by the empty array constant. If it is
|
||||||
// later filled with a double element, we try to grow it but pass in a double
|
// later filled with a double element, we try to grow it but pass in a double
|
||||||
@ -6557,6 +6567,11 @@ TNode<BoolT> CodeStubAssembler::IsJSFunction(SloppyTNode<HeapObject> object) {
|
|||||||
return IsJSFunctionMap(LoadMap(object));
|
return IsJSFunctionMap(LoadMap(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TNode<BoolT> CodeStubAssembler::IsJSBoundFunction(
|
||||||
|
SloppyTNode<HeapObject> object) {
|
||||||
|
return HasInstanceType(object, JS_BOUND_FUNCTION_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
TNode<BoolT> CodeStubAssembler::IsJSFunctionMap(SloppyTNode<Map> map) {
|
TNode<BoolT> CodeStubAssembler::IsJSFunctionMap(SloppyTNode<Map> map) {
|
||||||
return IsJSFunctionInstanceType(LoadMapInstanceType(map));
|
return IsJSFunctionInstanceType(LoadMapInstanceType(map));
|
||||||
}
|
}
|
||||||
@ -13102,25 +13117,25 @@ TNode<BoolT> CodeStubAssembler::IsElementsKindInRange(
|
|||||||
Int32Constant(higher_reference_kind - lower_reference_kind));
|
Int32Constant(higher_reference_kind - lower_reference_kind));
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::IsDebugActive() {
|
TNode<BoolT> CodeStubAssembler::IsDebugActive() {
|
||||||
TNode<Uint8T> is_debug_active = Load<Uint8T>(
|
TNode<Uint8T> is_debug_active = Load<Uint8T>(
|
||||||
ExternalConstant(ExternalReference::debug_is_active_address(isolate())));
|
ExternalConstant(ExternalReference::debug_is_active_address(isolate())));
|
||||||
return Word32NotEqual(is_debug_active, Int32Constant(0));
|
return Word32NotEqual(is_debug_active, Int32Constant(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::IsPromiseHookEnabled() {
|
TNode<BoolT> CodeStubAssembler::IsPromiseHookEnabled() {
|
||||||
const TNode<RawPtrT> promise_hook = Load<RawPtrT>(
|
const TNode<RawPtrT> promise_hook = Load<RawPtrT>(
|
||||||
ExternalConstant(ExternalReference::promise_hook_address(isolate())));
|
ExternalConstant(ExternalReference::promise_hook_address(isolate())));
|
||||||
return WordNotEqual(promise_hook, IntPtrConstant(0));
|
return WordNotEqual(promise_hook, IntPtrConstant(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::HasAsyncEventDelegate() {
|
TNode<BoolT> CodeStubAssembler::HasAsyncEventDelegate() {
|
||||||
const TNode<RawPtrT> async_event_delegate = Load<RawPtrT>(ExternalConstant(
|
const TNode<RawPtrT> async_event_delegate = Load<RawPtrT>(ExternalConstant(
|
||||||
ExternalReference::async_event_delegate_address(isolate())));
|
ExternalReference::async_event_delegate_address(isolate())));
|
||||||
return WordNotEqual(async_event_delegate, IntPtrConstant(0));
|
return WordNotEqual(async_event_delegate, IntPtrConstant(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::IsPromiseHookEnabledOrHasAsyncEventDelegate() {
|
TNode<BoolT> CodeStubAssembler::IsPromiseHookEnabledOrHasAsyncEventDelegate() {
|
||||||
const TNode<Uint8T> promise_hook_or_async_event_delegate =
|
const TNode<Uint8T> promise_hook_or_async_event_delegate =
|
||||||
Load<Uint8T>(ExternalConstant(
|
Load<Uint8T>(ExternalConstant(
|
||||||
ExternalReference::promise_hook_or_async_event_delegate_address(
|
ExternalReference::promise_hook_or_async_event_delegate_address(
|
||||||
@ -13128,7 +13143,7 @@ Node* CodeStubAssembler::IsPromiseHookEnabledOrHasAsyncEventDelegate() {
|
|||||||
return Word32NotEqual(promise_hook_or_async_event_delegate, Int32Constant(0));
|
return Word32NotEqual(promise_hook_or_async_event_delegate, Int32Constant(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::
|
TNode<BoolT> CodeStubAssembler::
|
||||||
IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate() {
|
IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate() {
|
||||||
const TNode<Uint8T> promise_hook_or_debug_is_active_or_async_event_delegate =
|
const TNode<Uint8T> promise_hook_or_debug_is_active_or_async_event_delegate =
|
||||||
Load<Uint8T>(ExternalConstant(
|
Load<Uint8T>(ExternalConstant(
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "src/objects/arguments.h"
|
#include "src/objects/arguments.h"
|
||||||
#include "src/objects/bigint.h"
|
#include "src/objects/bigint.h"
|
||||||
#include "src/objects/objects.h"
|
#include "src/objects/objects.h"
|
||||||
|
#include "src/objects/promise.h"
|
||||||
#include "src/objects/shared-function-info.h"
|
#include "src/objects/shared-function-info.h"
|
||||||
#include "src/objects/smi.h"
|
#include "src/objects/smi.h"
|
||||||
#include "src/roots/roots.h"
|
#include "src/roots/roots.h"
|
||||||
@ -2441,6 +2442,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
|||||||
TNode<BoolT> IsAllocationSiteInstanceType(SloppyTNode<Int32T> instance_type);
|
TNode<BoolT> IsAllocationSiteInstanceType(SloppyTNode<Int32T> instance_type);
|
||||||
TNode<BoolT> IsJSFunctionMap(SloppyTNode<Map> map);
|
TNode<BoolT> IsJSFunctionMap(SloppyTNode<Map> map);
|
||||||
TNode<BoolT> IsJSFunction(SloppyTNode<HeapObject> object);
|
TNode<BoolT> IsJSFunction(SloppyTNode<HeapObject> object);
|
||||||
|
TNode<BoolT> IsJSBoundFunction(SloppyTNode<HeapObject> object);
|
||||||
TNode<BoolT> IsJSGeneratorObject(TNode<HeapObject> object);
|
TNode<BoolT> IsJSGeneratorObject(TNode<HeapObject> object);
|
||||||
TNode<BoolT> IsJSGlobalProxyInstanceType(SloppyTNode<Int32T> instance_type);
|
TNode<BoolT> IsJSGlobalProxyInstanceType(SloppyTNode<Int32T> instance_type);
|
||||||
TNode<BoolT> IsJSGlobalProxyMap(SloppyTNode<Map> map);
|
TNode<BoolT> IsJSGlobalProxyMap(SloppyTNode<Map> map);
|
||||||
@ -2480,6 +2482,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
|||||||
TNode<BoolT> IsPropertyArray(SloppyTNode<HeapObject> object);
|
TNode<BoolT> IsPropertyArray(SloppyTNode<HeapObject> object);
|
||||||
TNode<BoolT> IsPropertyCell(SloppyTNode<HeapObject> object);
|
TNode<BoolT> IsPropertyCell(SloppyTNode<HeapObject> object);
|
||||||
TNode<BoolT> IsPromiseReaction(SloppyTNode<HeapObject> object);
|
TNode<BoolT> IsPromiseReaction(SloppyTNode<HeapObject> object);
|
||||||
|
TNode<BoolT> IsPromiseRejectReactionJobTask(SloppyTNode<HeapObject> object);
|
||||||
|
TNode<BoolT> IsPromiseFulfillReactionJobTask(SloppyTNode<HeapObject> object);
|
||||||
TNode<BoolT> IsPrototypeInitialArrayPrototype(SloppyTNode<Context> context,
|
TNode<BoolT> IsPrototypeInitialArrayPrototype(SloppyTNode<Context> context,
|
||||||
SloppyTNode<Map> map);
|
SloppyTNode<Map> map);
|
||||||
TNode<BoolT> IsPrototypeTypedArrayPrototype(SloppyTNode<Context> context,
|
TNode<BoolT> IsPrototypeTypedArrayPrototype(SloppyTNode<Context> context,
|
||||||
@ -3457,7 +3461,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
|||||||
TNode<Context> context);
|
TNode<Context> context);
|
||||||
|
|
||||||
// Debug helpers
|
// Debug helpers
|
||||||
Node* IsDebugActive();
|
TNode<BoolT> IsDebugActive();
|
||||||
|
|
||||||
// JSArrayBuffer helpers
|
// JSArrayBuffer helpers
|
||||||
TNode<Uint32T> LoadJSArrayBufferBitField(TNode<JSArrayBuffer> array_buffer);
|
TNode<Uint32T> LoadJSArrayBufferBitField(TNode<JSArrayBuffer> array_buffer);
|
||||||
@ -3510,10 +3514,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
|||||||
TNode<Context> context);
|
TNode<Context> context);
|
||||||
|
|
||||||
// Promise helpers
|
// Promise helpers
|
||||||
Node* IsPromiseHookEnabled();
|
TNode<BoolT> IsPromiseHookEnabled();
|
||||||
Node* HasAsyncEventDelegate();
|
TNode<BoolT> HasAsyncEventDelegate();
|
||||||
Node* IsPromiseHookEnabledOrHasAsyncEventDelegate();
|
TNode<BoolT> IsPromiseHookEnabledOrHasAsyncEventDelegate();
|
||||||
Node* IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate();
|
TNode<BoolT> IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate();
|
||||||
|
|
||||||
// for..in helpers
|
// for..in helpers
|
||||||
void CheckPrototypeEnumCache(Node* receiver, Node* receiver_map,
|
void CheckPrototypeEnumCache(Node* receiver, Node* receiver_map,
|
||||||
|
@ -74,6 +74,7 @@ class JSPromise : public TorqueGeneratedJSPromise<JSPromise, JSObject> {
|
|||||||
|
|
||||||
static const int kStatusShift = 0;
|
static const int kStatusShift = 0;
|
||||||
static const int kStatusMask = 0x3;
|
static const int kStatusMask = 0x3;
|
||||||
|
static const int kHasHandlerMask = 0x4;
|
||||||
STATIC_ASSERT(v8::Promise::kPending == 0);
|
STATIC_ASSERT(v8::Promise::kPending == 0);
|
||||||
STATIC_ASSERT(v8::Promise::kFulfilled == 1);
|
STATIC_ASSERT(v8::Promise::kFulfilled == 1);
|
||||||
STATIC_ASSERT(v8::Promise::kRejected == 2);
|
STATIC_ASSERT(v8::Promise::kRejected == 2);
|
||||||
|
Loading…
Reference in New Issue
Block a user