[csa] Tnodify builtins-async-generator-gen.cc

Remove TaggedIsAsyncGenerator since all but one use is to generate
asserts that are handled automatically by TNodes. The remaining use is
then just inlined.

Also removes unused IsFastJSIterResult function.

Bug: v8:6949
Change-Id: Id5631586b7e4d4f43d352493a3e2638cf449665f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1849516
Commit-Queue: Dan Elphick <delphick@chromium.org>
Reviewed-by: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64186}
This commit is contained in:
Dan Elphick 2019-10-09 12:44:52 +01:00 committed by Commit Bot
parent 31ec4d4456
commit 3709a0d91e

View File

@ -23,146 +23,142 @@ class AsyncGeneratorBuiltinsAssembler : public AsyncBuiltinsAssembler {
explicit AsyncGeneratorBuiltinsAssembler(CodeAssemblerState* state) explicit AsyncGeneratorBuiltinsAssembler(CodeAssemblerState* state)
: AsyncBuiltinsAssembler(state) {} : AsyncBuiltinsAssembler(state) {}
inline Node* TaggedIsAsyncGenerator(Node* tagged_object) { inline TNode<Smi> LoadGeneratorState(
TNode<BoolT> if_notsmi = TaggedIsNotSmi(tagged_object); const TNode<JSGeneratorObject> generator) {
return Select<BoolT>( return LoadObjectField<Smi>(generator,
if_notsmi, JSGeneratorObject::kContinuationOffset);
[=] {
return HasInstanceType(tagged_object, JS_ASYNC_GENERATOR_OBJECT_TYPE);
},
[=] { return if_notsmi; });
}
inline Node* LoadGeneratorState(Node* const generator) {
return LoadObjectField(generator, JSGeneratorObject::kContinuationOffset);
} }
inline TNode<BoolT> IsGeneratorStateClosed(SloppyTNode<Smi> const state) { inline TNode<BoolT> IsGeneratorStateClosed(const TNode<Smi> state) {
return SmiEqual(state, SmiConstant(JSGeneratorObject::kGeneratorClosed)); return SmiEqual(state, SmiConstant(JSGeneratorObject::kGeneratorClosed));
} }
inline TNode<BoolT> IsGeneratorClosed(Node* const generator) { inline TNode<BoolT> IsGeneratorClosed(
const TNode<JSGeneratorObject> generator) {
return IsGeneratorStateClosed(LoadGeneratorState(generator)); return IsGeneratorStateClosed(LoadGeneratorState(generator));
} }
inline TNode<BoolT> IsGeneratorStateSuspended(SloppyTNode<Smi> const state) { inline TNode<BoolT> IsGeneratorStateSuspended(const TNode<Smi> state) {
return SmiGreaterThanOrEqual(state, SmiConstant(0)); return SmiGreaterThanOrEqual(state, SmiConstant(0));
} }
inline TNode<BoolT> IsGeneratorSuspended(Node* const generator) { inline TNode<BoolT> IsGeneratorSuspended(
const TNode<JSGeneratorObject> generator) {
return IsGeneratorStateSuspended(LoadGeneratorState(generator)); return IsGeneratorStateSuspended(LoadGeneratorState(generator));
} }
inline TNode<BoolT> IsGeneratorStateSuspendedAtStart( inline TNode<BoolT> IsGeneratorStateSuspendedAtStart(const TNode<Smi> state) {
SloppyTNode<Smi> const state) {
return SmiEqual(state, SmiConstant(0)); return SmiEqual(state, SmiConstant(0));
} }
inline TNode<BoolT> IsGeneratorStateNotExecuting( inline TNode<BoolT> IsGeneratorStateNotExecuting(const TNode<Smi> state) {
SloppyTNode<Smi> const state) {
return SmiNotEqual(state, return SmiNotEqual(state,
SmiConstant(JSGeneratorObject::kGeneratorExecuting)); SmiConstant(JSGeneratorObject::kGeneratorExecuting));
} }
inline TNode<BoolT> IsGeneratorNotExecuting(Node* const generator) { inline TNode<BoolT> IsGeneratorNotExecuting(
const TNode<JSGeneratorObject> generator) {
return IsGeneratorStateNotExecuting(LoadGeneratorState(generator)); return IsGeneratorStateNotExecuting(LoadGeneratorState(generator));
} }
inline TNode<BoolT> IsGeneratorAwaiting(Node* const generator) { inline TNode<BoolT> IsGeneratorAwaiting(
const TNode<JSGeneratorObject> generator) {
TNode<Object> is_generator_awaiting = TNode<Object> is_generator_awaiting =
LoadObjectField(generator, JSAsyncGeneratorObject::kIsAwaitingOffset); LoadObjectField(generator, JSAsyncGeneratorObject::kIsAwaitingOffset);
return TaggedEqual(is_generator_awaiting, SmiConstant(1)); return TaggedEqual(is_generator_awaiting, SmiConstant(1));
} }
inline void SetGeneratorAwaiting(Node* const generator) { inline void SetGeneratorAwaiting(const TNode<JSGeneratorObject> generator) {
CSA_ASSERT(this, Word32BinaryNot(IsGeneratorAwaiting(generator))); CSA_ASSERT(this, Word32BinaryNot(IsGeneratorAwaiting(generator)));
StoreObjectFieldNoWriteBarrier( StoreObjectFieldNoWriteBarrier(
generator, JSAsyncGeneratorObject::kIsAwaitingOffset, SmiConstant(1)); generator, JSAsyncGeneratorObject::kIsAwaitingOffset, SmiConstant(1));
CSA_ASSERT(this, IsGeneratorAwaiting(generator)); CSA_ASSERT(this, IsGeneratorAwaiting(generator));
} }
inline void SetGeneratorNotAwaiting(Node* const generator) { inline void SetGeneratorNotAwaiting(
const TNode<JSGeneratorObject> generator) {
CSA_ASSERT(this, IsGeneratorAwaiting(generator)); CSA_ASSERT(this, IsGeneratorAwaiting(generator));
StoreObjectFieldNoWriteBarrier( StoreObjectFieldNoWriteBarrier(
generator, JSAsyncGeneratorObject::kIsAwaitingOffset, SmiConstant(0)); generator, JSAsyncGeneratorObject::kIsAwaitingOffset, SmiConstant(0));
CSA_ASSERT(this, Word32BinaryNot(IsGeneratorAwaiting(generator))); CSA_ASSERT(this, Word32BinaryNot(IsGeneratorAwaiting(generator)));
} }
inline void CloseGenerator(Node* const generator) { inline void CloseGenerator(const TNode<JSGeneratorObject> generator) {
StoreObjectFieldNoWriteBarrier( StoreObjectFieldNoWriteBarrier(
generator, JSGeneratorObject::kContinuationOffset, generator, JSGeneratorObject::kContinuationOffset,
SmiConstant(JSGeneratorObject::kGeneratorClosed)); SmiConstant(JSGeneratorObject::kGeneratorClosed));
} }
inline Node* IsFastJSIterResult(Node* const value, Node* const context) { inline TNode<HeapObject> LoadFirstAsyncGeneratorRequestFromQueue(
CSA_ASSERT(this, TaggedIsNotSmi(value)); const TNode<JSGeneratorObject> generator) {
TNode<NativeContext> const native_context = LoadNativeContext(context); return LoadObjectField<HeapObject>(generator,
return TaggedEqual( JSAsyncGeneratorObject::kQueueOffset);
LoadMap(value),
LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX));
} }
inline Node* LoadFirstAsyncGeneratorRequestFromQueue(Node* const generator) { inline TNode<Smi> LoadResumeTypeFromAsyncGeneratorRequest(
return LoadObjectField(generator, JSAsyncGeneratorObject::kQueueOffset); const TNode<AsyncGeneratorRequest> request) {
return LoadObjectField<Smi>(request,
AsyncGeneratorRequest::kResumeModeOffset);
} }
inline Node* LoadResumeTypeFromAsyncGeneratorRequest(Node* const request) { inline TNode<JSPromise> LoadPromiseFromAsyncGeneratorRequest(
return LoadObjectField(request, AsyncGeneratorRequest::kResumeModeOffset); const TNode<AsyncGeneratorRequest> request) {
return LoadObjectField<JSPromise>(request,
AsyncGeneratorRequest::kPromiseOffset);
} }
inline Node* LoadPromiseFromAsyncGeneratorRequest(Node* const request) { inline TNode<Object> LoadValueFromAsyncGeneratorRequest(
return LoadObjectField(request, AsyncGeneratorRequest::kPromiseOffset); const TNode<AsyncGeneratorRequest> request) {
}
inline Node* LoadValueFromAsyncGeneratorRequest(Node* const request) {
return LoadObjectField(request, AsyncGeneratorRequest::kValueOffset); return LoadObjectField(request, AsyncGeneratorRequest::kValueOffset);
} }
inline TNode<BoolT> IsAbruptResumeType(SloppyTNode<Smi> const resume_type) { inline TNode<BoolT> IsAbruptResumeType(const TNode<Smi> resume_type) {
return SmiNotEqual(resume_type, SmiConstant(JSGeneratorObject::kNext)); return SmiNotEqual(resume_type, SmiConstant(JSGeneratorObject::kNext));
} }
void AsyncGeneratorEnqueue(CodeStubArguments* args, Node* context, void AsyncGeneratorEnqueue(CodeStubArguments* args, TNode<Context> context,
Node* generator, Node* value, TNode<Object> receiver, TNode<Object> value,
JSAsyncGeneratorObject::ResumeMode resume_mode, JSAsyncGeneratorObject::ResumeMode resume_mode,
const char* method_name); const char* method_name);
Node* TakeFirstAsyncGeneratorRequestFromQueue(Node* generator); TNode<AsyncGeneratorRequest> TakeFirstAsyncGeneratorRequestFromQueue(
Node* TakeFirstAsyncGeneratorRequestFromQueueIfPresent(Node* generator, TNode<JSAsyncGeneratorObject> generator);
Label* if_not_present); void AddAsyncGeneratorRequestToQueue(TNode<JSAsyncGeneratorObject> generator,
void AddAsyncGeneratorRequestToQueue(Node* generator, Node* request); TNode<AsyncGeneratorRequest> request);
Node* AllocateAsyncGeneratorRequest( TNode<AsyncGeneratorRequest> AllocateAsyncGeneratorRequest(
JSAsyncGeneratorObject::ResumeMode resume_mode, Node* resume_value, JSAsyncGeneratorObject::ResumeMode resume_mode,
Node* promise); TNode<Object> resume_value, TNode<JSPromise> promise);
// Shared implementation of the catchable and uncatchable variations of Await // Shared implementation of the catchable and uncatchable variations of Await
// for AsyncGenerators. // for AsyncGenerators.
template <typename Descriptor> template <typename Descriptor>
void AsyncGeneratorAwait(bool is_catchable); void AsyncGeneratorAwait(bool is_catchable);
void AsyncGeneratorAwaitResumeClosure( void AsyncGeneratorAwaitResumeClosure(
Node* context, Node* value, TNode<Context> context, TNode<Object> value,
JSAsyncGeneratorObject::ResumeMode resume_mode); JSAsyncGeneratorObject::ResumeMode resume_mode);
}; };
// Shared implementation for the 3 Async Iterator protocol methods of Async // Shared implementation for the 3 Async Iterator protocol methods of Async
// Generators. // Generators.
void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorEnqueue( void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorEnqueue(
CodeStubArguments* args, Node* context, Node* generator, Node* value, CodeStubArguments* args, TNode<Context> context, TNode<Object> receiver,
JSAsyncGeneratorObject::ResumeMode resume_mode, const char* method_name) { TNode<Object> value, JSAsyncGeneratorObject::ResumeMode resume_mode,
const char* method_name) {
// AsyncGeneratorEnqueue produces a new Promise, and appends it to the list // AsyncGeneratorEnqueue produces a new Promise, and appends it to the list
// of async generator requests to be executed. If the generator is not // of async generator requests to be executed. If the generator is not
// presently executing, then this method will loop through, processing each // presently executing, then this method will loop through, processing each
// request from front to back. // request from front to back.
// This loop resides in AsyncGeneratorResumeNext. // This loop resides in AsyncGeneratorResumeNext.
TNode<JSPromise> promise = AllocateAndInitJSPromise(CAST(context)); TNode<JSPromise> promise = AllocateAndInitJSPromise(context);
Label enqueue(this), if_receiverisincompatible(this, Label::kDeferred); Label if_receiverisincompatible(this, Label::kDeferred);
GotoIf(TaggedIsSmi(receiver), &if_receiverisincompatible);
GotoIfNot(HasInstanceType(CAST(receiver), JS_ASYNC_GENERATOR_OBJECT_TYPE),
&if_receiverisincompatible);
Branch(TaggedIsAsyncGenerator(generator), &enqueue,
&if_receiverisincompatible);
BIND(&enqueue);
{ {
Label done(this); Label done(this);
Node* const req = const TNode<JSAsyncGeneratorObject> generator = CAST(receiver);
const TNode<AsyncGeneratorRequest> req =
AllocateAsyncGeneratorRequest(resume_mode, value, promise); AllocateAsyncGeneratorRequest(resume_mode, value, promise);
AddAsyncGeneratorRequestToQueue(generator, req); AddAsyncGeneratorRequestToQueue(generator, req);
@ -171,7 +167,7 @@ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorEnqueue(
// If state is not "executing", then // If state is not "executing", then
// Perform AsyncGeneratorResumeNext(Generator) // Perform AsyncGeneratorResumeNext(Generator)
// Check if the {receiver} is running or already closed. // Check if the {receiver} is running or already closed.
TNode<Smi> continuation = CAST(LoadGeneratorState(generator)); TNode<Smi> continuation = LoadGeneratorState(generator);
GotoIf(SmiEqual(continuation, GotoIf(SmiEqual(continuation,
SmiConstant(JSAsyncGeneratorObject::kGeneratorExecuting)), SmiConstant(JSAsyncGeneratorObject::kGeneratorExecuting)),
@ -186,20 +182,18 @@ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorEnqueue(
BIND(&if_receiverisincompatible); BIND(&if_receiverisincompatible);
{ {
Node* const error = CallBuiltin(Builtins::kRejectPromise, context, promise,
MakeTypeError(MessageTemplate::kIncompatibleMethodReceiver, context, MakeTypeError(MessageTemplate::kIncompatibleMethodReceiver,
StringConstant(method_name), generator); context, StringConstant(method_name), receiver),
CallBuiltin(Builtins::kRejectPromise, context, promise, error,
TrueConstant()); TrueConstant());
args->PopAndReturn(promise); args->PopAndReturn(promise);
} }
} }
Node* AsyncGeneratorBuiltinsAssembler::AllocateAsyncGeneratorRequest( TNode<AsyncGeneratorRequest>
JSAsyncGeneratorObject::ResumeMode resume_mode, Node* resume_value, AsyncGeneratorBuiltinsAssembler::AllocateAsyncGeneratorRequest(
Node* promise) { JSAsyncGeneratorObject::ResumeMode resume_mode, TNode<Object> resume_value,
CSA_SLOW_ASSERT(this, HasInstanceType(promise, JS_PROMISE_TYPE)); TNode<JSPromise> promise) {
TNode<HeapObject> request = Allocate(AsyncGeneratorRequest::kSize); TNode<HeapObject> request = Allocate(AsyncGeneratorRequest::kSize);
StoreMapNoWriteBarrier(request, RootIndex::kAsyncGeneratorRequestMap); StoreMapNoWriteBarrier(request, RootIndex::kAsyncGeneratorRequestMap);
StoreObjectFieldNoWriteBarrier(request, AsyncGeneratorRequest::kNextOffset, StoreObjectFieldNoWriteBarrier(request, AsyncGeneratorRequest::kNextOffset,
@ -213,15 +207,14 @@ Node* AsyncGeneratorBuiltinsAssembler::AllocateAsyncGeneratorRequest(
promise); promise);
StoreObjectFieldRoot(request, AsyncGeneratorRequest::kNextOffset, StoreObjectFieldRoot(request, AsyncGeneratorRequest::kNextOffset,
RootIndex::kUndefinedValue); RootIndex::kUndefinedValue);
return request; return CAST(request);
} }
void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwaitResumeClosure( void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwaitResumeClosure(
Node* context, Node* value, TNode<Context> context, TNode<Object> value,
JSAsyncGeneratorObject::ResumeMode resume_mode) { JSAsyncGeneratorObject::ResumeMode resume_mode) {
TNode<Object> const generator = const TNode<JSAsyncGeneratorObject> generator =
LoadContextElement(context, Context::EXTENSION_INDEX); CAST(LoadContextElement(context, Context::EXTENSION_INDEX));
CSA_SLOW_ASSERT(this, TaggedIsAsyncGenerator(generator));
SetGeneratorNotAwaiting(generator); SetGeneratorNotAwaiting(generator);
@ -259,12 +252,13 @@ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwait(bool is_catchable) {
} }
void AsyncGeneratorBuiltinsAssembler::AddAsyncGeneratorRequestToQueue( void AsyncGeneratorBuiltinsAssembler::AddAsyncGeneratorRequestToQueue(
Node* generator, Node* request) { TNode<JSAsyncGeneratorObject> generator,
VARIABLE(var_current, MachineRepresentation::kTagged); TNode<AsyncGeneratorRequest> request) {
TVARIABLE(HeapObject, var_current);
Label empty(this), loop(this, &var_current), done(this); Label empty(this), loop(this, &var_current), done(this);
var_current.Bind( var_current = LoadObjectField<HeapObject>(
LoadObjectField(generator, JSAsyncGeneratorObject::kQueueOffset)); generator, JSAsyncGeneratorObject::kQueueOffset);
Branch(IsUndefined(var_current.value()), &empty, &loop); Branch(IsUndefined(var_current.value()), &empty, &loop);
BIND(&empty); BIND(&empty);
@ -276,9 +270,9 @@ void AsyncGeneratorBuiltinsAssembler::AddAsyncGeneratorRequestToQueue(
BIND(&loop); BIND(&loop);
{ {
Label loop_next(this), next_empty(this); Label loop_next(this), next_empty(this);
Node* current = var_current.value(); TNode<AsyncGeneratorRequest> current = CAST(var_current.value());
TNode<Object> next = TNode<HeapObject> next = LoadObjectField<HeapObject>(
LoadObjectField(current, AsyncGeneratorRequest::kNextOffset); current, AsyncGeneratorRequest::kNextOffset);
Branch(IsUndefined(next), &next_empty, &loop_next); Branch(IsUndefined(next), &next_empty, &loop_next);
BIND(&next_empty); BIND(&next_empty);
@ -289,20 +283,20 @@ void AsyncGeneratorBuiltinsAssembler::AddAsyncGeneratorRequestToQueue(
BIND(&loop_next); BIND(&loop_next);
{ {
var_current.Bind(next); var_current = next;
Goto(&loop); Goto(&loop);
} }
} }
BIND(&done); BIND(&done);
} }
Node* AsyncGeneratorBuiltinsAssembler::TakeFirstAsyncGeneratorRequestFromQueue( TNode<AsyncGeneratorRequest>
Node* generator) { AsyncGeneratorBuiltinsAssembler::TakeFirstAsyncGeneratorRequestFromQueue(
TNode<JSAsyncGeneratorObject> generator) {
// Removes and returns the first AsyncGeneratorRequest from a // Removes and returns the first AsyncGeneratorRequest from a
// JSAsyncGeneratorObject's queue. Asserts that the queue is not empty. // JSAsyncGeneratorObject's queue. Asserts that the queue is not empty.
CSA_ASSERT(this, TaggedIsAsyncGenerator(generator)); TNode<AsyncGeneratorRequest> request = LoadObjectField<AsyncGeneratorRequest>(
TNode<AsyncGeneratorRequest> request = generator, JSAsyncGeneratorObject::kQueueOffset);
CAST(LoadObjectField(generator, JSAsyncGeneratorObject::kQueueOffset));
TNode<Object> next = TNode<Object> next =
LoadObjectField(request, AsyncGeneratorRequest::kNextOffset); LoadObjectField(request, AsyncGeneratorRequest::kNextOffset);
@ -323,7 +317,7 @@ TF_BUILTIN(AsyncGeneratorPrototypeNext, AsyncGeneratorBuiltinsAssembler) {
TNode<Object> generator = args.GetReceiver(); TNode<Object> generator = args.GetReceiver();
TNode<Object> value = args.GetOptionalArgumentValue(kValueArg); TNode<Object> value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(Descriptor::kContext); TNode<Context> context = CAST(Parameter(Descriptor::kContext));
AsyncGeneratorEnqueue(&args, context, generator, value, AsyncGeneratorEnqueue(&args, context, generator, value,
JSAsyncGeneratorObject::kNext, JSAsyncGeneratorObject::kNext,
@ -341,7 +335,7 @@ TF_BUILTIN(AsyncGeneratorPrototypeReturn, AsyncGeneratorBuiltinsAssembler) {
TNode<Object> generator = args.GetReceiver(); TNode<Object> generator = args.GetReceiver();
TNode<Object> value = args.GetOptionalArgumentValue(kValueArg); TNode<Object> value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(Descriptor::kContext); TNode<Context> context = CAST(Parameter(Descriptor::kContext));
AsyncGeneratorEnqueue(&args, context, generator, value, AsyncGeneratorEnqueue(&args, context, generator, value,
JSAsyncGeneratorObject::kReturn, JSAsyncGeneratorObject::kReturn,
@ -359,7 +353,7 @@ TF_BUILTIN(AsyncGeneratorPrototypeThrow, AsyncGeneratorBuiltinsAssembler) {
TNode<Object> generator = args.GetReceiver(); TNode<Object> generator = args.GetReceiver();
TNode<Object> value = args.GetOptionalArgumentValue(kValueArg); TNode<Object> value = args.GetOptionalArgumentValue(kValueArg);
Node* context = Parameter(Descriptor::kContext); TNode<Context> context = CAST(Parameter(Descriptor::kContext));
AsyncGeneratorEnqueue(&args, context, generator, value, AsyncGeneratorEnqueue(&args, context, generator, value,
JSAsyncGeneratorObject::kThrow, JSAsyncGeneratorObject::kThrow,
@ -367,15 +361,15 @@ TF_BUILTIN(AsyncGeneratorPrototypeThrow, AsyncGeneratorBuiltinsAssembler) {
} }
TF_BUILTIN(AsyncGeneratorAwaitResolveClosure, AsyncGeneratorBuiltinsAssembler) { TF_BUILTIN(AsyncGeneratorAwaitResolveClosure, AsyncGeneratorBuiltinsAssembler) {
Node* value = Parameter(Descriptor::kValue); TNode<Object> value = CAST(Parameter(Descriptor::kValue));
Node* context = Parameter(Descriptor::kContext); TNode<Context> context = CAST(Parameter(Descriptor::kContext));
AsyncGeneratorAwaitResumeClosure(context, value, AsyncGeneratorAwaitResumeClosure(context, value,
JSAsyncGeneratorObject::kNext); JSAsyncGeneratorObject::kNext);
} }
TF_BUILTIN(AsyncGeneratorAwaitRejectClosure, AsyncGeneratorBuiltinsAssembler) { TF_BUILTIN(AsyncGeneratorAwaitRejectClosure, AsyncGeneratorBuiltinsAssembler) {
Node* value = Parameter(Descriptor::kValue); TNode<Object> value = CAST(Parameter(Descriptor::kValue));
Node* context = Parameter(Descriptor::kContext); TNode<Context> context = CAST(Parameter(Descriptor::kContext));
AsyncGeneratorAwaitResumeClosure(context, value, AsyncGeneratorAwaitResumeClosure(context, value,
JSAsyncGeneratorObject::kThrow); JSAsyncGeneratorObject::kThrow);
} }
@ -392,8 +386,9 @@ TF_BUILTIN(AsyncGeneratorAwaitCaught, AsyncGeneratorBuiltinsAssembler) {
TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) { TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) {
using Descriptor = AsyncGeneratorResumeNextDescriptor; using Descriptor = AsyncGeneratorResumeNextDescriptor;
Node* const generator = Parameter(Descriptor::kGenerator); const TNode<JSAsyncGeneratorObject> generator =
Node* const context = Parameter(Descriptor::kContext); CAST(Parameter(Descriptor::kGenerator));
const TNode<Context> context = CAST(Parameter(Descriptor::kContext));
// The penultimate step of proposal-async-iteration/#sec-asyncgeneratorresolve // The penultimate step of proposal-async-iteration/#sec-asyncgeneratorresolve
// and proposal-async-iteration/#sec-asyncgeneratorreject both recursively // and proposal-async-iteration/#sec-asyncgeneratorreject both recursively
@ -403,12 +398,10 @@ TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) {
// performs a loop in AsyncGeneratorResumeNext, which continues as long as // performs a loop in AsyncGeneratorResumeNext, which continues as long as
// there is an AsyncGeneratorRequest in the queue, and as long as the // there is an AsyncGeneratorRequest in the queue, and as long as the
// generator is not suspended due to an AwaitExpression. // generator is not suspended due to an AwaitExpression.
VARIABLE(var_state, MachineRepresentation::kTaggedSigned, TVARIABLE(Smi, var_state, LoadGeneratorState(generator));
LoadGeneratorState(generator)); TVARIABLE(HeapObject, var_next,
VARIABLE(var_next, MachineRepresentation::kTagged, LoadFirstAsyncGeneratorRequestFromQueue(generator));
LoadFirstAsyncGeneratorRequestFromQueue(generator)); Label start(this, {&var_state, &var_next});
Variable* loop_variables[] = {&var_state, &var_next};
Label start(this, 2, loop_variables);
Goto(&start); Goto(&start);
BIND(&start); BIND(&start);
@ -420,9 +413,8 @@ TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) {
// Stop resuming if request queue is empty. // Stop resuming if request queue is empty.
ReturnIf(IsUndefined(var_next.value()), UndefinedConstant()); ReturnIf(IsUndefined(var_next.value()), UndefinedConstant());
Node* const next = var_next.value(); const TNode<AsyncGeneratorRequest> next = CAST(var_next.value());
TNode<Smi> const resume_type = const TNode<Smi> resume_type = LoadResumeTypeFromAsyncGeneratorRequest(next);
CAST(LoadResumeTypeFromAsyncGeneratorRequest(next));
Label if_abrupt(this), if_normal(this), resume_generator(this); Label if_abrupt(this), if_normal(this), resume_generator(this);
Branch(IsAbruptResumeType(resume_type), &if_abrupt, &if_normal); Branch(IsAbruptResumeType(resume_type), &if_abrupt, &if_normal);
@ -432,11 +424,11 @@ TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) {
GotoIfNot(IsGeneratorStateSuspendedAtStart(var_state.value()), GotoIfNot(IsGeneratorStateSuspendedAtStart(var_state.value()),
&settle_promise); &settle_promise);
CloseGenerator(generator); CloseGenerator(generator);
var_state.Bind(SmiConstant(JSGeneratorObject::kGeneratorClosed)); var_state = SmiConstant(JSGeneratorObject::kGeneratorClosed);
Goto(&settle_promise); Goto(&settle_promise);
BIND(&settle_promise); BIND(&settle_promise);
Node* next_value = LoadValueFromAsyncGeneratorRequest(next); TNode<Object> next_value = LoadValueFromAsyncGeneratorRequest(next);
Branch(SmiEqual(resume_type, SmiConstant(JSGeneratorObject::kReturn)), Branch(SmiEqual(resume_type, SmiConstant(JSGeneratorObject::kReturn)),
&if_return, &if_throw); &if_return, &if_throw);
@ -457,7 +449,7 @@ TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) {
GotoIfNot(IsGeneratorStateClosed(var_state.value()), &resume_generator); GotoIfNot(IsGeneratorStateClosed(var_state.value()), &resume_generator);
CallBuiltin(Builtins::kAsyncGeneratorReject, context, generator, CallBuiltin(Builtins::kAsyncGeneratorReject, context, generator,
next_value); next_value);
var_next.Bind(LoadFirstAsyncGeneratorRequestFromQueue(generator)); var_next = LoadFirstAsyncGeneratorRequestFromQueue(generator);
Goto(&start); Goto(&start);
} }
@ -466,8 +458,8 @@ TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) {
GotoIfNot(IsGeneratorStateClosed(var_state.value()), &resume_generator); GotoIfNot(IsGeneratorStateClosed(var_state.value()), &resume_generator);
CallBuiltin(Builtins::kAsyncGeneratorResolve, context, generator, CallBuiltin(Builtins::kAsyncGeneratorResolve, context, generator,
UndefinedConstant(), TrueConstant()); UndefinedConstant(), TrueConstant());
var_state.Bind(LoadGeneratorState(generator)); var_state = LoadGeneratorState(generator);
var_next.Bind(LoadFirstAsyncGeneratorRequestFromQueue(generator)); var_next = LoadFirstAsyncGeneratorRequestFromQueue(generator);
Goto(&start); Goto(&start);
} }
@ -478,19 +470,19 @@ TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) {
generator, JSGeneratorObject::kResumeModeOffset, resume_type); generator, JSGeneratorObject::kResumeModeOffset, resume_type);
CallStub(CodeFactory::ResumeGenerator(isolate()), context, CallStub(CodeFactory::ResumeGenerator(isolate()), context,
LoadValueFromAsyncGeneratorRequest(next), generator); LoadValueFromAsyncGeneratorRequest(next), generator);
var_state.Bind(LoadGeneratorState(generator)); var_state = LoadGeneratorState(generator);
var_next.Bind(LoadFirstAsyncGeneratorRequestFromQueue(generator)); var_next = LoadFirstAsyncGeneratorRequestFromQueue(generator);
Goto(&start); Goto(&start);
} }
} }
TF_BUILTIN(AsyncGeneratorResolve, AsyncGeneratorBuiltinsAssembler) { TF_BUILTIN(AsyncGeneratorResolve, AsyncGeneratorBuiltinsAssembler) {
Node* const generator = Parameter(Descriptor::kGenerator); const TNode<JSAsyncGeneratorObject> generator =
Node* const value = Parameter(Descriptor::kValue); CAST(Parameter(Descriptor::kGenerator));
Node* const done = Parameter(Descriptor::kDone); const TNode<Object> value = CAST(Parameter(Descriptor::kValue));
Node* const context = Parameter(Descriptor::kContext); const TNode<Object> done = CAST(Parameter(Descriptor::kDone));
const TNode<Context> context = CAST(Parameter(Descriptor::kContext));
CSA_SLOW_ASSERT(this, TaggedIsAsyncGenerator(generator));
CSA_ASSERT(this, Word32BinaryNot(IsGeneratorAwaiting(generator))); CSA_ASSERT(this, Word32BinaryNot(IsGeneratorAwaiting(generator)));
// This operation should be called only when the `value` parameter has been // This operation should be called only when the `value` parameter has been
@ -499,11 +491,12 @@ TF_BUILTIN(AsyncGeneratorResolve, AsyncGeneratorBuiltinsAssembler) {
// non-callable value. This can't be checked with assertions due to being // non-callable value. This can't be checked with assertions due to being
// observable, but keep it in mind. // observable, but keep it in mind.
Node* const next = TakeFirstAsyncGeneratorRequestFromQueue(generator); const TNode<AsyncGeneratorRequest> next =
Node* const promise = LoadPromiseFromAsyncGeneratorRequest(next); TakeFirstAsyncGeneratorRequestFromQueue(generator);
const TNode<JSPromise> promise = LoadPromiseFromAsyncGeneratorRequest(next);
// Let iteratorResult be CreateIterResultObject(value, done). // Let iteratorResult be CreateIterResultObject(value, done).
TNode<HeapObject> const iter_result = Allocate(JSIteratorResult::kSize); const TNode<HeapObject> iter_result = Allocate(JSIteratorResult::kSize);
{ {
TNode<Object> map = LoadContextElement(LoadNativeContext(context), TNode<Object> map = LoadContextElement(LoadNativeContext(context),
Context::ITERATOR_RESULT_MAP_INDEX); Context::ITERATOR_RESULT_MAP_INDEX);
@ -555,12 +548,14 @@ TF_BUILTIN(AsyncGeneratorResolve, AsyncGeneratorBuiltinsAssembler) {
TF_BUILTIN(AsyncGeneratorReject, AsyncGeneratorBuiltinsAssembler) { TF_BUILTIN(AsyncGeneratorReject, AsyncGeneratorBuiltinsAssembler) {
using Descriptor = AsyncGeneratorRejectDescriptor; using Descriptor = AsyncGeneratorRejectDescriptor;
Node* const generator = Parameter(Descriptor::kGenerator); const TNode<JSAsyncGeneratorObject> generator =
Node* const value = Parameter(Descriptor::kValue); CAST(Parameter(Descriptor::kGenerator));
Node* const context = Parameter(Descriptor::kContext); const TNode<Object> value = CAST(Parameter(Descriptor::kValue));
const TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Node* const next = TakeFirstAsyncGeneratorRequestFromQueue(generator); TNode<AsyncGeneratorRequest> next =
Node* const promise = LoadPromiseFromAsyncGeneratorRequest(next); TakeFirstAsyncGeneratorRequestFromQueue(generator);
TNode<JSPromise> promise = LoadPromiseFromAsyncGeneratorRequest(next);
Return(CallBuiltin(Builtins::kRejectPromise, context, promise, value, Return(CallBuiltin(Builtins::kRejectPromise, context, promise, value,
TrueConstant())); TrueConstant()));
@ -573,9 +568,10 @@ TF_BUILTIN(AsyncGeneratorYield, AsyncGeneratorBuiltinsAssembler) {
const TNode<Oddball> is_caught = CAST(Parameter(Descriptor::kIsCaught)); const TNode<Oddball> is_caught = CAST(Parameter(Descriptor::kIsCaught));
const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); const TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Node* const request = LoadFirstAsyncGeneratorRequestFromQueue(generator); const TNode<AsyncGeneratorRequest> request =
CAST(LoadFirstAsyncGeneratorRequestFromQueue(generator));
const TNode<JSPromise> outer_promise = const TNode<JSPromise> outer_promise =
CAST(LoadPromiseFromAsyncGeneratorRequest(request)); LoadPromiseFromAsyncGeneratorRequest(request);
const int on_resolve = Context::ASYNC_GENERATOR_YIELD_RESOLVE_SHARED_FUN; const int on_resolve = Context::ASYNC_GENERATOR_YIELD_RESOLVE_SHARED_FUN;
const int on_reject = Context::ASYNC_GENERATOR_AWAIT_REJECT_SHARED_FUN; const int on_reject = Context::ASYNC_GENERATOR_AWAIT_REJECT_SHARED_FUN;
@ -587,10 +583,10 @@ TF_BUILTIN(AsyncGeneratorYield, AsyncGeneratorBuiltinsAssembler) {
} }
TF_BUILTIN(AsyncGeneratorYieldResolveClosure, AsyncGeneratorBuiltinsAssembler) { TF_BUILTIN(AsyncGeneratorYieldResolveClosure, AsyncGeneratorBuiltinsAssembler) {
Node* const context = Parameter(Descriptor::kContext); const TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Node* const value = Parameter(Descriptor::kValue); const TNode<Object> value = CAST(Parameter(Descriptor::kValue));
TNode<Object> const generator = const TNode<JSAsyncGeneratorObject> generator =
LoadContextElement(context, Context::EXTENSION_INDEX); CAST(LoadContextElement(context, Context::EXTENSION_INDEX));
SetGeneratorNotAwaiting(generator); SetGeneratorNotAwaiting(generator);
@ -623,8 +619,8 @@ TF_BUILTIN(AsyncGeneratorReturn, AsyncGeneratorBuiltinsAssembler) {
CAST(Parameter(Descriptor::kGenerator)); CAST(Parameter(Descriptor::kGenerator));
const TNode<Object> value = CAST(Parameter(Descriptor::kValue)); const TNode<Object> value = CAST(Parameter(Descriptor::kValue));
const TNode<Oddball> is_caught = CAST(Parameter(Descriptor::kIsCaught)); const TNode<Oddball> is_caught = CAST(Parameter(Descriptor::kIsCaught));
Node* const req = LoadFirstAsyncGeneratorRequestFromQueue(generator); const TNode<AsyncGeneratorRequest> req =
CSA_ASSERT(this, IsNotUndefined(req)); CAST(LoadFirstAsyncGeneratorRequestFromQueue(generator));
Label perform_await(this); Label perform_await(this);
TVARIABLE(IntPtrT, var_on_resolve, TVARIABLE(IntPtrT, var_on_resolve,
@ -634,7 +630,7 @@ TF_BUILTIN(AsyncGeneratorReturn, AsyncGeneratorBuiltinsAssembler) {
IntPtrT, var_on_reject, IntPtrT, var_on_reject,
IntPtrConstant(Context::ASYNC_GENERATOR_RETURN_CLOSED_REJECT_SHARED_FUN)); IntPtrConstant(Context::ASYNC_GENERATOR_RETURN_CLOSED_REJECT_SHARED_FUN));
Node* const state = LoadGeneratorState(generator); const TNode<Smi> state = LoadGeneratorState(generator);
GotoIf(IsGeneratorStateClosed(state), &perform_await); GotoIf(IsGeneratorStateClosed(state), &perform_await);
var_on_resolve = var_on_resolve =
IntPtrConstant(Context::ASYNC_GENERATOR_RETURN_RESOLVE_SHARED_FUN); IntPtrConstant(Context::ASYNC_GENERATOR_RETURN_RESOLVE_SHARED_FUN);
@ -647,7 +643,7 @@ TF_BUILTIN(AsyncGeneratorReturn, AsyncGeneratorBuiltinsAssembler) {
SetGeneratorAwaiting(generator); SetGeneratorAwaiting(generator);
TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<Context> context = CAST(Parameter(Descriptor::kContext));
const TNode<JSPromise> outer_promise = const TNode<JSPromise> outer_promise =
CAST(LoadPromiseFromAsyncGeneratorRequest(req)); LoadPromiseFromAsyncGeneratorRequest(req);
Await(context, generator, value, outer_promise, var_on_resolve.value(), Await(context, generator, value, outer_promise, var_on_resolve.value(),
var_on_reject.value(), is_caught); var_on_reject.value(), is_caught);
@ -660,8 +656,8 @@ TF_BUILTIN(AsyncGeneratorReturn, AsyncGeneratorBuiltinsAssembler) {
// proposal-async-iteration/#sec-asyncgeneratoryield step 8.e // proposal-async-iteration/#sec-asyncgeneratoryield step 8.e
TF_BUILTIN(AsyncGeneratorReturnResolveClosure, TF_BUILTIN(AsyncGeneratorReturnResolveClosure,
AsyncGeneratorBuiltinsAssembler) { AsyncGeneratorBuiltinsAssembler) {
Node* const context = Parameter(Descriptor::kContext); const TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Node* const value = Parameter(Descriptor::kValue); const TNode<Object> value = CAST(Parameter(Descriptor::kValue));
AsyncGeneratorAwaitResumeClosure(context, value, JSGeneratorObject::kReturn); AsyncGeneratorAwaitResumeClosure(context, value, JSGeneratorObject::kReturn);
} }
@ -670,10 +666,10 @@ TF_BUILTIN(AsyncGeneratorReturnResolveClosure,
// AsyncGeneratorResumeNext. // AsyncGeneratorResumeNext.
TF_BUILTIN(AsyncGeneratorReturnClosedResolveClosure, TF_BUILTIN(AsyncGeneratorReturnClosedResolveClosure,
AsyncGeneratorBuiltinsAssembler) { AsyncGeneratorBuiltinsAssembler) {
Node* const context = Parameter(Descriptor::kContext); const TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Node* const value = Parameter(Descriptor::kValue); const TNode<Object> value = CAST(Parameter(Descriptor::kValue));
TNode<Object> const generator = const TNode<JSAsyncGeneratorObject> generator =
LoadContextElement(context, Context::EXTENSION_INDEX); CAST(LoadContextElement(context, Context::EXTENSION_INDEX));
SetGeneratorNotAwaiting(generator); SetGeneratorNotAwaiting(generator);
@ -688,10 +684,10 @@ TF_BUILTIN(AsyncGeneratorReturnClosedResolveClosure,
TF_BUILTIN(AsyncGeneratorReturnClosedRejectClosure, TF_BUILTIN(AsyncGeneratorReturnClosedRejectClosure,
AsyncGeneratorBuiltinsAssembler) { AsyncGeneratorBuiltinsAssembler) {
Node* const context = Parameter(Descriptor::kContext); const TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Node* const value = Parameter(Descriptor::kValue); const TNode<Object> value = CAST(Parameter(Descriptor::kValue));
TNode<Object> const generator = const TNode<JSAsyncGeneratorObject> generator =
LoadContextElement(context, Context::EXTENSION_INDEX); CAST(LoadContextElement(context, Context::EXTENSION_INDEX));
SetGeneratorNotAwaiting(generator); SetGeneratorNotAwaiting(generator);