134
132
#undef DECLARE_TYPE_ENUM
136
134
static const int kNoNumber = -1;
138
AstNode() : id_(GetNextId()) { count_++; }
135
static const int kFunctionEntryId = 2; // Using 0 could disguise errors.
136
// This AST id identifies the point after the declarations have been
137
// visited. We need it to capture the environment effects of declarations
138
// that emit code (function declarations).
139
static const int kDeclarationsId = 3;
141
// Override ZoneObject's new to count allocated AST nodes.
142
void* operator new(size_t size, Zone* zone) {
143
Isolate* isolate = zone->isolate();
144
isolate->set_ast_node_count(isolate->ast_node_count() + 1);
145
return zone->New(static_cast<int>(size));
140
150
virtual ~AstNode() { }
154
164
virtual BreakableStatement* AsBreakableStatement() { return NULL; }
155
165
virtual IterationStatement* AsIterationStatement() { return NULL; }
156
166
virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
157
virtual Slot* AsSlot() { return NULL; }
159
168
// True if the node is simple enough for us to inline calls containing it.
160
virtual bool IsInlineable() const { return false; }
169
virtual bool IsInlineable() const = 0;
162
static int Count() { return count_; }
163
static void ResetIds() { current_id_ = 0; }
164
unsigned id() const { return id_; }
171
static int Count() { return Isolate::Current()->ast_node_count(); }
172
static void ResetIds() { Isolate::Current()->set_ast_node_id(0); }
167
static unsigned GetNextId() { return current_id_++; }
168
static unsigned ReserveIdRange(int n) {
169
unsigned tmp = current_id_;
175
static unsigned GetNextId(Isolate* isolate) {
176
return ReserveIdRange(isolate, 1);
179
static unsigned ReserveIdRange(Isolate* isolate, int n) {
180
unsigned tmp = isolate->ast_node_id();
181
isolate->set_ast_node_id(tmp + n);
175
static unsigned current_id_;
176
static unsigned count_;
186
// Hidden to prevent accidental usage. It would have to load the
187
// current zone from the TLS.
188
void* operator new(size_t size);
190
friend class CaseClause; // Generates AST IDs.
216
explicit SmallMapList(int capacity) : list_(capacity) {}
218
void Reserve(int capacity) { list_.Reserve(capacity); }
219
void Clear() { list_.Clear(); }
221
bool is_empty() const { return list_.is_empty(); }
222
int length() const { return list_.length(); }
224
void Add(Handle<Map> handle) {
225
list_.Add(handle.location());
228
Handle<Map> at(int i) const {
229
return Handle<Map>(list_.at(i));
232
Handle<Map> first() const { return at(0); }
233
Handle<Map> last() const { return at(length() - 1); }
236
// The list stores pointers to Map*, that is Map**, so it's GC safe.
237
SmallPointerList<Map*> list_;
239
DISALLOW_COPY_AND_ASSIGN(SmallMapList);
200
243
class Expression: public AstNode {
251
virtual ZoneMapList* GetReceiverTypes() {
301
virtual SmallMapList* GetReceiverTypes() {
255
virtual Handle<Map> GetMonomorphicReceiverType() {
257
return Handle<Map>();
260
// Static type information for this expression.
261
StaticType* type() { return &type_; }
263
// True if the expression is a loop condition.
264
bool is_loop_condition() const {
265
return LoopConditionField::decode(bitfields_);
267
void set_is_loop_condition(bool flag) {
268
bitfields_ = (bitfields_ & ~LoopConditionField::mask()) |
269
LoopConditionField::encode(flag);
272
// The value of the expression is guaranteed to be a smi, because the
273
// top operation is a bit operation with a mask, or a shift.
274
bool GuaranteedSmiResult();
276
// AST analysis results.
277
void CopyAnalysisResultsFrom(Expression* other);
279
// True if the expression rooted at this node can be compiled by the
280
// side-effect free compiler.
281
bool side_effect_free() { return SideEffectFreeField::decode(bitfields_); }
282
void set_side_effect_free(bool is_side_effect_free) {
283
bitfields_ &= ~SideEffectFreeField::mask();
284
bitfields_ |= SideEffectFreeField::encode(is_side_effect_free);
287
// Will the use of this expression treat -0 the same as 0 in all cases?
288
// If so, we can return 0 instead of -0 if we want to, to optimize code.
289
bool no_negative_zero() { return NoNegativeZeroField::decode(bitfields_); }
290
void set_no_negative_zero(bool no_negative_zero) {
291
bitfields_ &= ~NoNegativeZeroField::mask();
292
bitfields_ |= NoNegativeZeroField::encode(no_negative_zero);
295
// Will ToInt32 (ECMA 262-3 9.5) or ToUint32 (ECMA 262-3 9.6)
296
// be applied to the value of this expression?
297
// If so, we may be able to optimize the calculation of the value.
298
bool to_int32() { return ToInt32Field::decode(bitfields_); }
299
void set_to_int32(bool to_int32) {
300
bitfields_ &= ~ToInt32Field::mask();
301
bitfields_ |= ToInt32Field::encode(to_int32);
304
// How many bitwise logical or shift operators are used in this expression?
305
int num_bit_ops() { return NumBitOpsField::decode(bitfields_); }
306
void set_num_bit_ops(int num_bit_ops) {
307
bitfields_ &= ~NumBitOpsField::mask();
308
num_bit_ops = Min(num_bit_ops, kMaxNumBitOps);
309
bitfields_ |= NumBitOpsField::encode(num_bit_ops);
313
static const int kMaxNumBitOps = (1 << 5) - 1;
318
// Using template BitField<type, start, size>.
319
class SideEffectFreeField : public BitField<bool, 0, 1> {};
320
class NoNegativeZeroField : public BitField<bool, 1, 1> {};
321
class ToInt32Field : public BitField<bool, 2, 1> {};
322
class NumBitOpsField : public BitField<int, 3, 5> {};
323
class LoopConditionField: public BitField<bool, 8, 1> {};
328
* A sentinel used during pre parsing that represents some expression
329
* that is a valid left hand side without having to actually build
332
class ValidLeftHandSideSentinel: public Expression {
334
virtual bool IsValidLeftHandSide() { return true; }
335
virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
336
static ValidLeftHandSideSentinel* instance() { return &instance_; }
339
static ValidLeftHandSideSentinel instance_;
305
Handle<Map> GetMonomorphicReceiverType() {
306
ASSERT(IsMonomorphic());
307
SmallMapList* types = GetReceiverTypes();
308
ASSERT(types != NULL && types->length() == 1);
312
unsigned id() const { return id_; }
313
unsigned test_id() const { return test_id_; }
399
380
ZoneList<Statement*>* statements() { return &statements_; }
400
381
bool is_initializer_block() const { return is_initializer_block_; }
383
Scope* block_scope() const { return block_scope_; }
384
void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; }
403
387
ZoneList<Statement*> statements_;
404
388
bool is_initializer_block_;
408
393
class Declaration: public AstNode {
410
Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
395
Declaration(VariableProxy* proxy,
397
FunctionLiteral* fun,
414
ASSERT(mode == Variable::VAR || mode == Variable::CONST);
403
ASSERT(mode == Variable::VAR ||
404
mode == Variable::CONST ||
405
mode == Variable::LET);
415
406
// At the moment there are no "const functions"'s in JavaScript...
416
ASSERT(fun == NULL || mode == Variable::VAR);
407
ASSERT(fun == NULL || mode == Variable::VAR || mode == Variable::LET);
419
410
DECLARE_NODE_TYPE(Declaration)
657
class WithEnterStatement: public Statement {
665
class WithStatement: public Statement {
659
explicit WithEnterStatement(Expression* expression, bool is_catch_block)
660
: expression_(expression), is_catch_block_(is_catch_block) { }
667
WithStatement(Expression* expression, Statement* statement)
668
: expression_(expression), statement_(statement) { }
662
DECLARE_NODE_TYPE(WithEnterStatement)
670
DECLARE_NODE_TYPE(WithStatement)
664
672
Expression* expression() const { return expression_; }
673
Statement* statement() const { return statement_; }
666
bool is_catch_block() const { return is_catch_block_; }
675
virtual bool IsInlineable() const;
669
678
Expression* expression_;
670
bool is_catch_block_;
674
class WithExitStatement: public Statement {
676
WithExitStatement() { }
678
DECLARE_NODE_TYPE(WithExitStatement)
679
Statement* statement_;
682
683
class CaseClause: public ZoneObject {
684
CaseClause(Expression* label, ZoneList<Statement*>* statements, int pos);
685
CaseClause(Isolate* isolate,
687
ZoneList<Statement*>* statements,
686
690
bool is_default() const { return label_ == NULL; }
687
691
Expression* label() const {
688
692
CHECK(!is_default());
691
JumpTarget* body_target() { return &body_target_; }
695
Label* body_target() { return &body_target_; }
692
696
ZoneList<Statement*>* statements() const { return statements_; }
694
int position() { return position_; }
698
int position() const { return position_; }
695
699
void set_position(int pos) { position_ = pos; }
701
int EntryId() { return entry_id_; }
702
int CompareId() { return compare_id_; }
697
704
// Type feedback information.
698
705
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
699
706
bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
736
746
// given if-statement has a then- or an else-part containing code.
737
747
class IfStatement: public Statement {
739
IfStatement(Expression* condition,
749
IfStatement(Isolate* isolate,
750
Expression* condition,
740
751
Statement* then_statement,
741
752
Statement* else_statement)
742
753
: condition_(condition),
743
754
then_statement_(then_statement),
744
755
else_statement_(else_statement),
745
then_id_(GetNextId()),
746
else_id_(GetNextId()) {
756
if_id_(GetNextId(isolate)),
757
then_id_(GetNextId(isolate)),
758
else_id_(GetNextId(isolate)) {
749
761
DECLARE_NODE_TYPE(IfStatement)
773
787
// stack in the compiler; this should probably be reworked.
774
788
class TargetCollector: public AstNode {
776
explicit TargetCollector(ZoneList<BreakTarget*>* targets)
777
: targets_(targets) {
790
TargetCollector(): targets_(0) { }
780
792
// Adds a jump target to the collector. The collector stores a pointer not
781
793
// a copy of the target to make binding work, so make sure not to pass in
782
794
// references to something on the stack.
783
void AddTarget(BreakTarget* target);
795
void AddTarget(Label* target);
785
797
// Virtual behaviour. TargetCollectors are never part of the AST.
786
798
virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
787
799
virtual TargetCollector* AsTargetCollector() { return this; }
789
ZoneList<BreakTarget*>* targets() { return targets_; }
801
ZoneList<Label*>* targets() { return &targets_; }
802
virtual bool IsInlineable() const;
792
ZoneList<BreakTarget*>* targets_;
805
ZoneList<Label*> targets_;
798
811
explicit TryStatement(Block* try_block)
799
812
: try_block_(try_block), escaping_targets_(NULL) { }
801
void set_escaping_targets(ZoneList<BreakTarget*>* targets) {
814
void set_escaping_targets(ZoneList<Label*>* targets) {
802
815
escaping_targets_ = targets;
805
818
Block* try_block() const { return try_block_; }
806
ZoneList<BreakTarget*>* escaping_targets() const { return escaping_targets_; }
819
ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
820
virtual bool IsInlineable() const;
809
823
Block* try_block_;
810
ZoneList<BreakTarget*>* escaping_targets_;
824
ZoneList<Label*>* escaping_targets_;
814
828
class TryCatchStatement: public TryStatement {
816
830
TryCatchStatement(Block* try_block,
817
VariableProxy* catch_var,
818
833
Block* catch_block)
819
834
: TryStatement(try_block),
820
catch_var_(catch_var),
821
837
catch_block_(catch_block) {
824
840
DECLARE_NODE_TYPE(TryCatchStatement)
826
VariableProxy* catch_var() const { return catch_var_; }
842
Scope* scope() { return scope_; }
843
Variable* variable() { return variable_; }
827
844
Block* catch_block() const { return catch_block_; }
845
virtual bool IsInlineable() const;
830
VariableProxy* catch_var_;
831
850
Block* catch_block_;
858
879
DECLARE_NODE_TYPE(EmptyStatement)
860
virtual bool IsInlineable() const { return true; }
881
virtual bool IsInlineable() const;
864
885
class Literal: public Expression {
866
explicit Literal(Handle<Object> handle) : handle_(handle) { }
887
Literal(Isolate* isolate, Handle<Object> handle)
888
: Expression(isolate), handle_(handle) { }
868
890
DECLARE_NODE_TYPE(Literal)
870
892
virtual bool IsTrivial() { return true; }
871
virtual bool IsInlineable() const { return true; }
872
893
virtual bool IsSmiLiteral() { return handle_->IsSmi(); }
874
895
// Check if this literal is identical to the other literal.
893
914
virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
895
916
// Identity testers.
896
bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); }
897
bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); }
917
bool IsNull() const {
918
ASSERT(!handle_.is_null());
919
return handle_->IsNull();
921
bool IsTrue() const {
922
ASSERT(!handle_.is_null());
923
return handle_->IsTrue();
898
925
bool IsFalse() const {
899
return handle_.is_identical_to(Factory::false_value());
926
ASSERT(!handle_.is_null());
927
return handle_->IsFalse();
902
930
Handle<Object> handle() const { return handle_; }
931
virtual bool IsInlineable() const;
905
934
Handle<Object> handle_;
965
1001
bool emit_store_;
968
ObjectLiteral(Handle<FixedArray> constant_properties,
1004
ObjectLiteral(Isolate* isolate,
1005
Handle<FixedArray> constant_properties,
969
1006
ZoneList<Property*>* properties,
970
1007
int literal_index,
972
1009
bool fast_elements,
974
: MaterializedLiteral(literal_index, is_simple, depth),
1012
: MaterializedLiteral(isolate, literal_index, is_simple, depth),
975
1013
constant_properties_(constant_properties),
976
1014
properties_(properties),
977
fast_elements_(fast_elements) {}
1015
fast_elements_(fast_elements),
1016
has_function_(has_function) {}
979
1018
DECLARE_NODE_TYPE(ObjectLiteral)
986
1025
bool fast_elements() const { return fast_elements_; }
1027
bool has_function() { return has_function_; }
989
1029
// Mark all computed expressions that are bound to a key that
990
1030
// is shadowed by a later occurrence of the same key. For the
991
1031
// marked expressions, no store code is emitted.
992
1032
void CalculateEmitStore();
1037
kHasFunction = 1 << 1
995
1041
Handle<FixedArray> constant_properties_;
996
1042
ZoneList<Property*>* properties_;
997
1043
bool fast_elements_;
1001
1048
// Node for capturing a regexp literal.
1002
1049
class RegExpLiteral: public MaterializedLiteral {
1004
RegExpLiteral(Handle<String> pattern,
1051
RegExpLiteral(Isolate* isolate,
1052
Handle<String> pattern,
1005
1053
Handle<String> flags,
1006
1054
int literal_index)
1007
: MaterializedLiteral(literal_index, false, 1),
1055
: MaterializedLiteral(isolate, literal_index, false, 1),
1008
1056
pattern_(pattern),
1009
1057
flags_(flags) {}
1022
1070
// for minimizing the work when constructing it at runtime.
1023
1071
class ArrayLiteral: public MaterializedLiteral {
1025
ArrayLiteral(Handle<FixedArray> constant_elements,
1073
ArrayLiteral(Isolate* isolate,
1074
Handle<FixedArray> constant_elements,
1026
1075
ZoneList<Expression*>* values,
1027
1076
int literal_index,
1028
1077
bool is_simple,
1030
: MaterializedLiteral(literal_index, is_simple, depth),
1079
: MaterializedLiteral(isolate, literal_index, is_simple, depth),
1031
1080
constant_elements_(constant_elements),
1032
1081
values_(values),
1033
first_element_id_(ReserveIdRange(values->length())) {}
1082
first_element_id_(ReserveIdRange(isolate, values->length())) {}
1035
1084
DECLARE_NODE_TYPE(ArrayLiteral)
1050
// Node for constructing a context extension object for a catch block.
1051
// The catch context extension object has one property, the catch
1052
// variable, which should be DontDelete.
1053
class CatchExtensionObject: public Expression {
1055
CatchExtensionObject(Literal* key, VariableProxy* value)
1056
: key_(key), value_(value) {
1059
DECLARE_NODE_TYPE(CatchExtensionObject)
1061
Literal* key() const { return key_; }
1062
VariableProxy* value() const { return value_; }
1066
VariableProxy* value_;
1070
1099
class VariableProxy: public Expression {
1072
explicit VariableProxy(Variable* var);
1101
VariableProxy(Isolate* isolate, Variable* var);
1074
1103
DECLARE_NODE_TYPE(VariableProxy)
1076
// Type testing & conversion
1077
virtual Property* AsProperty() {
1078
return var_ == NULL ? NULL : var_->AsProperty();
1081
Variable* AsVariable() {
1082
if (this == NULL || var_ == NULL) return NULL;
1083
Expression* rewrite = var_->rewrite();
1084
if (rewrite == NULL || rewrite->AsSlot() != NULL) return var_;
1088
1105
virtual bool IsValidLeftHandSide() {
1089
1106
return var_ == NULL ? true : var_->IsValidLeftHandSide();
1123
1138
bool inside_with_;
1124
1139
bool is_trivial_;
1126
VariableProxy(Handle<String> name, bool is_this, bool inside_with);
1127
explicit VariableProxy(bool is_this);
1142
VariableProxy(Isolate* isolate,
1143
Handle<String> name,
1146
int position = RelocInfo::kNoPosition);
1129
1148
friend class Scope;
1133
class VariableProxySentinel: public VariableProxy {
1135
virtual bool IsValidLeftHandSide() { return !is_this(); }
1136
static VariableProxySentinel* this_proxy() { return &this_proxy_; }
1137
static VariableProxySentinel* identifier_proxy() {
1138
return &identifier_proxy_;
1142
explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
1143
static VariableProxySentinel this_proxy_;
1144
static VariableProxySentinel identifier_proxy_;
1148
class Slot: public Expression {
1151
// A slot in the parameter section on the stack. index() is
1152
// the parameter index, counting left-to-right, starting at 0.
1155
// A slot in the local section on the stack. index() is
1156
// the variable index in the stack frame, starting at 0.
1159
// An indexed slot in a heap context. index() is the
1160
// variable index in the context object on the heap,
1161
// starting at 0. var()->scope() is the corresponding
1165
// A named slot in a heap context. var()->name() is the
1166
// variable name in the context object on the heap,
1167
// with lookup starting at the current context. index()
1172
Slot(Variable* var, Type type, int index)
1173
: var_(var), type_(type), index_(index) {
1174
ASSERT(var != NULL);
1177
virtual void Accept(AstVisitor* v);
1179
virtual Slot* AsSlot() { return this; }
1181
bool IsStackAllocated() { return type_ == PARAMETER || type_ == LOCAL; }
1184
Variable* var() const { return var_; }
1185
Type type() const { return type_; }
1186
int index() const { return index_; }
1187
bool is_arguments() const { return var_->is_arguments(); }
1196
1152
class Property: public Expression {
1198
// Synthetic properties are property lookups introduced by the system,
1199
// to objects that aren't visible to the user. Function calls to synthetic
1200
// properties should use the global object as receiver, not the base object
1201
// of the resolved Reference.
1202
enum Type { NORMAL, SYNTHETIC };
1203
Property(Expression* obj, Expression* key, int pos, Type type = NORMAL)
1154
Property(Isolate* isolate,
1158
: Expression(isolate),
1208
receiver_types_(NULL),
1209
1162
is_monomorphic_(false),
1210
1163
is_array_length_(false),
1211
1164
is_string_length_(false),
1212
is_function_prototype_(false),
1213
is_arguments_access_(false) { }
1165
is_string_access_(false),
1166
is_function_prototype_(false) { }
1215
1168
DECLARE_NODE_TYPE(Property)
1220
1173
Expression* obj() const { return obj_; }
1221
1174
Expression* key() const { return key_; }
1222
int position() const { return pos_; }
1223
bool is_synthetic() const { return type_ == SYNTHETIC; }
1175
virtual int position() const { return pos_; }
1225
1177
bool IsStringLength() const { return is_string_length_; }
1178
bool IsStringAccess() const { return is_string_access_; }
1226
1179
bool IsFunctionPrototype() const { return is_function_prototype_; }
1228
// Marks that this is actually an argument rewritten to a keyed property
1229
// accessing the argument through the arguments shadow object.
1230
void set_is_arguments_access(bool is_arguments_access) {
1231
is_arguments_access_ = is_arguments_access;
1233
bool is_arguments_access() const { return is_arguments_access_; }
1235
1181
// Type feedback information.
1236
1182
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1237
1183
virtual bool IsMonomorphic() { return is_monomorphic_; }
1238
virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
1184
virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1239
1185
virtual bool IsArrayLength() { return is_array_length_; }
1240
virtual Handle<Map> GetMonomorphicReceiverType() {
1241
return monomorphic_receiver_type_;
1244
// Returns a property singleton property access on 'this'. Used
1245
// during preparsing.
1246
static Property* this_property() { return &this_property_; }
1249
1188
Expression* obj_;
1250
1189
Expression* key_;
1254
ZoneMapList* receiver_types_;
1192
SmallMapList receiver_types_;
1255
1193
bool is_monomorphic_ : 1;
1256
1194
bool is_array_length_ : 1;
1257
1195
bool is_string_length_ : 1;
1196
bool is_string_access_ : 1;
1258
1197
bool is_function_prototype_ : 1;
1259
bool is_arguments_access_ : 1;
1260
Handle<Map> monomorphic_receiver_type_;
1262
// Dummy property used during preparsing.
1263
static Property this_property_;
1267
1201
class Call: public Expression {
1269
Call(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1270
: expression_(expression),
1203
Call(Isolate* isolate,
1204
Expression* expression,
1205
ZoneList<Expression*>* arguments,
1207
: Expression(isolate),
1208
expression_(expression),
1271
1209
arguments_(arguments),
1273
1211
is_monomorphic_(false),
1274
1212
check_type_(RECEIVER_MAP_CHECK),
1275
receiver_types_(NULL),
1276
return_id_(GetNextId()) {
1213
return_id_(GetNextId(isolate)) {
1279
1216
DECLARE_NODE_TYPE(Call)
1283
1220
Expression* expression() const { return expression_; }
1284
1221
ZoneList<Expression*>* arguments() const { return arguments_; }
1285
int position() { return pos_; }
1222
virtual int position() const { return pos_; }
1287
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1288
virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
1224
void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1225
CallKind call_kind);
1226
virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1289
1227
virtual bool IsMonomorphic() { return is_monomorphic_; }
1290
1228
CheckType check_type() const { return check_type_; }
1291
1229
Handle<JSFunction> target() { return target_; }
1313
1249
bool is_monomorphic_;
1314
1250
CheckType check_type_;
1315
ZoneMapList* receiver_types_;
1251
SmallMapList receiver_types_;
1316
1252
Handle<JSFunction> target_;
1317
1253
Handle<JSObject> holder_;
1318
1254
Handle<JSGlobalPropertyCell> cell_;
1320
1256
int return_id_;
1322
static Call sentinel_;
1326
1260
class CallNew: public Expression {
1328
CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1329
: expression_(expression), arguments_(arguments), pos_(pos) { }
1262
CallNew(Isolate* isolate,
1263
Expression* expression,
1264
ZoneList<Expression*>* arguments,
1266
: Expression(isolate),
1267
expression_(expression),
1268
arguments_(arguments),
1331
1271
DECLARE_NODE_TYPE(CallNew)
1349
1289
// implemented in JavaScript (see "v8natives.js").
1350
1290
class CallRuntime: public Expression {
1352
CallRuntime(Handle<String> name,
1353
Runtime::Function* function,
1292
CallRuntime(Isolate* isolate,
1293
Handle<String> name,
1294
const Runtime::Function* function,
1354
1295
ZoneList<Expression*>* arguments)
1355
: name_(name), function_(function), arguments_(arguments) { }
1296
: Expression(isolate),
1298
function_(function),
1299
arguments_(arguments) { }
1357
1301
DECLARE_NODE_TYPE(CallRuntime)
1359
1303
virtual bool IsInlineable() const;
1361
1305
Handle<String> name() const { return name_; }
1362
Runtime::Function* function() const { return function_; }
1306
const Runtime::Function* function() const { return function_; }
1363
1307
ZoneList<Expression*>* arguments() const { return arguments_; }
1364
1308
bool is_jsruntime() const { return function_ == NULL; }
1367
1311
Handle<String> name_;
1368
Runtime::Function* function_;
1312
const Runtime::Function* function_;
1369
1313
ZoneList<Expression*>* arguments_;
1373
1317
class UnaryOperation: public Expression {
1375
UnaryOperation(Token::Value op, Expression* expression)
1376
: op_(op), expression_(expression) {
1319
UnaryOperation(Isolate* isolate,
1321
Expression* expression,
1323
: Expression(isolate), op_(op), expression_(expression), pos_(pos) {
1377
1324
ASSERT(Token::IsUnaryOp(op));
1386
1333
Token::Value op() const { return op_; }
1387
1334
Expression* expression() const { return expression_; }
1335
virtual int position() const { return pos_; }
1390
1338
Token::Value op_;
1391
1339
Expression* expression_;
1395
1344
class BinaryOperation: public Expression {
1397
BinaryOperation(Token::Value op,
1346
BinaryOperation(Isolate* isolate,
1398
1348
Expression* left,
1399
1349
Expression* right,
1401
: op_(op), left_(left), right_(right), pos_(pos) {
1351
: Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
1402
1352
ASSERT(Token::IsBinaryOp(op));
1403
1353
right_id_ = (op == Token::AND || op == Token::OR)
1404
? static_cast<int>(GetNextId())
1354
? static_cast<int>(GetNextId(isolate))
1405
1355
: AstNode::kNoNumber;
1408
// Create the binary operation corresponding to a compound assignment.
1409
explicit BinaryOperation(Assignment* assignment);
1411
1358
DECLARE_NODE_TYPE(BinaryOperation)
1413
1360
virtual bool IsInlineable() const;
1436
class IncrementOperation: public Expression {
1438
IncrementOperation(Token::Value op, Expression* expr)
1439
: op_(op), expression_(expr) {
1440
ASSERT(Token::IsCountOp(op));
1443
DECLARE_NODE_TYPE(IncrementOperation)
1445
Token::Value op() const { return op_; }
1446
bool is_increment() { return op_ == Token::INC; }
1447
Expression* expression() const { return expression_; }
1451
Expression* expression_;
1456
1383
class CountOperation: public Expression {
1458
CountOperation(bool is_prefix, IncrementOperation* increment, int pos)
1459
: is_prefix_(is_prefix), increment_(increment), pos_(pos),
1460
assignment_id_(GetNextId()) {
1385
CountOperation(Isolate* isolate,
1390
: Expression(isolate),
1392
is_prefix_(is_prefix),
1395
assignment_id_(GetNextId(isolate)),
1396
count_id_(GetNextId(isolate)) {}
1463
1398
DECLARE_NODE_TYPE(CountOperation)
1465
1400
bool is_prefix() const { return is_prefix_; }
1466
1401
bool is_postfix() const { return !is_prefix_; }
1468
Token::Value op() const { return increment_->op(); }
1403
Token::Value op() const { return op_; }
1469
1404
Token::Value binary_op() {
1470
1405
return (op() == Token::INC) ? Token::ADD : Token::SUB;
1473
Expression* expression() const { return increment_->expression(); }
1474
IncrementOperation* increment() const { return increment_; }
1475
int position() const { return pos_; }
1408
Expression* expression() const { return expression_; }
1409
virtual int position() const { return pos_; }
1477
1411
virtual void MarkAsStatement() { is_prefix_ = true; }
1479
1413
virtual bool IsInlineable() const;
1415
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1416
virtual bool IsMonomorphic() { return is_monomorphic_; }
1417
virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1481
1419
// Bailout support.
1482
1420
int AssignmentId() const { return assignment_id_; }
1421
int CountId() const { return count_id_; }
1485
1425
bool is_prefix_;
1486
IncrementOperation* increment_;
1426
bool is_monomorphic_;
1427
Expression* expression_;
1488
1429
int assignment_id_;
1431
SmallMapList receiver_types_;
1492
1435
class CompareOperation: public Expression {
1494
CompareOperation(Token::Value op,
1437
CompareOperation(Isolate* isolate,
1495
1439
Expression* left,
1496
1440
Expression* right,
1498
: op_(op), left_(left), right_(right), pos_(pos), compare_type_(NONE) {
1442
: Expression(isolate),
1447
compare_type_(NONE) {
1499
1448
ASSERT(Token::IsCompareOp(op));
1546
1499
class Conditional: public Expression {
1548
Conditional(Expression* condition,
1501
Conditional(Isolate* isolate,
1502
Expression* condition,
1549
1503
Expression* then_expression,
1550
1504
Expression* else_expression,
1551
1505
int then_expression_position,
1552
1506
int else_expression_position)
1553
: condition_(condition),
1507
: Expression(isolate),
1508
condition_(condition),
1554
1509
then_expression_(then_expression),
1555
1510
else_expression_(else_expression),
1556
1511
then_expression_position_(then_expression_position),
1557
1512
else_expression_position_(else_expression_position),
1558
then_id_(GetNextId()),
1559
else_id_(GetNextId()) {
1513
then_id_(GetNextId(isolate)),
1514
else_id_(GetNextId(isolate)) {
1562
1517
DECLARE_NODE_TYPE(Conditional)
1639
1595
bool block_end_;
1641
1597
bool is_monomorphic_;
1642
ZoneMapList* receiver_types_;
1643
Handle<Map> monomorphic_receiver_type_;
1598
SmallMapList receiver_types_;
1647
1602
class Throw: public Expression {
1649
Throw(Expression* exception, int pos)
1650
: exception_(exception), pos_(pos) {}
1604
Throw(Isolate* isolate, Expression* exception, int pos)
1605
: Expression(isolate), exception_(exception), pos_(pos) {}
1652
1607
DECLARE_NODE_TYPE(Throw)
1654
1609
Expression* exception() const { return exception_; }
1655
int position() const { return pos_; }
1610
virtual int position() const { return pos_; }
1611
virtual bool IsInlineable() const;
1658
1614
Expression* exception_;
1686
1649
num_parameters_(num_parameters),
1687
1650
start_position_(start_position),
1688
1651
end_position_(end_position),
1689
is_expression_(is_expression),
1690
contains_loops_(contains_loops),
1691
strict_mode_(strict_mode),
1692
1652
function_token_position_(RelocInfo::kNoPosition),
1693
inferred_name_(Heap::empty_string()),
1694
try_full_codegen_(false),
1695
pretenure_(false) { }
1653
inferred_name_(HEAP->empty_string()),
1654
is_expression_(type != DECLARATION),
1655
is_anonymous_(type == ANONYMOUS_EXPRESSION),
1657
has_duplicate_parameters_(has_duplicate_parameters) {
1697
1660
DECLARE_NODE_TYPE(FunctionLiteral)
1746
1709
int num_parameters_;
1747
1710
int start_position_;
1748
1711
int end_position_;
1749
bool is_expression_;
1750
bool contains_loops_;
1752
1712
int function_token_position_;
1753
1713
Handle<String> inferred_name_;
1754
bool try_full_codegen_;
1714
bool is_expression_;
1755
1716
bool pretenure_;
1717
bool has_duplicate_parameters_;
1759
1721
class SharedFunctionInfoLiteral: public Expression {
1761
explicit SharedFunctionInfoLiteral(
1723
SharedFunctionInfoLiteral(
1762
1725
Handle<SharedFunctionInfo> shared_function_info)
1763
: shared_function_info_(shared_function_info) { }
1726
: Expression(isolate), shared_function_info_(shared_function_info) { }
1765
1728
DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
1767
1730
Handle<SharedFunctionInfo> shared_function_info() const {
1768
1731
return shared_function_info_;
1733
virtual bool IsInlineable() const;
1772
1736
Handle<SharedFunctionInfo> shared_function_info_;