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

Side by Side Diff: src/preparser.h

Issue 1259283002: [es6] Implement proper TDZ for parameters (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Adam's comments Created 5 years, 4 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
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/bailout-reason.h" 10 #include "src/bailout-reason.h"
11 #include "src/expression-classifier.h" 11 #include "src/expression-classifier.h"
12 #include "src/func-name-inferrer.h" 12 #include "src/func-name-inferrer.h"
13 #include "src/hashmap.h" 13 #include "src/hashmap.h"
14 #include "src/messages.h" 14 #include "src/messages.h"
15 #include "src/scanner.h" 15 #include "src/scanner.h"
16 #include "src/scopes.h" 16 #include "src/scopes.h"
17 #include "src/token.h" 17 #include "src/token.h"
18 18
19 namespace v8 { 19 namespace v8 {
20 namespace internal { 20 namespace internal {
21 21
22 22
23 enum FunctionNameValidity { 23 enum FunctionNameValidity {
24 kFunctionNameIsStrictReserved, 24 kFunctionNameIsStrictReserved,
25 kSkipFunctionNameCheck, 25 kSkipFunctionNameCheck,
26 kFunctionNameValidityUnknown 26 kFunctionNameValidityUnknown
27 }; 27 };
28 28
29 29
30 struct FormalParametersBase {
31 explicit FormalParametersBase(Scope* scope) : scope(scope) {}
32 Scope* scope;
33 bool has_rest = false;
34 bool is_simple = true;
35 int materialized_literals_count = 0;
36 };
37
38
30 // Common base class shared between parser and pre-parser. Traits encapsulate 39 // Common base class shared between parser and pre-parser. Traits encapsulate
31 // the differences between Parser and PreParser: 40 // the differences between Parser and PreParser:
32 41
33 // - Return types: For example, Parser functions return Expression* and 42 // - Return types: For example, Parser functions return Expression* and
34 // PreParser functions return PreParserExpression. 43 // PreParser functions return PreParserExpression.
35 44
36 // - Creating parse tree nodes: Parser generates an AST during the recursive 45 // - Creating parse tree nodes: Parser generates an AST during the recursive
37 // descent. PreParser doesn't create a tree. Instead, it passes around minimal 46 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
38 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain 47 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
39 // just enough data for the upper layer functions. PreParserFactory is 48 // just enough data for the upper layer functions. PreParserFactory is
(...skipping 1265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 // Return the object itself as AstVisitor and implement the needed 1314 // Return the object itself as AstVisitor and implement the needed
1306 // dummy method right in this class. 1315 // dummy method right in this class.
1307 PreParserFactory* visitor() { return this; } 1316 PreParserFactory* visitor() { return this; }
1308 int* ast_properties() { 1317 int* ast_properties() {
1309 static int dummy = 42; 1318 static int dummy = 42;
1310 return &dummy; 1319 return &dummy;
1311 } 1320 }
1312 }; 1321 };
1313 1322
1314 1323
1315 struct PreParserFormalParameters { 1324 struct PreParserFormalParameters : FormalParametersBase {
1316 explicit PreParserFormalParameters(Scope* scope) 1325 explicit PreParserFormalParameters(Scope* scope)
1317 : scope(scope), 1326 : FormalParametersBase(scope) {}
1318 arity(0), 1327 int arity = 0;
1319 has_rest(false), 1328
1320 is_simple(true), 1329 int Arity() const { return arity; }
adamk 2015/08/04 17:25:04 This upper/lower thing is a bit confusing now, but
1321 materialized_literals_count(0) {} 1330 PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy
1322 Scope* scope;
1323 int arity;
1324 bool has_rest;
1325 bool is_simple;
1326 int materialized_literals_count;
1327 }; 1331 };
1328 1332
1329 1333
1330 class PreParser; 1334 class PreParser;
1331 1335
1332 class PreParserTraits { 1336 class PreParserTraits {
1333 public: 1337 public:
1334 struct Type { 1338 struct Type {
1335 // TODO(marja): To be removed. The Traits object should contain all the data 1339 // TODO(marja): To be removed. The Traits object should contain all the data
1336 // it needs. 1340 // it needs.
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, 1603 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
1600 int* expected_property_count, bool* ok) { 1604 int* expected_property_count, bool* ok) {
1601 UNREACHABLE(); 1605 UNREACHABLE();
1602 } 1606 }
1603 1607
1604 V8_INLINE PreParserStatementList ParseEagerFunctionBody( 1608 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1605 PreParserIdentifier function_name, int pos, 1609 PreParserIdentifier function_name, int pos,
1606 const PreParserFormalParameters& parameters, FunctionKind kind, 1610 const PreParserFormalParameters& parameters, FunctionKind kind,
1607 FunctionLiteral::FunctionType function_type, bool* ok); 1611 FunctionLiteral::FunctionType function_type, bool* ok);
1608 1612
1609 V8_INLINE void ParseArrowFunctionFormalParameters( 1613 V8_INLINE void ParseArrowFunctionFormalParameterList(
1610 PreParserFormalParameters* parameters, 1614 PreParserFormalParameters* parameters,
1611 PreParserExpression expression, const Scanner::Location& params_loc, 1615 PreParserExpression expression, const Scanner::Location& params_loc,
1612 Scanner::Location* duplicate_loc, bool* ok); 1616 Scanner::Location* duplicate_loc, bool* ok);
1613 1617
1614 void ReindexLiterals(const PreParserFormalParameters& paramaters) {} 1618 void ReindexLiterals(const PreParserFormalParameters& paramaters) {}
1615 1619
1616 struct TemplateLiteralState {}; 1620 struct TemplateLiteralState {};
1617 1621
1618 TemplateLiteralState OpenTemplateLiteral(int pos) { 1622 TemplateLiteralState OpenTemplateLiteral(int pos) {
1619 return TemplateLiteralState(); 1623 return TemplateLiteralState();
(...skipping 10 matching lines...) Expand all
1630 return EmptyExpression(); 1634 return EmptyExpression();
1631 } 1635 }
1632 inline void MaterializeTemplateCallsiteLiterals(); 1636 inline void MaterializeTemplateCallsiteLiterals();
1633 PreParserExpression NoTemplateTag() { 1637 PreParserExpression NoTemplateTag() {
1634 return PreParserExpression::NoTemplateTag(); 1638 return PreParserExpression::NoTemplateTag();
1635 } 1639 }
1636 static bool IsTaggedTemplate(const PreParserExpression tag) { 1640 static bool IsTaggedTemplate(const PreParserExpression tag) {
1637 return !tag.IsNoTemplateTag(); 1641 return !tag.IsNoTemplateTag();
1638 } 1642 }
1639 1643
1640 void DeclareFormalParameter(PreParserFormalParameters* parameters, 1644 void AddFormalParameter(
1641 PreParserExpression pattern, bool is_rest, 1645 PreParserFormalParameters* parameters, PreParserExpression pattern,
1646 bool is_rest) {
1647 ++parameters->arity;
1648 }
1649 void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter,
1650 bool is_simple,
1642 ExpressionClassifier* classifier) {} 1651 ExpressionClassifier* classifier) {}
1643 1652
1644 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} 1653 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
1645 1654
1646 // Temporary glue; these functions will move to ParserBase. 1655 // Temporary glue; these functions will move to ParserBase.
1647 PreParserExpression ParseV8Intrinsic(bool* ok); 1656 PreParserExpression ParseV8Intrinsic(bool* ok);
1648 PreParserExpression ParseFunctionLiteral( 1657 PreParserExpression ParseFunctionLiteral(
1649 PreParserIdentifier name, Scanner::Location function_name_location, 1658 PreParserIdentifier name, Scanner::Location function_name_location,
1650 FunctionNameValidity function_name_validity, FunctionKind kind, 1659 FunctionNameValidity function_name_validity, FunctionKind kind,
1651 int function_token_position, FunctionLiteral::FunctionType type, 1660 int function_token_position, FunctionLiteral::FunctionType type,
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1828 return pre_parser_->factory()->NewCall(function, args, pos); 1837 return pre_parser_->factory()->NewCall(function, args, pos);
1829 } 1838 }
1830 1839
1831 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, 1840 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
1832 PreParserExpressionList args, 1841 PreParserExpressionList args,
1833 int pos) { 1842 int pos) {
1834 return pre_parser_->factory()->NewCallNew(function, args, pos); 1843 return pre_parser_->factory()->NewCallNew(function, args, pos);
1835 } 1844 }
1836 1845
1837 1846
1838 void PreParserTraits::ParseArrowFunctionFormalParameters( 1847 void PreParserTraits::ParseArrowFunctionFormalParameterList(
1839 PreParserFormalParameters* parameters, 1848 PreParserFormalParameters* parameters,
1840 PreParserExpression params, const Scanner::Location& params_loc, 1849 PreParserExpression params, const Scanner::Location& params_loc,
1841 Scanner::Location* duplicate_loc, bool* ok) { 1850 Scanner::Location* duplicate_loc, bool* ok) {
1842 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter 1851 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
1843 // lists that are too long. 1852 // lists that are too long.
1844 } 1853 }
1845 1854
1846 1855
1847 PreParserStatementList PreParser::ParseEagerFunctionBody( 1856 PreParserStatementList PreParser::ParseEagerFunctionBody(
1848 PreParserIdentifier function_name, int pos, 1857 PreParserIdentifier function_name, int pos,
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
2273 FormalParametersT parameters(scope); 2282 FormalParametersT parameters(scope);
2274 scope->set_start_position(beg_pos); 2283 scope->set_start_position(beg_pos);
2275 ExpressionClassifier args_classifier; 2284 ExpressionClassifier args_classifier;
2276 result = this->ParseArrowFunctionLiteral(parameters, args_classifier, 2285 result = this->ParseArrowFunctionLiteral(parameters, args_classifier,
2277 CHECK_OK); 2286 CHECK_OK);
2278 } else if (allow_harmony_arrow_functions() && 2287 } else if (allow_harmony_arrow_functions() &&
2279 allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) { 2288 allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) {
2280 // (...x) => y 2289 // (...x) => y
2281 Scope* scope = 2290 Scope* scope =
2282 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); 2291 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2283 FormalParametersT parameters(scope); 2292 FormalParametersT formals(scope);
2284 scope->set_start_position(beg_pos); 2293 scope->set_start_position(beg_pos);
2285 ExpressionClassifier args_classifier; 2294 ExpressionClassifier formals_classifier;
2286 const bool is_rest = true; 2295 const bool is_rest = true;
2287 this->ParseFormalParameter(is_rest, &parameters, &args_classifier, 2296 this->ParseFormalParameter(is_rest, &formals, &formals_classifier,
2288 CHECK_OK); 2297 CHECK_OK);
2298 Traits::DeclareFormalParameter(
2299 formals.scope, formals.at(0), formals.is_simple,
2300 &formals_classifier);
2289 if (peek() == Token::COMMA) { 2301 if (peek() == Token::COMMA) {
2290 ReportMessageAt(scanner()->peek_location(), 2302 ReportMessageAt(scanner()->peek_location(),
2291 MessageTemplate::kParamAfterRest); 2303 MessageTemplate::kParamAfterRest);
2292 *ok = false; 2304 *ok = false;
2293 return this->EmptyExpression(); 2305 return this->EmptyExpression();
2294 } 2306 }
2295 Expect(Token::RPAREN, CHECK_OK); 2307 Expect(Token::RPAREN, CHECK_OK);
2296 result = this->ParseArrowFunctionLiteral(parameters, args_classifier, 2308 result = this->ParseArrowFunctionLiteral(formals, formals_classifier,
2297 CHECK_OK); 2309 CHECK_OK);
2298 } else { 2310 } else {
2299 // Heuristically try to detect immediately called functions before 2311 // Heuristically try to detect immediately called functions before
2300 // seeing the call parentheses. 2312 // seeing the call parentheses.
2301 parenthesized_function_ = (peek() == Token::FUNCTION); 2313 parenthesized_function_ = (peek() == Token::FUNCTION);
2302 result = this->ParseExpression(true, classifier, CHECK_OK); 2314 result = this->ParseExpression(true, classifier, CHECK_OK);
2303 Expect(Token::RPAREN, CHECK_OK); 2315 Expect(Token::RPAREN, CHECK_OK);
2304 } 2316 }
2305 break; 2317 break;
2306 2318
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
2838 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, 2850 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2839 parenthesized_formals, CHECK_OK); 2851 parenthesized_formals, CHECK_OK);
2840 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); 2852 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos);
2841 Scope* scope = 2853 Scope* scope =
2842 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); 2854 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2843 FormalParametersT parameters(scope); 2855 FormalParametersT parameters(scope);
2844 checkpoint.Restore(&parameters.materialized_literals_count); 2856 checkpoint.Restore(&parameters.materialized_literals_count);
2845 2857
2846 scope->set_start_position(lhs_location.beg_pos); 2858 scope->set_start_position(lhs_location.beg_pos);
2847 Scanner::Location duplicate_loc = Scanner::Location::invalid(); 2859 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2848 this->ParseArrowFunctionFormalParameters(&parameters, expression, loc, 2860 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
2849 &duplicate_loc, CHECK_OK); 2861 &duplicate_loc, CHECK_OK);
2850 if (duplicate_loc.IsValid()) { 2862 if (duplicate_loc.IsValid()) {
2851 arrow_formals_classifier.RecordDuplicateFormalParameterError( 2863 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2852 duplicate_loc); 2864 duplicate_loc);
2853 } 2865 }
2854 expression = this->ParseArrowFunctionLiteral( 2866 expression = this->ParseArrowFunctionLiteral(
2855 parameters, arrow_formals_classifier, CHECK_OK); 2867 parameters, arrow_formals_classifier, CHECK_OK);
2856 return expression; 2868 return expression;
2857 } 2869 }
2858 2870
2859 // "expression" was not itself an arrow function parameter list, but it might 2871 // "expression" was not itself an arrow function parameter list, but it might
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
3640 3652
3641 if (parameters->is_simple) { 3653 if (parameters->is_simple) {
3642 parameters->is_simple = !is_rest && Traits::IsIdentifier(pattern); 3654 parameters->is_simple = !is_rest && Traits::IsIdentifier(pattern);
3643 } 3655 }
3644 parameters->has_rest = is_rest; 3656 parameters->has_rest = is_rest;
3645 if (is_rest && !Traits::IsIdentifier(pattern)) { 3657 if (is_rest && !Traits::IsIdentifier(pattern)) {
3646 ReportUnexpectedToken(next); 3658 ReportUnexpectedToken(next);
3647 *ok = false; 3659 *ok = false;
3648 return; 3660 return;
3649 } 3661 }
3650 ++parameters->arity; 3662 Traits::AddFormalParameter(parameters, pattern, is_rest);
3651 Traits::DeclareFormalParameter(parameters, pattern, is_rest, classifier);
3652 } 3663 }
3653 3664
3654 3665
3655 template <class Traits> 3666 template <class Traits>
3656 void ParserBase<Traits>::ParseFormalParameterList( 3667 void ParserBase<Traits>::ParseFormalParameterList(
3657 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { 3668 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3658 // FormalParameters[Yield,GeneratorParameter] : 3669 // FormalParameters[Yield,GeneratorParameter] :
3659 // [empty] 3670 // [empty]
3660 // FormalParameterList[?Yield, ?GeneratorParameter] 3671 // FormalParameterList[?Yield, ?GeneratorParameter]
3661 // 3672 //
3662 // FormalParameterList[Yield,GeneratorParameter] : 3673 // FormalParameterList[Yield,GeneratorParameter] :
3663 // FunctionRestParameter[?Yield] 3674 // FunctionRestParameter[?Yield]
3664 // FormalsList[?Yield, ?GeneratorParameter] 3675 // FormalsList[?Yield, ?GeneratorParameter]
3665 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield] 3676 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield]
3666 // 3677 //
3667 // FormalsList[Yield,GeneratorParameter] : 3678 // FormalsList[Yield,GeneratorParameter] :
3668 // FormalParameter[?Yield, ?GeneratorParameter] 3679 // FormalParameter[?Yield, ?GeneratorParameter]
3669 // FormalsList[?Yield, ?GeneratorParameter] , 3680 // FormalsList[?Yield, ?GeneratorParameter] ,
3670 // FormalParameter[?Yield,?GeneratorParameter] 3681 // FormalParameter[?Yield,?GeneratorParameter]
3671 3682
3672 DCHECK_EQ(0, parameters->arity); 3683 DCHECK_EQ(0, parameters->Arity());
3673 3684
3674 if (peek() != Token::RPAREN) { 3685 if (peek() != Token::RPAREN) {
3675 do { 3686 do {
3676 if (parameters->arity > Code::kMaxArguments) { 3687 if (parameters->Arity() > Code::kMaxArguments) {
3677 ReportMessage(MessageTemplate::kTooManyParameters); 3688 ReportMessage(MessageTemplate::kTooManyParameters);
3678 *ok = false; 3689 *ok = false;
3679 return; 3690 return;
3680 } 3691 }
3681 bool is_rest = allow_harmony_rest_parameters() && Check(Token::ELLIPSIS); 3692 bool is_rest = allow_harmony_rest_parameters() && Check(Token::ELLIPSIS);
3682 ParseFormalParameter(is_rest, parameters, classifier, ok); 3693 ParseFormalParameter(is_rest, parameters, classifier, ok);
3683 if (!*ok) return; 3694 if (!*ok) return;
3684 } while (!parameters->has_rest && Check(Token::COMMA)); 3695 } while (!parameters->has_rest && Check(Token::COMMA));
3685 3696
3686 if (parameters->has_rest && peek() == Token::COMMA) { 3697 if (parameters->has_rest && peek() == Token::COMMA) {
3687 ReportMessageAt(scanner()->peek_location(), 3698 ReportMessageAt(scanner()->peek_location(),
3688 MessageTemplate::kParamAfterRest); 3699 MessageTemplate::kParamAfterRest);
3689 *ok = false; 3700 *ok = false;
3701 return;
3690 } 3702 }
3691 } 3703 }
3704
3705 for (int i = 0; i < parameters->Arity(); ++i) {
3706 auto parameter = parameters->at(i);
3707 Traits::DeclareFormalParameter(
3708 parameters->scope, parameter, parameters->is_simple, classifier);
3709 }
3692 } 3710 }
3693 3711
3694 3712
3695 template <class Traits> 3713 template <class Traits>
3696 void ParserBase<Traits>::CheckArityRestrictions( 3714 void ParserBase<Traits>::CheckArityRestrictions(
3697 int param_count, FunctionLiteral::ArityRestriction arity_restriction, 3715 int param_count, FunctionLiteral::ArityRestriction arity_restriction,
3698 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) { 3716 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) {
3699 switch (arity_restriction) { 3717 switch (arity_restriction) {
3700 case FunctionLiteral::GETTER_ARITY: 3718 case FunctionLiteral::GETTER_ARITY:
3701 if (param_count != 0) { 3719 if (param_count != 0) {
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
4012 *ok = false; 4030 *ok = false;
4013 return; 4031 return;
4014 } 4032 }
4015 has_seen_constructor_ = true; 4033 has_seen_constructor_ = true;
4016 return; 4034 return;
4017 } 4035 }
4018 } 4036 }
4019 } } // v8::internal 4037 } } // v8::internal
4020 4038
4021 #endif // V8_PREPARSER_H 4039 #endif // V8_PREPARSER_H
OLDNEW
« src/parser.h ('K') | « src/parser.cc ('k') | test/mjsunit/harmony/destructuring.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698