OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/ast/ast.h" | 5 #include "src/ast/ast.h" |
6 | 6 |
7 #include <cmath> // For isfinite. | 7 #include <cmath> // For isfinite. |
8 | 8 |
9 #include "src/ast/prettyprinter.h" | 9 #include "src/ast/prettyprinter.h" |
10 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
11 #include "src/base/hashmap.h" | 11 #include "src/base/hashmap.h" |
12 #include "src/builtins.h" | 12 #include "src/builtins.h" |
13 #include "src/code-stubs.h" | 13 #include "src/code-stubs.h" |
14 #include "src/contexts.h" | 14 #include "src/contexts.h" |
15 #include "src/conversions.h" | 15 #include "src/conversions.h" |
16 #include "src/parsing/parser.h" | 16 #include "src/parsing/parser.h" |
17 #include "src/property-details.h" | 17 #include "src/property-details.h" |
18 #include "src/property.h" | 18 #include "src/property.h" |
19 #include "src/string-stream.h" | 19 #include "src/string-stream.h" |
20 #include "src/type-info.h" | 20 #include "src/type-info.h" |
21 | 21 |
22 namespace v8 { | 22 namespace v8 { |
23 namespace internal { | 23 namespace internal { |
24 | 24 |
25 // ---------------------------------------------------------------------------- | 25 // ---------------------------------------------------------------------------- |
26 // All the Accept member functions for each syntax tree node type. | |
27 | |
28 #define DECL_ACCEPT(type) \ | |
29 void type::Accept(AstVisitor* v) { v->Visit##type(this); } | |
30 AST_NODE_LIST(DECL_ACCEPT) | |
31 #undef DECL_ACCEPT | |
32 | |
33 | |
34 // ---------------------------------------------------------------------------- | |
35 // Implementation of other node functionality. | 26 // Implementation of other node functionality. |
36 | 27 |
37 #ifdef DEBUG | 28 #ifdef DEBUG |
38 | 29 |
39 void AstNode::Print(Isolate* isolate) { | 30 void AstNode::Print(Isolate* isolate) { |
40 AstPrinter::PrintOut(isolate, this); | 31 AstPrinter::PrintOut(isolate, this); |
41 } | 32 } |
42 | 33 |
43 | 34 |
44 void AstNode::PrettyPrint(Isolate* isolate) { | 35 void AstNode::PrettyPrint(Isolate* isolate) { |
45 PrettyPrinter::PrintOut(isolate, this); | 36 PrettyPrinter::PrintOut(isolate, this); |
46 } | 37 } |
47 | 38 |
48 #endif // DEBUG | 39 #endif // DEBUG |
49 | 40 |
41 #define RETURN_NODE(Node) \ | |
Igor Sheludko
2016/07/14 16:39:54
This and below changes should have already been in
Toon Verwaest
2016/07/15 07:07:19
Acknowledged.
| |
42 case k##Node: \ | |
43 return reinterpret_cast<Node*>(this); | |
44 | |
50 IterationStatement* AstNode::AsIterationStatement() { | 45 IterationStatement* AstNode::AsIterationStatement() { |
51 #define TEST_ITERATION(Name) \ | 46 switch (node_type()) { |
52 if (Is##Name()) return As##Name(); | 47 ITERATION_NODE_LIST(RETURN_NODE); |
53 ITERATION_NODE_LIST(TEST_ITERATION) | 48 default: |
54 #undef TEST_ITERATION | 49 return nullptr; |
55 return nullptr; | 50 } |
56 } | 51 } |
57 | 52 |
58 BreakableStatement* AstNode::AsBreakableStatement() { | 53 BreakableStatement* AstNode::AsBreakableStatement() { |
59 #define TEST_BREAKABLE(Name) \ | 54 switch (node_type()) { |
60 if (Is##Name()) return As##Name(); | 55 BREAKABLE_NODE_LIST(RETURN_NODE); |
61 BREAKABLE_NODE_LIST(TEST_BREAKABLE) | 56 ITERATION_NODE_LIST(RETURN_NODE); |
62 #undef TEST_BREAKABLE | 57 default: |
63 return AsIterationStatement(); | 58 return nullptr; |
59 } | |
64 } | 60 } |
65 | 61 |
66 MaterializedLiteral* AstNode::AsMaterializedLiteral() { | 62 MaterializedLiteral* AstNode::AsMaterializedLiteral() { |
67 #define TEST_LITERAL(Name) \ | 63 switch (node_type()) { |
68 if (Is##Name()) return As##Name(); | 64 LITERAL_NODE_LIST(RETURN_NODE); |
69 LITERAL_NODE_LIST(TEST_LITERAL) | 65 default: |
70 #undef TEST_LITERAL | 66 return nullptr; |
71 return nullptr; | 67 } |
72 } | 68 } |
73 | 69 |
70 #undef RETURN_NODE | |
71 | |
74 InitializationFlag Declaration::initialization() const { | 72 InitializationFlag Declaration::initialization() const { |
75 switch (node_type()) { | 73 switch (node_type()) { |
76 #define GENERATE_CASE(Name) \ | 74 #define GENERATE_CASE(Node) \ |
77 case k##Name: \ | 75 case k##Node: \ |
78 return reinterpret_cast<const Name*>(this)->initialization(); | 76 return reinterpret_cast<const Node*>(this)->initialization(); |
79 DECLARATION_NODE_LIST(GENERATE_CASE); | 77 DECLARATION_NODE_LIST(GENERATE_CASE); |
80 #undef GENERATE_CASE | 78 #undef GENERATE_CASE |
81 default: | 79 default: |
82 UNREACHABLE(); | 80 UNREACHABLE(); |
83 return kNeedsInitialization; | 81 return kNeedsInitialization; |
84 } | 82 } |
85 } | 83 } |
86 | 84 |
87 bool Expression::IsSmiLiteral() const { | 85 bool Expression::IsSmiLiteral() const { |
88 return IsLiteral() && AsLiteral()->value()->IsSmi(); | 86 return IsLiteral() && AsLiteral()->value()->IsSmi(); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
159 | 157 |
160 bool Statement::IsJump() const { | 158 bool Statement::IsJump() const { |
161 return (IsBlock() && AsBlock()->IsJump()) || | 159 return (IsBlock() && AsBlock()->IsJump()) || |
162 (IsExpressionStatement() && AsExpressionStatement()->IsJump()) || | 160 (IsExpressionStatement() && AsExpressionStatement()->IsJump()) || |
163 IsContinueStatement() || IsBreakStatement() || IsReturnStatement() || | 161 IsContinueStatement() || IsBreakStatement() || IsReturnStatement() || |
164 (IsIfStatement() && AsIfStatement()->IsJump()); | 162 (IsIfStatement() && AsIfStatement()->IsJump()); |
165 } | 163 } |
166 | 164 |
167 VariableProxy::VariableProxy(Zone* zone, Variable* var, int start_position, | 165 VariableProxy::VariableProxy(Zone* zone, Variable* var, int start_position, |
168 int end_position) | 166 int end_position) |
169 : Expression(zone, start_position), | 167 : Expression(zone, start_position, kVariableProxy), |
170 bit_field_(IsThisField::encode(var->is_this()) | | 168 bit_field_(IsThisField::encode(var->is_this()) | |
171 IsAssignedField::encode(false) | | 169 IsAssignedField::encode(false) | |
172 IsResolvedField::encode(false)), | 170 IsResolvedField::encode(false)), |
173 raw_name_(var->raw_name()), | 171 raw_name_(var->raw_name()), |
174 end_position_(end_position) { | 172 end_position_(end_position) { |
175 BindTo(var); | 173 BindTo(var); |
176 } | 174 } |
177 | 175 |
178 | |
179 VariableProxy::VariableProxy(Zone* zone, const AstRawString* name, | 176 VariableProxy::VariableProxy(Zone* zone, const AstRawString* name, |
180 Variable::Kind variable_kind, int start_position, | 177 Variable::Kind variable_kind, int start_position, |
181 int end_position) | 178 int end_position) |
182 : Expression(zone, start_position), | 179 : Expression(zone, start_position, kVariableProxy), |
183 bit_field_(IsThisField::encode(variable_kind == Variable::THIS) | | 180 bit_field_(IsThisField::encode(variable_kind == Variable::THIS) | |
184 IsAssignedField::encode(false) | | 181 IsAssignedField::encode(false) | |
185 IsResolvedField::encode(false)), | 182 IsResolvedField::encode(false)), |
186 raw_name_(name), | 183 raw_name_(name), |
187 end_position_(end_position) {} | 184 end_position_(end_position) {} |
188 | 185 |
189 | |
190 void VariableProxy::BindTo(Variable* var) { | 186 void VariableProxy::BindTo(Variable* var) { |
191 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name()); | 187 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name()); |
192 set_var(var); | 188 set_var(var); |
193 set_is_resolved(); | 189 set_is_resolved(); |
194 var->set_is_used(); | 190 var->set_is_used(); |
195 } | 191 } |
196 | 192 |
197 | 193 |
198 void VariableProxy::AssignFeedbackVectorSlots(Isolate* isolate, | 194 void VariableProxy::AssignFeedbackVectorSlots(Isolate* isolate, |
199 FeedbackVectorSpec* spec, | 195 FeedbackVectorSpec* spec, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 } | 228 } |
233 } | 229 } |
234 | 230 |
235 void ForInStatement::AssignFeedbackVectorSlots(Isolate* isolate, | 231 void ForInStatement::AssignFeedbackVectorSlots(Isolate* isolate, |
236 FeedbackVectorSpec* spec, | 232 FeedbackVectorSpec* spec, |
237 FeedbackVectorSlotCache* cache) { | 233 FeedbackVectorSlotCache* cache) { |
238 AssignVectorSlots(each(), spec, &each_slot_); | 234 AssignVectorSlots(each(), spec, &each_slot_); |
239 for_in_feedback_slot_ = spec->AddGeneralSlot(); | 235 for_in_feedback_slot_ = spec->AddGeneralSlot(); |
240 } | 236 } |
241 | 237 |
242 | |
243 Assignment::Assignment(Zone* zone, Token::Value op, Expression* target, | 238 Assignment::Assignment(Zone* zone, Token::Value op, Expression* target, |
244 Expression* value, int pos) | 239 Expression* value, int pos) |
245 : Expression(zone, pos), | 240 : Expression(zone, pos, kAssignment), |
246 bit_field_( | 241 bit_field_( |
247 IsUninitializedField::encode(false) | KeyTypeField::encode(ELEMENT) | | 242 IsUninitializedField::encode(false) | KeyTypeField::encode(ELEMENT) | |
248 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)), | 243 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)), |
249 target_(target), | 244 target_(target), |
250 value_(value), | 245 value_(value), |
251 binary_operation_(NULL) {} | 246 binary_operation_(NULL) {} |
252 | 247 |
253 | |
254 void Assignment::AssignFeedbackVectorSlots(Isolate* isolate, | 248 void Assignment::AssignFeedbackVectorSlots(Isolate* isolate, |
255 FeedbackVectorSpec* spec, | 249 FeedbackVectorSpec* spec, |
256 FeedbackVectorSlotCache* cache) { | 250 FeedbackVectorSlotCache* cache) { |
257 AssignVectorSlots(target(), spec, &slot_); | 251 AssignVectorSlots(target(), spec, &slot_); |
258 } | 252 } |
259 | 253 |
260 | 254 |
261 void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate, | 255 void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate, |
262 FeedbackVectorSpec* spec, | 256 FeedbackVectorSpec* spec, |
263 FeedbackVectorSlotCache* cache) { | 257 FeedbackVectorSlotCache* cache) { |
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
852 } else { | 846 } else { |
853 return is_super ? KEYED_SUPER_PROPERTY_CALL : KEYED_PROPERTY_CALL; | 847 return is_super ? KEYED_SUPER_PROPERTY_CALL : KEYED_PROPERTY_CALL; |
854 } | 848 } |
855 } | 849 } |
856 | 850 |
857 return OTHER_CALL; | 851 return OTHER_CALL; |
858 } | 852 } |
859 | 853 |
860 | 854 |
861 // ---------------------------------------------------------------------------- | 855 // ---------------------------------------------------------------------------- |
862 // Implementation of AstVisitor | |
863 | |
864 void AstVisitor::VisitDeclarations(ZoneList<Declaration*>* declarations) { | |
865 for (int i = 0; i < declarations->length(); i++) { | |
866 Visit(declarations->at(i)); | |
867 } | |
868 } | |
869 | |
870 | |
871 void AstVisitor::VisitStatements(ZoneList<Statement*>* statements) { | |
872 for (int i = 0; i < statements->length(); i++) { | |
873 Statement* stmt = statements->at(i); | |
874 Visit(stmt); | |
875 if (stmt->IsJump()) break; | |
876 } | |
877 } | |
878 | |
879 | |
880 void AstVisitor::VisitExpressions(ZoneList<Expression*>* expressions) { | |
881 for (int i = 0; i < expressions->length(); i++) { | |
882 // The variable statement visiting code may pass NULL expressions | |
883 // to this code. Maybe this should be handled by introducing an | |
884 // undefined expression or literal? Revisit this code if this | |
885 // changes | |
886 Expression* expression = expressions->at(i); | |
887 if (expression != NULL) Visit(expression); | |
888 } | |
889 } | |
890 | |
891 // ---------------------------------------------------------------------------- | |
892 // Implementation of AstTraversalVisitor | 856 // Implementation of AstTraversalVisitor |
893 | 857 |
894 #define RECURSE(call) \ | 858 #define RECURSE(call) \ |
895 do { \ | 859 do { \ |
896 DCHECK(!HasStackOverflow()); \ | 860 DCHECK(!HasStackOverflow()); \ |
897 call; \ | 861 call; \ |
898 if (HasStackOverflow()) return; \ | 862 if (HasStackOverflow()) return; \ |
899 } while (false) | 863 } while (false) |
900 | 864 |
901 #define RECURSE_EXPRESSION(call) \ | 865 #define RECURSE_EXPRESSION(call) \ |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1184 void AstTraversalVisitor::VisitRewritableExpression( | 1148 void AstTraversalVisitor::VisitRewritableExpression( |
1185 RewritableExpression* expr) { | 1149 RewritableExpression* expr) { |
1186 RECURSE(Visit(expr->expression())); | 1150 RECURSE(Visit(expr->expression())); |
1187 } | 1151 } |
1188 | 1152 |
1189 #undef RECURSE_EXPRESSION | 1153 #undef RECURSE_EXPRESSION |
1190 #undef RECURSE | 1154 #undef RECURSE |
1191 | 1155 |
1192 CaseClause::CaseClause(Zone* zone, Expression* label, | 1156 CaseClause::CaseClause(Zone* zone, Expression* label, |
1193 ZoneList<Statement*>* statements, int pos) | 1157 ZoneList<Statement*>* statements, int pos) |
1194 : Expression(zone, pos), | 1158 : Expression(zone, pos, kCaseClause), |
1195 label_(label), | 1159 label_(label), |
1196 statements_(statements), | 1160 statements_(statements), |
1197 compare_type_(Type::None()) {} | 1161 compare_type_(Type::None()) {} |
1198 | 1162 |
1199 uint32_t Literal::Hash() { | 1163 uint32_t Literal::Hash() { |
1200 return raw_value()->IsString() | 1164 return raw_value()->IsString() |
1201 ? raw_value()->AsString()->hash() | 1165 ? raw_value()->AsString()->hash() |
1202 : ComputeLongHash(double_to_uint64(raw_value()->AsNumber())); | 1166 : ComputeLongHash(double_to_uint64(raw_value()->AsNumber())); |
1203 } | 1167 } |
1204 | 1168 |
1205 | 1169 |
1206 // static | 1170 // static |
1207 bool Literal::Match(void* literal1, void* literal2) { | 1171 bool Literal::Match(void* literal1, void* literal2) { |
1208 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); | 1172 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); |
1209 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); | 1173 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); |
1210 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || | 1174 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || |
1211 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); | 1175 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); |
1212 } | 1176 } |
1213 | 1177 |
1214 | 1178 |
1215 } // namespace internal | 1179 } // namespace internal |
1216 } // namespace v8 | 1180 } // namespace v8 |
OLD | NEW |