diff options
Diffstat (limited to 'deps/v8/src/ast/ast.h')
-rw-r--r-- | deps/v8/src/ast/ast.h | 103 |
1 files changed, 79 insertions, 24 deletions
diff --git a/deps/v8/src/ast/ast.h b/deps/v8/src/ast/ast.h index 5a2346ad9f8..6c1e989d30b 100644 --- a/deps/v8/src/ast/ast.h +++ b/deps/v8/src/ast/ast.h @@ -249,7 +249,23 @@ class Expression : public AstNode { static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex; }; - +// V8's notion of BreakableStatement does not correspond to the notion of +// BreakableStatement in ECMAScript. In V8, the idea is that a +// BreakableStatement is a statement that can be the target of a break +// statement. The BreakableStatement AST node carries a list of labels, any of +// which can be used as an argument to the break statement in order to target +// it. +// +// Since we don't want to attach a list of labels to all kinds of statements, we +// only declare switchs, loops, and blocks as BreakableStatements. This means +// that we implement breaks targeting other statement forms as breaks targeting +// a substatement thereof. For instance, in "foo: if (b) { f(); break foo; }" we +// pretend that foo is the label of the inner block. That's okay because one +// can't observe the difference. +// +// This optimization makes it harder to detect invalid continue labels, see the +// need for own_labels in IterationStatement. +// class BreakableStatement : public Statement { public: enum BreakableType { @@ -257,6 +273,13 @@ class BreakableStatement : public Statement { TARGET_FOR_NAMED_ONLY }; + // A list of all labels declared on the path up to the previous + // BreakableStatement (if any). + // + // Example: "l1: for (;;) l2: l3: { l4: if (b) l5: { s } }" + // labels() of the ForStatement will be l1. + // labels() of the Block { l4: ... } will be l2, l3. + // labels() of the Block { s } will be l4, l5. ZonePtrList<const AstRawString>* labels() const; // Testers. @@ -441,11 +464,23 @@ class IterationStatement : public BreakableStatement { ZonePtrList<const AstRawString>* labels() const { return labels_; } + // A list of all labels that the iteration statement is directly prefixed + // with, i.e. all the labels that a continue statement in the body can use to + // continue this iteration statement. This is always a subset of {labels}. + // + // Example: "l1: { l2: if (b) l3: l4: for (;;) s }" + // labels() of the Block will be l1. + // labels() of the ForStatement will be l2, l3, l4. + // own_labels() of the ForStatement will be l3, l4. + ZonePtrList<const AstRawString>* own_labels() const { return own_labels_; } + protected: - IterationStatement(ZonePtrList<const AstRawString>* labels, int pos, + IterationStatement(ZonePtrList<const AstRawString>* labels, + ZonePtrList<const AstRawString>* own_labels, int pos, NodeType type) : BreakableStatement(TARGET_FOR_ANONYMOUS, pos, type), labels_(labels), + own_labels_(own_labels), body_(nullptr) {} void Initialize(Statement* body) { body_ = body; } @@ -454,6 +489,7 @@ class IterationStatement : public BreakableStatement { private: ZonePtrList<const AstRawString>* labels_; + ZonePtrList<const AstRawString>* own_labels_; Statement* body_; }; @@ -470,8 +506,10 @@ class DoWhileStatement final : public IterationStatement { private: friend class AstNodeFactory; - DoWhileStatement(ZonePtrList<const AstRawString>* labels, int pos) - : IterationStatement(labels, pos, kDoWhileStatement), cond_(nullptr) {} + DoWhileStatement(ZonePtrList<const AstRawString>* labels, + ZonePtrList<const AstRawString>* own_labels, int pos) + : IterationStatement(labels, own_labels, pos, kDoWhileStatement), + cond_(nullptr) {} Expression* cond_; }; @@ -489,8 +527,10 @@ class WhileStatement final : public IterationStatement { private: friend class AstNodeFactory; - WhileStatement(ZonePtrList<const AstRawString>* labels, int pos) - : IterationStatement(labels, pos, kWhileStatement), cond_(nullptr) {} + WhileStatement(ZonePtrList<const AstRawString>* labels, + ZonePtrList<const AstRawString>* own_labels, int pos) + : IterationStatement(labels, own_labels, pos, kWhileStatement), + cond_(nullptr) {} Expression* cond_; }; @@ -513,8 +553,9 @@ class ForStatement final : public IterationStatement { private: friend class AstNodeFactory; - ForStatement(ZonePtrList<const AstRawString>* labels, int pos) - : IterationStatement(labels, pos, kForStatement), + ForStatement(ZonePtrList<const AstRawString>* labels, + ZonePtrList<const AstRawString>* own_labels, int pos) + : IterationStatement(labels, own_labels, pos, kForStatement), init_(nullptr), cond_(nullptr), next_(nullptr) {} @@ -539,9 +580,10 @@ class ForEachStatement : public IterationStatement { } protected: - ForEachStatement(ZonePtrList<const AstRawString>* labels, int pos, + ForEachStatement(ZonePtrList<const AstRawString>* labels, + ZonePtrList<const AstRawString>* own_labels, int pos, NodeType type) - : IterationStatement(labels, pos, type) {} + : IterationStatement(labels, own_labels, pos, type) {} }; @@ -566,8 +608,9 @@ class ForInStatement final : public ForEachStatement { private: friend class AstNodeFactory; - ForInStatement(ZonePtrList<const AstRawString>* labels, int pos) - : ForEachStatement(labels, pos, kForInStatement), + ForInStatement(ZonePtrList<const AstRawString>* labels, + ZonePtrList<const AstRawString>* own_labels, int pos) + : ForEachStatement(labels, own_labels, pos, kForInStatement), each_(nullptr), subject_(nullptr) { bit_field_ = ForInTypeField::update(bit_field_, SLOW_FOR_IN); @@ -632,8 +675,9 @@ class ForOfStatement final : public ForEachStatement { private: friend class AstNodeFactory; - ForOfStatement(ZonePtrList<const AstRawString>* labels, int pos) - : ForEachStatement(labels, pos, kForOfStatement), + ForOfStatement(ZonePtrList<const AstRawString>* labels, + ZonePtrList<const AstRawString>* own_labels, int pos) + : ForEachStatement(labels, own_labels, pos, kForOfStatement), iterator_(nullptr), assign_iterator_(nullptr), next_result_(nullptr), @@ -2201,6 +2245,12 @@ class FunctionLiteral final : public Expression { bool is_anonymous_expression() const { return function_type() == kAnonymousExpression; } + + void mark_as_iife() { bit_field_ = IIFEBit::update(bit_field_, true); } + bool is_iife() const { return IIFEBit::decode(bit_field_); } + bool is_top_level() const { + return function_literal_id() == FunctionLiteral::kIdTypeTopLevel; + } bool is_wrapped() const { return function_type() == kWrapped; } LanguageMode language_mode() const; @@ -2333,7 +2383,7 @@ class FunctionLiteral final : public Expression { kHasDuplicateParameters) | DontOptimizeReasonField::encode(BailoutReason::kNoReason) | RequiresInstanceFieldsInitializer::encode(false) | - HasBracesField::encode(has_braces); + HasBracesField::encode(has_braces) | IIFEBit::encode(false); if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile(); DCHECK_EQ(body == nullptr, expected_property_count < 0); } @@ -2348,6 +2398,7 @@ class FunctionLiteral final : public Expression { : public BitField<bool, DontOptimizeReasonField::kNext, 1> {}; class HasBracesField : public BitField<bool, RequiresInstanceFieldsInitializer::kNext, 1> {}; + class IIFEBit : public BitField<bool, HasBracesField::kNext, 1> {}; int expected_property_count_; int parameter_count_; @@ -2803,9 +2854,11 @@ class AstNodeFactory final BASE_EMBEDDED { Block(zone_, labels, capacity, ignore_completion_value); } -#define STATEMENT_WITH_LABELS(NodeType) \ - NodeType* New##NodeType(ZonePtrList<const AstRawString>* labels, int pos) { \ - return new (zone_) NodeType(labels, pos); \ +#define STATEMENT_WITH_LABELS(NodeType) \ + NodeType* New##NodeType(ZonePtrList<const AstRawString>* labels, \ + ZonePtrList<const AstRawString>* own_labels, \ + int pos) { \ + return new (zone_) NodeType(labels, own_labels, pos); \ } STATEMENT_WITH_LABELS(DoWhileStatement) STATEMENT_WITH_LABELS(WhileStatement) @@ -2817,23 +2870,25 @@ class AstNodeFactory final BASE_EMBEDDED { return new (zone_) SwitchStatement(zone_, labels, tag, pos); } - ForEachStatement* NewForEachStatement(ForEachStatement::VisitMode visit_mode, - ZonePtrList<const AstRawString>* labels, - int pos) { + ForEachStatement* NewForEachStatement( + ForEachStatement::VisitMode visit_mode, + ZonePtrList<const AstRawString>* labels, + ZonePtrList<const AstRawString>* own_labels, int pos) { switch (visit_mode) { case ForEachStatement::ENUMERATE: { - return new (zone_) ForInStatement(labels, pos); + return new (zone_) ForInStatement(labels, own_labels, pos); } case ForEachStatement::ITERATE: { - return new (zone_) ForOfStatement(labels, pos); + return new (zone_) ForOfStatement(labels, own_labels, pos); } } UNREACHABLE(); } ForOfStatement* NewForOfStatement(ZonePtrList<const AstRawString>* labels, + ZonePtrList<const AstRawString>* own_labels, int pos) { - return new (zone_) ForOfStatement(labels, pos); + return new (zone_) ForOfStatement(labels, own_labels, pos); } ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) { |