Chromium Code Reviews| 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 #ifndef V8_PARSER_H_ | 5 #ifndef V8_PARSER_H_ |
| 6 #define V8_PARSER_H_ | 6 #define V8_PARSER_H_ |
| 7 | 7 |
| 8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
| 9 #include "src/ast.h" | 9 #include "src/ast.h" |
| 10 #include "src/compiler.h" // TODO(titzer): remove this include dependency | 10 #include "src/compiler.h" // TODO(titzer): remove this include dependency |
| (...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 881 V8_INLINE ZoneList<v8::internal::Expression*>* PrepareSpreadArguments( | 881 V8_INLINE ZoneList<v8::internal::Expression*>* PrepareSpreadArguments( |
| 882 ZoneList<v8::internal::Expression*>* list); | 882 ZoneList<v8::internal::Expression*>* list); |
| 883 V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) {} | 883 V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) {} |
| 884 V8_INLINE Expression* SpreadCall(Expression* function, | 884 V8_INLINE Expression* SpreadCall(Expression* function, |
| 885 ZoneList<v8::internal::Expression*>* args, | 885 ZoneList<v8::internal::Expression*>* args, |
| 886 int pos); | 886 int pos); |
| 887 V8_INLINE Expression* SpreadCallNew(Expression* function, | 887 V8_INLINE Expression* SpreadCallNew(Expression* function, |
| 888 ZoneList<v8::internal::Expression*>* args, | 888 ZoneList<v8::internal::Expression*>* args, |
| 889 int pos); | 889 int pos); |
| 890 | 890 |
| 891 // Rewrite all DestructuringAssignments in the current FunctionState. | |
| 892 V8_INLINE void RewriteDestructuringAssignments(); | |
| 893 | |
| 894 V8_INLINE void ShouldRewriteDestructuringAssignment(Expression* assignment); | |
| 895 | |
| 891 private: | 896 private: |
| 892 Parser* parser_; | 897 Parser* parser_; |
| 893 }; | 898 }; |
| 894 | 899 |
| 895 | 900 |
| 896 class Parser : public ParserBase<ParserTraits> { | 901 class Parser : public ParserBase<ParserTraits> { |
| 897 public: | 902 public: |
| 898 explicit Parser(ParseInfo* info); | 903 explicit Parser(ParseInfo* info); |
| 899 ~Parser() { | 904 ~Parser() { |
| 900 delete reusable_preparser_; | 905 delete reusable_preparser_; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1028 Scanner::Location bindings_loc; | 1033 Scanner::Location bindings_loc; |
| 1029 }; | 1034 }; |
| 1030 | 1035 |
| 1031 class PatternRewriter : private AstVisitor { | 1036 class PatternRewriter : private AstVisitor { |
| 1032 public: | 1037 public: |
| 1033 static void DeclareAndInitializeVariables( | 1038 static void DeclareAndInitializeVariables( |
| 1034 Block* block, const DeclarationDescriptor* declaration_descriptor, | 1039 Block* block, const DeclarationDescriptor* declaration_descriptor, |
| 1035 const DeclarationParsingResult::Declaration* declaration, | 1040 const DeclarationParsingResult::Declaration* declaration, |
| 1036 ZoneList<const AstRawString*>* names, bool* ok); | 1041 ZoneList<const AstRawString*>* names, bool* ok); |
| 1037 | 1042 |
| 1043 static void RewriteDestructuringAssignment(Parser* parser, | |
| 1044 Assignment* assignment, | |
| 1045 Scope* Scope, bool* ok); | |
| 1046 | |
| 1038 void set_initializer_position(int pos) { initializer_position_ = pos; } | 1047 void set_initializer_position(int pos) { initializer_position_ = pos; } |
| 1039 | 1048 |
| 1040 private: | 1049 private: |
| 1041 PatternRewriter() {} | 1050 PatternRewriter() {} |
| 1042 | 1051 |
| 1043 #define DECLARE_VISIT(type) void Visit##type(v8::internal::type* node) override; | 1052 #define DECLARE_VISIT(type) void Visit##type(v8::internal::type* node) override; |
| 1044 // Visiting functions for AST nodes make this an AstVisitor. | 1053 // Visiting functions for AST nodes make this an AstVisitor. |
| 1045 AST_NODE_LIST(DECLARE_VISIT) | 1054 AST_NODE_LIST(DECLARE_VISIT) |
| 1046 #undef DECLARE_VISIT | 1055 #undef DECLARE_VISIT |
| 1047 void Visit(AstNode* node) override; | 1056 void Visit(AstNode* node) override; |
| 1048 | 1057 |
| 1058 enum PatternContext { | |
| 1059 BINDING, | |
| 1060 INITIALIZER, | |
| 1061 ASSIGNMENT, | |
| 1062 ASSIGNMENT_INITIALIZER | |
| 1063 }; | |
| 1064 | |
| 1065 PatternContext context() const { return context_; } | |
| 1066 void set_context(PatternContext context) { context_ = context; } | |
| 1067 | |
| 1049 void RecurseIntoSubpattern(AstNode* pattern, Expression* value) { | 1068 void RecurseIntoSubpattern(AstNode* pattern, Expression* value) { |
| 1050 Expression* old_value = current_value_; | 1069 Expression* old_value = current_value_; |
| 1051 current_value_ = value; | 1070 current_value_ = value; |
| 1052 pattern->Accept(this); | 1071 pattern->Accept(this); |
| 1053 current_value_ = old_value; | 1072 current_value_ = old_value; |
| 1054 } | 1073 } |
| 1055 | 1074 |
| 1075 void VisitObjectLiteral(ObjectLiteral* node, Variable** temp_var); | |
| 1076 void VisitArrayLiteral(ArrayLiteral* node, Variable** temp_var); | |
| 1077 | |
| 1078 bool IsBindingContext() const { return IsBindingContext(context_); } | |
| 1079 bool IsInitializerContext() const { return context_ != ASSIGNMENT; } | |
| 1080 bool IsAssignmentContext() const { return IsAssignmentContext(context_); } | |
| 1081 bool IsAssignmentContext(PatternContext c) const { | |
| 1082 return c == ASSIGNMENT || c == ASSIGNMENT_INITIALIZER; | |
| 1083 } | |
| 1084 bool IsBindingContext(PatternContext c) const { | |
| 1085 return c == BINDING || c == INITIALIZER; | |
| 1086 } | |
| 1087 PatternContext SetAssignmentContextIfNeeded(Expression* node) { | |
| 1088 PatternContext old_context = context(); | |
| 1089 if (node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN) { | |
| 1090 set_context(ASSIGNMENT); | |
| 1091 } | |
| 1092 return old_context; | |
| 1093 } | |
| 1094 | |
| 1095 PatternContext SetInitializerContextIfNeeded(Expression* node) { | |
|
adamk
2015/11/25 21:05:28
Any reason all of these functions need to be in th
caitp (gmail)
2015/11/25 21:41:51
No real reason, it was just convenient while writi
| |
| 1096 // Set appropriate initializer context for BindingElement and | |
| 1097 // AssignmentElement nodes | |
| 1098 PatternContext old_context = context(); | |
| 1099 if (node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN) { | |
| 1100 switch (old_context) { | |
| 1101 case BINDING: | |
| 1102 set_context(INITIALIZER); | |
| 1103 break; | |
| 1104 case ASSIGNMENT: | |
| 1105 set_context(ASSIGNMENT_INITIALIZER); | |
| 1106 break; | |
| 1107 default: | |
| 1108 break; | |
| 1109 } | |
| 1110 } | |
| 1111 return old_context; | |
| 1112 } | |
| 1113 | |
| 1056 Variable* CreateTempVar(Expression* value = nullptr); | 1114 Variable* CreateTempVar(Expression* value = nullptr); |
| 1057 | 1115 |
| 1058 AstNodeFactory* factory() const { return descriptor_->parser->factory(); } | 1116 AstNodeFactory* factory() const { return parser_->factory(); } |
| 1059 AstValueFactory* ast_value_factory() const { | 1117 AstValueFactory* ast_value_factory() const { |
| 1060 return descriptor_->parser->ast_value_factory(); | 1118 return parser_->ast_value_factory(); |
| 1061 } | 1119 } |
| 1062 Zone* zone() const { return descriptor_->parser->zone(); } | 1120 Zone* zone() const { return parser_->zone(); } |
| 1121 Scope* scope() const { return scope_; } | |
| 1063 | 1122 |
| 1123 Scope* scope_; | |
| 1124 Parser* parser_; | |
| 1125 PatternContext context_; | |
| 1064 Expression* pattern_; | 1126 Expression* pattern_; |
| 1065 int initializer_position_; | 1127 int initializer_position_; |
| 1066 Block* block_; | 1128 Block* block_; |
| 1067 const DeclarationDescriptor* descriptor_; | 1129 const DeclarationDescriptor* descriptor_; |
| 1068 ZoneList<const AstRawString*>* names_; | 1130 ZoneList<const AstRawString*>* names_; |
| 1069 Expression* current_value_; | 1131 Expression* current_value_; |
| 1070 bool* ok_; | 1132 bool* ok_; |
| 1071 }; | 1133 }; |
| 1072 | 1134 |
| 1073 | 1135 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1203 ZoneList<v8::internal::Expression*>* PrepareSpreadArguments( | 1265 ZoneList<v8::internal::Expression*>* PrepareSpreadArguments( |
| 1204 ZoneList<v8::internal::Expression*>* list); | 1266 ZoneList<v8::internal::Expression*>* list); |
| 1205 Expression* SpreadCall(Expression* function, | 1267 Expression* SpreadCall(Expression* function, |
| 1206 ZoneList<v8::internal::Expression*>* args, int pos); | 1268 ZoneList<v8::internal::Expression*>* args, int pos); |
| 1207 Expression* SpreadCallNew(Expression* function, | 1269 Expression* SpreadCallNew(Expression* function, |
| 1208 ZoneList<v8::internal::Expression*>* args, int pos); | 1270 ZoneList<v8::internal::Expression*>* args, int pos); |
| 1209 | 1271 |
| 1210 void SetLanguageMode(Scope* scope, LanguageMode mode); | 1272 void SetLanguageMode(Scope* scope, LanguageMode mode); |
| 1211 void RaiseLanguageMode(LanguageMode mode); | 1273 void RaiseLanguageMode(LanguageMode mode); |
| 1212 | 1274 |
| 1275 V8_INLINE void RewriteDestructuringAssignments(); | |
| 1276 | |
| 1277 friend class InitializerRewriter; | |
| 1278 void RewriteParameterInitializer(Expression* expr, Scope* scope); | |
| 1279 | |
| 1213 Scanner scanner_; | 1280 Scanner scanner_; |
| 1214 PreParser* reusable_preparser_; | 1281 PreParser* reusable_preparser_; |
| 1215 Scope* original_scope_; // for ES5 function declarations in sloppy eval | 1282 Scope* original_scope_; // for ES5 function declarations in sloppy eval |
| 1216 Target* target_stack_; // for break, continue statements | 1283 Target* target_stack_; // for break, continue statements |
| 1217 ScriptCompiler::CompileOptions compile_options_; | 1284 ScriptCompiler::CompileOptions compile_options_; |
| 1218 ParseData* cached_parse_data_; | 1285 ParseData* cached_parse_data_; |
| 1219 | 1286 |
| 1220 PendingCompilationErrorHandler pending_error_handler_; | 1287 PendingCompilationErrorHandler pending_error_handler_; |
| 1221 | 1288 |
| 1222 // Other information which will be stored in Parser and moved to Isolate after | 1289 // Other information which will be stored in Parser and moved to Isolate after |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1391 } | 1458 } |
| 1392 } | 1459 } |
| 1393 } | 1460 } |
| 1394 | 1461 |
| 1395 | 1462 |
| 1396 DoExpression* ParserTraits::ParseDoExpression(bool* ok) { | 1463 DoExpression* ParserTraits::ParseDoExpression(bool* ok) { |
| 1397 return parser_->ParseDoExpression(ok); | 1464 return parser_->ParseDoExpression(ok); |
| 1398 } | 1465 } |
| 1399 | 1466 |
| 1400 | 1467 |
| 1468 void ParserTraits::RewriteDestructuringAssignments() { | |
| 1469 parser_->RewriteDestructuringAssignments(); | |
| 1470 } | |
| 1471 | |
| 1472 | |
| 1473 void Parser::RewriteDestructuringAssignments() { | |
|
adamk
2015/11/25 21:05:28
Another "why is this in the header?" question.
| |
| 1474 FunctionState* func = function_state_; | |
| 1475 if (!allow_harmony_destructuring_assignment()) return; | |
| 1476 typedef typename ParserBase<ParserTraits>::DestructuringAssignment Pair; | |
| 1477 const List<Pair>& assignments = func->destructuring_assignments_to_rewrite(); | |
| 1478 for (int i = assignments.length() - 1; i >= 0; --i) { | |
| 1479 // Rewrite list in reverse, so that nested assignment patterns are rewritten | |
| 1480 // correctly. | |
| 1481 Pair pair = assignments.at(i); | |
| 1482 Assignment* to_rewrite = pair.assignment->AsAssignment(); | |
| 1483 Scope* scope = pair.scope; | |
| 1484 DCHECK_NOT_NULL(to_rewrite); | |
| 1485 DCHECK(to_rewrite->is_destructuring_assignment()); | |
| 1486 if (!to_rewrite->destructuring_assignment()) { | |
| 1487 bool ok = true; | |
| 1488 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope, | |
| 1489 &ok); | |
| 1490 DCHECK(ok); | |
| 1491 } | |
| 1492 } | |
| 1493 } | |
| 1494 | |
| 1495 | |
| 1496 void ParserTraits::ShouldRewriteDestructuringAssignment(Expression* expr) { | |
|
adamk
2015/11/25 21:05:28
And here...
Also, as mentioned before, this name
caitp (gmail)
2015/11/25 21:41:51
Acknowledged.
| |
| 1497 DCHECK(expr->IsAssignment()); | |
| 1498 Assignment* assignment = expr->AsAssignment(); | |
| 1499 DCHECK(!assignment->is_destructuring_assignment()); | |
| 1500 DCHECK_EQ(Token::ASSIGN, assignment->op()); | |
| 1501 assignment->set_is_destructuring_assignment(); | |
| 1502 parser_->function_state_->AddDestructuringAssignment( | |
| 1503 Parser::DestructuringAssignment(assignment, parser_->scope_)); | |
| 1504 } | |
| 1505 | |
| 1506 inline void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) { | |
|
adamk
2015/11/25 21:05:28
And here and the below. parser.h is long enough as
| |
| 1507 Variable* temp_var = nullptr; | |
| 1508 VisitObjectLiteral(node, &temp_var); | |
| 1509 } | |
| 1510 | |
| 1511 inline void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { | |
| 1512 Variable* temp_var = nullptr; | |
| 1513 VisitArrayLiteral(node, &temp_var); | |
| 1514 } | |
| 1515 | |
| 1401 } // namespace internal | 1516 } // namespace internal |
| 1402 } // namespace v8 | 1517 } // namespace v8 |
| 1403 | 1518 |
| 1404 #endif // V8_PARSER_H_ | 1519 #endif // V8_PARSER_H_ |
| OLD | NEW |