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

Side by Side Diff: src/preparser.h

Issue 382893003: Implement basic code generation for arrow functions (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Test failures fixed, some minor corrections Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('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 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/func-name-inferrer.h" 10 #include "src/func-name-inferrer.h"
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 } 1003 }
1004 PreParserExpression NewFunctionLiteral( 1004 PreParserExpression NewFunctionLiteral(
1005 PreParserIdentifier name, AstValueFactory* ast_value_factory, 1005 PreParserIdentifier name, AstValueFactory* ast_value_factory,
1006 const PreParserScope& scope, PreParserStatementList body, 1006 const PreParserScope& scope, PreParserStatementList body,
1007 int materialized_literal_count, int expected_property_count, 1007 int materialized_literal_count, int expected_property_count,
1008 int handler_count, int parameter_count, 1008 int handler_count, int parameter_count,
1009 FunctionLiteral::ParameterFlag has_duplicate_parameters, 1009 FunctionLiteral::ParameterFlag has_duplicate_parameters,
1010 FunctionLiteral::FunctionType function_type, 1010 FunctionLiteral::FunctionType function_type,
1011 FunctionLiteral::IsFunctionFlag is_function, 1011 FunctionLiteral::IsFunctionFlag is_function,
1012 FunctionLiteral::IsParenthesizedFlag is_parenthesized, 1012 FunctionLiteral::IsParenthesizedFlag is_parenthesized,
1013 FunctionLiteral::IsGeneratorFlag is_generator, int position) { 1013 FunctionLiteral::KindFlag kind, int position) {
1014 return PreParserExpression::Default(); 1014 return PreParserExpression::Default();
1015 } 1015 }
1016 1016
1017 // Return the object itself as AstVisitor and implement the needed 1017 // Return the object itself as AstVisitor and implement the needed
1018 // dummy method right in this class. 1018 // dummy method right in this class.
1019 PreParserFactory* visitor() { return this; } 1019 PreParserFactory* visitor() { return this; }
1020 BailoutReason dont_optimize_reason() { return kNoReason; } 1020 BailoutReason dont_optimize_reason() { return kNoReason; }
1021 int* ast_properties() { 1021 int* ast_properties() {
1022 static int dummy = 42; 1022 static int dummy = 42;
1023 return &dummy; 1023 return &dummy;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 // operations interleaved with the recursive descent. 1105 // operations interleaved with the recursive descent.
1106 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { 1106 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
1107 // PreParser should not use FuncNameInferrer. 1107 // PreParser should not use FuncNameInferrer.
1108 UNREACHABLE(); 1108 UNREACHABLE();
1109 } 1109 }
1110 static void PushPropertyName(FuncNameInferrer* fni, 1110 static void PushPropertyName(FuncNameInferrer* fni,
1111 PreParserExpression expression) { 1111 PreParserExpression expression) {
1112 // PreParser should not use FuncNameInferrer. 1112 // PreParser should not use FuncNameInferrer.
1113 UNREACHABLE(); 1113 UNREACHABLE();
1114 } 1114 }
1115 static void InferFunctionName(FuncNameInferrer* fni,
1116 PreParserExpression expression) {
1117 // PreParser should not use FuncNameInferrer.
1118 UNREACHABLE();
1119 }
1115 1120
1116 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( 1121 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
1117 PreParserScope* scope, PreParserExpression value, bool* has_function) {} 1122 PreParserScope* scope, PreParserExpression value, bool* has_function) {}
1118 1123
1119 static void CheckAssigningFunctionLiteralToProperty( 1124 static void CheckAssigningFunctionLiteralToProperty(
1120 PreParserExpression left, PreParserExpression right) {} 1125 PreParserExpression left, PreParserExpression right) {}
1121 1126
1122 // PreParser doesn't need to keep track of eval calls. 1127 // PreParser doesn't need to keep track of eval calls.
1123 static void CheckPossibleEvalCall(PreParserExpression expression, 1128 static void CheckPossibleEvalCall(PreParserExpression expression,
1124 PreParserScope* scope) {} 1129 PreParserScope* scope) {}
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 case Token::LBRACE: 1706 case Token::LBRACE:
1702 result = this->ParseObjectLiteral(CHECK_OK); 1707 result = this->ParseObjectLiteral(CHECK_OK);
1703 break; 1708 break;
1704 1709
1705 case Token::LPAREN: 1710 case Token::LPAREN:
1706 Consume(Token::LPAREN); 1711 Consume(Token::LPAREN);
1707 if (allow_arrow_functions() && peek() == Token::RPAREN) { 1712 if (allow_arrow_functions() && peek() == Token::RPAREN) {
1708 // Arrow functions are the only expression type constructions 1713 // Arrow functions are the only expression type constructions
1709 // for which an empty parameter list "()" is valid input. 1714 // for which an empty parameter list "()" is valid input.
1710 Consume(Token::RPAREN); 1715 Consume(Token::RPAREN);
1711 return this->ParseArrowFunctionLiteral(pos, this->EmptyArrowParamList(), 1716 result = this->ParseArrowFunctionLiteral(
1712 CHECK_OK); 1717 pos, this->EmptyArrowParamList(), CHECK_OK);
1713 } else { 1718 } else {
1714 // Heuristically try to detect immediately called functions before 1719 // Heuristically try to detect immediately called functions before
1715 // seeing the call parentheses. 1720 // seeing the call parentheses.
1716 parenthesized_function_ = (peek() == Token::FUNCTION); 1721 parenthesized_function_ = (peek() == Token::FUNCTION);
1717 result = this->ParseExpression(true, CHECK_OK); 1722 result = this->ParseExpression(true, CHECK_OK);
1718 result->increase_parenthesization_level(); 1723 result->increase_parenthesization_level();
1719 Expect(Token::RPAREN, CHECK_OK); 1724 Expect(Token::RPAREN, CHECK_OK);
1720 } 1725 }
1721 break; 1726 break;
1722 1727
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
1996 Scanner::Location lhs_location = scanner()->peek_location(); 2001 Scanner::Location lhs_location = scanner()->peek_location();
1997 2002
1998 if (peek() == Token::YIELD && is_generator()) { 2003 if (peek() == Token::YIELD && is_generator()) {
1999 return this->ParseYieldExpression(ok); 2004 return this->ParseYieldExpression(ok);
2000 } 2005 }
2001 2006
2002 if (fni_ != NULL) fni_->Enter(); 2007 if (fni_ != NULL) fni_->Enter();
2003 ExpressionT expression = 2008 ExpressionT expression =
2004 this->ParseConditionalExpression(accept_IN, CHECK_OK); 2009 this->ParseConditionalExpression(accept_IN, CHECK_OK);
2005 2010
2006 if (allow_arrow_functions() && peek() == Token::ARROW) 2011 if (allow_arrow_functions() && peek() == Token::ARROW) {
2007 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos, expression, 2012 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
2008 CHECK_OK); 2013 expression, CHECK_OK);
2014 return expression;
2015 }
2009 2016
2010 if (!Token::IsAssignmentOp(peek())) { 2017 if (!Token::IsAssignmentOp(peek())) {
2011 if (fni_ != NULL) fni_->Leave(); 2018 if (fni_ != NULL) fni_->Leave();
2012 // Parsed conditional expression only (no assignment). 2019 // Parsed conditional expression only (no assignment).
2013 return expression; 2020 return expression;
2014 } 2021 }
2015 2022
2016 expression = this->CheckAndRewriteReferenceExpression( 2023 expression = this->CheckAndRewriteReferenceExpression(
2017 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); 2024 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
2018 expression = this->MarkExpressionAsAssigned(expression); 2025 expression = this->MarkExpressionAsAssigned(expression);
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
2469 2476
2470 template <class Traits> 2477 template <class Traits>
2471 typename ParserBase<Traits>::ExpressionT 2478 typename ParserBase<Traits>::ExpressionT
2472 ParserBase<Traits>::ParseArrowFunctionLiteralBody( 2479 ParserBase<Traits>::ParseArrowFunctionLiteralBody(
2473 FunctionState* function_state, typename Traits::Type::ScopePtr scope, 2480 FunctionState* function_state, typename Traits::Type::ScopePtr scope,
2474 int num_parameters, const Scanner::Location& eval_args_error_loc, 2481 int num_parameters, const Scanner::Location& eval_args_error_loc,
2475 const Scanner::Location& dupe_error_loc, 2482 const Scanner::Location& dupe_error_loc,
2476 const Scanner::Location& reserved_loc, 2483 const Scanner::Location& reserved_loc,
2477 FunctionLiteral::IsParenthesizedFlag parenthesized, int start_pos, 2484 FunctionLiteral::IsParenthesizedFlag parenthesized, int start_pos,
2478 bool* ok) { 2485 bool* ok) {
2486 typename Traits::Type::StatementList body;
2487 typename Traits::Type::AstProperties ast_properties;
2488 BailoutReason dont_optimize_reason = kNoReason;
2479 int materialized_literal_count = -1; 2489 int materialized_literal_count = -1;
2480 int expected_property_count = -1; 2490 int expected_property_count = -1;
2491 int handler_count = 0;
2481 2492
2482 Expect(Token::ARROW, CHECK_OK); 2493 Expect(Token::ARROW, CHECK_OK);
2483 2494
2484 if (peek() == Token::LBRACE) { 2495 if (peek() == Token::LBRACE) {
2485 // Multiple statemente body 2496 // Multiple statemente body
2486 Consume(Token::LBRACE); 2497 Consume(Token::LBRACE);
2487 bool is_lazily_parsed = 2498 bool is_lazily_parsed =
2488 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); 2499 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation());
2489 if (is_lazily_parsed) { 2500 if (is_lazily_parsed) {
2501 body = this->NewStatementList(0, zone());
2490 this->SkipLazyFunctionBody(this->EmptyIdentifier(), 2502 this->SkipLazyFunctionBody(this->EmptyIdentifier(),
2491 &materialized_literal_count, 2503 &materialized_literal_count,
2492 &expected_property_count, CHECK_OK); 2504 &expected_property_count, CHECK_OK);
2493 } else { 2505 } else {
2494 this->ParseEagerFunctionBody(this->EmptyIdentifier(), 2506 body = this->ParseEagerFunctionBody(
2495 RelocInfo::kNoPosition, NULL, 2507 this->EmptyIdentifier(), RelocInfo::kNoPosition, NULL,
2496 Token::INIT_VAR, false, // Not a generator. 2508 Token::INIT_VAR, false, // Not a generator.
2497 CHECK_OK); 2509 CHECK_OK);
2510 materialized_literal_count = function_state->materialized_literal_count();
2511 expected_property_count = function_state->expected_property_count();
2512 handler_count = function_state->handler_count();
2498 } 2513 }
2499 } else { 2514 } else {
2500 // Single-expression body 2515 // Single-expression body
2501 ParseAssignmentExpression(true, CHECK_OK); 2516 int pos = position();
2517 parenthesized_function_ = false;
2518 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK);
2519 body = this->NewStatementList(1, zone());
2520 body->Add(factory()->NewReturnStatement(expression, pos), zone());
2521 materialized_literal_count = function_state->materialized_literal_count();
2522 expected_property_count = function_state->expected_property_count();
2523 handler_count = function_state->handler_count();
2502 } 2524 }
2503 2525
2504 scope->set_start_position(start_pos); 2526 scope->set_start_position(start_pos);
2505 scope->set_end_position(scanner()->location().end_pos); 2527 scope->set_end_position(scanner()->location().end_pos);
2506 2528
2507 // Arrow function *parameter lists* are always checked as in strict mode. 2529 // Arrow function *parameter lists* are always checked as in strict mode.
2508 this->CheckStrictFunctionNameAndParameters( 2530 this->CheckStrictFunctionNameAndParameters(
2509 this->EmptyIdentifier(), false, Scanner::Location::invalid(), 2531 this->EmptyIdentifier(), false, Scanner::Location::invalid(),
2510 Scanner::Location::invalid(), dupe_error_loc, 2532 Scanner::Location::invalid(), dupe_error_loc,
2511 Scanner::Location::invalid(), CHECK_OK); 2533 Scanner::Location::invalid(), CHECK_OK);
2512 2534
2513 // Validate strict mode. 2535 // Validate strict mode.
2514 if (strict_mode() == STRICT) { 2536 if (strict_mode() == STRICT) {
2515 CheckOctalLiteral(start_pos, scanner()->location().end_pos, CHECK_OK); 2537 CheckOctalLiteral(start_pos, scanner()->location().end_pos, CHECK_OK);
2516 } 2538 }
2517 2539
2518 if (allow_harmony_scoping() && strict_mode() == STRICT) 2540 if (allow_harmony_scoping() && strict_mode() == STRICT)
2519 this->CheckConflictingVarDeclarations(scope, CHECK_OK); 2541 this->CheckConflictingVarDeclarations(scope, CHECK_OK);
2520 2542
2521 // TODO(aperez): Generate a proper FunctionLiteral instead of 2543 ast_properties = *factory()->visitor()->ast_properties();
2522 // returning a dummy value. 2544 dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
2545
2523 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( 2546 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
2524 this->EmptyIdentifierString(), this->ast_value_factory(), scope, 2547 this->EmptyIdentifierString(), this->ast_value_factory(), scope, body,
2525 this->NewStatementList(0, zone()), 0, 0, 0, num_parameters, 2548 materialized_literal_count, expected_property_count, handler_count,
2526 FunctionLiteral::kNoDuplicateParameters, 2549 num_parameters, FunctionLiteral::kNoDuplicateParameters,
2527 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, 2550 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
2528 FunctionLiteral::kNotParenthesized, FunctionLiteral::kNotGenerator, 2551 parenthesized, FunctionLiteral::kArrowFunction, start_pos);
2529 start_pos); 2552
2530 function_literal->set_function_token_position(start_pos); 2553 function_literal->set_function_token_position(start_pos);
2554 function_literal->set_ast_properties(&ast_properties);
2555 function_literal->set_dont_optimize_reason(dont_optimize_reason);
2556
2557 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
2558
2531 return function_literal; 2559 return function_literal;
2532 } 2560 }
2533 2561
2534 2562
2535 template <typename Traits> 2563 template <typename Traits>
2536 typename ParserBase<Traits>::ExpressionT 2564 typename ParserBase<Traits>::ExpressionT
2537 ParserBase<Traits>::CheckAndRewriteReferenceExpression( 2565 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
2538 ExpressionT expression, 2566 ExpressionT expression,
2539 Scanner::Location location, const char* message, bool* ok) { 2567 Scanner::Location location, const char* message, bool* ok) {
2540 if (strict_mode() == STRICT && this->IsIdentifier(expression) && 2568 if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2588 parser()->ReportMessage("accessor_get_set"); 2616 parser()->ReportMessage("accessor_get_set");
2589 } 2617 }
2590 *ok = false; 2618 *ok = false;
2591 } 2619 }
2592 } 2620 }
2593 2621
2594 2622
2595 } } // v8::internal 2623 } } // v8::internal
2596 2624
2597 #endif // V8_PREPARSER_H 2625 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698