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/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 Loading... |
1139 if (ok) ok = Check(Token::RPAREN); | 1139 if (ok) ok = Check(Token::RPAREN); |
1140 } else { | 1140 } else { |
1141 // BindingIdentifier | 1141 // BindingIdentifier |
1142 ParseFormalParameter(scope, &error_locs, has_rest, &ok); | 1142 ParseFormalParameter(scope, &error_locs, has_rest, &ok); |
1143 } | 1143 } |
1144 | 1144 |
1145 if (ok) { | 1145 if (ok) { |
1146 ExpressionClassifier classifier; | 1146 ExpressionClassifier classifier; |
1147 Expression* expression = ParseArrowFunctionLiteral( | 1147 Expression* expression = ParseArrowFunctionLiteral( |
1148 scope, error_locs, has_rest, &classifier, &ok); | 1148 scope, error_locs, has_rest, &classifier, &ok); |
1149 // TODO(dslomov): report error if not a valid expression. | 1149 ValidateExpression(&classifier, &ok); |
1150 if (ok) { | 1150 if (ok) { |
1151 // Scanning must end at the same position that was recorded | 1151 // Scanning must end at the same position that was recorded |
1152 // previously. If not, parsing has been interrupted due to a stack | 1152 // previously. If not, parsing has been interrupted due to a stack |
1153 // overflow, at which point the partially parsed arrow function | 1153 // overflow, at which point the partially parsed arrow function |
1154 // concise body happens to be a valid expression. This is a problem | 1154 // concise body happens to be a valid expression. This is a problem |
1155 // only for arrow functions with single expression bodies, since there | 1155 // only for arrow functions with single expression bodies, since there |
1156 // is no end token such as "}" for normal functions. | 1156 // is no end token such as "}" for normal functions. |
1157 if (scanner()->location().end_pos == shared_info->end_position()) { | 1157 if (scanner()->location().end_pos == shared_info->end_position()) { |
1158 // The pre-parser saw an arrow function here, so the full parser | 1158 // The pre-parser saw an arrow function here, so the full parser |
1159 // must produce a FunctionLiteral. | 1159 // must produce a FunctionLiteral. |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1609 | 1609 |
1610 case Token::CLASS: | 1610 case Token::CLASS: |
1611 // TODO(ES6): Support parsing anonymous class declarations here. | 1611 // TODO(ES6): Support parsing anonymous class declarations here. |
1612 result = ParseClassDeclaration(&names, CHECK_OK); | 1612 result = ParseClassDeclaration(&names, CHECK_OK); |
1613 break; | 1613 break; |
1614 | 1614 |
1615 default: { | 1615 default: { |
1616 int pos = peek_position(); | 1616 int pos = peek_position(); |
1617 ExpressionClassifier classifier; | 1617 ExpressionClassifier classifier; |
1618 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); | 1618 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); |
1619 // TODO(dslomov): report error if not a valid expression. | 1619 ValidateExpression(&classifier, CHECK_OK); |
1620 | 1620 |
1621 ExpectSemicolon(CHECK_OK); | 1621 ExpectSemicolon(CHECK_OK); |
1622 result = factory()->NewExpressionStatement(expr, pos); | 1622 result = factory()->NewExpressionStatement(expr, pos); |
1623 break; | 1623 break; |
1624 } | 1624 } |
1625 } | 1625 } |
1626 | 1626 |
1627 const AstRawString* default_string = ast_value_factory()->default_string(); | 1627 const AstRawString* default_string = ast_value_factory()->default_string(); |
1628 | 1628 |
1629 DCHECK_LE(names.length(), 1); | 1629 DCHECK_LE(names.length(), 1); |
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2369 int nvars = 0; // the number of variables declared | 2369 int nvars = 0; // the number of variables declared |
2370 int bindings_start = peek_position(); | 2370 int bindings_start = peek_position(); |
2371 const AstRawString* name = NULL; | 2371 const AstRawString* name = NULL; |
2372 const AstRawString* first_name = NULL; | 2372 const AstRawString* first_name = NULL; |
2373 bool is_for_iteration_variable; | 2373 bool is_for_iteration_variable; |
2374 do { | 2374 do { |
2375 if (fni_ != NULL) fni_->Enter(); | 2375 if (fni_ != NULL) fni_->Enter(); |
2376 | 2376 |
2377 // Parse variable name. | 2377 // Parse variable name. |
2378 if (nvars > 0) Consume(Token::COMMA); | 2378 if (nvars > 0) Consume(Token::COMMA); |
2379 name = ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); | 2379 |
| 2380 { |
| 2381 ExpressionClassifier pattern_classifier; |
| 2382 Token::Value next = peek(); |
| 2383 Expression* pattern = |
| 2384 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); |
| 2385 ValidateBindingPattern(&pattern_classifier, CHECK_OK); |
| 2386 if (pattern->IsVariableProxy() && |
| 2387 pattern->AsVariableProxy()->IsValidReferenceExpression()) { |
| 2388 scope_->RemoveUnresolved(pattern->AsVariableProxy()); |
| 2389 name = pattern->AsVariableProxy()->raw_name(); |
| 2390 } else { |
| 2391 ReportUnexpectedToken(next); |
| 2392 *ok = false; |
| 2393 return nullptr; |
| 2394 } |
| 2395 } |
| 2396 |
2380 if (!first_name) first_name = name; | 2397 if (!first_name) first_name = name; |
2381 Scanner::Location variable_loc = scanner()->location(); | 2398 Scanner::Location variable_loc = scanner()->location(); |
2382 if (fni_ != NULL) fni_->PushVariableName(name); | 2399 if (fni_ != NULL) fni_->PushVariableName(name); |
2383 | 2400 |
2384 // Declare variable. | 2401 // Declare variable. |
2385 // Note that we *always* must treat the initial value via a separate init | 2402 // Note that we *always* must treat the initial value via a separate init |
2386 // assignment for variables and constants because the value must be assigned | 2403 // assignment for variables and constants because the value must be assigned |
2387 // when the variable is encountered in the source. But the variable/constant | 2404 // when the variable is encountered in the source. But the variable/constant |
2388 // is declared (and set to 'undefined') upon entering the function within | 2405 // is declared (and set to 'undefined') upon entering the function within |
2389 // which the variable or constant is declared. Only function variables have | 2406 // which the variable or constant is declared. Only function variables have |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2448 Expression* value = NULL; | 2465 Expression* value = NULL; |
2449 int pos = -1; | 2466 int pos = -1; |
2450 // Harmony consts have non-optional initializers. | 2467 // Harmony consts have non-optional initializers. |
2451 if (peek() == Token::ASSIGN || | 2468 if (peek() == Token::ASSIGN || |
2452 (mode == CONST && !is_for_iteration_variable)) { | 2469 (mode == CONST && !is_for_iteration_variable)) { |
2453 Expect(Token::ASSIGN, CHECK_OK); | 2470 Expect(Token::ASSIGN, CHECK_OK); |
2454 pos = position(); | 2471 pos = position(); |
2455 ExpressionClassifier classifier; | 2472 ExpressionClassifier classifier; |
2456 value = ParseAssignmentExpression(var_context != kForStatement, | 2473 value = ParseAssignmentExpression(var_context != kForStatement, |
2457 &classifier, CHECK_OK); | 2474 &classifier, CHECK_OK); |
2458 // TODO(dslomov): check that expression is valid. | 2475 ValidateExpression(&classifier, CHECK_OK); |
2459 variable_loc.end_pos = scanner()->location().end_pos; | 2476 variable_loc.end_pos = scanner()->location().end_pos; |
2460 | 2477 |
2461 if (first_initializer_loc && !first_initializer_loc->IsValid()) { | 2478 if (first_initializer_loc && !first_initializer_loc->IsValid()) { |
2462 *first_initializer_loc = variable_loc; | 2479 *first_initializer_loc = variable_loc; |
2463 } | 2480 } |
2464 | 2481 |
2465 // Don't infer if it is "a = function(){...}();"-like expression. | 2482 // Don't infer if it is "a = function(){...}();"-like expression. |
2466 if (fni_ != NULL && | 2483 if (fni_ != NULL && |
2467 value->AsCall() == NULL && | 2484 value->AsCall() == NULL && |
2468 value->AsCallNew() == NULL) { | 2485 value->AsCallNew() == NULL) { |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2639 if (is_strong(language_mode()) && | 2656 if (is_strong(language_mode()) && |
2640 i::IsConstructor(function_state_->kind())) { | 2657 i::IsConstructor(function_state_->kind())) { |
2641 bool is_this = peek() == Token::THIS; | 2658 bool is_this = peek() == Token::THIS; |
2642 Expression* expr; | 2659 Expression* expr; |
2643 ExpressionClassifier classifier; | 2660 ExpressionClassifier classifier; |
2644 if (is_this) { | 2661 if (is_this) { |
2645 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK); | 2662 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK); |
2646 } else { | 2663 } else { |
2647 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK); | 2664 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK); |
2648 } | 2665 } |
2649 // TODO(dslomov): report error if not a valid expression. | 2666 ValidateExpression(&classifier, CHECK_OK); |
2650 switch (peek()) { | 2667 switch (peek()) { |
2651 case Token::SEMICOLON: | 2668 case Token::SEMICOLON: |
2652 Consume(Token::SEMICOLON); | 2669 Consume(Token::SEMICOLON); |
2653 break; | 2670 break; |
2654 case Token::RBRACE: | 2671 case Token::RBRACE: |
2655 case Token::EOS: | 2672 case Token::EOS: |
2656 break; | 2673 break; |
2657 default: | 2674 default: |
2658 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { | 2675 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { |
2659 ReportMessageAt(function_state_->this_location(), | 2676 ReportMessageAt(function_state_->this_location(), |
(...skipping 1708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4368 proxy, CONST, block_scope, pos, is_class_declaration, | 4385 proxy, CONST, block_scope, pos, is_class_declaration, |
4369 scope_->class_declaration_group_start()); | 4386 scope_->class_declaration_group_start()); |
4370 Declare(declaration, true, CHECK_OK); | 4387 Declare(declaration, true, CHECK_OK); |
4371 } | 4388 } |
4372 | 4389 |
4373 Expression* extends = NULL; | 4390 Expression* extends = NULL; |
4374 if (Check(Token::EXTENDS)) { | 4391 if (Check(Token::EXTENDS)) { |
4375 block_scope->set_start_position(scanner()->location().end_pos); | 4392 block_scope->set_start_position(scanner()->location().end_pos); |
4376 ExpressionClassifier classifier; | 4393 ExpressionClassifier classifier; |
4377 extends = ParseLeftHandSideExpression(&classifier, CHECK_OK); | 4394 extends = ParseLeftHandSideExpression(&classifier, CHECK_OK); |
4378 // TODO(dslomov): report error if not a valid expression. | 4395 ValidateExpression(&classifier, CHECK_OK); |
4379 } else { | 4396 } else { |
4380 block_scope->set_start_position(scanner()->location().end_pos); | 4397 block_scope->set_start_position(scanner()->location().end_pos); |
4381 } | 4398 } |
4382 | 4399 |
4383 | 4400 |
4384 ClassLiteralChecker checker(this); | 4401 ClassLiteralChecker checker(this); |
4385 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); | 4402 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); |
4386 FunctionLiteral* constructor = NULL; | 4403 FunctionLiteral* constructor = NULL; |
4387 bool has_seen_constructor = false; | 4404 bool has_seen_constructor = false; |
4388 | 4405 |
4389 Expect(Token::LBRACE, CHECK_OK); | 4406 Expect(Token::LBRACE, CHECK_OK); |
4390 | 4407 |
4391 const bool has_extends = extends != nullptr; | 4408 const bool has_extends = extends != nullptr; |
4392 while (peek() != Token::RBRACE) { | 4409 while (peek() != Token::RBRACE) { |
4393 if (Check(Token::SEMICOLON)) continue; | 4410 if (Check(Token::SEMICOLON)) continue; |
4394 if (fni_ != NULL) fni_->Enter(); | 4411 if (fni_ != NULL) fni_->Enter(); |
4395 const bool in_class = true; | 4412 const bool in_class = true; |
4396 const bool is_static = false; | 4413 const bool is_static = false; |
4397 bool is_computed_name = false; // Classes do not care about computed | 4414 bool is_computed_name = false; // Classes do not care about computed |
4398 // property names here. | 4415 // property names here. |
4399 ExpressionClassifier classifier; | 4416 ExpressionClassifier classifier; |
4400 ObjectLiteral::Property* property = ParsePropertyDefinition( | 4417 ObjectLiteral::Property* property = ParsePropertyDefinition( |
4401 &checker, in_class, has_extends, is_static, &is_computed_name, | 4418 &checker, in_class, has_extends, is_static, &is_computed_name, |
4402 &has_seen_constructor, &classifier, CHECK_OK); | 4419 &has_seen_constructor, &classifier, CHECK_OK); |
4403 // TODO(dslomov): report error if not a valid expression. | 4420 ValidateExpression(&classifier, CHECK_OK); |
4404 | 4421 |
4405 if (has_seen_constructor && constructor == NULL) { | 4422 if (has_seen_constructor && constructor == NULL) { |
4406 constructor = GetPropertyValue(property)->AsFunctionLiteral(); | 4423 constructor = GetPropertyValue(property)->AsFunctionLiteral(); |
4407 DCHECK_NOT_NULL(constructor); | 4424 DCHECK_NOT_NULL(constructor); |
4408 } else { | 4425 } else { |
4409 properties->Add(property, zone()); | 4426 properties->Add(property, zone()); |
4410 } | 4427 } |
4411 | 4428 |
4412 if (fni_ != NULL) { | 4429 if (fni_ != NULL) { |
4413 fni_->Infer(); | 4430 fni_->Infer(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4445 | 4462 |
4446 int pos = peek_position(); | 4463 int pos = peek_position(); |
4447 Expect(Token::MOD, CHECK_OK); | 4464 Expect(Token::MOD, CHECK_OK); |
4448 // Allow "eval" or "arguments" for backward compatibility. | 4465 // Allow "eval" or "arguments" for backward compatibility. |
4449 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers, | 4466 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers, |
4450 CHECK_OK); | 4467 CHECK_OK); |
4451 Scanner::Location spread_pos; | 4468 Scanner::Location spread_pos; |
4452 ExpressionClassifier classifier; | 4469 ExpressionClassifier classifier; |
4453 ZoneList<Expression*>* args = | 4470 ZoneList<Expression*>* args = |
4454 ParseArguments(&spread_pos, &classifier, CHECK_OK); | 4471 ParseArguments(&spread_pos, &classifier, CHECK_OK); |
4455 // TODO(dslomov): report error if not a valid expression. | 4472 ValidateExpression(&classifier, CHECK_OK); |
4456 | 4473 |
4457 DCHECK(!spread_pos.IsValid()); | 4474 DCHECK(!spread_pos.IsValid()); |
4458 | 4475 |
4459 if (extension_ != NULL) { | 4476 if (extension_ != NULL) { |
4460 // The extension structures are only accessible while parsing the | 4477 // The extension structures are only accessible while parsing the |
4461 // very first time not when reparsing because of lazy compilation. | 4478 // very first time not when reparsing because of lazy compilation. |
4462 scope_->DeclarationScope()->ForceEagerCompilation(); | 4479 scope_->DeclarationScope()->ForceEagerCompilation(); |
4463 } | 4480 } |
4464 | 4481 |
4465 const Runtime::Function* function = Runtime::FunctionForName(name->string()); | 4482 const Runtime::Function* function = Runtime::FunctionForName(name->string()); |
(...skipping 1356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5822 | 5839 |
5823 Expression* Parser::SpreadCallNew(Expression* function, | 5840 Expression* Parser::SpreadCallNew(Expression* function, |
5824 ZoneList<v8::internal::Expression*>* args, | 5841 ZoneList<v8::internal::Expression*>* args, |
5825 int pos) { | 5842 int pos) { |
5826 args->InsertAt(0, function, zone()); | 5843 args->InsertAt(0, function, zone()); |
5827 | 5844 |
5828 return factory()->NewCallRuntime( | 5845 return factory()->NewCallRuntime( |
5829 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5846 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
5830 } | 5847 } |
5831 } } // namespace v8::internal | 5848 } } // namespace v8::internal |
OLD | NEW |