diff options
author | Ben Murdoch <benm@google.com> | 2017-06-06 11:06:27 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2017-06-07 12:29:44 +0100 |
commit | 62ed631aa0ff23db68a47fd423efa9c019ff2c9e (patch) | |
tree | 1df435310690642f8fd4628d6d16462d05ffc797 /src/ast/ast.h | |
parent | b0475911e4499628ec03ff93ce693450724887c2 (diff) | |
download | v8-62ed631aa0ff23db68a47fd423efa9c019ff2c9e.tar.gz |
Merge V8 5.8.283.32
Test: Build V8 for arm, arm64, x86, x86_64, mips, mips64 and
set a PAC script from the UI on bullhead
Change-Id: I7cc773b5daca34d869e768a1deebae3876f2dfac
Diffstat (limited to 'src/ast/ast.h')
-rw-r--r-- | src/ast/ast.h | 670 |
1 files changed, 357 insertions, 313 deletions
diff --git a/src/ast/ast.h b/src/ast/ast.h index 99e0672a..90e94bb8 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -14,11 +14,12 @@ #include "src/factory.h" #include "src/globals.h" #include "src/isolate.h" +#include "src/label.h" #include "src/list.h" +#include "src/objects/literal-objects.h" #include "src/parsing/token.h" #include "src/runtime/runtime.h" #include "src/small-pointer-list.h" -#include "src/utils.h" namespace v8 { namespace internal { @@ -102,6 +103,7 @@ namespace internal { V(SuperCallReference) \ V(CaseClause) \ V(EmptyParentheses) \ + V(GetIterator) \ V(DoExpression) \ V(RewritableExpression) @@ -125,27 +127,29 @@ class TypeFeedbackOracle; AST_NODE_LIST(DEF_FORWARD_DECLARATION) #undef DEF_FORWARD_DECLARATION - -class FeedbackVectorSlotCache { +class FeedbackSlotCache { public: - explicit FeedbackVectorSlotCache(Zone* zone) - : zone_(zone), - hash_map_(ZoneHashMap::kDefaultHashMapCapacity, - ZoneAllocationPolicy(zone)) {} + typedef std::pair<TypeofMode, Variable*> Key; + + explicit FeedbackSlotCache(Zone* zone) : map_(zone) {} - void Put(Variable* variable, FeedbackVectorSlot slot) { - ZoneHashMap::Entry* entry = hash_map_.LookupOrInsert( - variable, ComputePointerHash(variable), ZoneAllocationPolicy(zone_)); - entry->value = reinterpret_cast<void*>(slot.ToInt()); + void Put(TypeofMode typeof_mode, Variable* variable, FeedbackSlot slot) { + Key key = std::make_pair(typeof_mode, variable); + auto entry = std::make_pair(key, slot); + map_.insert(entry); } - ZoneHashMap::Entry* Get(Variable* variable) const { - return hash_map_.Lookup(variable, ComputePointerHash(variable)); + FeedbackSlot Get(TypeofMode typeof_mode, Variable* variable) const { + Key key = std::make_pair(typeof_mode, variable); + auto iter = map_.find(key); + if (iter != map_.end()) { + return iter->second; + } + return FeedbackSlot(); } private: - Zone* zone_; - ZoneHashMap hash_map_; + ZoneMap<Key, FeedbackSlot> map_; }; @@ -154,7 +158,7 @@ class AstProperties final BASE_EMBEDDED { enum Flag { kNoFlags = 0, kDontSelfOptimize = 1 << 0, - kDontCrankshaft = 1 << 1 + kMustUseIgnitionTurbo = 1 << 1 }; typedef base::Flags<Flag> Flags; @@ -190,6 +194,7 @@ class AstNode: public ZoneObject { int position() const { return position_; } #ifdef DEBUG + void Print(); void Print(Isolate* isolate); #endif // DEBUG @@ -317,6 +322,9 @@ class Expression : public AstNode { // True iff the expression is a literal represented as a smi. bool IsSmiLiteral() const; + // True iff the expression is a literal represented as a number. + bool IsNumberLiteral() const; + // True iff the expression is a string literal. bool IsStringLiteral() const; @@ -466,9 +474,6 @@ class Block final : public BreakableStatement { class IgnoreCompletionField : public BitField<bool, BreakableStatement::kNextBitFieldIndex, 1> {}; - - protected: - static const uint8_t kNextBitFieldIndex = IgnoreCompletionField::kNext; }; @@ -484,9 +489,6 @@ class DoExpression final : public Expression { } bool IsAnonymousFunctionDefinition() const; - protected: - static const uint8_t kNextBitFieldIndex = Expression::kNextBitFieldIndex; - private: friend class AstNodeFactory; @@ -518,8 +520,6 @@ class Declaration : public AstNode { Declaration(VariableProxy* proxy, Scope* scope, int pos, NodeType type) : AstNode(pos, type), proxy_(proxy), scope_(scope), next_(nullptr) {} - static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex; - private: VariableProxy* proxy_; // Nested scope from which the declaration originated. @@ -734,10 +734,10 @@ class ForInStatement final : public ForEachStatement { void set_subject(Expression* e) { subject_ = e; } // Type feedback information. - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache); - FeedbackVectorSlot EachFeedbackSlot() const { return each_slot_; } - FeedbackVectorSlot ForInFeedbackSlot() { + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache); + FeedbackSlot EachFeedbackSlot() const { return each_slot_; } + FeedbackSlot ForInFeedbackSlot() { DCHECK(!for_in_feedback_slot_.IsInvalid()); return for_in_feedback_slot_; } @@ -773,14 +773,11 @@ class ForInStatement final : public ForEachStatement { Expression* each_; Expression* subject_; - FeedbackVectorSlot each_slot_; - FeedbackVectorSlot for_in_feedback_slot_; + FeedbackSlot each_slot_; + FeedbackSlot for_in_feedback_slot_; class ForInTypeField : public BitField<ForInType, ForEachStatement::kNextBitFieldIndex, 1> {}; - - protected: - static const uint8_t kNextBitFieldIndex = ForInTypeField::kNext; }; @@ -826,12 +823,6 @@ class ForOfStatement final : public ForEachStatement { void set_result_done(Expression* e) { result_done_ = e; } void set_assign_each(Expression* e) { assign_each_ = e; } - BailoutId ContinueId() const { return EntryId(); } - BailoutId StackCheckId() const { return BackEdgeId(); } - - static int num_ids() { return parent_num_ids() + 1; } - BailoutId BackEdgeId() const { return BailoutId(local_id(0)); } - private: friend class AstNodeFactory; @@ -842,8 +833,6 @@ class ForOfStatement final : public ForEachStatement { next_result_(NULL), result_done_(NULL), assign_each_(NULL) {} - static int parent_num_ids() { return ForEachStatement::num_ids(); } - int local_id(int n) const { return base_id() + parent_num_ids() + n; } Variable* iterator_; Expression* assign_iterator_; @@ -908,17 +897,25 @@ class BreakStatement final : public JumpStatement { class ReturnStatement final : public JumpStatement { public: + enum Type { kNormal, kAsyncReturn }; Expression* expression() const { return expression_; } void set_expression(Expression* e) { expression_ = e; } + Type type() const { return TypeField::decode(bit_field_); } + bool is_async_return() const { return type() == kAsyncReturn; } private: friend class AstNodeFactory; - ReturnStatement(Expression* expression, int pos) - : JumpStatement(pos, kReturnStatement), expression_(expression) {} + ReturnStatement(Expression* expression, Type type, int pos) + : JumpStatement(pos, kReturnStatement), expression_(expression) { + bit_field_ |= TypeField::encode(type); + } Expression* expression_; + + class TypeField + : public BitField<Type, JumpStatement::kNextBitFieldIndex, 1> {}; }; @@ -930,30 +927,16 @@ class WithStatement final : public Statement { Statement* statement() const { return statement_; } void set_statement(Statement* s) { statement_ = s; } - void set_base_id(int id) { base_id_ = id; } - static int num_ids() { return parent_num_ids() + 2; } - BailoutId ToObjectId() const { return BailoutId(local_id(0)); } - BailoutId EntryId() const { return BailoutId(local_id(1)); } - private: friend class AstNodeFactory; WithStatement(Scope* scope, Expression* expression, Statement* statement, int pos) : Statement(pos, kWithStatement), - base_id_(BailoutId::None().ToInt()), scope_(scope), expression_(expression), statement_(statement) {} - static int parent_num_ids() { return 0; } - int base_id() const { - DCHECK(!BailoutId(base_id_).IsNone()); - return base_id_; - } - int local_id(int n) const { return base_id() + parent_num_ids() + n; } - - int base_id_; Scope* scope_; Expression* expression_; Statement* statement_; @@ -981,12 +964,10 @@ class CaseClause final : public Expression { // CaseClause will have both a slot in the feedback vector and the // TypeFeedbackId to record the type information. TypeFeedbackId is used by // full codegen and the feedback vector slot is used by interpreter. - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache); + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache); - FeedbackVectorSlot CompareOperationFeedbackSlot() { - return type_feedback_slot_; - } + FeedbackSlot CompareOperationFeedbackSlot() { return feedback_slot_; } private: friend class AstNodeFactory; @@ -999,7 +980,7 @@ class CaseClause final : public Expression { Label body_target_; ZoneList<Statement*>* statements_; AstType* compare_type_; - FeedbackVectorSlot type_feedback_slot_; + FeedbackSlot feedback_slot_; }; @@ -1174,26 +1155,10 @@ class TryFinallyStatement final : public TryStatement { class DebuggerStatement final : public Statement { - public: - void set_base_id(int id) { base_id_ = id; } - static int num_ids() { return parent_num_ids() + 1; } - BailoutId DebugBreakId() const { return BailoutId(local_id(0)); } - private: friend class AstNodeFactory; - explicit DebuggerStatement(int pos) - : Statement(pos, kDebuggerStatement), - base_id_(BailoutId::None().ToInt()) {} - - static int parent_num_ids() { return 0; } - int base_id() const { - DCHECK(!BailoutId(base_id_).IsNone()); - return base_id_; - } - int local_id(int n) const { return base_id() + parent_num_ids() + n; } - - int base_id_; + explicit DebuggerStatement(int pos) : Statement(pos, kDebuggerStatement) {} }; @@ -1212,22 +1177,15 @@ class SloppyBlockFunctionStatement final : public Statement { public: Statement* statement() const { return statement_; } void set_statement(Statement* statement) { statement_ = statement; } - Scope* scope() const { return scope_; } - SloppyBlockFunctionStatement* next() { return next_; } - void set_next(SloppyBlockFunctionStatement* next) { next_ = next; } private: friend class AstNodeFactory; - SloppyBlockFunctionStatement(Statement* statement, Scope* scope) + explicit SloppyBlockFunctionStatement(Statement* statement) : Statement(kNoSourcePosition, kSloppyBlockFunctionStatement), - statement_(statement), - scope_(scope), - next_(nullptr) {} + statement_(statement) {} Statement* statement_; - Scope* const scope_; - SloppyBlockFunctionStatement* next_; }; @@ -1275,32 +1233,32 @@ class Literal final : public Expression { const AstValue* value_; }; - -class AstLiteralReindexer; - -// Base class for literals that needs space in the corresponding JSFunction. +// Base class for literals that need space in the type feedback vector. class MaterializedLiteral : public Expression { public: - int literal_index() { return literal_index_; } - int depth() const { // only callable after initialization. DCHECK(depth_ >= 1); return depth_; } + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache) { + literal_slot_ = spec->AddLiteralSlot(); + } + + FeedbackSlot literal_slot() const { return literal_slot_; } + private: int depth_ : 31; - int literal_index_; - - friend class AstLiteralReindexer; + FeedbackSlot literal_slot_; class IsSimpleField : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; protected: - MaterializedLiteral(int literal_index, int pos, NodeType type) - : Expression(pos, type), depth_(0), literal_index_(literal_index) { + MaterializedLiteral(int pos, NodeType type) + : Expression(pos, type), depth_(0) { bit_field_ |= IsSimpleField::encode(false); } @@ -1317,6 +1275,9 @@ class MaterializedLiteral : public Expression { depth_ = depth; } + // Populate the depth field and any flags the literal has. + void InitDepthAndFlags(); + // Populate the constant properties/elements fixed array. void BuildConstants(Isolate* isolate); friend class ArrayLiteral; @@ -1342,16 +1303,20 @@ class LiteralProperty : public ZoneObject { bool is_computed_name() const { return is_computed_name_; } - FeedbackVectorSlot GetSlot(int offset = 0) const { + FeedbackSlot GetSlot(int offset = 0) const { DCHECK_LT(offset, static_cast<int>(arraysize(slots_))); return slots_[offset]; } - void SetSlot(FeedbackVectorSlot slot, int offset = 0) { + FeedbackSlot GetStoreDataPropertySlot() const; + + void SetSlot(FeedbackSlot slot, int offset = 0) { DCHECK_LT(offset, static_cast<int>(arraysize(slots_))); slots_[offset] = slot; } + void SetStoreDataPropertySlot(FeedbackSlot slot); + bool NeedsSetFunctionName() const; protected: @@ -1360,7 +1325,7 @@ class LiteralProperty : public ZoneObject { Expression* key_; Expression* value_; - FeedbackVectorSlot slots_[2]; + FeedbackSlot slots_[2]; bool is_computed_name_; }; @@ -1374,8 +1339,9 @@ class ObjectLiteralProperty final : public LiteralProperty { COMPUTED, // Property with computed value (execution time). MATERIALIZED_LITERAL, // Property value is a materialized literal. GETTER, - SETTER, // Property is an accessor function. - PROTOTYPE // Property is __proto__. + SETTER, // Property is an accessor function. + PROTOTYPE, // Property is __proto__. + SPREAD }; Kind kind() const { return kind_; } @@ -1411,7 +1377,8 @@ class ObjectLiteral final : public MaterializedLiteral { public: typedef ObjectLiteralProperty Property; - Handle<FixedArray> constant_properties() const { + Handle<BoilerplateDescription> constant_properties() const { + DCHECK(!constant_properties_.is_null()); return constant_properties_; } int properties_count() const { return boilerplate_properties_; } @@ -1424,10 +1391,25 @@ class ObjectLiteral final : public MaterializedLiteral { bool has_shallow_properties() const { return depth() == 1 && !has_elements() && !may_store_doubles(); } + bool has_rest_property() const { + return HasRestPropertyField::decode(bit_field_); + } // Decide if a property should be in the object boilerplate. static bool IsBoilerplateProperty(Property* property); + // Populate the depth field and flags. + void InitDepthAndFlags(); + + // Get the constant properties fixed array, populating it if necessary. + Handle<BoilerplateDescription> GetOrBuildConstantProperties( + Isolate* isolate) { + if (constant_properties_.is_null()) { + BuildConstantProperties(isolate); + } + return constant_properties(); + } + // Populate the constant properties fixed array. void BuildConstantProperties(Isolate* isolate); @@ -1436,6 +1418,9 @@ class ObjectLiteral final : public MaterializedLiteral { // marked expressions, no store code is emitted. void CalculateEmitStore(Zone* zone); + // Determines whether the {FastCloneShallowObject} builtin can be used. + bool IsFastCloningSupported() const; + // Assemble bitfield of flags for the CreateObjectLiteral helper. int ComputeFlags(bool disable_mementos = false) const { int flags = fast_elements() ? kFastElements : kNoFlags; @@ -1452,7 +1437,8 @@ class ObjectLiteral final : public MaterializedLiteral { kNoFlags = 0, kFastElements = 1, kShallowProperties = 1 << 1, - kDisableMementos = 1 << 2 + kDisableMementos = 1 << 2, + kHasRestProperty = 1 << 3, }; struct Accessors: public ZoneObject { @@ -1465,43 +1451,37 @@ class ObjectLiteral final : public MaterializedLiteral { BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); } // Return an AST id for a property that is used in simulate instructions. - BailoutId GetIdForPropertyName(int i) { - return BailoutId(local_id(2 * i + 1)); - } - BailoutId GetIdForPropertySet(int i) { - return BailoutId(local_id(2 * i + 2)); - } + BailoutId GetIdForPropertySet(int i) { return BailoutId(local_id(i + 1)); } // Unlike other AST nodes, this number of bailout IDs allocated for an // ObjectLiteral can vary, so num_ids() is not a static method. - int num_ids() const { - return parent_num_ids() + 1 + 2 * properties()->length(); - } + int num_ids() const { return parent_num_ids() + 1 + properties()->length(); } // Object literals need one feedback slot for each non-trivial value, as well // as some slots for home objects. - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache); + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache); private: friend class AstNodeFactory; - ObjectLiteral(ZoneList<Property*>* properties, int literal_index, - uint32_t boilerplate_properties, int pos) - : MaterializedLiteral(literal_index, pos, kObjectLiteral), + ObjectLiteral(ZoneList<Property*>* properties, + uint32_t boilerplate_properties, int pos, + bool has_rest_property) + : MaterializedLiteral(pos, kObjectLiteral), boilerplate_properties_(boilerplate_properties), properties_(properties) { bit_field_ |= FastElementsField::encode(false) | HasElementsField::encode(false) | - MayStoreDoublesField::encode(false); + MayStoreDoublesField::encode(false) | + HasRestPropertyField::encode(has_rest_property); } static int parent_num_ids() { return MaterializedLiteral::num_ids(); } int local_id(int n) const { return base_id() + parent_num_ids() + n; } uint32_t boilerplate_properties_; - FeedbackVectorSlot slot_; - Handle<FixedArray> constant_properties_; + Handle<BoilerplateDescription> constant_properties_; ZoneList<Property*>* properties_; class FastElementsField @@ -1510,9 +1490,8 @@ class ObjectLiteral final : public MaterializedLiteral { }; class MayStoreDoublesField : public BitField<bool, HasElementsField::kNext, 1> {}; - - protected: - static const uint8_t kNextBitFieldIndex = MayStoreDoublesField::kNext; + class HasRestPropertyField + : public BitField<bool, MayStoreDoublesField::kNext, 1> {}; }; @@ -1543,14 +1522,14 @@ class AccessorTable class RegExpLiteral final : public MaterializedLiteral { public: Handle<String> pattern() const { return pattern_->string(); } + const AstRawString* raw_pattern() const { return pattern_; } int flags() const { return flags_; } private: friend class AstNodeFactory; - RegExpLiteral(const AstRawString* pattern, int flags, int literal_index, - int pos) - : MaterializedLiteral(literal_index, pos, kRegExpLiteral), + RegExpLiteral(const AstRawString* pattern, int flags, int pos) + : MaterializedLiteral(pos, kRegExpLiteral), flags_(flags), pattern_(pattern) { set_depth(1); @@ -1565,12 +1544,10 @@ class RegExpLiteral final : public MaterializedLiteral { // for minimizing the work when constructing it at runtime. class ArrayLiteral final : public MaterializedLiteral { public: - Handle<FixedArray> constant_elements() const { return constant_elements_; } - ElementsKind constant_elements_kind() const { - DCHECK_EQ(2, constant_elements_->length()); - return static_cast<ElementsKind>( - Smi::cast(constant_elements_->get(0))->value()); + Handle<ConstantElementsPair> constant_elements() const { + return constant_elements_; } + ElementsKind constant_elements_kind() const; ZoneList<Expression*>* values() const { return values_; } @@ -1583,9 +1560,23 @@ class ArrayLiteral final : public MaterializedLiteral { // ArrayLiteral can vary, so num_ids() is not a static method. int num_ids() const { return parent_num_ids() + 1 + values()->length(); } + // Populate the depth field and flags. + void InitDepthAndFlags(); + + // Get the constant elements fixed array, populating it if necessary. + Handle<ConstantElementsPair> GetOrBuildConstantElements(Isolate* isolate) { + if (constant_elements_.is_null()) { + BuildConstantElements(isolate); + } + return constant_elements(); + } + // Populate the constant elements fixed array. void BuildConstantElements(Isolate* isolate); + // Determines whether the {FastCloneShallowArray} builtin can be used. + bool IsFastCloningSupported() const; + // Assemble bitfield of flags for the CreateArrayLiteral helper. int ComputeFlags(bool disable_mementos = false) const { int flags = depth() == 1 ? kShallowElements : kNoFlags; @@ -1603,10 +1594,7 @@ class ArrayLiteral final : public MaterializedLiteral { ZoneList<Expression*>::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; - } + void RewindSpreads(); enum Flags { kNoFlags = 0, @@ -1614,16 +1602,15 @@ class ArrayLiteral final : public MaterializedLiteral { kDisableMementos = 1 << 1 }; - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache); - FeedbackVectorSlot LiteralFeedbackSlot() const { return literal_slot_; } + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache); + FeedbackSlot LiteralFeedbackSlot() const { return literal_slot_; } private: friend class AstNodeFactory; - ArrayLiteral(ZoneList<Expression*>* values, int first_spread_index, - int literal_index, int pos) - : MaterializedLiteral(literal_index, pos, kArrayLiteral), + ArrayLiteral(ZoneList<Expression*>* values, int first_spread_index, int pos) + : MaterializedLiteral(pos, kArrayLiteral), first_spread_index_(first_spread_index), values_(values) {} @@ -1631,8 +1618,8 @@ class ArrayLiteral final : public MaterializedLiteral { int local_id(int n) const { return base_id() + parent_num_ids() + n; } int first_spread_index_; - FeedbackVectorSlot literal_slot_; - Handle<FixedArray> constant_elements_; + FeedbackSlot literal_slot_; + Handle<ConstantElementsPair> constant_elements_; ZoneList<Expression*>* values_; }; @@ -1663,6 +1650,9 @@ class VariableProxy final : public Expression { bool is_assigned() const { return IsAssignedField::decode(bit_field_); } void set_is_assigned() { bit_field_ = IsAssignedField::update(bit_field_, true); + if (is_resolved()) { + var()->set_maybe_assigned(); + } } bool is_resolved() const { return IsResolvedField::decode(bit_field_); } @@ -1690,10 +1680,10 @@ class VariableProxy final : public Expression { return var()->IsUnallocated() || var()->IsLookupSlot(); } - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache); + void AssignFeedbackSlots(FeedbackVectorSpec* spec, TypeofMode typeof_mode, + FeedbackSlotCache* cache); - FeedbackVectorSlot VariableFeedbackSlot() { return variable_feedback_slot_; } + FeedbackSlot VariableFeedbackSlot() { return variable_feedback_slot_; } static int num_ids() { return parent_num_ids() + 1; } BailoutId BeforeId() const { return BailoutId(local_id(0)); } @@ -1719,7 +1709,7 @@ class VariableProxy final : public Expression { class HoleCheckModeField : public BitField<HoleCheckMode, IsNewTargetField::kNext, 1> {}; - FeedbackVectorSlot variable_feedback_slot_; + FeedbackSlot variable_feedback_slot_; union { const AstRawString* raw_name_; // if !is_resolved_ Variable* var_; // if is_resolved_ @@ -1786,17 +1776,16 @@ class Property final : public Expression { bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); } - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache) { - FeedbackVectorSlotKind kind = key()->IsPropertyName() - ? FeedbackVectorSlotKind::LOAD_IC - : FeedbackVectorSlotKind::KEYED_LOAD_IC; - property_feedback_slot_ = spec->AddSlot(kind); + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache) { + if (key()->IsPropertyName()) { + property_feedback_slot_ = spec->AddLoadICSlot(); + } else { + property_feedback_slot_ = spec->AddKeyedLoadICSlot(); + } } - FeedbackVectorSlot PropertyFeedbackSlot() const { - return property_feedback_slot_; - } + FeedbackSlot PropertyFeedbackSlot() const { return property_feedback_slot_; } // Returns the properties assign type. static LhsKind GetAssignType(Property* property) { @@ -1829,7 +1818,7 @@ class Property final : public Expression { class InlineCacheStateField : public BitField<InlineCacheState, KeyTypeField::kNext, 4> {}; - FeedbackVectorSlot property_feedback_slot_; + FeedbackSlot property_feedback_slot_; Expression* obj_; Expression* key_; SmallMapList receiver_types_; @@ -1844,10 +1833,10 @@ class Call final : public Expression { void set_expression(Expression* e) { expression_ = e; } // Type feedback information. - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache); + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache); - FeedbackVectorSlot CallFeedbackICSlot() const { return ic_slot_; } + FeedbackSlot CallFeedbackICSlot() const { return ic_slot_; } SmallMapList* GetReceiverTypes() { if (expression()->IsProperty()) { @@ -1876,11 +1865,9 @@ class Call final : public Expression { allocation_site_ = site; } - static int num_ids() { return parent_num_ids() + 4; } + static int num_ids() { return parent_num_ids() + 2; } BailoutId ReturnId() const { return BailoutId(local_id(0)); } - BailoutId EvalId() const { return BailoutId(local_id(1)); } - BailoutId LookupId() const { return BailoutId(local_id(2)); } - BailoutId CallId() const { return BailoutId(local_id(3)); } + BailoutId CallId() const { return BailoutId(local_id(1)); } bool is_uninitialized() const { return IsUninitializedField::decode(bit_field_); @@ -1899,6 +1886,10 @@ class Call final : public Expression { } void MarkTail() { bit_field_ = IsTailField::update(bit_field_, true); } + bool only_last_arg_is_spread() { + return !arguments_->is_empty() && arguments_->last()->IsSpread(); + } + enum CallType { GLOBAL_CALL, WITH_CALL, @@ -1948,7 +1939,7 @@ class Call final : public Expression { class IsTailField : public BitField<bool, IsUninitializedField::kNext, 1> {}; class IsPossiblyEvalField : public BitField<bool, IsTailField::kNext, 1> {}; - FeedbackVectorSlot ic_slot_; + FeedbackSlot ic_slot_; Expression* expression_; ZoneList<Expression*>* arguments_; Handle<JSFunction> target_; @@ -1964,14 +1955,14 @@ class CallNew final : public Expression { void set_expression(Expression* e) { expression_ = e; } // Type feedback information. - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache) { + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache) { // CallNew stores feedback in the exact same way as Call. We can // piggyback on the type feedback infrastructure for calls. callnew_feedback_slot_ = spec->AddCallICSlot(); } - FeedbackVectorSlot CallNewFeedbackSlot() { + FeedbackSlot CallNewFeedbackSlot() { DCHECK(!callnew_feedback_slot_.IsInvalid()); return callnew_feedback_slot_; } @@ -1998,6 +1989,10 @@ class CallNew final : public Expression { set_is_monomorphic(true); } + bool only_last_arg_is_spread() { + return !arguments_->is_empty() && arguments_->last()->IsSpread(); + } + private: friend class AstNodeFactory; @@ -2011,7 +2006,7 @@ class CallNew final : public Expression { static int parent_num_ids() { return Expression::num_ids(); } int local_id(int n) const { return base_id() + parent_num_ids() + n; } - FeedbackVectorSlot callnew_feedback_slot_; + FeedbackSlot callnew_feedback_slot_; Expression* expression_; ZoneList<Expression*>* arguments_; Handle<JSFunction> target_; @@ -2046,10 +2041,7 @@ class CallRuntime final : public Expression { static int num_ids() { return parent_num_ids() + 1; } BailoutId CallId() { return BailoutId(local_id(0)); } - - const char* debug_name() { - return is_jsruntime() ? "(context function)" : function_->name; - } + const char* debug_name(); private: friend class AstNodeFactory; @@ -2138,12 +2130,10 @@ class BinaryOperation final : public Expression { // BinaryOperation will have both a slot in the feedback vector and the // TypeFeedbackId to record the type information. TypeFeedbackId is used // by full codegen and the feedback vector slot is used by interpreter. - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache); + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache); - FeedbackVectorSlot BinaryOperationFeedbackSlot() const { - return type_feedback_slot_; - } + FeedbackSlot BinaryOperationFeedbackSlot() const { return feedback_slot_; } TypeFeedbackId BinaryOperationFeedbackId() const { return TypeFeedbackId(local_id(1)); @@ -2181,7 +2171,7 @@ class BinaryOperation final : public Expression { Expression* left_; Expression* right_; Handle<AllocationSite> allocation_site_; - FeedbackVectorSlot type_feedback_slot_; + FeedbackSlot feedback_slot_; class OperatorField : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {}; @@ -2227,13 +2217,13 @@ class CountOperation final : public Expression { } // Feedback slot for binary operation is only used by ignition. - FeedbackVectorSlot CountBinaryOpFeedbackSlot() const { + FeedbackSlot CountBinaryOpFeedbackSlot() const { return binary_operation_slot_; } - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache); - FeedbackVectorSlot CountSlot() const { return slot_; } + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache); + FeedbackSlot CountSlot() const { return slot_; } private: friend class AstNodeFactory; @@ -2255,8 +2245,8 @@ class CountOperation final : public Expression { : public BitField<KeyedAccessStoreMode, KeyTypeField::kNext, 3> {}; class TokenField : public BitField<Token::Value, StoreModeField::kNext, 7> {}; - FeedbackVectorSlot slot_; - FeedbackVectorSlot binary_operation_slot_; + FeedbackSlot slot_; + FeedbackSlot binary_operation_slot_; AstType* type_; Expression* expression_; SmallMapList receiver_types_; @@ -2283,12 +2273,10 @@ class CompareOperation final : public Expression { // CompareOperation will have both a slot in the feedback vector and the // TypeFeedbackId to record the type information. TypeFeedbackId is used // by full codegen and the feedback vector slot is used by interpreter. - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache); + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache); - FeedbackVectorSlot CompareOperationFeedbackSlot() const { - return type_feedback_slot_; - } + FeedbackSlot CompareOperationFeedbackSlot() const { return feedback_slot_; } // Match special cases. bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check); @@ -2315,7 +2303,7 @@ class CompareOperation final : public Expression { Expression* right_; AstType* combined_type_; - FeedbackVectorSlot type_feedback_slot_; + FeedbackSlot feedback_slot_; class OperatorField : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {}; }; @@ -2429,9 +2417,9 @@ class Assignment final : public Expression { bit_field_ = StoreModeField::update(bit_field_, mode); } - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache); - FeedbackVectorSlot AssignmentSlot() const { return slot_; } + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache); + FeedbackSlot AssignmentSlot() const { return slot_; } private: friend class AstNodeFactory; @@ -2449,7 +2437,7 @@ class Assignment final : public Expression { : public BitField<KeyedAccessStoreMode, KeyTypeField::kNext, 3> {}; class TokenField : public BitField<Token::Value, StoreModeField::kNext, 7> {}; - FeedbackVectorSlot slot_; + FeedbackSlot slot_; Expression* target_; Expression* value_; BinaryOperation* binary_operation_; @@ -2571,6 +2559,8 @@ class FunctionLiteral final : public Expression { kAccessorOrMethod }; + enum IdType { kIdTypeInvalid = -1, kIdTypeTopLevel = 0 }; + enum ParameterFlag { kNoDuplicateParameters, kHasDuplicateParameters }; enum EagerCompileHint { kShouldEagerCompile, kShouldLazyCompile }; @@ -2594,9 +2584,15 @@ class FunctionLiteral final : public Expression { } LanguageMode language_mode() const; + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache) { + literal_feedback_slot_ = spec->AddCreateClosureSlot(); + } + + FeedbackSlot LiteralFeedbackSlot() const { return literal_feedback_slot_; } + static bool NeedsHomeObject(Expression* expr); - int materialized_literal_count() { return materialized_literal_count_; } int expected_property_count() { return expected_property_count_; } int parameter_count() { return parameter_count_; } int function_length() { return function_length_; } @@ -2644,8 +2640,6 @@ class FunctionLiteral final : public Expression { return HasDuplicateParameters::decode(bit_field_); } - bool is_function() const { return IsFunction::decode(bit_field_); } - // This is used as a heuristic on when to eagerly compile a function // literal. We consider the following constructs as hints that the // function will be called immediately: @@ -2691,38 +2685,27 @@ class FunctionLiteral final : public Expression { int yield_count() { return yield_count_; } void set_yield_count(int yield_count) { yield_count_ = yield_count; } - bool requires_class_field_init() { - return RequiresClassFieldInit::decode(bit_field_); - } - void set_requires_class_field_init(bool requires_class_field_init) { - bit_field_ = - RequiresClassFieldInit::update(bit_field_, requires_class_field_init); - } - bool is_class_field_initializer() { - return IsClassFieldInitializer::decode(bit_field_); - } - void set_is_class_field_initializer(bool is_class_field_initializer) { - bit_field_ = - IsClassFieldInitializer::update(bit_field_, is_class_field_initializer); - } - int return_position() { return std::max(start_position(), end_position() - (has_braces_ ? 1 : 0)); } + int function_literal_id() const { return function_literal_id_; } + void set_function_literal_id(int function_literal_id) { + function_literal_id_ = function_literal_id; + } + private: friend class AstNodeFactory; FunctionLiteral(Zone* zone, const AstString* name, AstValueFactory* ast_value_factory, DeclarationScope* scope, - ZoneList<Statement*>* body, int materialized_literal_count, - int expected_property_count, int parameter_count, - int function_length, FunctionType function_type, + ZoneList<Statement*>* body, int expected_property_count, + int parameter_count, int function_length, + FunctionType function_type, ParameterFlag has_duplicate_parameters, EagerCompileHint eager_compile_hint, int position, - bool is_function, bool has_braces) + bool has_braces, int function_literal_id) : Expression(position, kFunctionLiteral), - materialized_literal_count_(materialized_literal_count), expected_property_count_(expected_property_count), parameter_count_(parameter_count), function_length_(function_length), @@ -2733,16 +2716,14 @@ class FunctionLiteral final : public Expression { scope_(scope), body_(body), raw_inferred_name_(ast_value_factory->empty_string()), - ast_properties_(zone) { - bit_field_ |= - FunctionTypeBits::encode(function_type) | Pretenure::encode(false) | - HasDuplicateParameters::encode(has_duplicate_parameters == - kHasDuplicateParameters) | - IsFunction::encode(is_function) | - RequiresClassFieldInit::encode(false) | - ShouldNotBeUsedOnceHintField::encode(false) | - DontOptimizeReasonField::encode(kNoReason) | - IsClassFieldInitializer::encode(false); + ast_properties_(zone), + function_literal_id_(function_literal_id) { + bit_field_ |= FunctionTypeBits::encode(function_type) | + Pretenure::encode(false) | + HasDuplicateParameters::encode(has_duplicate_parameters == + kHasDuplicateParameters) | + ShouldNotBeUsedOnceHintField::encode(false) | + DontOptimizeReasonField::encode(kNoReason); if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile(); } @@ -2750,17 +2731,12 @@ class FunctionLiteral final : public Expression { : public BitField<FunctionType, Expression::kNextBitFieldIndex, 2> {}; class Pretenure : public BitField<bool, FunctionTypeBits::kNext, 1> {}; class HasDuplicateParameters : public BitField<bool, Pretenure::kNext, 1> {}; - class IsFunction : public BitField<bool, HasDuplicateParameters::kNext, 1> {}; class ShouldNotBeUsedOnceHintField - : public BitField<bool, IsFunction::kNext, 1> {}; - class RequiresClassFieldInit - : public BitField<bool, ShouldNotBeUsedOnceHintField::kNext, 1> {}; - class IsClassFieldInitializer - : public BitField<bool, RequiresClassFieldInit::kNext, 1> {}; + : public BitField<bool, HasDuplicateParameters::kNext, 1> {}; class DontOptimizeReasonField - : public BitField<BailoutReason, IsClassFieldInitializer::kNext, 8> {}; + : public BitField<BailoutReason, ShouldNotBeUsedOnceHintField::kNext, 8> { + }; - int materialized_literal_count_; int expected_property_count_; int parameter_count_; int function_length_; @@ -2774,6 +2750,8 @@ class FunctionLiteral final : public Expression { const AstString* raw_inferred_name_; Handle<String> inferred_name_; AstProperties ast_properties_; + int function_literal_id_; + FeedbackSlot literal_feedback_slot_; }; // Property is used for passing information @@ -2808,62 +2786,55 @@ class ClassLiteral final : public Expression { ZoneList<Property*>* properties() const { return properties_; } int start_position() const { return position(); } int end_position() const { return end_position_; } - - VariableProxy* static_initializer_proxy() const { - return static_initializer_proxy_; + bool has_name_static_property() const { + return HasNameStaticProperty::decode(bit_field_); } - void set_static_initializer_proxy(VariableProxy* proxy) { - static_initializer_proxy_ = proxy; + bool has_static_computed_names() const { + return HasStaticComputedNames::decode(bit_field_); } - BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); } - BailoutId PrototypeId() { return BailoutId(local_id(1)); } - - // Return an AST id for a property that is used in simulate instructions. - BailoutId GetIdForProperty(int i) { return BailoutId(local_id(i + 2)); } - - // 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() + 2 + properties()->length(); } - // Object literals need one feedback slot for each non-trivial value, as well // as some slots for home objects. - void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec, - FeedbackVectorSlotCache* cache); + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache); bool NeedsProxySlot() const { return class_variable_proxy() != nullptr && class_variable_proxy()->var()->IsUnallocated(); } - FeedbackVectorSlot PrototypeSlot() const { return prototype_slot_; } - FeedbackVectorSlot ProxySlot() const { return proxy_slot_; } + FeedbackSlot HomeObjectSlot() const { return home_object_slot_; } + FeedbackSlot ProxySlot() const { return proxy_slot_; } private: friend class AstNodeFactory; ClassLiteral(VariableProxy* class_variable_proxy, Expression* extends, FunctionLiteral* constructor, ZoneList<Property*>* properties, - int start_position, int end_position) + int start_position, int end_position, + bool has_name_static_property, bool has_static_computed_names) : Expression(start_position, kClassLiteral), end_position_(end_position), class_variable_proxy_(class_variable_proxy), extends_(extends), constructor_(constructor), - properties_(properties), - static_initializer_proxy_(nullptr) {} - - static int parent_num_ids() { return Expression::num_ids(); } - int local_id(int n) const { return base_id() + parent_num_ids() + n; } + properties_(properties) { + bit_field_ |= HasNameStaticProperty::encode(has_name_static_property) | + HasStaticComputedNames::encode(has_static_computed_names); + } int end_position_; - FeedbackVectorSlot prototype_slot_; - FeedbackVectorSlot proxy_slot_; + FeedbackSlot home_object_slot_; + FeedbackSlot proxy_slot_; VariableProxy* class_variable_proxy_; Expression* extends_; FunctionLiteral* constructor_; ZoneList<Property*>* properties_; - VariableProxy* static_initializer_proxy_; + + class HasNameStaticProperty + : public BitField<bool, Expression::kNextBitFieldIndex, 1> {}; + class HasStaticComputedNames + : public BitField<bool, HasNameStaticProperty::kNext, 1> {}; }; @@ -2871,6 +2842,14 @@ class NativeFunctionLiteral final : public Expression { public: Handle<String> name() const { return name_->string(); } v8::Extension* extension() const { return extension_; } + FeedbackSlot LiteralFeedbackSlot() const { return literal_feedback_slot_; } + + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache) { + // TODO(mvstanton): The FeedbackSlotCache can be adapted + // to always return the same slot for this case. + literal_feedback_slot_ = spec->AddCreateClosureSlot(); + } private: friend class AstNodeFactory; @@ -2883,6 +2862,7 @@ class NativeFunctionLiteral final : public Expression { const AstRawString* name_; v8::Extension* extension_; + FeedbackSlot literal_feedback_slot_; }; @@ -2955,7 +2935,59 @@ class EmptyParentheses final : public Expression { explicit EmptyParentheses(int pos) : Expression(pos, kEmptyParentheses) {} }; +// Represents the spec operation `GetIterator()` +// (defined at https://tc39.github.io/ecma262/#sec-getiterator). Ignition +// desugars this into a LoadIC / JSLoadNamed, CallIC, and a type-check to +// validate return value of the Symbol.iterator() call. +enum class IteratorType { kNormal, kAsync }; +class GetIterator final : public Expression { + public: + IteratorType hint() const { return hint_; } + + Expression* iterable() const { return iterable_; } + void set_iterable(Expression* iterable) { iterable_ = iterable; } + + static int num_ids() { return parent_num_ids(); } + void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode, + FeedbackSlotCache* cache) { + iterator_property_feedback_slot_ = spec->AddLoadICSlot(); + iterator_call_feedback_slot_ = spec->AddCallICSlot(); + if (hint() == IteratorType::kAsync) { + async_iterator_property_feedback_slot_ = spec->AddLoadICSlot(); + async_iterator_call_feedback_slot_ = spec->AddCallICSlot(); + } + } + + FeedbackSlot IteratorPropertyFeedbackSlot() const { + return iterator_property_feedback_slot_; + } + + FeedbackSlot IteratorCallFeedbackSlot() const { + return iterator_call_feedback_slot_; + } + + FeedbackSlot AsyncIteratorPropertyFeedbackSlot() const { + return async_iterator_property_feedback_slot_; + } + + FeedbackSlot AsyncIteratorCallFeedbackSlot() const { + return async_iterator_call_feedback_slot_; + } + + private: + friend class AstNodeFactory; + + explicit GetIterator(Expression* iterable, IteratorType hint, int pos) + : Expression(pos, kGetIterator), hint_(hint), iterable_(iterable) {} + + IteratorType hint_; + Expression* iterable_; + FeedbackSlot iterator_property_feedback_slot_; + FeedbackSlot iterator_call_feedback_slot_; + FeedbackSlot async_iterator_property_feedback_slot_; + FeedbackSlot async_iterator_call_feedback_slot_; +}; // ---------------------------------------------------------------------------- // Basic visitor @@ -3170,6 +3202,11 @@ class AstNodeFactory final BASE_EMBEDDED { return NULL; } + ForOfStatement* NewForOfStatement(ZoneList<const AstRawString*>* labels, + int pos) { + return new (zone_) ForOfStatement(labels, pos); + } + ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) { return new (zone_) ExpressionStatement(expression, pos); } @@ -3183,7 +3220,13 @@ class AstNodeFactory final BASE_EMBEDDED { } ReturnStatement* NewReturnStatement(Expression* expression, int pos) { - return new (zone_) ReturnStatement(expression, pos); + return new (zone_) + ReturnStatement(expression, ReturnStatement::kNormal, pos); + } + + ReturnStatement* NewAsyncReturnStatement(Expression* expression, int pos) { + return new (zone_) + ReturnStatement(expression, ReturnStatement::kAsyncReturn, pos); } WithStatement* NewWithStatement(Scope* scope, @@ -3217,15 +3260,6 @@ class AstNodeFactory final BASE_EMBEDDED { try_block, scope, variable, catch_block, HandlerTable::UNCAUGHT, pos); } - TryCatchStatement* NewTryCatchStatementForPromiseReject(Block* try_block, - Scope* scope, - Variable* variable, - Block* catch_block, - int pos) { - return new (zone_) TryCatchStatement( - try_block, scope, variable, catch_block, HandlerTable::PROMISE, pos); - } - TryCatchStatement* NewTryCatchStatementForDesugaring(Block* try_block, Scope* scope, Variable* variable, @@ -3258,9 +3292,9 @@ class AstNodeFactory final BASE_EMBEDDED { return new (zone_) EmptyStatement(pos); } - SloppyBlockFunctionStatement* NewSloppyBlockFunctionStatement(Scope* scope) { - return new (zone_) SloppyBlockFunctionStatement( - NewEmptyStatement(kNoSourcePosition), scope); + SloppyBlockFunctionStatement* NewSloppyBlockFunctionStatement() { + return new (zone_) + SloppyBlockFunctionStatement(NewEmptyStatement(kNoSourcePosition)); } CaseClause* NewCaseClause( @@ -3273,8 +3307,8 @@ class AstNodeFactory final BASE_EMBEDDED { } // A JavaScript symbol (ECMA-262 edition 6). - Literal* NewSymbolLiteral(const char* name, int pos) { - return new (zone_) Literal(ast_value_factory_->NewSymbol(name), pos); + Literal* NewSymbolLiteral(AstSymbol symbol, int pos) { + return new (zone_) Literal(ast_value_factory_->NewSymbol(symbol), pos); } Literal* NewNumberLiteral(double number, int pos, bool with_dot = false) { @@ -3303,10 +3337,10 @@ class AstNodeFactory final BASE_EMBEDDED { } ObjectLiteral* NewObjectLiteral( - ZoneList<ObjectLiteral::Property*>* properties, int literal_index, - uint32_t boilerplate_properties, int pos) { - return new (zone_) - ObjectLiteral(properties, literal_index, boilerplate_properties, pos); + ZoneList<ObjectLiteral::Property*>* properties, + uint32_t boilerplate_properties, int pos, bool has_rest_property) { + return new (zone_) ObjectLiteral(properties, boilerplate_properties, pos, + has_rest_property); } ObjectLiteral::Property* NewObjectLiteralProperty( @@ -3324,21 +3358,18 @@ class AstNodeFactory final BASE_EMBEDDED { } RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, int flags, - int literal_index, int pos) { - return new (zone_) RegExpLiteral(pattern, flags, literal_index, pos); + int pos) { + return new (zone_) RegExpLiteral(pattern, flags, pos); } ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values, - int literal_index, int pos) { - return new (zone_) ArrayLiteral(values, -1, literal_index, pos); + return new (zone_) ArrayLiteral(values, -1, pos); } ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values, - int first_spread_index, int literal_index, - int pos) { - return new (zone_) - ArrayLiteral(values, first_spread_index, literal_index, pos); + int first_spread_index, int pos) { + return new (zone_) ArrayLiteral(values, first_spread_index, pos); } VariableProxy* NewVariableProxy(Variable* var, @@ -3437,9 +3468,13 @@ class AstNodeFactory final BASE_EMBEDDED { Expression* value, int pos) { DCHECK(Token::IsAssignmentOp(op)); + + if (op != Token::INIT && target->IsVariableProxy()) { + target->AsVariableProxy()->set_is_assigned(); + } + Assignment* assign = new (zone_) Assignment(op, target, value, pos); if (assign->is_compound()) { - DCHECK(Token::IsAssignmentOp(op)); assign->binary_operation_ = NewBinaryOperation(assign->binary_op(), target, value, pos + 1); } @@ -3458,32 +3493,33 @@ class AstNodeFactory final BASE_EMBEDDED { FunctionLiteral* NewFunctionLiteral( const AstRawString* name, DeclarationScope* scope, - ZoneList<Statement*>* body, int materialized_literal_count, - int expected_property_count, int parameter_count, int function_length, + ZoneList<Statement*>* body, int expected_property_count, + int parameter_count, int function_length, FunctionLiteral::ParameterFlag has_duplicate_parameters, FunctionLiteral::FunctionType function_type, FunctionLiteral::EagerCompileHint eager_compile_hint, int position, - bool has_braces) { + bool has_braces, int function_literal_id) { return new (zone_) FunctionLiteral( - zone_, name, ast_value_factory_, scope, body, - materialized_literal_count, expected_property_count, parameter_count, - function_length, function_type, has_duplicate_parameters, - eager_compile_hint, position, true, has_braces); + zone_, name, ast_value_factory_, scope, body, expected_property_count, + parameter_count, function_length, function_type, + has_duplicate_parameters, eager_compile_hint, position, has_braces, + function_literal_id); } // 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( - DeclarationScope* scope, ZoneList<Statement*>* body, - int materialized_literal_count, int expected_property_count, - int parameter_count) { + FunctionLiteral* NewScriptOrEvalFunctionLiteral(DeclarationScope* scope, + ZoneList<Statement*>* body, + int expected_property_count, + int parameter_count) { return new (zone_) FunctionLiteral( zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope, - body, materialized_literal_count, expected_property_count, - parameter_count, parameter_count, FunctionLiteral::kAnonymousExpression, + body, expected_property_count, parameter_count, parameter_count, + FunctionLiteral::kAnonymousExpression, FunctionLiteral::kNoDuplicateParameters, - FunctionLiteral::kShouldLazyCompile, 0, false, true); + FunctionLiteral::kShouldLazyCompile, 0, true, + FunctionLiteral::kIdTypeTopLevel); } ClassLiteral::Property* NewClassLiteralProperty( @@ -3496,9 +3532,12 @@ class AstNodeFactory final BASE_EMBEDDED { ClassLiteral* NewClassLiteral(VariableProxy* proxy, Expression* extends, FunctionLiteral* constructor, ZoneList<ClassLiteral::Property*>* properties, - int start_position, int end_position) { - return new (zone_) ClassLiteral(proxy, extends, constructor, properties, - start_position, end_position); + int start_position, int end_position, + bool has_name_static_property, + bool has_static_computed_names) { + return new (zone_) ClassLiteral( + proxy, extends, constructor, properties, start_position, end_position, + has_name_static_property, has_static_computed_names); } NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name, @@ -3534,6 +3573,11 @@ class AstNodeFactory final BASE_EMBEDDED { return new (zone_) EmptyParentheses(pos); } + GetIterator* NewGetIterator(Expression* iterable, IteratorType hint, + int pos) { + return new (zone_) GetIterator(iterable, hint, pos); + } + Zone* zone() const { return zone_; } void set_zone(Zone* zone) { zone_ = zone; } |