summaryrefslogtreecommitdiff
path: root/deps/v8/src/ast.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ast.h')
-rw-r--r--deps/v8/src/ast.h459
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_