From 77453e909510c777894d626bca81f4aa488c771a Mon Sep 17 00:00:00 2001 From: Ben Murdoch Date: Wed, 18 May 2016 11:27:45 +0100 Subject: Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e, and updates the x64 makefile properly so it doesn't break that build. b/29178923 Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605 (cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632) --- src/ast/ast-expression-rewriter.cc | 6 +- src/ast/ast-expression-rewriter.h | 2 - src/ast/ast-expression-visitor.cc | 5 +- src/ast/ast-expression-visitor.h | 2 - src/ast/ast-literal-reindexer.cc | 9 +- src/ast/ast-numbering.cc | 17 +- src/ast/ast-value-factory.cc | 2 + src/ast/ast-value-factory.h | 3 + src/ast/ast.cc | 43 ++++- src/ast/ast.h | 358 ++++++++++++++++++++----------------- src/ast/modules.cc | 1 - src/ast/modules.h | 19 +- src/ast/prettyprinter.cc | 80 +++++---- src/ast/prettyprinter.h | 3 + src/ast/scopeinfo.cc | 76 +------- src/ast/scopes.cc | 170 ++---------------- src/ast/scopes.h | 57 +++--- src/ast/variables.cc | 3 - src/ast/variables.h | 56 +----- 19 files changed, 346 insertions(+), 566 deletions(-) (limited to 'src/ast') diff --git a/src/ast/ast-expression-rewriter.cc b/src/ast/ast-expression-rewriter.cc index 49cc7f6f..edee91d3 100644 --- a/src/ast/ast-expression-rewriter.cc +++ b/src/ast/ast-expression-rewriter.cc @@ -398,10 +398,10 @@ void AstExpressionRewriter::VisitDoExpression(DoExpression* node) { } -void AstExpressionRewriter::VisitRewritableAssignmentExpression( - RewritableAssignmentExpression* node) { +void AstExpressionRewriter::VisitRewritableExpression( + RewritableExpression* node) { REWRITE_THIS(node); - AST_REWRITE_PROPERTY(Expression, node, expression); + AST_REWRITE(Expression, node->expression(), node->Rewrite(replacement)); } diff --git a/src/ast/ast-expression-rewriter.h b/src/ast/ast-expression-rewriter.h index 916842ab..1da3fa82 100644 --- a/src/ast/ast-expression-rewriter.h +++ b/src/ast/ast-expression-rewriter.h @@ -8,9 +8,7 @@ #include "src/allocation.h" #include "src/ast/ast.h" #include "src/ast/scopes.h" -#include "src/effects.h" #include "src/type-info.h" -#include "src/types.h" #include "src/zone.h" namespace v8 { diff --git a/src/ast/ast-expression-visitor.cc b/src/ast/ast-expression-visitor.cc index 6b2550c5..dbf4ea46 100644 --- a/src/ast/ast-expression-visitor.cc +++ b/src/ast/ast-expression-visitor.cc @@ -208,6 +208,7 @@ void AstExpressionVisitor::VisitNativeFunctionLiteral( void AstExpressionVisitor::VisitDoExpression(DoExpression* expr) { + VisitExpression(expr); RECURSE(VisitBlock(expr->block())); RECURSE(VisitVariableProxy(expr->result())); } @@ -399,8 +400,8 @@ void AstExpressionVisitor::VisitSuperCallReference(SuperCallReference* expr) { } -void AstExpressionVisitor::VisitRewritableAssignmentExpression( - RewritableAssignmentExpression* expr) { +void AstExpressionVisitor::VisitRewritableExpression( + RewritableExpression* expr) { VisitExpression(expr); RECURSE(Visit(expr->expression())); } diff --git a/src/ast/ast-expression-visitor.h b/src/ast/ast-expression-visitor.h index cda624d5..545a45c4 100644 --- a/src/ast/ast-expression-visitor.h +++ b/src/ast/ast-expression-visitor.h @@ -8,9 +8,7 @@ #include "src/allocation.h" #include "src/ast/ast.h" #include "src/ast/scopes.h" -#include "src/effects.h" #include "src/type-info.h" -#include "src/types.h" #include "src/zone.h" namespace v8 { diff --git a/src/ast/ast-literal-reindexer.cc b/src/ast/ast-literal-reindexer.cc index fce33e70..1f79b122 100644 --- a/src/ast/ast-literal-reindexer.cc +++ b/src/ast/ast-literal-reindexer.cc @@ -44,7 +44,8 @@ void AstLiteralReindexer::VisitNativeFunctionLiteral( void AstLiteralReindexer::VisitDoExpression(DoExpression* node) { - // TODO(caitp): literals in do expressions need re-indexing too. + Visit(node->block()); + Visit(node->result()); } @@ -76,8 +77,8 @@ void AstLiteralReindexer::VisitSuperCallReference(SuperCallReference* node) { } -void AstLiteralReindexer::VisitRewritableAssignmentExpression( - RewritableAssignmentExpression* node) { +void AstLiteralReindexer::VisitRewritableExpression( + RewritableExpression* node) { Visit(node->expression()); } @@ -187,6 +188,8 @@ void AstLiteralReindexer::VisitCompareOperation(CompareOperation* node) { void AstLiteralReindexer::VisitSpread(Spread* node) { + // This is reachable because ParserBase::ParseArrowFunctionLiteral calls + // ReindexLiterals before calling RewriteDestructuringAssignments. Visit(node->expression()); } diff --git a/src/ast/ast-numbering.cc b/src/ast/ast-numbering.cc index 6c2b696a..272f9bde 100644 --- a/src/ast/ast-numbering.cc +++ b/src/ast/ast-numbering.cc @@ -306,7 +306,6 @@ void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) { void AstNumberingVisitor::VisitTryCatchStatement(TryCatchStatement* node) { IncrementNodeCount(); DisableOptimization(kTryCatchStatement); - node->set_base_id(ReserveIdRange(TryCatchStatement::num_ids())); Visit(node->try_block()); Visit(node->catch_block()); } @@ -315,7 +314,6 @@ void AstNumberingVisitor::VisitTryCatchStatement(TryCatchStatement* node) { void AstNumberingVisitor::VisitTryFinallyStatement(TryFinallyStatement* node) { IncrementNodeCount(); DisableOptimization(kTryFinallyStatement); - node->set_base_id(ReserveIdRange(TryFinallyStatement::num_ids())); Visit(node->try_block()); Visit(node->finally_block()); } @@ -372,11 +370,7 @@ void AstNumberingVisitor::VisitCompareOperation(CompareOperation* node) { } -void AstNumberingVisitor::VisitSpread(Spread* node) { - IncrementNodeCount(); - DisableCrankshaft(kSpread); - Visit(node->expression()); -} +void AstNumberingVisitor::VisitSpread(Spread* node) { UNREACHABLE(); } void AstNumberingVisitor::VisitEmptyParentheses(EmptyParentheses* node) { @@ -510,6 +504,9 @@ void AstNumberingVisitor::VisitArrayLiteral(ArrayLiteral* node) { void AstNumberingVisitor::VisitCall(Call* node) { IncrementNodeCount(); + if (node->tail_call_mode() == TailCallMode::kAllow) { + DisableOptimization(kTailCall); + } ReserveFeedbackSlots(node); node->set_base_id(ReserveIdRange(Call::num_ids())); Visit(node->expression()); @@ -557,10 +554,10 @@ void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) { } -void AstNumberingVisitor::VisitRewritableAssignmentExpression( - RewritableAssignmentExpression* node) { +void AstNumberingVisitor::VisitRewritableExpression( + RewritableExpression* node) { IncrementNodeCount(); - node->set_base_id(ReserveIdRange(RewritableAssignmentExpression::num_ids())); + node->set_base_id(ReserveIdRange(RewritableExpression::num_ids())); Visit(node->expression()); } diff --git a/src/ast/ast-value-factory.cc b/src/ast/ast-value-factory.cc index 2e17fbcf..189d4cc0 100644 --- a/src/ast/ast-value-factory.cc +++ b/src/ast/ast-value-factory.cc @@ -172,6 +172,8 @@ void AstValue::Internalize(Isolate* isolate) { if (symbol_name_[0] == 'i') { DCHECK_EQ(0, strcmp(symbol_name_, "iterator_symbol")); value_ = isolate->factory()->iterator_symbol(); + } else if (strcmp(symbol_name_, "hasInstance_symbol") == 0) { + value_ = isolate->factory()->has_instance_symbol(); } else { DCHECK_EQ(0, strcmp(symbol_name_, "home_object_symbol")); value_ = isolate->factory()->home_object_symbol(); diff --git a/src/ast/ast-value-factory.h b/src/ast/ast-value-factory.h index 4ae912ea..85e8277d 100644 --- a/src/ast/ast-value-factory.h +++ b/src/ast/ast-value-factory.h @@ -255,6 +255,7 @@ class AstValue : public ZoneObject { F(dot_catch, ".catch") \ F(empty, "") \ F(eval, "eval") \ + F(function, "function") \ F(get_space, "get ") \ F(let, "let") \ F(native, "native") \ @@ -263,9 +264,11 @@ class AstValue : public ZoneObject { F(proto, "__proto__") \ F(prototype, "prototype") \ F(rest_parameter, ".rest_parameter") \ + F(return, "return") \ F(set_space, "set ") \ F(this, "this") \ F(this_function, ".this_function") \ + F(throw, "throw") \ F(undefined, "undefined") \ F(use_asm, "use asm") \ F(use_strong, "use strong") \ diff --git a/src/ast/ast.cc b/src/ast/ast.cc index 69e7351a..9b2c6388 100644 --- a/src/ast/ast.cc +++ b/src/ast/ast.cc @@ -5,6 +5,8 @@ #include "src/ast/ast.h" #include // For isfinite. + +#include "src/ast/prettyprinter.h" #include "src/ast/scopes.h" #include "src/builtins.h" #include "src/code-stubs.h" @@ -32,6 +34,25 @@ AST_NODE_LIST(DECL_ACCEPT) // ---------------------------------------------------------------------------- // Implementation of other node functionality. +#ifdef DEBUG + +void AstNode::Print() { Print(Isolate::Current()); } + + +void AstNode::Print(Isolate* isolate) { + AstPrinter::PrintOut(isolate, this); +} + + +void AstNode::PrettyPrint() { PrettyPrint(Isolate::Current()); } + + +void AstNode::PrettyPrint(Isolate* isolate) { + PrettyPrinter::PrintOut(isolate, this); +} + +#endif // DEBUG + bool Expression::IsSmiLiteral() const { return IsLiteral() && AsLiteral()->value()->IsSmi(); @@ -254,14 +275,21 @@ ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory, } } +bool ObjectLiteralProperty::NeedsSetFunctionName() const { + return is_computed_name_ && + (value_->IsAnonymousFunctionDefinition() || + (value_->IsFunctionLiteral() && + IsConciseMethod(value_->AsFunctionLiteral()->kind()))); +} void ClassLiteral::AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, FeedbackVectorSlotCache* cache) { // This logic that computes the number of slots needed for vector store // ICs must mirror FullCodeGenerator::VisitClassLiteral. + prototype_slot_ = spec->AddLoadICSlot(); if (NeedsProxySlot()) { - slot_ = spec->AddStoreICSlot(); + proxy_slot_ = spec->AddStoreICSlot(); } for (int i = 0; i < properties()->length(); i++) { @@ -476,10 +504,11 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate) { void ArrayLiteral::BuildConstantElements(Isolate* isolate) { + DCHECK_LT(first_spread_index_, 0); + if (!constant_elements_.is_null()) return; - int constants_length = - first_spread_index_ >= 0 ? first_spread_index_ : values()->length(); + int constants_length = values()->length(); // Allocate a fixed array to hold all the object literals. Handle array = isolate->factory()->NewJSArray( @@ -487,7 +516,7 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) { Strength::WEAK, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); // Fill in the literals. - bool is_simple = (first_spread_index_ < 0); + bool is_simple = true; int depth_acc = 1; bool is_holey = false; int array_index = 0; @@ -553,7 +582,7 @@ void ArrayLiteral::AssignFeedbackVectorSlots(Isolate* isolate, int array_index = 0; for (; array_index < values()->length(); array_index++) { Expression* subexpr = values()->at(array_index); - if (subexpr->IsSpread()) break; + DCHECK(!subexpr->IsSpread()); if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; // We'll reuse the same literal slot for all of the non-constant @@ -797,14 +826,12 @@ void AstVisitor::VisitExpressions(ZoneList* expressions) { } } - CaseClause::CaseClause(Zone* zone, Expression* label, ZoneList* statements, int pos) : Expression(zone, pos), label_(label), statements_(statements), - compare_type_(Type::None(zone)) {} - + compare_type_(Type::None()) {} uint32_t Literal::Hash() { return raw_value()->IsString() diff --git a/src/ast/ast.h b/src/ast/ast.h index 7f00955a..dcb440d7 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -91,7 +91,7 @@ namespace internal { V(CaseClause) \ V(EmptyParentheses) \ V(DoExpression) \ - V(RewritableAssignmentExpression) + V(RewritableExpression) #define AST_NODE_LIST(V) \ DECLARATION_NODE_LIST(V) \ @@ -196,15 +196,18 @@ class AstNode: public ZoneObject { virtual NodeType node_type() const = 0; int position() const { return position_; } +#ifdef DEBUG + void PrettyPrint(Isolate* isolate); + void PrettyPrint(); + void Print(Isolate* isolate); + void Print(); +#endif // DEBUG + // Type testing & conversion functions overridden by concrete subclasses. #define DECLARE_NODE_FUNCTIONS(type) \ - bool Is##type() const { return node_type() == AstNode::k##type; } \ - type* As##type() { \ - return Is##type() ? reinterpret_cast(this) : NULL; \ - } \ - const type* As##type() const { \ - return Is##type() ? reinterpret_cast(this) : NULL; \ - } + V8_INLINE bool Is##type() const; \ + V8_INLINE type* As##type(); \ + V8_INLINE const type* As##type() const; AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) #undef DECLARE_NODE_FUNCTIONS @@ -237,7 +240,6 @@ class Statement : public AstNode { bool IsEmpty() { return AsEmptyStatement() != NULL; } virtual bool IsJump() const { return false; } - virtual void MarkTail() {} }; @@ -317,6 +319,10 @@ class Expression : public AstNode { // names because [] for string objects is handled only by keyed ICs. virtual bool IsPropertyName() const { return false; } + // True iff the expression is a class or function expression without + // a syntactic name. + virtual bool IsAnonymousFunctionDefinition() const { return false; } + // True iff the expression is a literal represented as a smi. bool IsSmiLiteral() const; @@ -365,14 +371,6 @@ class Expression : public AstNode { BailoutId id() const { return BailoutId(local_id(0)); } TypeFeedbackId test_id() const { return TypeFeedbackId(local_id(1)); } - // Parenthesized expressions in the form `( Expression )`. - void set_is_parenthesized() { - bit_field_ = ParenthesizedField::update(bit_field_, true); - } - bool is_parenthesized() const { - return ParenthesizedField::decode(bit_field_); - } - protected: Expression(Zone* zone, int pos) : AstNode(pos), @@ -395,8 +393,6 @@ class Expression : public AstNode { int base_id_; Bounds bounds_; class ToBooleanTypesField : public BitField16 {}; - class ParenthesizedField - : public BitField16 {}; uint16_t bit_field_; // Ends with 16-bit field; deriving classes in turn begin with // 16-bit fields for optimum packing efficiency. @@ -471,10 +467,6 @@ class Block final : public BreakableStatement { && labels() == NULL; // Good enough as an approximation... } - void MarkTail() override { - if (!statements_.is_empty()) statements_.last()->MarkTail(); - } - Scope* scope() const { return scope_; } void set_scope(Scope* scope) { scope_ = scope; } @@ -505,8 +497,6 @@ class DoExpression final : public Expression { VariableProxy* result() { return result_; } void set_result(VariableProxy* v) { result_ = v; } - void MarkTail() override { block_->MarkTail(); } - protected: DoExpression(Zone* zone, Block* block, VariableProxy* result, int pos) : Expression(zone, pos), block_(block), result_(result) { @@ -555,24 +545,10 @@ class VariableDeclaration final : public Declaration { return mode() == VAR ? kCreatedInitialized : kNeedsInitialization; } - bool is_class_declaration() const { return is_class_declaration_; } - - // VariableDeclarations can be grouped into consecutive declaration - // groups. Each VariableDeclaration is associated with the start position of - // the group it belongs to. The positions are used for strong mode scope - // checks for classes and functions. - int declaration_group_start() const { return declaration_group_start_; } - protected: VariableDeclaration(Zone* zone, VariableProxy* proxy, VariableMode mode, - Scope* scope, int pos, bool is_class_declaration = false, - int declaration_group_start = -1) - : Declaration(zone, proxy, mode, scope, pos), - is_class_declaration_(is_class_declaration), - declaration_group_start_(declaration_group_start) {} - - bool is_class_declaration_; - int declaration_group_start_; + Scope* scope, int pos) + : Declaration(zone, proxy, mode, scope, pos) {} }; @@ -820,6 +796,10 @@ class ForEachStatement : public IterationStatement { FeedbackVectorSlotCache* cache) override; FeedbackVectorSlot EachFeedbackSlot() const { return each_slot_; } + static const char* VisitModeString(VisitMode mode) { + return mode == ITERATE ? "for-of" : "for-in"; + } + protected: ForEachStatement(Zone* zone, ZoneList* labels, int pos) : IterationStatement(zone, labels, pos), each_(NULL), subject_(NULL) {} @@ -857,9 +837,9 @@ class ForInStatement final : public ForEachStatement { static int num_ids() { return parent_num_ids() + 6; } BailoutId BodyId() const { return BailoutId(local_id(0)); } - BailoutId PrepareId() const { return BailoutId(local_id(1)); } - BailoutId EnumId() const { return BailoutId(local_id(2)); } - BailoutId ToObjectId() const { return BailoutId(local_id(3)); } + BailoutId EnumId() const { return BailoutId(local_id(1)); } + BailoutId ToObjectId() const { return BailoutId(local_id(2)); } + BailoutId PrepareId() const { return BailoutId(local_id(3)); } BailoutId FilterId() const { return BailoutId(local_id(4)); } BailoutId AssignmentId() const { return BailoutId(local_id(5)); } BailoutId ContinueId() const override { return EntryId(); } @@ -885,11 +865,13 @@ class ForOfStatement final : public ForEachStatement { void Initialize(Expression* each, Expression* subject, Statement* body, + Variable* iterator, Expression* assign_iterator, Expression* next_result, Expression* result_done, Expression* assign_each) { ForEachStatement::Initialize(each, subject, body); + iterator_ = iterator; assign_iterator_ = assign_iterator; next_result_ = next_result; result_done_ = result_done; @@ -900,6 +882,10 @@ class ForOfStatement final : public ForEachStatement { return subject(); } + Variable* iterator() const { + return iterator_; + } + // iterator = subject[Symbol.iterator]() Expression* assign_iterator() const { return assign_iterator_; @@ -934,6 +920,7 @@ class ForOfStatement final : public ForEachStatement { protected: ForOfStatement(Zone* zone, ZoneList* labels, int pos) : ForEachStatement(zone, labels, pos), + iterator_(NULL), assign_iterator_(NULL), next_result_(NULL), result_done_(NULL), @@ -943,6 +930,7 @@ class ForOfStatement final : public ForEachStatement { private: int local_id(int n) const { return base_id() + parent_num_ids() + n; } + Variable* iterator_; Expression* assign_iterator_; Expression* next_result_; Expression* result_done_; @@ -957,7 +945,6 @@ class ExpressionStatement final : public Statement { void set_expression(Expression* e) { expression_ = e; } Expression* expression() const { return expression_; } bool IsJump() const override { return expression_->IsThrow(); } - void MarkTail() override { expression_->MarkTail(); } protected: ExpressionStatement(Zone* zone, Expression* expression, int pos) @@ -1039,8 +1026,6 @@ class WithStatement final : public Statement { BailoutId ToObjectId() const { return BailoutId(local_id(0)); } BailoutId EntryId() const { return BailoutId(local_id(1)); } - void MarkTail() override { statement_->MarkTail(); } - protected: WithStatement(Zone* zone, Scope* scope, Expression* expression, Statement* statement, int pos) @@ -1083,10 +1068,6 @@ class CaseClause final : public Expression { BailoutId EntryId() const { return BailoutId(local_id(0)); } TypeFeedbackId CompareId() { return TypeFeedbackId(local_id(1)); } - void MarkTail() override { - if (!statements_->is_empty()) statements_->last()->MarkTail(); - } - Type* compare_type() { return compare_type_; } void set_compare_type(Type* type) { compare_type_ = type; } @@ -1119,10 +1100,6 @@ class SwitchStatement final : public BreakableStatement { void set_tag(Expression* t) { tag_ = t; } - void MarkTail() override { - if (!cases_->is_empty()) cases_->last()->MarkTail(); - } - protected: SwitchStatement(Zone* zone, ZoneList* labels, int pos) : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos), @@ -1160,11 +1137,6 @@ class IfStatement final : public Statement { && HasElseStatement() && else_statement()->IsJump(); } - void MarkTail() override { - then_statement_->MarkTail(); - else_statement_->MarkTail(); - } - void set_base_id(int id) { base_id_ = id; } static int num_ids() { return parent_num_ids() + 3; } BailoutId IfId() const { return BailoutId(local_id(0)); } @@ -1201,27 +1173,12 @@ class TryStatement : public Statement { Block* try_block() const { return try_block_; } void set_try_block(Block* b) { try_block_ = b; } - void set_base_id(int id) { base_id_ = id; } - static int num_ids() { return parent_num_ids() + 1; } - BailoutId HandlerId() const { return BailoutId(local_id(0)); } - protected: TryStatement(Zone* zone, Block* try_block, int pos) - : Statement(zone, pos), - try_block_(try_block), - base_id_(BailoutId::None().ToInt()) {} - static int parent_num_ids() { return 0; } - - int base_id() const { - DCHECK(!BailoutId(base_id_).IsNone()); - return base_id_; - } + : Statement(zone, pos), try_block_(try_block) {} private: - int local_id(int n) const { return base_id() + parent_num_ids() + n; } - Block* try_block_; - int base_id_; }; @@ -1234,8 +1191,6 @@ class TryCatchStatement final : public TryStatement { Block* catch_block() const { return catch_block_; } void set_catch_block(Block* b) { catch_block_ = b; } - void MarkTail() override { catch_block_->MarkTail(); } - protected: TryCatchStatement(Zone* zone, Block* try_block, Scope* scope, Variable* variable, Block* catch_block, int pos) @@ -1258,8 +1213,6 @@ class TryFinallyStatement final : public TryStatement { Block* finally_block() const { return finally_block_; } void set_finally_block(Block* b) { finally_block_ = b; } - void MarkTail() override { finally_block_->MarkTail(); } - protected: TryFinallyStatement(Zone* zone, Block* try_block, Block* finally_block, int pos) @@ -1472,6 +1425,8 @@ class ObjectLiteralProperty final : public ZoneObject { void set_receiver_type(Handle map) { receiver_type_ = map; } + bool NeedsSetFunctionName() const; + protected: friend class AstNodeFactory; @@ -1510,6 +1465,9 @@ class ObjectLiteral final : public MaterializedLiteral { bool may_store_doubles() const { return may_store_doubles_; } bool has_function() const { return has_function_; } bool has_elements() const { return has_elements_; } + bool has_shallow_properties() const { + return depth() == 1 && !has_elements() && !may_store_doubles(); + } // Decide if a property should be in the object boilerplate. static bool IsBoilerplateProperty(Property* property); @@ -1526,7 +1484,7 @@ class ObjectLiteral final : public MaterializedLiteral { int ComputeFlags(bool disable_mementos = false) const { int flags = fast_elements() ? kFastElements : kNoFlags; flags |= has_function() ? kHasFunction : kNoFlags; - if (depth() == 1 && !has_elements() && !may_store_doubles()) { + if (has_shallow_properties()) { flags |= kShallowProperties; } if (disable_mementos) { @@ -1683,6 +1641,19 @@ class ArrayLiteral final : public MaterializedLiteral { return flags; } + // Provide a mechanism for iterating through values to rewrite spreads. + ZoneList::iterator FirstSpread() const { + return (first_spread_index_ >= 0) ? values_->begin() + first_spread_index_ + : values_->end(); + } + ZoneList::iterator EndValue() const { return values_->end(); } + + // Rewind an array literal omitting everything from the first spread on. + void RewindSpreads() { + values_->Rewind(first_spread_index_); + first_spread_index_ = -1; + } + enum Flags { kNoFlags = 0, kShallowElements = 1, @@ -1975,7 +1946,10 @@ class Call final : public Expression { bit_field_ = IsUninitializedField::update(bit_field_, b); } - bool is_tail() const { return IsTailField::decode(bit_field_); } + TailCallMode tail_call_mode() const { + return IsTailField::decode(bit_field_) ? TailCallMode::kAllow + : TailCallMode::kDisallow; + } void MarkTail() override { bit_field_ = IsTailField::update(bit_field_, true); } @@ -2349,7 +2323,7 @@ class CompareOperation final : public Expression { op_(op), left_(left), right_(right), - combined_type_(Type::None(zone)) { + combined_type_(Type::None()) { DCHECK(Token::IsCompareOp(op)); } static int parent_num_ids() { return Expression::num_ids(); } @@ -2372,17 +2346,20 @@ class Spread final : public Expression { Expression* expression() const { return expression_; } void set_expression(Expression* e) { expression_ = e; } + int expression_position() const { return expr_pos_; } + static int num_ids() { return parent_num_ids(); } protected: - Spread(Zone* zone, Expression* expression, int pos) - : Expression(zone, pos), expression_(expression) {} + Spread(Zone* zone, Expression* expression, int pos, int expr_pos) + : Expression(zone, pos), expression_(expression), expr_pos_(expr_pos) {} static int parent_num_ids() { return Expression::num_ids(); } private: int local_id(int n) const { return base_id() + parent_num_ids() + n; } Expression* expression_; + int expr_pos_; }; @@ -2505,18 +2482,32 @@ class Assignment final : public Expression { }; -class RewritableAssignmentExpression : public Expression { +// The RewritableExpression class is a wrapper for AST nodes that wait +// for some potential rewriting. However, even if such nodes are indeed +// rewritten, the RewritableExpression wrapper nodes will survive in the +// final AST and should be just ignored, i.e., they should be treated as +// equivalent to the wrapped nodes. For this reason and to simplify later +// phases, RewritableExpressions are considered as exceptions of AST nodes +// in the following sense: +// +// 1. IsRewritableExpression and AsRewritableExpression behave as usual. +// 2. All other Is* and As* methods are practically delegated to the +// wrapped node, i.e. IsArrayLiteral() will return true iff the +// wrapped node is an array literal. +// +// Furthermore, an invariant that should be respected is that the wrapped +// node is not a RewritableExpression. +class RewritableExpression : public Expression { public: - DECLARE_NODE_TYPE(RewritableAssignmentExpression) + DECLARE_NODE_TYPE(RewritableExpression) - Expression* expression() { return expr_; } + Expression* expression() const { return expr_; } bool is_rewritten() const { return is_rewritten_; } - void set_expression(Expression* e) { expr_ = e; } - void Rewrite(Expression* new_expression) { DCHECK(!is_rewritten()); DCHECK_NOT_NULL(new_expression); + DCHECK(!new_expression->IsRewritableExpression()); expr_ = new_expression; is_rewritten_ = true; } @@ -2524,10 +2515,12 @@ class RewritableAssignmentExpression : public Expression { static int num_ids() { return parent_num_ids(); } protected: - RewritableAssignmentExpression(Zone* zone, Expression* expression) + RewritableExpression(Zone* zone, Expression* expression) : Expression(zone, expression->position()), is_rewritten_(false), - expr_(expression) {} + expr_(expression) { + DCHECK(!expression->IsRewritableExpression()); + } private: int local_id(int n) const { return base_id() + parent_num_ids() + n; } @@ -2555,26 +2548,6 @@ class Yield final : public Expression { void set_generator_object(Expression* e) { generator_object_ = e; } void set_expression(Expression* e) { expression_ = e; } - // Type feedback information. - bool HasFeedbackSlots() const { return yield_kind() == kDelegating; } - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache) override { - if (HasFeedbackSlots()) { - yield_first_feedback_slot_ = spec->AddKeyedLoadICSlot(); - keyed_load_feedback_slot_ = spec->AddLoadICSlot(); - done_feedback_slot_ = spec->AddLoadICSlot(); - } - } - - FeedbackVectorSlot KeyedLoadFeedbackSlot() { - DCHECK(!HasFeedbackSlots() || !yield_first_feedback_slot_.IsInvalid()); - return yield_first_feedback_slot_; - } - - FeedbackVectorSlot DoneFeedbackSlot() { return keyed_load_feedback_slot_; } - - FeedbackVectorSlot ValueFeedbackSlot() { return done_feedback_slot_; } - protected: Yield(Zone* zone, Expression* generator_object, Expression* expression, Kind yield_kind, int pos) @@ -2587,9 +2560,6 @@ class Yield final : public Expression { Expression* generator_object_; Expression* expression_; Kind yield_kind_; - FeedbackVectorSlot yield_first_feedback_slot_; - FeedbackVectorSlot keyed_load_feedback_slot_; - FeedbackVectorSlot done_feedback_slot_; }; @@ -2615,15 +2585,13 @@ class FunctionLiteral final : public Expression { kAnonymousExpression, kNamedExpression, kDeclaration, - kGlobalOrEval + kAccessorOrMethod }; enum ParameterFlag { kNoDuplicateParameters, kHasDuplicateParameters }; enum EagerCompileHint { kShouldEagerCompile, kShouldLazyCompile }; - enum ArityRestriction { kNormalArity, kGetterArity, kSetterArity }; - DECLARE_NODE_TYPE(FunctionLiteral) Handle name() const { return raw_name_->string(); } @@ -2636,8 +2604,13 @@ class FunctionLiteral final : public Expression { int start_position() const; int end_position() const; int SourceSize() const { return end_position() - start_position(); } - bool is_expression() const { return IsExpression::decode(bitfield_); } - bool is_anonymous() const { return IsAnonymous::decode(bitfield_); } + bool is_declaration() const { return IsDeclaration::decode(bitfield_); } + bool is_named_expression() const { + return IsNamedExpression::decode(bitfield_); + } + bool is_anonymous_expression() const { + return IsAnonymousExpression::decode(bitfield_); + } LanguageMode language_mode() const; static bool NeedsHomeObject(Expression* expr); @@ -2729,6 +2702,10 @@ class FunctionLiteral final : public Expression { dont_optimize_reason_ = reason; } + bool IsAnonymousFunctionDefinition() const final { + return is_anonymous_expression(); + } + protected: FunctionLiteral(Zone* zone, const AstString* name, AstValueFactory* ast_value_factory, Scope* scope, @@ -2737,7 +2714,7 @@ class FunctionLiteral final : public Expression { FunctionType function_type, ParameterFlag has_duplicate_parameters, EagerCompileHint eager_compile_hint, FunctionKind kind, - int position) + int position, bool is_function) : Expression(zone, position), raw_name_(name), scope_(scope), @@ -2750,26 +2727,28 @@ class FunctionLiteral final : public Expression { parameter_count_(parameter_count), function_token_position_(RelocInfo::kNoPosition) { bitfield_ = - IsExpression::encode(function_type != kDeclaration) | - IsAnonymous::encode(function_type == kAnonymousExpression) | + IsDeclaration::encode(function_type == kDeclaration) | + IsNamedExpression::encode(function_type == kNamedExpression) | + IsAnonymousExpression::encode(function_type == kAnonymousExpression) | Pretenure::encode(false) | HasDuplicateParameters::encode(has_duplicate_parameters == kHasDuplicateParameters) | - IsFunction::encode(function_type != kGlobalOrEval) | + IsFunction::encode(is_function) | ShouldEagerCompile::encode(eager_compile_hint == kShouldEagerCompile) | FunctionKindBits::encode(kind) | ShouldBeUsedOnceHint::encode(false); DCHECK(IsValidFunctionKind(kind)); } private: - class IsExpression : public BitField16 {}; - class IsAnonymous : public BitField16 {}; - class Pretenure : public BitField16 {}; - class HasDuplicateParameters : public BitField16 {}; - class IsFunction : public BitField16 {}; - class ShouldEagerCompile : public BitField16 {}; - class FunctionKindBits : public BitField16 {}; - class ShouldBeUsedOnceHint : public BitField16 {}; + class IsDeclaration : public BitField16 {}; + class IsNamedExpression : public BitField16 {}; + class IsAnonymousExpression : public BitField16 {}; + class Pretenure : public BitField16 {}; + class HasDuplicateParameters : public BitField16 {}; + class IsFunction : public BitField16 {}; + class ShouldEagerCompile : public BitField16 {}; + class ShouldBeUsedOnceHint : public BitField16 {}; + class FunctionKindBits : public BitField16 {}; // Start with 16-bit field, which should get packed together // with Expression's trailing 16-bit field. @@ -2796,13 +2775,6 @@ class ClassLiteral final : public Expression { DECLARE_NODE_TYPE(ClassLiteral) - Handle name() const { return raw_name_->string(); } - const AstRawString* raw_name() const { return raw_name_; } - void set_raw_name(const AstRawString* name) { - DCHECK_NULL(raw_name_); - raw_name_ = name; - } - Scope* scope() const { return scope_; } VariableProxy* class_variable_proxy() const { return class_variable_proxy_; } Expression* extends() const { return extends_; } @@ -2817,13 +2789,14 @@ class ClassLiteral final : public Expression { BailoutId DeclsId() const { return BailoutId(local_id(1)); } BailoutId ExitId() { return BailoutId(local_id(2)); } BailoutId CreateLiteralId() const { return BailoutId(local_id(3)); } + BailoutId PrototypeId() { return BailoutId(local_id(4)); } // Return an AST id for a property that is used in simulate instructions. - BailoutId GetIdForProperty(int i) { return BailoutId(local_id(i + 4)); } + BailoutId GetIdForProperty(int i) { return BailoutId(local_id(i + 5)); } // Unlike other AST nodes, this number of bailout IDs allocated for an // ClassLiteral can vary, so num_ids() is not a static method. - int num_ids() const { return parent_num_ids() + 4 + properties()->length(); } + int num_ids() const { return parent_num_ids() + 5 + properties()->length(); } // Object literals need one feedback slot for each non-trivial value, as well // as some slots for home objects. @@ -2835,15 +2808,19 @@ class ClassLiteral final : public Expression { class_variable_proxy()->var()->IsUnallocated(); } - FeedbackVectorSlot ProxySlot() const { return slot_; } + FeedbackVectorSlot PrototypeSlot() const { return prototype_slot_; } + FeedbackVectorSlot ProxySlot() const { return proxy_slot_; } + + bool IsAnonymousFunctionDefinition() const final { + return constructor()->raw_name()->length() == 0; + } protected: - ClassLiteral(Zone* zone, const AstRawString* name, Scope* scope, - VariableProxy* class_variable_proxy, Expression* extends, - FunctionLiteral* constructor, ZoneList* properties, - int start_position, int end_position) + ClassLiteral(Zone* zone, Scope* scope, VariableProxy* class_variable_proxy, + Expression* extends, FunctionLiteral* constructor, + ZoneList* properties, int start_position, + int end_position) : Expression(zone, start_position), - raw_name_(name), scope_(scope), class_variable_proxy_(class_variable_proxy), extends_(extends), @@ -2856,14 +2833,14 @@ class ClassLiteral final : public Expression { private: int local_id(int n) const { return base_id() + parent_num_ids() + n; } - const AstRawString* raw_name_; Scope* scope_; VariableProxy* class_variable_proxy_; Expression* extends_; FunctionLiteral* constructor_; ZoneList* properties_; int end_position_; - FeedbackVectorSlot slot_; + FeedbackVectorSlot prototype_slot_; + FeedbackVectorSlot proxy_slot_; }; @@ -3095,12 +3072,11 @@ class AstNodeFactory final BASE_EMBEDDED { AstValueFactory* ast_value_factory() const { return ast_value_factory_; } - VariableDeclaration* NewVariableDeclaration( - VariableProxy* proxy, VariableMode mode, Scope* scope, int pos, - bool is_class_declaration = false, int declaration_group_start = -1) { + VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy, + VariableMode mode, Scope* scope, + int pos) { return new (parser_zone_) - VariableDeclaration(parser_zone_, proxy, mode, scope, pos, - is_class_declaration, declaration_group_start); + VariableDeclaration(parser_zone_, proxy, mode, scope, pos); } FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy, @@ -3389,8 +3365,8 @@ class AstNodeFactory final BASE_EMBEDDED { CompareOperation(local_zone_, op, left, right, pos); } - Spread* NewSpread(Expression* expression, int pos) { - return new (local_zone_) Spread(local_zone_, expression, pos); + Spread* NewSpread(Expression* expression, int pos, int expr_pos) { + return new (local_zone_) Spread(local_zone_, expression, pos, expr_pos); } Conditional* NewConditional(Expression* condition, @@ -3401,12 +3377,9 @@ class AstNodeFactory final BASE_EMBEDDED { local_zone_, condition, then_expression, else_expression, position); } - RewritableAssignmentExpression* NewRewritableAssignmentExpression( - Expression* expression) { + RewritableExpression* NewRewritableExpression(Expression* expression) { DCHECK_NOT_NULL(expression); - DCHECK(expression->IsAssignment()); - return new (local_zone_) - RewritableAssignmentExpression(local_zone_, expression); + return new (local_zone_) RewritableExpression(local_zone_, expression); } Assignment* NewAssignment(Token::Value op, @@ -3449,16 +3422,31 @@ class AstNodeFactory final BASE_EMBEDDED { parser_zone_, name, ast_value_factory_, scope, body, materialized_literal_count, expected_property_count, parameter_count, function_type, has_duplicate_parameters, eager_compile_hint, kind, - position); + position, true); + } + + // Creates a FunctionLiteral representing a top-level script, the + // result of an eval (top-level or otherwise), or the result of calling + // the Function constructor. + FunctionLiteral* NewScriptOrEvalFunctionLiteral( + Scope* scope, ZoneList* body, int materialized_literal_count, + int expected_property_count) { + return new (parser_zone_) FunctionLiteral( + parser_zone_, ast_value_factory_->empty_string(), ast_value_factory_, + scope, body, materialized_literal_count, expected_property_count, 0, + FunctionLiteral::kAnonymousExpression, + FunctionLiteral::kNoDuplicateParameters, + FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction, 0, + false); } - ClassLiteral* NewClassLiteral(const AstRawString* name, Scope* scope, - VariableProxy* proxy, Expression* extends, + ClassLiteral* NewClassLiteral(Scope* scope, VariableProxy* proxy, + Expression* extends, FunctionLiteral* constructor, ZoneList* properties, int start_position, int end_position) { return new (parser_zone_) - ClassLiteral(parser_zone_, name, scope, proxy, extends, constructor, + ClassLiteral(parser_zone_, scope, proxy, extends, constructor, properties, start_position, end_position); } @@ -3529,6 +3517,46 @@ class AstNodeFactory final BASE_EMBEDDED { }; +// Type testing & conversion functions overridden by concrete subclasses. +// Inline functions for AstNode. + +#define DECLARE_NODE_FUNCTIONS(type) \ + bool AstNode::Is##type() const { \ + NodeType mine = node_type(); \ + if (mine == AstNode::kRewritableExpression && \ + AstNode::k##type != AstNode::kRewritableExpression) \ + mine = reinterpret_cast(this) \ + ->expression() \ + ->node_type(); \ + return mine == AstNode::k##type; \ + } \ + type* AstNode::As##type() { \ + NodeType mine = node_type(); \ + AstNode* result = this; \ + if (mine == AstNode::kRewritableExpression && \ + AstNode::k##type != AstNode::kRewritableExpression) { \ + result = \ + reinterpret_cast(this)->expression(); \ + mine = result->node_type(); \ + } \ + return mine == AstNode::k##type ? reinterpret_cast(result) : NULL; \ + } \ + const type* AstNode::As##type() const { \ + NodeType mine = node_type(); \ + const AstNode* result = this; \ + if (mine == AstNode::kRewritableExpression && \ + AstNode::k##type != AstNode::kRewritableExpression) { \ + result = \ + reinterpret_cast(this)->expression(); \ + mine = result->node_type(); \ + } \ + return mine == AstNode::k##type ? reinterpret_cast(result) \ + : NULL; \ + } +AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) +#undef DECLARE_NODE_FUNCTIONS + + } // namespace internal } // namespace v8 diff --git a/src/ast/modules.cc b/src/ast/modules.cc index 225cd8d6..f895756e 100644 --- a/src/ast/modules.cc +++ b/src/ast/modules.cc @@ -13,7 +13,6 @@ namespace internal { void ModuleDescriptor::AddLocalExport(const AstRawString* export_name, const AstRawString* local_name, Zone* zone, bool* ok) { - DCHECK(!IsFrozen()); void* key = const_cast(export_name); ZoneAllocationPolicy allocator(zone); diff --git a/src/ast/modules.h b/src/ast/modules.h index e3c66dce..1fdf526c 100644 --- a/src/ast/modules.h +++ b/src/ast/modules.h @@ -26,8 +26,7 @@ class ModuleDescriptor : public ZoneObject { // --------------------------------------------------------------------------- // Mutators. - // Add a name to the list of exports. If it already exists, or this descriptor - // is frozen, that's an error. + // Add a name to the list of exports. If it already exists, that's an error. void AddLocalExport(const AstRawString* export_name, const AstRawString* local_name, Zone* zone, bool* ok); @@ -35,30 +34,22 @@ class ModuleDescriptor : public ZoneObject { // if not already present. void AddModuleRequest(const AstRawString* module_specifier, Zone* zone); - // Do not allow any further refinements, directly or through unification. - void Freeze() { frozen_ = true; } - // Assign an index. void Allocate(int index) { - DCHECK(IsFrozen() && index_ == -1); + DCHECK_EQ(-1, index_); index_ = index; } // --------------------------------------------------------------------------- // Accessors. - // Check whether this is closed (i.e. fully determined). - bool IsFrozen() { return frozen_; } - int Length() { - DCHECK(IsFrozen()); ZoneHashMap* exports = exports_; return exports ? exports->occupancy() : 0; } // The context slot in the hosting script context pointing to this module. int Index() { - DCHECK(IsFrozen()); return index_; } @@ -104,12 +95,8 @@ class ModuleDescriptor : public ZoneObject { // Implementation. private: explicit ModuleDescriptor(Zone* zone) - : frozen_(false), - exports_(NULL), - requested_modules_(1, zone), - index_(-1) {} + : exports_(NULL), requested_modules_(1, zone), index_(-1) {} - bool frozen_; ZoneHashMap* exports_; // Module exports and their types (allocated lazily) ZoneList requested_modules_; int index_; diff --git a/src/ast/prettyprinter.cc b/src/ast/prettyprinter.cc index 1f6b8c31..0e9986a4 100644 --- a/src/ast/prettyprinter.cc +++ b/src/ast/prettyprinter.cc @@ -412,8 +412,7 @@ void CallPrinter::VisitSuperCallReference(SuperCallReference* node) { } -void CallPrinter::VisitRewritableAssignmentExpression( - RewritableAssignmentExpression* node) { +void CallPrinter::VisitRewritableExpression(RewritableExpression* node) { Find(node->expression()); } @@ -719,7 +718,7 @@ void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) { void PrettyPrinter::VisitClassLiteral(ClassLiteral* node) { Print("(class "); - PrintLiteral(node->name(), false); + PrintLiteral(node->constructor()->name(), false); if (node->extends()) { Print(" extends "); Visit(node->extends()); @@ -929,8 +928,7 @@ void PrettyPrinter::VisitSuperCallReference(SuperCallReference* node) { } -void PrettyPrinter::VisitRewritableAssignmentExpression( - RewritableAssignmentExpression* node) { +void PrettyPrinter::VisitRewritableExpression(RewritableExpression* node) { Visit(node->expression()); } @@ -1203,6 +1201,14 @@ const char* AstPrinter::PrintProgram(FunctionLiteral* program) { } +void AstPrinter::PrintOut(Isolate* isolate, AstNode* node) { + AstPrinter printer(isolate); + printer.Init(); + printer.Visit(node); + PrintF("%s", printer.Output()); +} + + void AstPrinter::PrintDeclarations(ZoneList* declarations) { if (declarations->length() > 0) { IndentedScope indent(this, "DECLS"); @@ -1390,6 +1396,10 @@ void AstPrinter::VisitForOfStatement(ForOfStatement* node) { PrintIndentedVisit("FOR", node->each()); PrintIndentedVisit("OF", node->iterable()); PrintIndentedVisit("BODY", node->body()); + PrintIndentedVisit("INIT", node->assign_iterator()); + PrintIndentedVisit("NEXT", node->next_result()); + PrintIndentedVisit("EACH", node->assign_each()); + PrintIndentedVisit("DONE", node->result_done()); } @@ -1429,9 +1439,7 @@ void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) { void AstPrinter::VisitClassLiteral(ClassLiteral* node) { IndentedScope indent(this, "CLASS LITERAL", node->position()); - if (node->raw_name() != nullptr) { - PrintLiteralIndented("NAME", node->name(), false); - } + PrintLiteralIndented("NAME", node->constructor()->name(), false); if (node->extends() != nullptr) { PrintIndentedVisit("EXTENDS", node->extends()); } @@ -1544,31 +1552,36 @@ void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) { void AstPrinter::VisitVariableProxy(VariableProxy* node) { - Variable* var = node->var(); EmbeddedVector buf; int pos = FormatSlotNode(&buf, node, "VAR PROXY", node->VariableFeedbackSlot()); - switch (var->location()) { - case VariableLocation::UNALLOCATED: - break; - case VariableLocation::PARAMETER: - SNPrintF(buf + pos, " parameter[%d]", var->index()); - break; - case VariableLocation::LOCAL: - SNPrintF(buf + pos, " local[%d]", var->index()); - break; - case VariableLocation::CONTEXT: - SNPrintF(buf + pos, " context[%d]", var->index()); - break; - case VariableLocation::GLOBAL: - SNPrintF(buf + pos, " global[%d]", var->index()); - break; - case VariableLocation::LOOKUP: - SNPrintF(buf + pos, " lookup"); - break; + if (!node->is_resolved()) { + SNPrintF(buf + pos, " unresolved"); + PrintLiteralWithModeIndented(buf.start(), nullptr, node->name()); + } else { + Variable* var = node->var(); + switch (var->location()) { + case VariableLocation::UNALLOCATED: + break; + case VariableLocation::PARAMETER: + SNPrintF(buf + pos, " parameter[%d]", var->index()); + break; + case VariableLocation::LOCAL: + SNPrintF(buf + pos, " local[%d]", var->index()); + break; + case VariableLocation::CONTEXT: + SNPrintF(buf + pos, " context[%d]", var->index()); + break; + case VariableLocation::GLOBAL: + SNPrintF(buf + pos, " global[%d]", var->index()); + break; + case VariableLocation::LOOKUP: + SNPrintF(buf + pos, " lookup"); + break; + } + PrintLiteralWithModeIndented(buf.start(), var, node->name()); } - PrintLiteralWithModeIndented(buf.start(), var, node->name()); } @@ -1580,7 +1593,9 @@ void AstPrinter::VisitAssignment(Assignment* node) { void AstPrinter::VisitYield(Yield* node) { - IndentedScope indent(this, "YIELD", node->position()); + EmbeddedVector buf; + SNPrintF(buf, "YIELD (kind %d)", node->yield_kind()); + IndentedScope indent(this, buf.start(), node->position()); Visit(node->expression()); } @@ -1608,7 +1623,9 @@ void AstPrinter::VisitProperty(Property* node) { void AstPrinter::VisitCall(Call* node) { EmbeddedVector buf; - FormatSlotNode(&buf, node, "CALL", node->CallFeedbackICSlot()); + const char* name = + node->tail_call_mode() == TailCallMode::kAllow ? "TAIL CALL" : "CALL"; + FormatSlotNode(&buf, node, name, node->CallFeedbackICSlot()); IndentedScope indent(this, buf.start()); Visit(node->expression()); @@ -1686,8 +1703,7 @@ void AstPrinter::VisitSuperCallReference(SuperCallReference* node) { } -void AstPrinter::VisitRewritableAssignmentExpression( - RewritableAssignmentExpression* node) { +void AstPrinter::VisitRewritableExpression(RewritableExpression* node) { Visit(node->expression()); } diff --git a/src/ast/prettyprinter.h b/src/ast/prettyprinter.h index 7e4dcdc8..0186203d 100644 --- a/src/ast/prettyprinter.h +++ b/src/ast/prettyprinter.h @@ -104,6 +104,9 @@ class AstPrinter: public PrettyPrinter { const char* PrintProgram(FunctionLiteral* program); + // Print a node to stdout. + static void PrintOut(Isolate* isolate, AstNode* node); + // Individual nodes #define DECLARE_VISIT(type) virtual void Visit##type(type* node); AST_NODE_LIST(DECLARE_VISIT) diff --git a/src/ast/scopeinfo.cc b/src/ast/scopeinfo.cc index 668879fe..4ffc020f 100644 --- a/src/ast/scopeinfo.cc +++ b/src/ast/scopeinfo.cc @@ -19,16 +19,12 @@ Handle ScopeInfo::Create(Isolate* isolate, Zone* zone, ZoneList stack_locals(scope->StackLocalCount(), zone); ZoneList context_locals(scope->ContextLocalCount(), zone); ZoneList context_globals(scope->ContextGlobalCount(), zone); - ZoneList strong_mode_free_variables(0, zone); scope->CollectStackAndContextLocals(&stack_locals, &context_locals, - &context_globals, - &strong_mode_free_variables); + &context_globals); const int stack_local_count = stack_locals.length(); const int context_local_count = context_locals.length(); const int context_global_count = context_globals.length(); - const int strong_mode_free_variable_count = - strong_mode_free_variables.length(); // Make sure we allocate the correct amount. DCHECK_EQ(scope->ContextLocalCount(), context_local_count); DCHECK_EQ(scope->ContextGlobalCount(), context_global_count); @@ -77,7 +73,6 @@ Handle ScopeInfo::Create(Isolate* isolate, Zone* zone, const int length = kVariablePartIndex + parameter_count + (1 + stack_local_count) + 2 * context_local_count + 2 * context_global_count + - 3 * strong_mode_free_variable_count + (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); Factory* factory = isolate->factory(); @@ -104,7 +99,6 @@ Handle ScopeInfo::Create(Isolate* isolate, Zone* zone, scope_info->SetStackLocalCount(stack_local_count); scope_info->SetContextLocalCount(context_local_count); scope_info->SetContextGlobalCount(context_global_count); - scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); int index = kVariablePartIndex; // Add parameters. @@ -173,25 +167,6 @@ Handle ScopeInfo::Create(Isolate* isolate, Zone* zone, scope_info->set(index++, Smi::FromInt(value)); } - DCHECK(index == scope_info->StrongModeFreeVariableNameEntriesIndex()); - for (int i = 0; i < strong_mode_free_variable_count; ++i) { - scope_info->set(index++, *strong_mode_free_variables[i]->name()); - } - - DCHECK(index == scope_info->StrongModeFreeVariablePositionEntriesIndex()); - for (int i = 0; i < strong_mode_free_variable_count; ++i) { - // Unfortunately, the source code positions are stored as int even though - // int32_t would be enough (given the maximum source code length). - Handle start_position = factory->NewNumberFromInt( - static_cast(strong_mode_free_variables[i] - ->strong_mode_reference_start_position())); - scope_info->set(index++, *start_position); - Handle end_position = factory->NewNumberFromInt( - static_cast(strong_mode_free_variables[i] - ->strong_mode_reference_end_position())); - scope_info->set(index++, *end_position); - } - // If the receiver is allocated, add its index. DCHECK(index == scope_info->ReceiverEntryIndex()); if (has_receiver) { @@ -226,7 +201,6 @@ Handle ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { const int stack_local_count = 0; const int context_local_count = 1; const int context_global_count = 0; - const int strong_mode_free_variable_count = 0; const bool has_simple_parameters = true; const VariableAllocationInfo receiver_info = CONTEXT; const VariableAllocationInfo function_name_info = NONE; @@ -237,7 +211,6 @@ Handle ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { const int length = kVariablePartIndex + parameter_count + (1 + stack_local_count) + 2 * context_local_count + 2 * context_global_count + - 3 * strong_mode_free_variable_count + (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); Factory* factory = isolate->factory(); @@ -259,7 +232,6 @@ Handle ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { scope_info->SetStackLocalCount(stack_local_count); scope_info->SetContextLocalCount(context_local_count); scope_info->SetContextGlobalCount(context_global_count); - scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); int index = kVariablePartIndex; const int first_slot_index = 0; @@ -276,9 +248,6 @@ Handle ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { ContextLocalMaybeAssignedFlag::encode(kNotAssigned); scope_info->set(index++, Smi::FromInt(value)); - DCHECK(index == scope_info->StrongModeFreeVariableNameEntriesIndex()); - DCHECK(index == scope_info->StrongModeFreeVariablePositionEntriesIndex()); - // And here we record that this scopeinfo binds a receiver. DCHECK(index == scope_info->ReceiverEntryIndex()); const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0; @@ -482,35 +451,6 @@ bool ScopeInfo::LocalIsSynthetic(int var) { } -String* ScopeInfo::StrongModeFreeVariableName(int var) { - DCHECK(0 <= var && var < StrongModeFreeVariableCount()); - int info_index = StrongModeFreeVariableNameEntriesIndex() + var; - return String::cast(get(info_index)); -} - - -int ScopeInfo::StrongModeFreeVariableStartPosition(int var) { - DCHECK(0 <= var && var < StrongModeFreeVariableCount()); - int info_index = StrongModeFreeVariablePositionEntriesIndex() + var * 2; - int32_t value = 0; - bool ok = get(info_index)->ToInt32(&value); - USE(ok); - DCHECK(ok); - return value; -} - - -int ScopeInfo::StrongModeFreeVariableEndPosition(int var) { - DCHECK(0 <= var && var < StrongModeFreeVariableCount()); - int info_index = StrongModeFreeVariablePositionEntriesIndex() + var * 2 + 1; - int32_t value = 0; - bool ok = get(info_index)->ToInt32(&value); - USE(ok); - DCHECK(ok); - return value; -} - - int ScopeInfo::StackSlotIndex(String* name) { DCHECK(name->IsInternalizedString()); if (length() > 0) { @@ -691,20 +631,8 @@ int ScopeInfo::ContextGlobalInfoEntriesIndex() { } -int ScopeInfo::StrongModeFreeVariableNameEntriesIndex() { - return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); -} - - -int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() { - return StrongModeFreeVariableNameEntriesIndex() + - StrongModeFreeVariableCount(); -} - - int ScopeInfo::ReceiverEntryIndex() { - return StrongModeFreeVariablePositionEntriesIndex() + - 2 * StrongModeFreeVariableCount(); + return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); } diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc index c2b05b7c..7c87ce39 100644 --- a/src/ast/scopes.cc +++ b/src/ast/scopes.cc @@ -27,12 +27,10 @@ VariableMap::VariableMap(Zone* zone) zone_(zone) {} VariableMap::~VariableMap() {} - Variable* VariableMap::Declare(Scope* scope, const AstRawString* name, VariableMode mode, Variable::Kind kind, InitializationFlag initialization_flag, - MaybeAssignedFlag maybe_assigned_flag, - int declaration_group_start) { + MaybeAssignedFlag maybe_assigned_flag) { // AstRawStrings are unambiguous, i.e., the same string is always represented // by the same AstRawString*. // FIXME(marja): fix the type of Lookup. @@ -42,14 +40,8 @@ Variable* VariableMap::Declare(Scope* scope, const AstRawString* name, if (p->value == NULL) { // The variable has not been declared yet -> insert it. DCHECK(p->key == name); - if (kind == Variable::CLASS) { - p->value = new (zone()) - ClassVariable(scope, name, mode, initialization_flag, - maybe_assigned_flag, declaration_group_start); - } else { - p->value = new (zone()) Variable( - scope, name, mode, kind, initialization_flag, maybe_assigned_flag); - } + p->value = new (zone()) Variable(scope, name, mode, kind, + initialization_flag, maybe_assigned_flag); } return reinterpret_cast(p->value); } @@ -103,8 +95,7 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, sloppy_block_function_map_(zone), already_resolved_(false), ast_value_factory_(ast_value_factory), - zone_(zone), - class_declaration_group_start_(-1) { + zone_(zone) { SetDefaults(scope_type, outer_scope, Handle::null(), function_kind); // The outermost scope must be a script scope. @@ -112,7 +103,6 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, DCHECK(!HasIllegalRedeclaration()); } - Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, Handle scope_info, AstValueFactory* value_factory) : inner_scopes_(4, zone), @@ -125,8 +115,7 @@ Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, sloppy_block_function_map_(zone), already_resolved_(true), ast_value_factory_(value_factory), - zone_(zone), - class_declaration_group_start_(-1) { + zone_(zone) { SetDefaults(scope_type, NULL, scope_info); if (!scope_info.is_null()) { num_heap_slots_ = scope_info_->ContextLength(); @@ -137,7 +126,6 @@ Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, AddInnerScope(inner_scope); } - Scope::Scope(Zone* zone, Scope* inner_scope, const AstRawString* catch_variable_name, AstValueFactory* value_factory) @@ -151,8 +139,7 @@ Scope::Scope(Zone* zone, Scope* inner_scope, sloppy_block_function_map_(zone), already_resolved_(true), ast_value_factory_(value_factory), - zone_(zone), - class_declaration_group_start_(-1) { + zone_(zone) { SetDefaults(CATCH_SCOPE, NULL, Handle::null()); AddInnerScope(inner_scope); ++num_var_or_const_; @@ -528,19 +515,17 @@ Variable* Scope::DeclareParameter( return var; } - Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, InitializationFlag init_flag, Variable::Kind kind, - MaybeAssignedFlag maybe_assigned_flag, - int declaration_group_start) { + MaybeAssignedFlag maybe_assigned_flag) { DCHECK(!already_resolved()); // This function handles VAR, LET, and CONST modes. DYNAMIC variables are - // introduces during variable allocation, and TEMPORARY variables are + // introduced during variable allocation, and TEMPORARY variables are // allocated via NewTemporary(). DCHECK(IsDeclaredVariableMode(mode)); ++num_var_or_const_; return variables_.Declare(this, name, mode, kind, init_flag, - maybe_assigned_flag, declaration_group_start); + maybe_assigned_flag); } @@ -660,11 +645,9 @@ class VarAndOrder { int order_; }; - -void Scope::CollectStackAndContextLocals( - ZoneList* stack_locals, ZoneList* context_locals, - ZoneList* context_globals, - ZoneList* strong_mode_free_variables) { +void Scope::CollectStackAndContextLocals(ZoneList* stack_locals, + ZoneList* context_locals, + ZoneList* context_globals) { DCHECK(stack_locals != NULL); DCHECK(context_locals != NULL); DCHECK(context_globals != NULL); @@ -691,11 +674,6 @@ void Scope::CollectStackAndContextLocals( p != NULL; p = variables_.Next(p)) { Variable* var = reinterpret_cast(p->value); - if (strong_mode_free_variables && var->has_strong_mode_reference() && - var->mode() == DYNAMIC_GLOBAL) { - strong_mode_free_variables->Add(var, zone()); - } - if (var->is_used()) { vars.Add(VarAndOrder(var, p->order), zone()); } @@ -1017,9 +995,7 @@ void Scope::Print(int n) { if (HasTrivialOuterContext()) { Indent(n1, "// scope has trivial outer context\n"); } - if (is_strong(language_mode())) { - Indent(n1, "// strong mode scope\n"); - } else if (is_strict(language_mode())) { + if (is_strict(language_mode())) { Indent(n1, "// strict mode scope\n"); } if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n"); @@ -1204,10 +1180,6 @@ bool Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy, switch (binding_kind) { case BOUND: - // We found a variable binding. - if (is_strong(language_mode())) { - if (!CheckStrongModeDeclaration(proxy, var)) return false; - } break; case BOUND_EVAL_SHADOWED: @@ -1245,126 +1217,12 @@ bool Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy, DCHECK(var != NULL); if (proxy->is_assigned()) var->set_maybe_assigned(); - if (is_strong(language_mode())) { - // Record that the variable is referred to from strong mode. Also, record - // the position. - var->RecordStrongModeReference(proxy->position(), proxy->end_position()); - } - proxy->BindTo(var); return true; } -bool Scope::CheckStrongModeDeclaration(VariableProxy* proxy, Variable* var) { - // Check for declaration-after use (for variables) in strong mode. Note that - // we can only do this in the case where we have seen the declaration. And we - // always allow referencing functions (for now). - - // This might happen during lazy compilation; we don't keep track of - // initializer positions for variables stored in ScopeInfo, so we cannot check - // bindings against them. TODO(marja, rossberg): remove this hack. - if (var->initializer_position() == RelocInfo::kNoPosition) return true; - - // Allow referencing the class name from methods of that class, even though - // the initializer position for class names is only after the body. - Scope* scope = this; - while (scope) { - if (scope->ClassVariableForMethod() == var) return true; - scope = scope->outer_scope(); - } - - // Allow references from methods to classes declared later, if we detect no - // problematic dependency cycles. Note that we can be inside multiple methods - // at the same time, and it's enough if we find one where the reference is - // allowed. - if (var->is_class() && - var->AsClassVariable()->declaration_group_start() >= 0) { - for (scope = this; scope && scope != var->scope(); - scope = scope->outer_scope()) { - ClassVariable* class_var = scope->ClassVariableForMethod(); - // A method is referring to some other class, possibly declared - // later. Referring to a class declared earlier is always OK and covered - // by the code outside this if. Here we only need to allow special cases - // for referring to a class which is declared later. - - // Referring to a class C declared later is OK under the following - // circumstances: - - // 1. The class declarations are in a consecutive group with no other - // declarations or statements in between, and - - // 2. There is no dependency cycle where the first edge is an - // initialization time dependency (computed property name or extends - // clause) from C to something that depends on this class directly or - // transitively. - if (class_var && - class_var->declaration_group_start() == - var->AsClassVariable()->declaration_group_start()) { - return true; - } - - // TODO(marja,rossberg): implement the dependency cycle detection. Here we - // undershoot the target and allow referring to any class in the same - // consectuive declaration group. - - // The cycle detection can work roughly like this: 1) detect init-time - // references here (they are free variables which are inside the class - // scope but not inside a method scope - no parser changes needed to - // detect them) 2) if we encounter an init-time reference here, allow it, - // but record it for a later dependency cycle check 3) also record - // non-init-time references here 4) after scope analysis is done, analyse - // the dependency cycles: an illegal cycle is one starting with an - // init-time reference and leading back to the starting point with either - // non-init-time and init-time references. - } - } - - // If both the use and the declaration are inside an eval scope (possibly - // indirectly), or one of them is, we need to check whether they are inside - // the same eval scope or different ones. - - // TODO(marja,rossberg): Detect errors across different evals (depends on the - // future of eval in strong mode). - const Scope* eval_for_use = NearestOuterEvalScope(); - const Scope* eval_for_declaration = var->scope()->NearestOuterEvalScope(); - - if (proxy->position() != RelocInfo::kNoPosition && - proxy->position() < var->initializer_position() && !var->is_function() && - eval_for_use == eval_for_declaration) { - DCHECK(proxy->end_position() != RelocInfo::kNoPosition); - ReportMessage(proxy->position(), proxy->end_position(), - MessageTemplate::kStrongUseBeforeDeclaration, - proxy->raw_name()); - return false; - } - return true; -} - - -ClassVariable* Scope::ClassVariableForMethod() const { - // TODO(marja, rossberg): This fails to find a class variable in the following - // cases: - // let A = class { ... } - // It needs to be investigated whether this causes any practical problems. - if (!is_function_scope()) return nullptr; - if (IsInObjectLiteral(function_kind_)) return nullptr; - if (!IsConciseMethod(function_kind_) && !IsClassConstructor(function_kind_) && - !IsAccessorFunction(function_kind_)) { - return nullptr; - } - DCHECK_NOT_NULL(outer_scope_); - // The class scope contains at most one variable, the class name. - DCHECK(outer_scope_->variables_.occupancy() <= 1); - if (outer_scope_->variables_.occupancy() == 0) return nullptr; - VariableMap::Entry* p = outer_scope_->variables_.Start(); - Variable* var = reinterpret_cast(p->value); - if (!var->is_class()) return nullptr; - return var->AsClassVariable(); -} - - bool Scope::ResolveVariablesRecursively(ParseInfo* info, AstNodeFactory* factory) { DCHECK(info->script_scope()->is_script_scope()); @@ -1646,7 +1504,7 @@ void Scope::AllocateVariablesRecursively(Isolate* isolate) { } // If scope is already resolved, we still need to allocate - // variables in inner scopes which might not had been resolved yet. + // variables in inner scopes which might not have been resolved yet. if (already_resolved()) return; // The number of slots required for variables. num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; diff --git a/src/ast/scopes.h b/src/ast/scopes.h index 6c261f63..76f761db 100644 --- a/src/ast/scopes.h +++ b/src/ast/scopes.h @@ -24,8 +24,7 @@ class VariableMap: public ZoneHashMap { Variable* Declare(Scope* scope, const AstRawString* name, VariableMode mode, Variable::Kind kind, InitializationFlag initialization_flag, - MaybeAssignedFlag maybe_assigned_flag = kNotAssigned, - int declaration_group_start = -1); + MaybeAssignedFlag maybe_assigned_flag = kNotAssigned); Variable* Lookup(const AstRawString* name); @@ -163,8 +162,7 @@ class Scope: public ZoneObject { // declared before, the previously declared variable is returned. Variable* DeclareLocal(const AstRawString* name, VariableMode mode, InitializationFlag init_flag, Variable::Kind kind, - MaybeAssignedFlag maybe_assigned_flag = kNotAssigned, - int declaration_group_start = -1); + MaybeAssignedFlag maybe_assigned_flag = kNotAssigned); // Declare an implicit global variable in this scope which must be a // script scope. The variable was introduced (possibly from an inner @@ -377,12 +375,6 @@ class Scope: public ZoneObject { IsClassConstructor(function_kind()))); } - const Scope* NearestOuterEvalScope() const { - if (is_eval_scope()) return this; - if (outer_scope() == nullptr) return nullptr; - return outer_scope()->NearestOuterEvalScope(); - } - // --------------------------------------------------------------------------- // Accessors. @@ -428,7 +420,24 @@ class Scope: public ZoneObject { // Returns the default function arity excluding default or rest parameters. int default_function_length() const { return arity_; } - int num_parameters() const { return params_.length(); } + // Returns the number of formal parameters, up to but not including the + // rest parameter index (if the function has rest parameters), i.e. it + // says 2 for + // + // function foo(a, b) { ... } + // + // and + // + // function foo(a, b, ...c) { ... } + // + // but for + // + // function foo(a, b, c = 1) { ... } + // + // we return 3 here. + int num_parameters() const { + return has_rest_parameter() ? params_.length() - 1 : params_.length(); + } // A function can have at most one rest parameter. Returns Variable* or NULL. Variable* rest_parameter(int* index) const { @@ -486,25 +495,15 @@ class Scope: public ZoneObject { // The ModuleDescriptor for this scope; only for module scopes. ModuleDescriptor* module() const { return module_descriptor_; } - - void set_class_declaration_group_start(int position) { - class_declaration_group_start_ = position; - } - - int class_declaration_group_start() const { - return class_declaration_group_start_; - } - // --------------------------------------------------------------------------- // Variable allocation. // Collect stack and context allocated local variables in this scope. Note // that the function variable - if present - is not collected and should be // handled separately. - void CollectStackAndContextLocals( - ZoneList* stack_locals, ZoneList* context_locals, - ZoneList* context_globals, - ZoneList* strong_mode_free_variables = nullptr); + void CollectStackAndContextLocals(ZoneList* stack_locals, + ZoneList* context_locals, + ZoneList* context_globals); // Current number of var or const locals. int num_var_or_const() { return num_var_or_const_; } @@ -767,12 +766,6 @@ class Scope: public ZoneObject { MUST_USE_RESULT bool ResolveVariablesRecursively(ParseInfo* info, AstNodeFactory* factory); - bool CheckStrongModeDeclaration(VariableProxy* proxy, Variable* var); - - // If this scope is a method scope of a class, return the corresponding - // class variable, otherwise nullptr. - ClassVariable* ClassVariableForMethod() const; - // Scope analysis. void PropagateScopeInfo(bool outer_scope_calls_sloppy_eval); bool HasTrivialContext() const; @@ -837,10 +830,6 @@ class Scope: public ZoneObject { Zone* zone_; PendingCompilationErrorHandler pending_error_handler_; - - // For tracking which classes are declared consecutively. Needed for strong - // mode. - int class_declaration_group_start_; }; } // namespace internal diff --git a/src/ast/variables.cc b/src/ast/variables.cc index 8e007823..7b9a5d29 100644 --- a/src/ast/variables.cc +++ b/src/ast/variables.cc @@ -40,9 +40,6 @@ Variable::Variable(Scope* scope, const AstRawString* name, VariableMode mode, location_(VariableLocation::UNALLOCATED), index_(-1), initializer_position_(RelocInfo::kNoPosition), - has_strong_mode_reference_(false), - strong_mode_reference_start_position_(RelocInfo::kNoPosition), - strong_mode_reference_end_position_(RelocInfo::kNoPosition), local_if_not_shadowed_(NULL), is_from_eval_(false), force_context_allocation_(false), diff --git a/src/ast/variables.h b/src/ast/variables.h index ca5d1cdd..b8bb07ea 100644 --- a/src/ast/variables.h +++ b/src/ast/variables.h @@ -15,12 +15,9 @@ namespace internal { // variables. Variables themselves are never directly referred to from the AST, // they are maintained by scopes, and referred to from VariableProxies and Slots // after binding and variable allocation. - -class ClassVariable; - class Variable: public ZoneObject { public: - enum Kind { NORMAL, FUNCTION, CLASS, THIS, ARGUMENTS }; + enum Kind { NORMAL, FUNCTION, THIS, ARGUMENTS }; Variable(Scope* scope, const AstRawString* name, VariableMode mode, Kind kind, InitializationFlag initialization_flag, @@ -84,7 +81,6 @@ class Variable: public ZoneObject { } bool is_function() const { return kind_ == FUNCTION; } - bool is_class() const { return kind_ == CLASS; } bool is_this() const { return kind_ == THIS; } bool is_arguments() const { return kind_ == ARGUMENTS; } @@ -98,11 +94,6 @@ class Variable: public ZoneObject { return is_this() || *name() == *isolate->factory()->this_string(); } - ClassVariable* AsClassVariable() { - DCHECK(is_class()); - return reinterpret_cast(this); - } - // True if the variable is named eval and not known to be shadowed. bool is_possibly_eval(Isolate* isolate) const { return IsVariable(isolate->factory()->eval_string()); @@ -132,24 +123,6 @@ class Variable: public ZoneObject { static int CompareIndex(Variable* const* v, Variable* const* w); - void RecordStrongModeReference(int start_position, int end_position) { - // Record the earliest reference to the variable. Used in error messages for - // strong mode references to undeclared variables. - if (has_strong_mode_reference_ && - strong_mode_reference_start_position_ < start_position) - return; - has_strong_mode_reference_ = true; - strong_mode_reference_start_position_ = start_position; - strong_mode_reference_end_position_ = end_position; - } - - bool has_strong_mode_reference() const { return has_strong_mode_reference_; } - int strong_mode_reference_start_position() const { - return strong_mode_reference_start_position_; - } - int strong_mode_reference_end_position() const { - return strong_mode_reference_end_position_; - } PropertyAttributes DeclarationPropertyAttributes() const { int property_attributes = NONE; if (IsImmutableVariableMode(mode_)) { @@ -169,11 +142,6 @@ class Variable: public ZoneObject { VariableLocation location_; int index_; int initializer_position_; - // Tracks whether the variable is bound to a VariableProxy which is in strong - // mode, and if yes, the source location of the reference. - bool has_strong_mode_reference_; - int strong_mode_reference_start_position_; - int strong_mode_reference_end_position_; // If this field is set, this variable references the stored locally bound // variable, but it might be shadowed by variable bindings introduced by @@ -190,28 +158,6 @@ class Variable: public ZoneObject { InitializationFlag initialization_flag_; MaybeAssignedFlag maybe_assigned_; }; - -class ClassVariable : public Variable { - public: - ClassVariable(Scope* scope, const AstRawString* name, VariableMode mode, - InitializationFlag initialization_flag, - MaybeAssignedFlag maybe_assigned_flag = kNotAssigned, - int declaration_group_start = -1) - : Variable(scope, name, mode, Variable::CLASS, initialization_flag, - maybe_assigned_flag), - declaration_group_start_(declaration_group_start) {} - - int declaration_group_start() const { return declaration_group_start_; } - void set_declaration_group_start(int declaration_group_start) { - declaration_group_start_ = declaration_group_start; - } - - private: - // For classes we keep track of consecutive groups of delcarations. They are - // needed for strong mode scoping checks. TODO(marja, rossberg): Implement - // checks for functions too. - int declaration_group_start_; -}; } // namespace internal } // namespace v8 -- cgit v1.2.3