Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: src/parser.h

Issue 1309813007: [es6] implement destructuring assignment (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Cache te right scope in DeclareAndInitializeVariables() Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698