Commit 31b88650 authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[ignition] desugar yield* in the BytecodeGenerator

Async generator yield* is still desugared in the parser, to be moved to the BytecodeGenerator in a future CL.

Bug: v8:6472
Change-Id: I8b33e2f9e931949f7375540099cd8ec3a6b27cf1
Reviewed-on: https://chromium-review.googlesource.com/539335
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46165}
parent b00de2a9
......@@ -270,6 +270,9 @@ void AstExpressionRewriter::VisitSuspend(Suspend* node) {
AST_REWRITE_PROPERTY(Expression, node, expression);
}
void AstExpressionRewriter::VisitYieldStar(YieldStar* node) {
VisitSuspend(node);
}
void AstExpressionRewriter::VisitThrow(Throw* node) {
REWRITE_THIS(node);
......
......@@ -240,6 +240,10 @@ void AstNumberingVisitor::VisitSuspend(Suspend* node) {
Visit(node->expression());
}
void AstNumberingVisitor::VisitYieldStar(YieldStar* node) {
VisitSuspend(node);
ReserveFeedbackSlots(node);
}
void AstNumberingVisitor::VisitThrow(Throw* node) {
IncrementNodeCount();
......
......@@ -362,6 +362,12 @@ void AstTraversalVisitor<Subclass>::VisitSuspend(Suspend* expr) {
RECURSE_EXPRESSION(Visit(expr->expression()));
}
template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitYieldStar(YieldStar* expr) {
PROCESS_EXPRESSION(expr);
RECURSE_EXPRESSION(Visit(expr->expression()));
}
template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitThrow(Throw* expr) {
PROCESS_EXPRESSION(expr);
......
......@@ -92,6 +92,7 @@ namespace internal {
V(VariableProxy) \
V(Literal) \
V(Suspend) \
V(YieldStar) \
V(Throw) \
V(CallRuntime) \
V(UnaryOperation) \
......@@ -2250,7 +2251,7 @@ class RewritableExpression final : public Expression {
// Our Yield is different from the JS yield in that it "returns" its argument as
// is, without wrapping it in an iterator result object. Such wrapping, if
// desired, must be done beforehand (see the parser).
class Suspend final : public Expression {
class Suspend : public Expression {
public:
// With {kNoControl}, the {Suspend} behaves like yield, except that it never
// throws and never causes the current generator to return. This is used to
......@@ -2300,10 +2301,11 @@ class Suspend final : public Expression {
private:
friend class AstNodeFactory;
friend class YieldStar;
Suspend(Expression* expression, int pos, OnAbruptResume on_abrupt_resume,
SuspendFlags flags)
: Expression(pos, kSuspend), suspend_id_(-1), expression_(expression) {
Suspend(NodeType node_type, Expression* expression, int pos,
OnAbruptResume on_abrupt_resume, SuspendFlags flags)
: Expression(pos, node_type), suspend_id_(-1), expression_(expression) {
bit_field_ |= OnAbruptResumeField::encode(on_abrupt_resume) |
FlagsField::encode(flags);
}
......@@ -2318,6 +2320,74 @@ class Suspend final : public Expression {
static_cast<int>(SuspendFlags::kBitWidth)> {};
};
class YieldStar final : public Suspend {
public:
void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
FeedbackSlotCache* cache) {
load_iterable_iterator_slot_ = spec->AddLoadICSlot();
load_iterator_return_slot_ = spec->AddLoadICSlot();
load_iterator_next_slot_ = spec->AddLoadICSlot();
load_iterator_throw_slot_ = spec->AddLoadICSlot();
load_output_done_slot_ = spec->AddLoadICSlot();
load_output_value_slot_ = spec->AddLoadICSlot();
call_iterable_iterator_slot_ = spec->AddCallICSlot();
call_iterator_return_slot1_ = spec->AddCallICSlot();
call_iterator_return_slot2_ = spec->AddCallICSlot();
call_iterator_next_slot_ = spec->AddCallICSlot();
call_iterator_throw_slot_ = spec->AddCallICSlot();
}
FeedbackSlot load_iterable_iterator_slot() const {
return load_iterable_iterator_slot_;
}
FeedbackSlot load_iterator_return_slot() const {
return load_iterator_return_slot_;
}
FeedbackSlot load_iterator_next_slot() const {
return load_iterator_next_slot_;
}
FeedbackSlot load_iterator_throw_slot() const {
return load_iterator_throw_slot_;
}
FeedbackSlot load_output_done_slot() const { return load_output_done_slot_; }
FeedbackSlot load_output_value_slot() const {
return load_output_value_slot_;
}
FeedbackSlot call_iterable_iterator_slot() const {
return call_iterable_iterator_slot_;
}
FeedbackSlot call_iterator_return_slot1() const {
return call_iterator_return_slot1_;
}
FeedbackSlot call_iterator_return_slot2() const {
return call_iterator_return_slot2_;
}
FeedbackSlot call_iterator_next_slot() const {
return call_iterator_next_slot_;
}
FeedbackSlot call_iterator_throw_slot() const {
return call_iterator_throw_slot_;
}
private:
friend class AstNodeFactory;
YieldStar(Expression* expression, int pos, SuspendFlags flags)
: Suspend(kYieldStar, expression, pos,
Suspend::OnAbruptResume::kNoControl, flags) {}
FeedbackSlot load_iterable_iterator_slot_;
FeedbackSlot load_iterator_return_slot_;
FeedbackSlot load_iterator_next_slot_;
FeedbackSlot load_iterator_throw_slot_;
FeedbackSlot load_output_done_slot_;
FeedbackSlot load_output_value_slot_;
FeedbackSlot call_iterable_iterator_slot_;
FeedbackSlot call_iterator_return_slot1_;
FeedbackSlot call_iterator_return_slot2_;
FeedbackSlot call_iterator_next_slot_;
FeedbackSlot call_iterator_throw_slot_;
};
class Throw final : public Expression {
public:
......@@ -3312,7 +3382,13 @@ class AstNodeFactory final BASE_EMBEDDED {
Suspend::OnAbruptResume on_abrupt_resume,
SuspendFlags flags) {
if (!expression) expression = NewUndefinedLiteral(pos);
return new (zone_) Suspend(expression, pos, on_abrupt_resume, flags);
return new (zone_)
Suspend(AstNode::kSuspend, expression, pos, on_abrupt_resume, flags);
}
YieldStar* NewYieldStar(Expression* expression, int pos, SuspendFlags flags) {
if (!expression) expression = NewUndefinedLiteral(pos);
return new (zone_) YieldStar(expression, pos, flags);
}
Throw* NewThrow(Expression* exception, int pos) {
......
......@@ -256,6 +256,8 @@ void CallPrinter::VisitAssignment(Assignment* node) {
void CallPrinter::VisitSuspend(Suspend* node) { Find(node->expression()); }
void CallPrinter::VisitYieldStar(YieldStar* node) { Find(node->expression()); }
void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); }
......@@ -1119,6 +1121,12 @@ void AstPrinter::VisitSuspend(Suspend* node) {
Visit(node->expression());
}
void AstPrinter::VisitYieldStar(YieldStar* node) {
EmbeddedVector<char, 128> buf;
SNPrintF(buf, "YIELD_STAR id %d", node->suspend_id());
IndentedScope indent(this, buf.start(), node->position());
Visit(node->expression());
}
void AstPrinter::VisitThrow(Throw* node) {
IndentedScope indent(this, "THROW", node->position());
......
......@@ -1377,6 +1377,10 @@ void AstGraphBuilder::VisitSuspend(Suspend* expr) {
UNREACHABLE();
}
void AstGraphBuilder::VisitYieldStar(YieldStar* expr) {
// Generator functions are supported only by going through Ignition first.
UNREACHABLE();
}
void AstGraphBuilder::VisitThrow(Throw* expr) {
VisitForValue(expr->exception());
......
......@@ -149,10 +149,9 @@ void ALAA::VisitObjectLiteral(ObjectLiteral* e) {
void ALAA::VisitArrayLiteral(ArrayLiteral* e) { VisitExpressions(e->values()); }
void ALAA::VisitSuspend(Suspend* stmt) {
Visit(stmt->expression());
}
void ALAA::VisitSuspend(Suspend* e) { Visit(e->expression()); }
void ALAA::VisitYieldStar(YieldStar* e) { Visit(e->expression()); }
void ALAA::VisitThrow(Throw* stmt) { Visit(stmt->exception()); }
......
......@@ -1357,6 +1357,10 @@ void FullCodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
Visit(expr->expression());
}
void FullCodeGenerator::VisitYieldStar(YieldStar* expr) {
// Resumable functions are not supported.
UNREACHABLE();
}
bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) {
Expression* sub_expr;
......
This diff is collapsed.
......@@ -137,8 +137,14 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildNewLocalWithContext(Scope* scope);
void BuildGeneratorPrologue();
void BuildGeneratorSuspend(Suspend* expr, RegisterList registers_to_save);
void BuildGeneratorSuspend(Suspend* expr, Register value,
RegisterList registers_to_save);
void BuildGeneratorResume(Suspend* expr, RegisterList registers_to_restore);
void BuildAbruptResume(Suspend* expr);
void BuildGetIterator(Expression* iterable, IteratorType hint,
FeedbackSlot load_slot, FeedbackSlot call_slot,
FeedbackSlot async_load_slot,
FeedbackSlot async_call_slot);
void VisitArgumentsObject(Variable* variable);
void VisitRestArgumentsArray(Variable* rest);
......@@ -175,6 +181,8 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
// Visit the header/body of a loop iteration.
void VisitIterationHeader(IterationStatement* stmt,
LoopBuilder* loop_builder);
void VisitIterationHeader(int first_suspend_id, int suspend_count,
LoopBuilder* loop_builder);
void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop_builder);
// Visit a statement and switch scopes, the context is in the accumulator.
......
......@@ -103,6 +103,7 @@ class RegisterList {
RegisterList() : first_reg_index_(Register().index()), register_count_(0) {}
RegisterList(int first_reg_index, int register_count)
: first_reg_index_(first_reg_index), register_count_(register_count) {}
explicit RegisterList(Register r) : RegisterList(r.index(), 1) {}
// Increases/decreases the size of the register list by one.
void IncrementRegisterCount() { register_count_++; }
......
......@@ -4315,6 +4315,11 @@ Expression* Parser::RewriteYieldStar(Expression* iterable, int pos) {
IteratorType type =
is_async_generator() ? IteratorType::kAsync : IteratorType::kNormal;
if (type == IteratorType::kNormal) {
return factory()->NewYieldStar(iterable, pos,
SuspendFlags::kGeneratorYieldStar);
}
// Forward definition for break/continue statements.
WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos);
......@@ -4506,7 +4511,7 @@ Expression* Parser::RewriteYieldStar(Expression* iterable, int pos) {
{
Expression* output_proxy = factory()->NewVariableProxy(var_output);
Suspend* yield = BuildSuspend(output_proxy, nopos, Suspend::kNoControl,
SuspendFlags::kYieldStar);
SuspendFlags::kYield);
yield_output = factory()->NewExpressionStatement(yield, nopos);
}
......
......@@ -768,6 +768,7 @@ NOT_A_PATTERN(VariableDeclaration)
NOT_A_PATTERN(WhileStatement)
NOT_A_PATTERN(WithStatement)
NOT_A_PATTERN(Suspend)
NOT_A_PATTERN(YieldStar)
#undef NOT_A_PATTERN
} // namespace internal
......
......@@ -29,7 +29,6 @@ RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_ExportFromRuntime) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
......@@ -42,7 +41,6 @@ RUNTIME_FUNCTION(Runtime_ExportFromRuntime) {
return *container;
}
RUNTIME_FUNCTION(Runtime_InstallToContext) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
......@@ -67,21 +65,18 @@ RUNTIME_FUNCTION(Runtime_InstallToContext) {
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_Throw) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
return isolate->Throw(args[0]);
}
RUNTIME_FUNCTION(Runtime_ReThrow) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
return isolate->ReThrow(args[0]);
}
RUNTIME_FUNCTION(Runtime_ThrowStackOverflow) {
SealHandleScope shs(isolate);
DCHECK_LE(0, args.length());
......@@ -166,14 +161,12 @@ RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler) {
return isolate->UnwindAndFindHandler();
}
RUNTIME_FUNCTION(Runtime_PromoteScheduledException) {
SealHandleScope shs(isolate);
DCHECK_EQ(0, args.length());
return isolate->PromoteScheduledException();
}
RUNTIME_FUNCTION(Runtime_ThrowReferenceError) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
......@@ -182,7 +175,6 @@ RUNTIME_FUNCTION(Runtime_ThrowReferenceError) {
isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
}
RUNTIME_FUNCTION(Runtime_NewTypeError) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
......@@ -193,7 +185,6 @@ RUNTIME_FUNCTION(Runtime_NewTypeError) {
return *isolate->factory()->NewTypeError(message_template, arg0);
}
RUNTIME_FUNCTION(Runtime_NewReferenceError) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
......@@ -204,7 +195,6 @@ RUNTIME_FUNCTION(Runtime_NewReferenceError) {
return *isolate->factory()->NewReferenceError(message_template, arg0);
}
RUNTIME_FUNCTION(Runtime_NewSyntaxError) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
......@@ -260,6 +250,13 @@ RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject) {
NewTypeError(MessageTemplate::kIteratorResultNotAnObject, value));
}
RUNTIME_FUNCTION(Runtime_ThrowThrowMethodMissing) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kThrowMethodMissing));
}
RUNTIME_FUNCTION(Runtime_ThrowSymbolIteratorInvalid) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
......@@ -316,14 +313,12 @@ RUNTIME_FUNCTION(Runtime_StackGuard) {
return isolate->stack_guard()->HandleInterrupts();
}
RUNTIME_FUNCTION(Runtime_Interrupt) {
SealHandleScope shs(isolate);
DCHECK_EQ(0, args.length());
return isolate->stack_guard()->HandleInterrupts();
}
RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
......@@ -334,7 +329,6 @@ RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
}
RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
......@@ -370,12 +364,10 @@ RUNTIME_FUNCTION(Runtime_AllocateSeqTwoByteString) {
return *result;
}
RUNTIME_FUNCTION(Runtime_IS_VAR) {
UNREACHABLE(); // implemented as macro in the parser
}
namespace {
bool ComputeLocation(Isolate* isolate, MessageLocation* target) {
......@@ -400,7 +392,6 @@ bool ComputeLocation(Isolate* isolate, MessageLocation* target) {
return false;
}
Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object) {
MessageLocation location;
if (ComputeLocation(isolate, &location)) {
......@@ -475,7 +466,6 @@ RUNTIME_FUNCTION(Runtime_CreateListFromArrayLike) {
isolate, object, ElementTypes::kAll));
}
RUNTIME_FUNCTION(Runtime_IncrementUseCounter) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
......
......@@ -333,6 +333,7 @@ namespace internal {
F(ThrowInvalidStringLength, 0, 1) \
F(ThrowInvalidTypedArrayAlignment, 2, 1) \
F(ThrowIteratorResultNotAnObject, 1, 1) \
F(ThrowThrowMethodMissing, 0, 1) \
F(ThrowSymbolIteratorInvalid, 0, 1) \
F(ThrowNonCallableInInstanceOfCheck, 0, 1) \
F(ThrowNonObjectInInstanceOfCheck, 0, 1) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment