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

Side by Side Diff: src/parser.cc

Issue 1065983005: Introduce "expression classifier" to the parser. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Added operator== and operator!= to Scanner::Location 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 | « src/flag-definitions.h ('k') | src/preparser.h » ('j') | no next file with comments »
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 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 if (Check(Token::LPAREN)) { 1139 if (Check(Token::LPAREN)) {
1140 // '(' StrictFormalParameters ')' 1140 // '(' StrictFormalParameters ')'
1141 ParseFormalParameterList(scope, &error_locs, &has_rest, &ok); 1141 ParseFormalParameterList(scope, &error_locs, &has_rest, &ok);
1142 if (ok) ok = Check(Token::RPAREN); 1142 if (ok) ok = Check(Token::RPAREN);
1143 } else { 1143 } else {
1144 // BindingIdentifier 1144 // BindingIdentifier
1145 ParseFormalParameter(scope, &error_locs, has_rest, &ok); 1145 ParseFormalParameter(scope, &error_locs, has_rest, &ok);
1146 } 1146 }
1147 1147
1148 if (ok) { 1148 if (ok) {
1149 Expression* expression = 1149 ExpressionClassifier classifier;
1150 ParseArrowFunctionLiteral(scope, error_locs, has_rest, &ok); 1150 Expression* expression = ParseArrowFunctionLiteral(
1151 scope, error_locs, has_rest, &classifier, &ok);
1152 // TODO(dslomov): report error if not a valid expression.
1151 if (ok) { 1153 if (ok) {
1152 // Scanning must end at the same position that was recorded 1154 // Scanning must end at the same position that was recorded
1153 // previously. If not, parsing has been interrupted due to a stack 1155 // previously. If not, parsing has been interrupted due to a stack
1154 // overflow, at which point the partially parsed arrow function 1156 // overflow, at which point the partially parsed arrow function
1155 // concise body happens to be a valid expression. This is a problem 1157 // concise body happens to be a valid expression. This is a problem
1156 // only for arrow functions with single expression bodies, since there 1158 // only for arrow functions with single expression bodies, since there
1157 // is no end token such as "}" for normal functions. 1159 // is no end token such as "}" for normal functions.
1158 if (scanner()->location().end_pos == shared_info->end_position()) { 1160 if (scanner()->location().end_pos == shared_info->end_position()) {
1159 // The pre-parser saw an arrow function here, so the full parser 1161 // The pre-parser saw an arrow function here, so the full parser
1160 // must produce a FunctionLiteral. 1162 // must produce a FunctionLiteral.
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
1607 result = ParseFunctionDeclaration(&names, CHECK_OK); 1609 result = ParseFunctionDeclaration(&names, CHECK_OK);
1608 break; 1610 break;
1609 1611
1610 case Token::CLASS: 1612 case Token::CLASS:
1611 // TODO(ES6): Support parsing anonymous class declarations here. 1613 // TODO(ES6): Support parsing anonymous class declarations here.
1612 result = ParseClassDeclaration(&names, CHECK_OK); 1614 result = ParseClassDeclaration(&names, CHECK_OK);
1613 break; 1615 break;
1614 1616
1615 default: { 1617 default: {
1616 int pos = peek_position(); 1618 int pos = peek_position();
1617 Expression* expr = ParseAssignmentExpression(true, CHECK_OK); 1619 ExpressionClassifier classifier;
1620 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK);
1621 // TODO(dslomov): report error if not a valid expression.
1622
1618 ExpectSemicolon(CHECK_OK); 1623 ExpectSemicolon(CHECK_OK);
1619 result = factory()->NewExpressionStatement(expr, pos); 1624 result = factory()->NewExpressionStatement(expr, pos);
1620 break; 1625 break;
1621 } 1626 }
1622 } 1627 }
1623 1628
1624 const AstRawString* default_string = ast_value_factory()->default_string(); 1629 const AstRawString* default_string = ast_value_factory()->default_string();
1625 1630
1626 DCHECK_LE(names.length(), 1); 1631 DCHECK_LE(names.length(), 1);
1627 if (names.length() == 1) { 1632 if (names.length() == 1) {
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after
2421 // Declare() call above). 2426 // Declare() call above).
2422 2427
2423 Scope* initialization_scope = is_const ? declaration_scope : scope_; 2428 Scope* initialization_scope = is_const ? declaration_scope : scope_;
2424 Expression* value = NULL; 2429 Expression* value = NULL;
2425 int pos = -1; 2430 int pos = -1;
2426 // Harmony consts have non-optional initializers. 2431 // Harmony consts have non-optional initializers.
2427 if (peek() == Token::ASSIGN || 2432 if (peek() == Token::ASSIGN ||
2428 (mode == CONST && !is_for_iteration_variable)) { 2433 (mode == CONST && !is_for_iteration_variable)) {
2429 Expect(Token::ASSIGN, CHECK_OK); 2434 Expect(Token::ASSIGN, CHECK_OK);
2430 pos = position(); 2435 pos = position();
2431 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 2436 ExpressionClassifier classifier;
2437 value = ParseAssignmentExpression(var_context != kForStatement,
2438 &classifier, CHECK_OK);
2439 // TODO(dslomov): check that expression is valid.
2432 variable_loc.end_pos = scanner()->location().end_pos; 2440 variable_loc.end_pos = scanner()->location().end_pos;
2433 2441
2434 if (first_initializer_loc && !first_initializer_loc->IsValid()) { 2442 if (first_initializer_loc && !first_initializer_loc->IsValid()) {
2435 *first_initializer_loc = variable_loc; 2443 *first_initializer_loc = variable_loc;
2436 } 2444 }
2437 2445
2438 // Don't infer if it is "a = function(){...}();"-like expression. 2446 // Don't infer if it is "a = function(){...}();"-like expression.
2439 if (fni_ != NULL && 2447 if (fni_ != NULL &&
2440 value->AsCall() == NULL && 2448 value->AsCall() == NULL &&
2441 value->AsCallNew() == NULL) { 2449 value->AsCallNew() == NULL) {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
2606 ReportUnexpectedToken(Next()); 2614 ReportUnexpectedToken(Next());
2607 *ok = false; 2615 *ok = false;
2608 return nullptr; 2616 return nullptr;
2609 2617
2610 case Token::THIS: 2618 case Token::THIS:
2611 case Token::SUPER: 2619 case Token::SUPER:
2612 if (is_strong(language_mode()) && 2620 if (is_strong(language_mode()) &&
2613 i::IsConstructor(function_state_->kind())) { 2621 i::IsConstructor(function_state_->kind())) {
2614 bool is_this = peek() == Token::THIS; 2622 bool is_this = peek() == Token::THIS;
2615 Expression* expr; 2623 Expression* expr;
2624 ExpressionClassifier classifier;
2616 if (is_this) { 2625 if (is_this) {
2617 expr = ParseStrongInitializationExpression(CHECK_OK); 2626 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
2618 } else { 2627 } else {
2619 expr = ParseStrongSuperCallExpression(CHECK_OK); 2628 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
2620 } 2629 }
2630 // TODO(dslomov): report error if not a valid expression.
2621 switch (peek()) { 2631 switch (peek()) {
2622 case Token::SEMICOLON: 2632 case Token::SEMICOLON:
2623 Consume(Token::SEMICOLON); 2633 Consume(Token::SEMICOLON);
2624 break; 2634 break;
2625 case Token::RBRACE: 2635 case Token::RBRACE:
2626 case Token::EOS: 2636 case Token::EOS:
2627 break; 2637 break;
2628 default: 2638 default:
2629 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { 2639 if (!scanner()->HasAnyLineTerminatorBeforeNext()) {
2630 ReportMessageAt(function_state_->this_location(), 2640 ReportMessageAt(function_state_->this_location(),
(...skipping 1700 matching lines...) Expand 10 before | Expand all | Expand 10 after
4331 if (name != NULL) { 4341 if (name != NULL) {
4332 proxy = NewUnresolved(name, CONST); 4342 proxy = NewUnresolved(name, CONST);
4333 Declaration* declaration = 4343 Declaration* declaration =
4334 factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos); 4344 factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos);
4335 Declare(declaration, true, CHECK_OK); 4345 Declare(declaration, true, CHECK_OK);
4336 } 4346 }
4337 4347
4338 Expression* extends = NULL; 4348 Expression* extends = NULL;
4339 if (Check(Token::EXTENDS)) { 4349 if (Check(Token::EXTENDS)) {
4340 block_scope->set_start_position(scanner()->location().end_pos); 4350 block_scope->set_start_position(scanner()->location().end_pos);
4341 extends = ParseLeftHandSideExpression(CHECK_OK); 4351 ExpressionClassifier classifier;
4352 extends = ParseLeftHandSideExpression(&classifier, CHECK_OK);
4353 // TODO(dslomov): report error if not a valid expression.
4342 } else { 4354 } else {
4343 block_scope->set_start_position(scanner()->location().end_pos); 4355 block_scope->set_start_position(scanner()->location().end_pos);
4344 } 4356 }
4345 4357
4346 4358
4347 ClassLiteralChecker checker(this); 4359 ClassLiteralChecker checker(this);
4348 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); 4360 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
4349 FunctionLiteral* constructor = NULL; 4361 FunctionLiteral* constructor = NULL;
4350 bool has_seen_constructor = false; 4362 bool has_seen_constructor = false;
4351 4363
4352 Expect(Token::LBRACE, CHECK_OK); 4364 Expect(Token::LBRACE, CHECK_OK);
4353 4365
4354 const bool has_extends = extends != nullptr; 4366 const bool has_extends = extends != nullptr;
4355 while (peek() != Token::RBRACE) { 4367 while (peek() != Token::RBRACE) {
4356 if (Check(Token::SEMICOLON)) continue; 4368 if (Check(Token::SEMICOLON)) continue;
4357 if (fni_ != NULL) fni_->Enter(); 4369 if (fni_ != NULL) fni_->Enter();
4358 const bool in_class = true; 4370 const bool in_class = true;
4359 const bool is_static = false; 4371 const bool is_static = false;
4360 bool is_computed_name = false; // Classes do not care about computed 4372 bool is_computed_name = false; // Classes do not care about computed
4361 // property names here. 4373 // property names here.
4374 ExpressionClassifier classifier;
4362 ObjectLiteral::Property* property = ParsePropertyDefinition( 4375 ObjectLiteral::Property* property = ParsePropertyDefinition(
4363 &checker, in_class, has_extends, is_static, &is_computed_name, 4376 &checker, in_class, has_extends, is_static, &is_computed_name,
4364 &has_seen_constructor, CHECK_OK); 4377 &has_seen_constructor, &classifier, CHECK_OK);
4378 // TODO(dslomov): report error if not a valid expression.
4365 4379
4366 if (has_seen_constructor && constructor == NULL) { 4380 if (has_seen_constructor && constructor == NULL) {
4367 constructor = GetPropertyValue(property)->AsFunctionLiteral(); 4381 constructor = GetPropertyValue(property)->AsFunctionLiteral();
4368 DCHECK_NOT_NULL(constructor); 4382 DCHECK_NOT_NULL(constructor);
4369 } else { 4383 } else {
4370 properties->Add(property, zone()); 4384 properties->Add(property, zone());
4371 } 4385 }
4372 4386
4373 if (fni_ != NULL) { 4387 if (fni_ != NULL) {
4374 fni_->Infer(); 4388 fni_->Infer();
(...skipping 28 matching lines...) Expand all
4403 Expression* Parser::ParseV8Intrinsic(bool* ok) { 4417 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4404 // CallRuntime :: 4418 // CallRuntime ::
4405 // '%' Identifier Arguments 4419 // '%' Identifier Arguments
4406 4420
4407 int pos = peek_position(); 4421 int pos = peek_position();
4408 Expect(Token::MOD, CHECK_OK); 4422 Expect(Token::MOD, CHECK_OK);
4409 // Allow "eval" or "arguments" for backward compatibility. 4423 // Allow "eval" or "arguments" for backward compatibility.
4410 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers, 4424 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers,
4411 CHECK_OK); 4425 CHECK_OK);
4412 Scanner::Location spread_pos; 4426 Scanner::Location spread_pos;
4413 ZoneList<Expression*>* args = ParseArguments(&spread_pos, CHECK_OK); 4427 ExpressionClassifier classifier;
4428 ZoneList<Expression*>* args =
4429 ParseArguments(&spread_pos, &classifier, CHECK_OK);
4430 // TODO(dslomov): report error if not a valid expression.
4414 4431
4415 DCHECK(!spread_pos.IsValid()); 4432 DCHECK(!spread_pos.IsValid());
4416 4433
4417 if (extension_ != NULL) { 4434 if (extension_ != NULL) {
4418 // The extension structures are only accessible while parsing the 4435 // The extension structures are only accessible while parsing the
4419 // very first time not when reparsing because of lazy compilation. 4436 // very first time not when reparsing because of lazy compilation.
4420 scope_->DeclarationScope()->ForceEagerCompilation(); 4437 scope_->DeclarationScope()->ForceEagerCompilation();
4421 } 4438 }
4422 4439
4423 const Runtime::Function* function = Runtime::FunctionForName(name->string()); 4440 const Runtime::Function* function = Runtime::FunctionForName(name->string());
(...skipping 1356 matching lines...) Expand 10 before | Expand all | Expand 10 after
5780 5797
5781 Expression* Parser::SpreadCallNew(Expression* function, 5798 Expression* Parser::SpreadCallNew(Expression* function,
5782 ZoneList<v8::internal::Expression*>* args, 5799 ZoneList<v8::internal::Expression*>* args,
5783 int pos) { 5800 int pos) {
5784 args->InsertAt(0, function, zone()); 5801 args->InsertAt(0, function, zone());
5785 5802
5786 return factory()->NewCallRuntime( 5803 return factory()->NewCallRuntime(
5787 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5804 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5788 } 5805 }
5789 } } // namespace v8::internal 5806 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/flag-definitions.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698