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 #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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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, ¶meters, &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 Loading... | |
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(¶meters.materialized_literals_count); | 2856 checkpoint.Restore(¶meters.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(¶meters, expression, loc, | 2860 this->ParseArrowFunctionFormalParameterList(¶meters, 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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |