diff options
Diffstat (limited to 'deps/v8/src/ast.h')
-rw-r--r-- | deps/v8/src/ast.h | 459 |
1 files changed, 215 insertions, 244 deletions
diff --git a/deps/v8/src/ast.h b/deps/v8/src/ast.h index 2aee5d72a..045404a49 100644 --- a/deps/v8/src/ast.h +++ b/deps/v8/src/ast.h @@ -1,4 +1,4 @@ -// Copyright 2010 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -28,10 +28,10 @@ #ifndef V8_AST_H_ #define V8_AST_H_ +#include "allocation.h" #include "execution.h" #include "factory.h" #include "jsregexp.h" -#include "jump-target.h" #include "runtime.h" #include "token.h" #include "variables.h" @@ -60,8 +60,8 @@ namespace internal { V(ContinueStatement) \ V(BreakStatement) \ V(ReturnStatement) \ - V(WithEnterStatement) \ - V(WithExitStatement) \ + V(EnterWithContextStatement) \ + V(ExitContextStatement) \ V(SwitchStatement) \ V(DoWhileStatement) \ V(WhileStatement) \ @@ -80,7 +80,6 @@ namespace internal { V(RegExpLiteral) \ V(ObjectLiteral) \ V(ArrayLiteral) \ - V(CatchExtensionObject) \ V(Assignment) \ V(Throw) \ V(Property) \ @@ -88,7 +87,6 @@ namespace internal { V(CallNew) \ V(CallRuntime) \ V(UnaryOperation) \ - V(IncrementOperation) \ V(CountOperation) \ V(BinaryOperation) \ V(CompareOperation) \ @@ -134,8 +132,12 @@ class AstNode: public ZoneObject { #undef DECLARE_TYPE_ENUM static const int kNoNumber = -1; + static const int kFunctionEntryId = 2; // Using 0 could disguise errors. - AstNode() : id_(GetNextId()) { count_++; } + AstNode() { + Isolate* isolate = Isolate::Current(); + isolate->set_ast_node_count(isolate->ast_node_count() + 1); + } virtual ~AstNode() { } @@ -157,24 +159,21 @@ class AstNode: public ZoneObject { virtual Slot* AsSlot() { return NULL; } // True if the node is simple enough for us to inline calls containing it. - virtual bool IsInlineable() const { return false; } + virtual bool IsInlineable() const = 0; - static int Count() { return count_; } - static void ResetIds() { current_id_ = 0; } - unsigned id() const { return id_; } + static int Count() { return Isolate::Current()->ast_node_count(); } + static void ResetIds() { Isolate::Current()->set_ast_node_id(0); } protected: - static unsigned GetNextId() { return current_id_++; } + static unsigned GetNextId() { return ReserveIdRange(1); } static unsigned ReserveIdRange(int n) { - unsigned tmp = current_id_; - current_id_ += n; + Isolate* isolate = Isolate::Current(); + unsigned tmp = isolate->ast_node_id(); + isolate->set_ast_node_id(tmp + n); return tmp; } - private: - static unsigned current_id_; - static unsigned count_; - unsigned id_; + friend class CaseClause; // Generates AST IDs. }; @@ -211,7 +210,12 @@ class Expression: public AstNode { kTest }; - Expression() : bitfields_(0) {} + Expression() : id_(GetNextId()), test_id_(GetNextId()) {} + + virtual int position() const { + UNREACHABLE(); + return 0; + } virtual Expression* AsExpression() { return this; } @@ -257,70 +261,12 @@ class Expression: public AstNode { return Handle<Map>(); } - // Static type information for this expression. - StaticType* type() { return &type_; } - - // True if the expression is a loop condition. - bool is_loop_condition() const { - return LoopConditionField::decode(bitfields_); - } - void set_is_loop_condition(bool flag) { - bitfields_ = (bitfields_ & ~LoopConditionField::mask()) | - LoopConditionField::encode(flag); - } - - // The value of the expression is guaranteed to be a smi, because the - // top operation is a bit operation with a mask, or a shift. - bool GuaranteedSmiResult(); - - // AST analysis results. - void CopyAnalysisResultsFrom(Expression* other); - - // True if the expression rooted at this node can be compiled by the - // side-effect free compiler. - bool side_effect_free() { return SideEffectFreeField::decode(bitfields_); } - void set_side_effect_free(bool is_side_effect_free) { - bitfields_ &= ~SideEffectFreeField::mask(); - bitfields_ |= SideEffectFreeField::encode(is_side_effect_free); - } - - // Will the use of this expression treat -0 the same as 0 in all cases? - // If so, we can return 0 instead of -0 if we want to, to optimize code. - bool no_negative_zero() { return NoNegativeZeroField::decode(bitfields_); } - void set_no_negative_zero(bool no_negative_zero) { - bitfields_ &= ~NoNegativeZeroField::mask(); - bitfields_ |= NoNegativeZeroField::encode(no_negative_zero); - } - - // Will ToInt32 (ECMA 262-3 9.5) or ToUint32 (ECMA 262-3 9.6) - // be applied to the value of this expression? - // If so, we may be able to optimize the calculation of the value. - bool to_int32() { return ToInt32Field::decode(bitfields_); } - void set_to_int32(bool to_int32) { - bitfields_ &= ~ToInt32Field::mask(); - bitfields_ |= ToInt32Field::encode(to_int32); - } - - // How many bitwise logical or shift operators are used in this expression? - int num_bit_ops() { return NumBitOpsField::decode(bitfields_); } - void set_num_bit_ops(int num_bit_ops) { - bitfields_ &= ~NumBitOpsField::mask(); - num_bit_ops = Min(num_bit_ops, kMaxNumBitOps); - bitfields_ |= NumBitOpsField::encode(num_bit_ops); - } + unsigned id() const { return id_; } + unsigned test_id() const { return test_id_; } private: - static const int kMaxNumBitOps = (1 << 5) - 1; - - uint32_t bitfields_; - StaticType type_; - - // Using template BitField<type, start, size>. - class SideEffectFreeField : public BitField<bool, 0, 1> {}; - class NoNegativeZeroField : public BitField<bool, 1, 1> {}; - class ToInt32Field : public BitField<bool, 2, 1> {}; - class NumBitOpsField : public BitField<int, 3, 5> {}; - class LoopConditionField: public BitField<bool, 8, 1> {}; + unsigned id_; + unsigned test_id_; }; @@ -333,10 +279,7 @@ class ValidLeftHandSideSentinel: public Expression { public: virtual bool IsValidLeftHandSide() { return true; } virtual void Accept(AstVisitor* v) { UNREACHABLE(); } - static ValidLeftHandSideSentinel* instance() { return &instance_; } - - private: - static ValidLeftHandSideSentinel instance_; + virtual bool IsInlineable() const; }; @@ -355,7 +298,7 @@ class BreakableStatement: public Statement { virtual BreakableStatement* AsBreakableStatement() { return this; } // Code generation - BreakTarget* break_target() { return &break_target_; } + Label* break_target() { return &break_target_; } // Testers. bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; } @@ -370,7 +313,7 @@ class BreakableStatement: public Statement { private: ZoneStringList* labels_; Type type_; - BreakTarget break_target_; + Label break_target_; int entry_id_; int exit_id_; }; @@ -421,6 +364,7 @@ class Declaration: public AstNode { VariableProxy* proxy() const { return proxy_; } Variable::Mode mode() const { return mode_; } FunctionLiteral* fun() const { return fun_; } // may be NULL + virtual bool IsInlineable() const; private: VariableProxy* proxy_; @@ -441,7 +385,7 @@ class IterationStatement: public BreakableStatement { virtual int ContinueId() const = 0; // Code generation - BreakTarget* continue_target() { return &continue_target_; } + Label* continue_target() { return &continue_target_; } protected: explicit inline IterationStatement(ZoneStringList* labels); @@ -452,7 +396,7 @@ class IterationStatement: public BreakableStatement { private: Statement* body_; - BreakTarget continue_target_; + Label continue_target_; int osr_entry_id_; }; @@ -479,6 +423,8 @@ class DoWhileStatement: public IterationStatement { virtual int ContinueId() const { return continue_id_; } int BackEdgeId() const { return back_edge_id_; } + virtual bool IsInlineable() const; + private: Expression* cond_; int condition_position_; @@ -505,6 +451,7 @@ class WhileStatement: public IterationStatement { void set_may_have_function_literal(bool value) { may_have_function_literal_ = value; } + virtual bool IsInlineable() const; // Bailout support. virtual int ContinueId() const { return EntryId(); } @@ -552,6 +499,7 @@ class ForStatement: public IterationStatement { bool is_fast_smi_loop() { return loop_variable_ != NULL; } Variable* loop_variable() { return loop_variable_; } void set_loop_variable(Variable* var) { loop_variable_ = var; } + virtual bool IsInlineable() const; private: Statement* init_; @@ -579,6 +527,7 @@ class ForInStatement: public IterationStatement { Expression* each() const { return each_; } Expression* enumerable() const { return enumerable_; } + virtual bool IsInlineable() const; // Bailout support. int AssignmentId() const { return assignment_id_; } @@ -619,6 +568,7 @@ class ContinueStatement: public Statement { DECLARE_NODE_TYPE(ContinueStatement) IterationStatement* target() const { return target_; } + virtual bool IsInlineable() const; private: IterationStatement* target_; @@ -633,6 +583,7 @@ class BreakStatement: public Statement { DECLARE_NODE_TYPE(BreakStatement) BreakableStatement* target() const { return target_; } + virtual bool IsInlineable() const; private: BreakableStatement* target_; @@ -654,28 +605,27 @@ class ReturnStatement: public Statement { }; -class WithEnterStatement: public Statement { +class EnterWithContextStatement: public Statement { public: - explicit WithEnterStatement(Expression* expression, bool is_catch_block) - : expression_(expression), is_catch_block_(is_catch_block) { } + explicit EnterWithContextStatement(Expression* expression) + : expression_(expression) { } - DECLARE_NODE_TYPE(WithEnterStatement) + DECLARE_NODE_TYPE(EnterWithContextStatement) Expression* expression() const { return expression_; } - bool is_catch_block() const { return is_catch_block_; } + virtual bool IsInlineable() const; private: Expression* expression_; - bool is_catch_block_; }; -class WithExitStatement: public Statement { +class ExitContextStatement: public Statement { public: - WithExitStatement() { } + virtual bool IsInlineable() const; - DECLARE_NODE_TYPE(WithExitStatement) + DECLARE_NODE_TYPE(ExitContextStatement) }; @@ -688,12 +638,15 @@ class CaseClause: public ZoneObject { CHECK(!is_default()); return label_; } - JumpTarget* body_target() { return &body_target_; } + Label* body_target() { return &body_target_; } ZoneList<Statement*>* statements() const { return statements_; } - int position() { return position_; } + int position() const { return position_; } void set_position(int pos) { position_ = pos; } + int EntryId() { return entry_id_; } + int CompareId() { return compare_id_; } + // Type feedback information. void RecordTypeFeedback(TypeFeedbackOracle* oracle); bool IsSmiCompare() { return compare_type_ == SMI_ONLY; } @@ -701,11 +654,13 @@ class CaseClause: public ZoneObject { private: Expression* label_; - JumpTarget body_target_; + Label body_target_; ZoneList<Statement*>* statements_; int position_; enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY }; CompareTypeFeedback compare_type_; + int compare_id_; + int entry_id_; }; @@ -722,6 +677,7 @@ class SwitchStatement: public BreakableStatement { Expression* tag() const { return tag_; } ZoneList<CaseClause*>* cases() const { return cases_; } + virtual bool IsInlineable() const; private: Expression* tag_; @@ -742,6 +698,7 @@ class IfStatement: public Statement { : condition_(condition), then_statement_(then_statement), else_statement_(else_statement), + if_id_(GetNextId()), then_id_(GetNextId()), else_id_(GetNextId()) { } @@ -757,6 +714,7 @@ class IfStatement: public Statement { Statement* then_statement() const { return then_statement_; } Statement* else_statement() const { return else_statement_; } + int IfId() const { return if_id_; } int ThenId() const { return then_id_; } int ElseId() const { return else_id_; } @@ -764,6 +722,7 @@ class IfStatement: public Statement { Expression* condition_; Statement* then_statement_; Statement* else_statement_; + int if_id_; int then_id_; int else_id_; }; @@ -773,23 +732,22 @@ class IfStatement: public Statement { // stack in the compiler; this should probably be reworked. class TargetCollector: public AstNode { public: - explicit TargetCollector(ZoneList<BreakTarget*>* targets) - : targets_(targets) { - } + TargetCollector(): targets_(0) { } // Adds a jump target to the collector. The collector stores a pointer not // a copy of the target to make binding work, so make sure not to pass in // references to something on the stack. - void AddTarget(BreakTarget* target); + void AddTarget(Label* target); // Virtual behaviour. TargetCollectors are never part of the AST. virtual void Accept(AstVisitor* v) { UNREACHABLE(); } virtual TargetCollector* AsTargetCollector() { return this; } - ZoneList<BreakTarget*>* targets() { return targets_; } + ZoneList<Label*>* targets() { return &targets_; } + virtual bool IsInlineable() const; private: - ZoneList<BreakTarget*>* targets_; + ZoneList<Label*> targets_; }; @@ -798,36 +756,36 @@ class TryStatement: public Statement { explicit TryStatement(Block* try_block) : try_block_(try_block), escaping_targets_(NULL) { } - void set_escaping_targets(ZoneList<BreakTarget*>* targets) { + void set_escaping_targets(ZoneList<Label*>* targets) { escaping_targets_ = targets; } Block* try_block() const { return try_block_; } - ZoneList<BreakTarget*>* escaping_targets() const { return escaping_targets_; } + ZoneList<Label*>* escaping_targets() const { return escaping_targets_; } + virtual bool IsInlineable() const; private: Block* try_block_; - ZoneList<BreakTarget*>* escaping_targets_; + ZoneList<Label*>* escaping_targets_; }; class TryCatchStatement: public TryStatement { public: - TryCatchStatement(Block* try_block, - VariableProxy* catch_var, - Block* catch_block) + TryCatchStatement(Block* try_block, Handle<String> name, Block* catch_block) : TryStatement(try_block), - catch_var_(catch_var), + name_(name), catch_block_(catch_block) { } DECLARE_NODE_TYPE(TryCatchStatement) - VariableProxy* catch_var() const { return catch_var_; } Block* catch_block() const { return catch_block_; } + Handle<String> name() const { return name_; } + virtual bool IsInlineable() const; private: - VariableProxy* catch_var_; + Handle<String> name_; Block* catch_block_; }; @@ -841,6 +799,7 @@ class TryFinallyStatement: public TryStatement { DECLARE_NODE_TYPE(TryFinallyStatement) Block* finally_block() const { return finally_block_; } + virtual bool IsInlineable() const; private: Block* finally_block_; @@ -850,6 +809,7 @@ class TryFinallyStatement: public TryStatement { class DebuggerStatement: public Statement { public: DECLARE_NODE_TYPE(DebuggerStatement) + virtual bool IsInlineable() const; }; @@ -857,7 +817,7 @@ class EmptyStatement: public Statement { public: DECLARE_NODE_TYPE(EmptyStatement) - virtual bool IsInlineable() const { return true; } + virtual bool IsInlineable() const; }; @@ -868,7 +828,6 @@ class Literal: public Expression { DECLARE_NODE_TYPE(Literal) virtual bool IsTrivial() { return true; } - virtual bool IsInlineable() const { return true; } virtual bool IsSmiLiteral() { return handle_->IsSmi(); } // Check if this literal is identical to the other literal. @@ -893,13 +852,21 @@ class Literal: public Expression { virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); } // Identity testers. - bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); } - bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); } + bool IsNull() const { + ASSERT(!handle_.is_null()); + return handle_->IsNull(); + } + bool IsTrue() const { + ASSERT(!handle_.is_null()); + return handle_->IsTrue(); + } bool IsFalse() const { - return handle_.is_identical_to(Factory::false_value()); + ASSERT(!handle_.is_null()); + return handle_->IsFalse(); } Handle<Object> handle() const { return handle_; } + virtual bool IsInlineable() const; private: Handle<Object> handle_; @@ -921,6 +888,7 @@ class MaterializedLiteral: public Expression { bool is_simple() const { return is_simple_; } int depth() const { return depth_; } + virtual bool IsInlineable() const; private: int literal_index_; @@ -970,11 +938,13 @@ class ObjectLiteral: public MaterializedLiteral { int literal_index, bool is_simple, bool fast_elements, - int depth) + int depth, + bool has_function) : MaterializedLiteral(literal_index, is_simple, depth), constant_properties_(constant_properties), properties_(properties), - fast_elements_(fast_elements) {} + fast_elements_(fast_elements), + has_function_(has_function) {} DECLARE_NODE_TYPE(ObjectLiteral) @@ -985,16 +955,24 @@ class ObjectLiteral: public MaterializedLiteral { bool fast_elements() const { return fast_elements_; } + bool has_function() { return has_function_; } // Mark all computed expressions that are bound to a key that // is shadowed by a later occurrence of the same key. For the // marked expressions, no store code is emitted. void CalculateEmitStore(); + enum Flags { + kNoFlags = 0, + kFastElements = 1, + kHasFunction = 1 << 1 + }; + private: Handle<FixedArray> constant_properties_; ZoneList<Property*>* properties_; bool fast_elements_; + bool has_function_; }; @@ -1047,26 +1025,6 @@ class ArrayLiteral: public MaterializedLiteral { }; -// Node for constructing a context extension object for a catch block. -// The catch context extension object has one property, the catch -// variable, which should be DontDelete. -class CatchExtensionObject: public Expression { - public: - CatchExtensionObject(Literal* key, VariableProxy* value) - : key_(key), value_(value) { - } - - DECLARE_NODE_TYPE(CatchExtensionObject) - - Literal* key() const { return key_; } - VariableProxy* value() const { return value_; } - - private: - Literal* key_; - VariableProxy* value_; -}; - - class VariableProxy: public Expression { public: explicit VariableProxy(Variable* var); @@ -1074,16 +1032,7 @@ class VariableProxy: public Expression { DECLARE_NODE_TYPE(VariableProxy) // Type testing & conversion - virtual Property* AsProperty() { - return var_ == NULL ? NULL : var_->AsProperty(); - } - - Variable* AsVariable() { - if (this == NULL || var_ == NULL) return NULL; - Expression* rewrite = var_->rewrite(); - if (rewrite == NULL || rewrite->AsSlot() != NULL) return var_; - return NULL; - } + Variable* AsVariable() { return (this == NULL) ? NULL : var_; } virtual bool IsValidLeftHandSide() { return var_ == NULL ? true : var_->IsValidLeftHandSide(); @@ -1110,6 +1059,7 @@ class VariableProxy: public Expression { Variable* var() const { return var_; } bool is_this() const { return is_this_; } bool inside_with() const { return inside_with_; } + int position() const { return position_; } void MarkAsTrivial() { is_trivial_ = true; } @@ -1122,8 +1072,12 @@ class VariableProxy: public Expression { bool is_this_; bool inside_with_; bool is_trivial_; + int position_; - VariableProxy(Handle<String> name, bool is_this, bool inside_with); + VariableProxy(Handle<String> name, + bool is_this, + bool inside_with, + int position = RelocInfo::kNoPosition); explicit VariableProxy(bool is_this); friend class Scope; @@ -1133,15 +1087,11 @@ class VariableProxy: public Expression { class VariableProxySentinel: public VariableProxy { public: virtual bool IsValidLeftHandSide() { return !is_this(); } - static VariableProxySentinel* this_proxy() { return &this_proxy_; } - static VariableProxySentinel* identifier_proxy() { - return &identifier_proxy_; - } private: explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { } - static VariableProxySentinel this_proxy_; - static VariableProxySentinel identifier_proxy_; + + friend class AstSentinels; }; @@ -1185,6 +1135,7 @@ class Slot: public Expression { Type type() const { return type_; } int index() const { return index_; } bool is_arguments() const { return var_->is_arguments(); } + virtual bool IsInlineable() const; private: Variable* var_; @@ -1209,8 +1160,8 @@ class Property: public Expression { is_monomorphic_(false), is_array_length_(false), is_string_length_(false), - is_function_prototype_(false), - is_arguments_access_(false) { } + is_string_access_(false), + is_function_prototype_(false) { } DECLARE_NODE_TYPE(Property) @@ -1219,19 +1170,13 @@ class Property: public Expression { Expression* obj() const { return obj_; } Expression* key() const { return key_; } - int position() const { return pos_; } + virtual int position() const { return pos_; } bool is_synthetic() const { return type_ == SYNTHETIC; } bool IsStringLength() const { return is_string_length_; } + bool IsStringAccess() const { return is_string_access_; } bool IsFunctionPrototype() const { return is_function_prototype_; } - // Marks that this is actually an argument rewritten to a keyed property - // accessing the argument through the arguments shadow object. - void set_is_arguments_access(bool is_arguments_access) { - is_arguments_access_ = is_arguments_access; - } - bool is_arguments_access() const { return is_arguments_access_; } - // Type feedback information. void RecordTypeFeedback(TypeFeedbackOracle* oracle); virtual bool IsMonomorphic() { return is_monomorphic_; } @@ -1241,10 +1186,6 @@ class Property: public Expression { return monomorphic_receiver_type_; } - // Returns a property singleton property access on 'this'. Used - // during preparsing. - static Property* this_property() { return &this_property_; } - private: Expression* obj_; Expression* key_; @@ -1255,12 +1196,9 @@ class Property: public Expression { bool is_monomorphic_ : 1; bool is_array_length_ : 1; bool is_string_length_ : 1; + bool is_string_access_ : 1; bool is_function_prototype_ : 1; - bool is_arguments_access_ : 1; Handle<Map> monomorphic_receiver_type_; - - // Dummy property used during preparsing. - static Property this_property_; }; @@ -1282,9 +1220,10 @@ class Call: public Expression { Expression* expression() const { return expression_; } ZoneList<Expression*>* arguments() const { return arguments_; } - int position() { return pos_; } + virtual int position() const { return pos_; } - void RecordTypeFeedback(TypeFeedbackOracle* oracle); + void RecordTypeFeedback(TypeFeedbackOracle* oracle, + CallKind call_kind); virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; } virtual bool IsMonomorphic() { return is_monomorphic_; } CheckType check_type() const { return check_type_; } @@ -1293,13 +1232,11 @@ class Call: public Expression { Handle<JSGlobalPropertyCell> cell() { return cell_; } bool ComputeTarget(Handle<Map> type, Handle<String> name); - bool ComputeGlobalTarget(Handle<GlobalObject> global, Handle<String> name); + bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup); // Bailout support. int ReturnId() const { return return_id_; } - static Call* sentinel() { return &sentinel_; } - #ifdef DEBUG // Used to assert that the FullCodeGenerator records the return site. bool return_is_recorded_; @@ -1318,8 +1255,36 @@ class Call: public Expression { Handle<JSGlobalPropertyCell> cell_; int return_id_; +}; + + +class AstSentinels { + public: + ~AstSentinels() { } + + // Returns a property singleton property access on 'this'. Used + // during preparsing. + Property* this_property() { return &this_property_; } + VariableProxySentinel* this_proxy() { return &this_proxy_; } + VariableProxySentinel* identifier_proxy() { return &identifier_proxy_; } + ValidLeftHandSideSentinel* valid_left_hand_side_sentinel() { + return &valid_left_hand_side_sentinel_; + } + Call* call_sentinel() { return &call_sentinel_; } + EmptyStatement* empty_statement() { return &empty_statement_; } + + private: + AstSentinels(); + VariableProxySentinel this_proxy_; + VariableProxySentinel identifier_proxy_; + ValidLeftHandSideSentinel valid_left_hand_side_sentinel_; + Property this_property_; + Call call_sentinel_; + EmptyStatement empty_statement_; + + friend class Isolate; - static Call sentinel_; + DISALLOW_COPY_AND_ASSIGN(AstSentinels); }; @@ -1334,7 +1299,7 @@ class CallNew: public Expression { Expression* expression() const { return expression_; } ZoneList<Expression*>* arguments() const { return arguments_; } - int position() { return pos_; } + virtual int position() const { return pos_; } private: Expression* expression_; @@ -1350,7 +1315,7 @@ class CallNew: public Expression { class CallRuntime: public Expression { public: CallRuntime(Handle<String> name, - Runtime::Function* function, + const Runtime::Function* function, ZoneList<Expression*>* arguments) : name_(name), function_(function), arguments_(arguments) { } @@ -1359,21 +1324,21 @@ class CallRuntime: public Expression { virtual bool IsInlineable() const; Handle<String> name() const { return name_; } - Runtime::Function* function() const { return function_; } + const Runtime::Function* function() const { return function_; } ZoneList<Expression*>* arguments() const { return arguments_; } bool is_jsruntime() const { return function_ == NULL; } private: Handle<String> name_; - Runtime::Function* function_; + const Runtime::Function* function_; ZoneList<Expression*>* arguments_; }; class UnaryOperation: public Expression { public: - UnaryOperation(Token::Value op, Expression* expression) - : op_(op), expression_(expression) { + UnaryOperation(Token::Value op, Expression* expression, int pos) + : op_(op), expression_(expression), pos_(pos) { ASSERT(Token::IsUnaryOp(op)); } @@ -1385,10 +1350,12 @@ class UnaryOperation: public Expression { Token::Value op() const { return op_; } Expression* expression() const { return expression_; } + virtual int position() const { return pos_; } private: Token::Value op_; Expression* expression_; + int pos_; }; @@ -1405,9 +1372,6 @@ class BinaryOperation: public Expression { : AstNode::kNoNumber; } - // Create the binary operation corresponding to a compound assignment. - explicit BinaryOperation(Assignment* assignment); - DECLARE_NODE_TYPE(BinaryOperation) virtual bool IsInlineable() const; @@ -1417,7 +1381,7 @@ class BinaryOperation: public Expression { Token::Value op() const { return op_; } Expression* left() const { return left_; } Expression* right() const { return right_; } - int position() const { return pos_; } + virtual int position() const { return pos_; } // Bailout support. int RightId() const { return right_id_; } @@ -1433,59 +1397,55 @@ class BinaryOperation: public Expression { }; -class IncrementOperation: public Expression { - public: - IncrementOperation(Token::Value op, Expression* expr) - : op_(op), expression_(expr) { - ASSERT(Token::IsCountOp(op)); - } - - DECLARE_NODE_TYPE(IncrementOperation) - - Token::Value op() const { return op_; } - bool is_increment() { return op_ == Token::INC; } - Expression* expression() const { return expression_; } - - private: - Token::Value op_; - Expression* expression_; - int pos_; -}; - - class CountOperation: public Expression { public: - CountOperation(bool is_prefix, IncrementOperation* increment, int pos) - : is_prefix_(is_prefix), increment_(increment), pos_(pos), - assignment_id_(GetNextId()) { - } + CountOperation(Token::Value op, bool is_prefix, Expression* expr, int pos) + : op_(op), + is_prefix_(is_prefix), + expression_(expr), + pos_(pos), + assignment_id_(GetNextId()), + count_id_(GetNextId()), + receiver_types_(NULL) { } DECLARE_NODE_TYPE(CountOperation) bool is_prefix() const { return is_prefix_; } bool is_postfix() const { return !is_prefix_; } - Token::Value op() const { return increment_->op(); } + Token::Value op() const { return op_; } Token::Value binary_op() { return (op() == Token::INC) ? Token::ADD : Token::SUB; } - Expression* expression() const { return increment_->expression(); } - IncrementOperation* increment() const { return increment_; } - int position() const { return pos_; } + Expression* expression() const { return expression_; } + virtual int position() const { return pos_; } virtual void MarkAsStatement() { is_prefix_ = true; } virtual bool IsInlineable() const; + void RecordTypeFeedback(TypeFeedbackOracle* oracle); + virtual bool IsMonomorphic() { return is_monomorphic_; } + virtual Handle<Map> GetMonomorphicReceiverType() { + return monomorphic_receiver_type_; + } + virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; } + // Bailout support. int AssignmentId() const { return assignment_id_; } + int CountId() const { return count_id_; } private: + Token::Value op_; bool is_prefix_; - IncrementOperation* increment_; + bool is_monomorphic_; + Expression* expression_; int pos_; int assignment_id_; + int count_id_; + Handle<Map> monomorphic_receiver_type_; + ZoneMapList* receiver_types_; }; @@ -1504,7 +1464,7 @@ class CompareOperation: public Expression { Token::Value op() const { return op_; } Expression* left() const { return left_; } Expression* right() const { return right_; } - int position() const { return pos_; } + virtual int position() const { return pos_; } virtual bool IsInlineable() const; @@ -1513,6 +1473,10 @@ class CompareOperation: public Expression { bool IsSmiCompare() { return compare_type_ == SMI_ONLY; } bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; } + // Match special cases. + bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check); + bool IsLiteralCompareUndefined(Expression** expr); + private: Token::Value op_; Expression* left_; @@ -1599,7 +1563,7 @@ class Assignment: public Expression { Token::Value op() const { return op_; } Expression* target() const { return target_; } Expression* value() const { return value_; } - int position() { return pos_; } + virtual int position() const { return pos_; } BinaryOperation* binary_operation() const { return binary_operation_; } // This check relies on the definition order of token in token.h. @@ -1652,7 +1616,8 @@ class Throw: public Expression { DECLARE_NODE_TYPE(Throw) Expression* exception() const { return exception_; } - int position() const { return pos_; } + virtual int position() const { return pos_; } + virtual bool IsInlineable() const; private: Expression* exception_; @@ -1673,8 +1638,7 @@ class FunctionLiteral: public Expression { int start_position, int end_position, bool is_expression, - bool contains_loops, - bool strict_mode) + bool has_duplicate_parameters) : name_(name), scope_(scope), body_(body), @@ -1686,13 +1650,12 @@ class FunctionLiteral: public Expression { num_parameters_(num_parameters), start_position_(start_position), end_position_(end_position), - is_expression_(is_expression), - contains_loops_(contains_loops), - strict_mode_(strict_mode), function_token_position_(RelocInfo::kNoPosition), - inferred_name_(Heap::empty_string()), - try_full_codegen_(false), - pretenure_(false) { } + inferred_name_(HEAP->empty_string()), + is_expression_(is_expression), + pretenure_(false), + has_duplicate_parameters_(has_duplicate_parameters) { + } DECLARE_NODE_TYPE(FunctionLiteral) @@ -1704,8 +1667,7 @@ class FunctionLiteral: public Expression { int start_position() const { return start_position_; } int end_position() const { return end_position_; } bool is_expression() const { return is_expression_; } - bool contains_loops() const { return contains_loops_; } - bool strict_mode() const { return strict_mode_; } + bool strict_mode() const; int materialized_literal_count() { return materialized_literal_count_; } int expected_property_count() { return expected_property_count_; } @@ -1729,11 +1691,11 @@ class FunctionLiteral: public Expression { inferred_name_ = inferred_name; } - bool try_full_codegen() { return try_full_codegen_; } - void set_try_full_codegen(bool flag) { try_full_codegen_ = flag; } - bool pretenure() { return pretenure_; } void set_pretenure(bool value) { pretenure_ = value; } + virtual bool IsInlineable() const; + + bool has_duplicate_parameters() { return has_duplicate_parameters_; } private: Handle<String> name_; @@ -1746,13 +1708,11 @@ class FunctionLiteral: public Expression { int num_parameters_; int start_position_; int end_position_; - bool is_expression_; - bool contains_loops_; - bool strict_mode_; int function_token_position_; Handle<String> inferred_name_; - bool try_full_codegen_; + bool is_expression_; bool pretenure_; + bool has_duplicate_parameters_; }; @@ -1767,6 +1727,7 @@ class SharedFunctionInfoLiteral: public Expression { Handle<SharedFunctionInfo> shared_function_info() const { return shared_function_info_; } + virtual bool IsInlineable() const; private: Handle<SharedFunctionInfo> shared_function_info_; @@ -1776,6 +1737,7 @@ class SharedFunctionInfoLiteral: public Expression { class ThisFunction: public Expression { public: DECLARE_NODE_TYPE(ThisFunction) + virtual bool IsInlineable() const; }; @@ -1944,6 +1906,7 @@ class RegExpCharacterClass: public RegExpTree { uc16 standard_type() { return set_.standard_set_type(); } ZoneList<CharacterRange>* ranges() { return set_.ranges(); } bool is_negated() { return is_negated_; } + private: CharacterSet set_; bool is_negated_; @@ -2028,6 +1991,7 @@ class RegExpQuantifier: public RegExpTree { bool is_non_greedy() { return type_ == NON_GREEDY; } bool is_greedy() { return type_ == GREEDY; } RegExpTree* body() { return body_; } + private: RegExpTree* body_; int min_; @@ -2060,6 +2024,7 @@ class RegExpCapture: public RegExpTree { int index() { return index_; } static int StartRegister(int index) { return index * 2; } static int EndRegister(int index) { return index * 2 + 1; } + private: RegExpTree* body_; int index_; @@ -2090,6 +2055,7 @@ class RegExpLookahead: public RegExpTree { bool is_positive() { return is_positive_; } int capture_count() { return capture_count_; } int capture_from() { return capture_from_; } + private: RegExpTree* body_; bool is_positive_; @@ -2138,7 +2104,7 @@ class RegExpEmpty: public RegExpTree { class AstVisitor BASE_EMBEDDED { public: - AstVisitor() : stack_overflow_(false) { } + AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { } virtual ~AstVisitor() { } // Stack overflow check and dynamic dispatch. @@ -2168,10 +2134,15 @@ class AstVisitor BASE_EMBEDDED { AST_NODE_LIST(DEF_VISIT) #undef DEF_VISIT + protected: + Isolate* isolate() { return isolate_; } + private: + Isolate* isolate_; bool stack_overflow_; }; + } } // namespace v8::internal #endif // V8_AST_H_ |