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

Side by Side Diff: src/parser.cc

Issue 1066933005: Use ExpressionClassifier for bindings. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 months 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
« no previous file with comments | « no previous file | src/preparser.h » ('j') | src/preparser.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 if (ok) ok = Check(Token::RPAREN); 1138 if (ok) ok = Check(Token::RPAREN);
1139 } else { 1139 } else {
1140 // BindingIdentifier 1140 // BindingIdentifier
1141 ParseFormalParameter(scope, &error_locs, has_rest, &ok); 1141 ParseFormalParameter(scope, &error_locs, has_rest, &ok);
1142 } 1142 }
1143 1143
1144 if (ok) { 1144 if (ok) {
1145 ExpressionClassifier classifier; 1145 ExpressionClassifier classifier;
1146 Expression* expression = ParseArrowFunctionLiteral( 1146 Expression* expression = ParseArrowFunctionLiteral(
1147 scope, error_locs, has_rest, &classifier, &ok); 1147 scope, error_locs, has_rest, &classifier, &ok);
1148 // TODO(dslomov): report error if not a valid expression. 1148 ValidateExpression(&classifier, &ok);
1149 if (ok) { 1149 if (ok) {
1150 // Scanning must end at the same position that was recorded 1150 // Scanning must end at the same position that was recorded
1151 // previously. If not, parsing has been interrupted due to a stack 1151 // previously. If not, parsing has been interrupted due to a stack
1152 // overflow, at which point the partially parsed arrow function 1152 // overflow, at which point the partially parsed arrow function
1153 // concise body happens to be a valid expression. This is a problem 1153 // concise body happens to be a valid expression. This is a problem
1154 // only for arrow functions with single expression bodies, since there 1154 // only for arrow functions with single expression bodies, since there
1155 // is no end token such as "}" for normal functions. 1155 // is no end token such as "}" for normal functions.
1156 if (scanner()->location().end_pos == shared_info->end_position()) { 1156 if (scanner()->location().end_pos == shared_info->end_position()) {
1157 // The pre-parser saw an arrow function here, so the full parser 1157 // The pre-parser saw an arrow function here, so the full parser
1158 // must produce a FunctionLiteral. 1158 // must produce a FunctionLiteral.
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
1600 1600
1601 case Token::CLASS: 1601 case Token::CLASS:
1602 // TODO(ES6): Support parsing anonymous class declarations here. 1602 // TODO(ES6): Support parsing anonymous class declarations here.
1603 result = ParseClassDeclaration(&names, CHECK_OK); 1603 result = ParseClassDeclaration(&names, CHECK_OK);
1604 break; 1604 break;
1605 1605
1606 default: { 1606 default: {
1607 int pos = peek_position(); 1607 int pos = peek_position();
1608 ExpressionClassifier classifier; 1608 ExpressionClassifier classifier;
1609 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); 1609 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK);
1610 // TODO(dslomov): report error if not a valid expression. 1610 ValidateExpression(&classifier, CHECK_OK);
1611 1611
1612 ExpectSemicolon(CHECK_OK); 1612 ExpectSemicolon(CHECK_OK);
1613 result = factory()->NewExpressionStatement(expr, pos); 1613 result = factory()->NewExpressionStatement(expr, pos);
1614 break; 1614 break;
1615 } 1615 }
1616 } 1616 }
1617 1617
1618 const AstRawString* default_string = ast_value_factory()->default_string(); 1618 const AstRawString* default_string = ast_value_factory()->default_string();
1619 1619
1620 DCHECK_LE(names.length(), 1); 1620 DCHECK_LE(names.length(), 1);
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
2356 int nvars = 0; // the number of variables declared 2356 int nvars = 0; // the number of variables declared
2357 int bindings_start = peek_position(); 2357 int bindings_start = peek_position();
2358 const AstRawString* name = NULL; 2358 const AstRawString* name = NULL;
2359 const AstRawString* first_name = NULL; 2359 const AstRawString* first_name = NULL;
2360 bool is_for_iteration_variable; 2360 bool is_for_iteration_variable;
2361 do { 2361 do {
2362 if (fni_ != NULL) fni_->Enter(); 2362 if (fni_ != NULL) fni_->Enter();
2363 2363
2364 // Parse variable name. 2364 // Parse variable name.
2365 if (nvars > 0) Consume(Token::COMMA); 2365 if (nvars > 0) Consume(Token::COMMA);
2366 name = ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); 2366
2367 {
2368 ExpressionClassifier pattern_classifier;
2369 Token::Value next = peek();
2370 Expression* pattern =
2371 ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
2372 ValidateBindingPattern(&pattern_classifier, CHECK_OK);
2373 if (pattern->IsVariableProxy() &&
2374 pattern->AsVariableProxy()->IsValidReferenceExpression()) {
2375 scope_->RemoveUnresolved(pattern->AsVariableProxy());
Dmitry Lomov (no reviews) 2015/04/23 16:29:24 Here, instead of adding an unresolved proxy and th
arv (Not doing code reviews) 2015/04/23 16:52:52 I like this better. I doubt it matters for perform
2376 name = pattern->AsVariableProxy()->raw_name();
2377 } else {
2378 ReportUnexpectedToken(next);
2379 *ok = false;
2380 return nullptr;
2381 }
2382 }
2383
2367 if (!first_name) first_name = name; 2384 if (!first_name) first_name = name;
2368 Scanner::Location variable_loc = scanner()->location(); 2385 Scanner::Location variable_loc = scanner()->location();
2369 if (fni_ != NULL) fni_->PushVariableName(name); 2386 if (fni_ != NULL) fni_->PushVariableName(name);
2370 2387
2371 // Declare variable. 2388 // Declare variable.
2372 // Note that we *always* must treat the initial value via a separate init 2389 // Note that we *always* must treat the initial value via a separate init
2373 // assignment for variables and constants because the value must be assigned 2390 // assignment for variables and constants because the value must be assigned
2374 // when the variable is encountered in the source. But the variable/constant 2391 // when the variable is encountered in the source. But the variable/constant
2375 // is declared (and set to 'undefined') upon entering the function within 2392 // is declared (and set to 'undefined') upon entering the function within
2376 // which the variable or constant is declared. Only function variables have 2393 // which the variable or constant is declared. Only function variables have
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2435 Expression* value = NULL; 2452 Expression* value = NULL;
2436 int pos = -1; 2453 int pos = -1;
2437 // Harmony consts have non-optional initializers. 2454 // Harmony consts have non-optional initializers.
2438 if (peek() == Token::ASSIGN || 2455 if (peek() == Token::ASSIGN ||
2439 (mode == CONST && !is_for_iteration_variable)) { 2456 (mode == CONST && !is_for_iteration_variable)) {
2440 Expect(Token::ASSIGN, CHECK_OK); 2457 Expect(Token::ASSIGN, CHECK_OK);
2441 pos = position(); 2458 pos = position();
2442 ExpressionClassifier classifier; 2459 ExpressionClassifier classifier;
2443 value = ParseAssignmentExpression(var_context != kForStatement, 2460 value = ParseAssignmentExpression(var_context != kForStatement,
2444 &classifier, CHECK_OK); 2461 &classifier, CHECK_OK);
2445 // TODO(dslomov): check that expression is valid. 2462 ValidateExpression(&classifier, CHECK_OK);
2446 variable_loc.end_pos = scanner()->location().end_pos; 2463 variable_loc.end_pos = scanner()->location().end_pos;
2447 2464
2448 if (first_initializer_loc && !first_initializer_loc->IsValid()) { 2465 if (first_initializer_loc && !first_initializer_loc->IsValid()) {
2449 *first_initializer_loc = variable_loc; 2466 *first_initializer_loc = variable_loc;
2450 } 2467 }
2451 2468
2452 // Don't infer if it is "a = function(){...}();"-like expression. 2469 // Don't infer if it is "a = function(){...}();"-like expression.
2453 if (fni_ != NULL && 2470 if (fni_ != NULL &&
2454 value->AsCall() == NULL && 2471 value->AsCall() == NULL &&
2455 value->AsCallNew() == NULL) { 2472 value->AsCallNew() == NULL) {
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
2626 if (is_strong(language_mode()) && 2643 if (is_strong(language_mode()) &&
2627 i::IsConstructor(function_state_->kind())) { 2644 i::IsConstructor(function_state_->kind())) {
2628 bool is_this = peek() == Token::THIS; 2645 bool is_this = peek() == Token::THIS;
2629 Expression* expr; 2646 Expression* expr;
2630 ExpressionClassifier classifier; 2647 ExpressionClassifier classifier;
2631 if (is_this) { 2648 if (is_this) {
2632 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK); 2649 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
2633 } else { 2650 } else {
2634 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK); 2651 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
2635 } 2652 }
2636 // TODO(dslomov): report error if not a valid expression. 2653 ValidateExpression(&classifier, CHECK_OK);
2637 switch (peek()) { 2654 switch (peek()) {
2638 case Token::SEMICOLON: 2655 case Token::SEMICOLON:
2639 Consume(Token::SEMICOLON); 2656 Consume(Token::SEMICOLON);
2640 break; 2657 break;
2641 case Token::RBRACE: 2658 case Token::RBRACE:
2642 case Token::EOS: 2659 case Token::EOS:
2643 break; 2660 break;
2644 default: 2661 default:
2645 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { 2662 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
2646 ReportMessageAt(function_state_->this_location(), 2663 ReportMessageAt(function_state_->this_location(),
(...skipping 1708 matching lines...) Expand 10 before | Expand all | Expand 10 after
4355 proxy, CONST, block_scope, pos, is_class_declaration, 4372 proxy, CONST, block_scope, pos, is_class_declaration,
4356 scope_->class_declaration_group_start()); 4373 scope_->class_declaration_group_start());
4357 Declare(declaration, true, CHECK_OK); 4374 Declare(declaration, true, CHECK_OK);
4358 } 4375 }
4359 4376
4360 Expression* extends = NULL; 4377 Expression* extends = NULL;
4361 if (Check(Token::EXTENDS)) { 4378 if (Check(Token::EXTENDS)) {
4362 block_scope->set_start_position(scanner()->location().end_pos); 4379 block_scope->set_start_position(scanner()->location().end_pos);
4363 ExpressionClassifier classifier; 4380 ExpressionClassifier classifier;
4364 extends = ParseLeftHandSideExpression(&classifier, CHECK_OK); 4381 extends = ParseLeftHandSideExpression(&classifier, CHECK_OK);
4365 // TODO(dslomov): report error if not a valid expression. 4382 ValidateExpression(&classifier, CHECK_OK);
4366 } else { 4383 } else {
4367 block_scope->set_start_position(scanner()->location().end_pos); 4384 block_scope->set_start_position(scanner()->location().end_pos);
4368 } 4385 }
4369 4386
4370 4387
4371 ClassLiteralChecker checker(this); 4388 ClassLiteralChecker checker(this);
4372 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); 4389 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
4373 FunctionLiteral* constructor = NULL; 4390 FunctionLiteral* constructor = NULL;
4374 bool has_seen_constructor = false; 4391 bool has_seen_constructor = false;
4375 4392
4376 Expect(Token::LBRACE, CHECK_OK); 4393 Expect(Token::LBRACE, CHECK_OK);
4377 4394
4378 const bool has_extends = extends != nullptr; 4395 const bool has_extends = extends != nullptr;
4379 while (peek() != Token::RBRACE) { 4396 while (peek() != Token::RBRACE) {
4380 if (Check(Token::SEMICOLON)) continue; 4397 if (Check(Token::SEMICOLON)) continue;
4381 if (fni_ != NULL) fni_->Enter(); 4398 if (fni_ != NULL) fni_->Enter();
4382 const bool in_class = true; 4399 const bool in_class = true;
4383 const bool is_static = false; 4400 const bool is_static = false;
4384 bool is_computed_name = false; // Classes do not care about computed 4401 bool is_computed_name = false; // Classes do not care about computed
4385 // property names here. 4402 // property names here.
4386 ExpressionClassifier classifier; 4403 ExpressionClassifier classifier;
4387 ObjectLiteral::Property* property = ParsePropertyDefinition( 4404 ObjectLiteral::Property* property = ParsePropertyDefinition(
4388 &checker, in_class, has_extends, is_static, &is_computed_name, 4405 &checker, in_class, has_extends, is_static, &is_computed_name,
4389 &has_seen_constructor, &classifier, CHECK_OK); 4406 &has_seen_constructor, &classifier, CHECK_OK);
4390 // TODO(dslomov): report error if not a valid expression. 4407 ValidateExpression(&classifier, CHECK_OK);
4391 4408
4392 if (has_seen_constructor && constructor == NULL) { 4409 if (has_seen_constructor && constructor == NULL) {
4393 constructor = GetPropertyValue(property)->AsFunctionLiteral(); 4410 constructor = GetPropertyValue(property)->AsFunctionLiteral();
4394 DCHECK_NOT_NULL(constructor); 4411 DCHECK_NOT_NULL(constructor);
4395 } else { 4412 } else {
4396 properties->Add(property, zone()); 4413 properties->Add(property, zone());
4397 } 4414 }
4398 4415
4399 if (fni_ != NULL) { 4416 if (fni_ != NULL) {
4400 fni_->Infer(); 4417 fni_->Infer();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4432 4449
4433 int pos = peek_position(); 4450 int pos = peek_position();
4434 Expect(Token::MOD, CHECK_OK); 4451 Expect(Token::MOD, CHECK_OK);
4435 // Allow "eval" or "arguments" for backward compatibility. 4452 // Allow "eval" or "arguments" for backward compatibility.
4436 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers, 4453 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers,
4437 CHECK_OK); 4454 CHECK_OK);
4438 Scanner::Location spread_pos; 4455 Scanner::Location spread_pos;
4439 ExpressionClassifier classifier; 4456 ExpressionClassifier classifier;
4440 ZoneList<Expression*>* args = 4457 ZoneList<Expression*>* args =
4441 ParseArguments(&spread_pos, &classifier, CHECK_OK); 4458 ParseArguments(&spread_pos, &classifier, CHECK_OK);
4442 // TODO(dslomov): report error if not a valid expression. 4459 ValidateExpression(&classifier, CHECK_OK);
4443 4460
4444 DCHECK(!spread_pos.IsValid()); 4461 DCHECK(!spread_pos.IsValid());
4445 4462
4446 if (extension_ != NULL) { 4463 if (extension_ != NULL) {
4447 // The extension structures are only accessible while parsing the 4464 // The extension structures are only accessible while parsing the
4448 // very first time not when reparsing because of lazy compilation. 4465 // very first time not when reparsing because of lazy compilation.
4449 scope_->DeclarationScope()->ForceEagerCompilation(); 4466 scope_->DeclarationScope()->ForceEagerCompilation();
4450 } 4467 }
4451 4468
4452 const Runtime::Function* function = Runtime::FunctionForName(name->string()); 4469 const Runtime::Function* function = Runtime::FunctionForName(name->string());
(...skipping 1356 matching lines...) Expand 10 before | Expand all | Expand 10 after
5809 5826
5810 Expression* Parser::SpreadCallNew(Expression* function, 5827 Expression* Parser::SpreadCallNew(Expression* function,
5811 ZoneList<v8::internal::Expression*>* args, 5828 ZoneList<v8::internal::Expression*>* args,
5812 int pos) { 5829 int pos) {
5813 args->InsertAt(0, function, zone()); 5830 args->InsertAt(0, function, zone());
5814 5831
5815 return factory()->NewCallRuntime( 5832 return factory()->NewCallRuntime(
5816 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5833 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5817 } 5834 }
5818 } } // namespace v8::internal 5835 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/preparser.h » ('j') | src/preparser.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698