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

Side by Side Diff: src/preparser.h

Issue 1300103005: [parser] disallow language mode directive in body of function with non-simple parameters (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: flag implications don't work in test suite? Created 5 years, 3 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/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/bailout-reason.h" 8 #include "src/bailout-reason.h"
9 #include "src/expression-classifier.h" 9 #include "src/expression-classifier.h"
10 #include "src/func-name-inferrer.h" 10 #include "src/func-name-inferrer.h"
(...skipping 1630 matching lines...) Expand 10 before | Expand all | Expand 10 after
1641 static bool IsTaggedTemplate(const PreParserExpression tag) { 1641 static bool IsTaggedTemplate(const PreParserExpression tag) {
1642 return !tag.IsNoTemplateTag(); 1642 return !tag.IsNoTemplateTag();
1643 } 1643 }
1644 1644
1645 void AddFormalParameter( 1645 void AddFormalParameter(
1646 PreParserFormalParameters* parameters, PreParserExpression pattern, 1646 PreParserFormalParameters* parameters, PreParserExpression pattern,
1647 PreParserExpression initializer, bool is_rest) { 1647 PreParserExpression initializer, bool is_rest) {
1648 ++parameters->arity; 1648 ++parameters->arity;
1649 } 1649 }
1650 void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter, 1650 void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter,
1651 bool is_simple, 1651 ExpressionClassifier* classifier) {
1652 ExpressionClassifier* classifier) {} 1652 if (!classifier->is_simple_parameter_list()) {
1653 scope->SetHasNonSimpleParameters();
1654 }
1655 }
1653 1656
1654 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} 1657 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
1655 1658
1656 // Temporary glue; these functions will move to ParserBase. 1659 // Temporary glue; these functions will move to ParserBase.
1657 PreParserExpression ParseV8Intrinsic(bool* ok); 1660 PreParserExpression ParseV8Intrinsic(bool* ok);
1658 PreParserExpression ParseFunctionLiteral( 1661 PreParserExpression ParseFunctionLiteral(
1659 PreParserIdentifier name, Scanner::Location function_name_location, 1662 PreParserIdentifier name, Scanner::Location function_name_location,
1660 FunctionNameValidity function_name_validity, FunctionKind kind, 1663 FunctionNameValidity function_name_validity, FunctionKind kind,
1661 int function_token_position, FunctionLiteral::FunctionType type, 1664 int function_token_position, FunctionLiteral::FunctionType type,
1662 FunctionLiteral::ArityRestriction arity_restriction, 1665 FunctionLiteral::ArityRestriction arity_restriction,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1740 1743
1741 // Parses a single function literal, from the opening parentheses before 1744 // Parses a single function literal, from the opening parentheses before
1742 // parameters to the closing brace after the body. 1745 // parameters to the closing brace after the body.
1743 // Returns a FunctionEntry describing the body of the function in enough 1746 // Returns a FunctionEntry describing the body of the function in enough
1744 // detail that it can be lazily compiled. 1747 // detail that it can be lazily compiled.
1745 // The scanner is expected to have matched the "function" or "function*" 1748 // The scanner is expected to have matched the "function" or "function*"
1746 // keyword and parameters, and have consumed the initial '{'. 1749 // keyword and parameters, and have consumed the initial '{'.
1747 // At return, unless an error occurred, the scanner is positioned before the 1750 // At return, unless an error occurred, the scanner is positioned before the
1748 // the final '}'. 1751 // the final '}'.
1749 PreParseResult PreParseLazyFunction( 1752 PreParseResult PreParseLazyFunction(
1750 LanguageMode language_mode, FunctionKind kind, ParserRecorder* log, 1753 LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters,
1751 Scanner::BookmarkScope* bookmark = nullptr); 1754 ParserRecorder* log, Scanner::BookmarkScope* bookmark = nullptr);
1752 1755
1753 private: 1756 private:
1754 friend class PreParserTraits; 1757 friend class PreParserTraits;
1755 1758
1756 static const int kLazyParseTrialLimit = 200; 1759 static const int kLazyParseTrialLimit = 200;
1757 1760
1758 // These types form an algebra over syntactic categories that is just 1761 // These types form an algebra over syntactic categories that is just
1759 // rich enough to let us recognize and propagate the constructs that 1762 // rich enough to let us recognize and propagate the constructs that
1760 // are either being counted in the preparser data, or is important 1763 // are either being counted in the preparser data, or is important
1761 // to throw the correct syntax error exceptions. 1764 // to throw the correct syntax error exceptions.
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
2276 MessageTemplate::kUnexpectedToken, 2279 MessageTemplate::kUnexpectedToken,
2277 Token::String(Token::RPAREN)); 2280 Token::String(Token::RPAREN));
2278 result = factory()->NewEmptyParentheses(beg_pos); 2281 result = factory()->NewEmptyParentheses(beg_pos);
2279 } else if (allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) { 2282 } else if (allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) {
2280 // (...x)=>x. The continuation that looks for the => is in 2283 // (...x)=>x. The continuation that looks for the => is in
2281 // ParseAssignmentExpression. 2284 // ParseAssignmentExpression.
2282 int ellipsis_pos = scanner()->location().beg_pos; 2285 int ellipsis_pos = scanner()->location().beg_pos;
2283 classifier->RecordExpressionError(scanner()->location(), 2286 classifier->RecordExpressionError(scanner()->location(),
2284 MessageTemplate::kUnexpectedToken, 2287 MessageTemplate::kUnexpectedToken,
2285 Token::String(Token::ELLIPSIS)); 2288 Token::String(Token::ELLIPSIS));
2289 classifier->RecordNonSimpleParameter();
2286 Scanner::Location expr_loc = scanner()->peek_location(); 2290 Scanner::Location expr_loc = scanner()->peek_location();
2287 Token::Value tok = peek(); 2291 Token::Value tok = peek();
2288 result = this->ParseAssignmentExpression(true, classifier, CHECK_OK); 2292 result = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
2289 // Patterns are not allowed as rest parameters. There is no way we can 2293 // Patterns are not allowed as rest parameters. There is no way we can
2290 // succeed so go ahead and use the convenient ReportUnexpectedToken 2294 // succeed so go ahead and use the convenient ReportUnexpectedToken
2291 // interface. 2295 // interface.
2292 if (!Traits::IsIdentifier(result)) { 2296 if (!Traits::IsIdentifier(result)) {
2293 ReportUnexpectedTokenAt(expr_loc, tok); 2297 ReportUnexpectedTokenAt(expr_loc, tok);
2294 *ok = false; 2298 *ok = false;
2295 return this->EmptyExpression(); 2299 return this->EmptyExpression();
2296 } 2300 }
2297 result = factory()->NewSpread(result, ellipsis_pos); 2301 result = factory()->NewSpread(result, ellipsis_pos);
2302
2298 if (peek() == Token::COMMA) { 2303 if (peek() == Token::COMMA) {
2299 ReportMessageAt(scanner()->peek_location(), 2304 ReportMessageAt(scanner()->peek_location(),
2300 MessageTemplate::kParamAfterRest); 2305 MessageTemplate::kParamAfterRest);
2301 *ok = false; 2306 *ok = false;
2302 return this->EmptyExpression(); 2307 return this->EmptyExpression();
2303 } 2308 }
2304 Expect(Token::RPAREN, CHECK_OK); 2309 Expect(Token::RPAREN, CHECK_OK);
2305 } else { 2310 } else {
2306 // Heuristically try to detect immediately called functions before 2311 // Heuristically try to detect immediately called functions before
2307 // seeing the call parentheses. 2312 // seeing the call parentheses.
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2378 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { 2383 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
2379 // Expression :: 2384 // Expression ::
2380 // AssignmentExpression 2385 // AssignmentExpression
2381 // Expression ',' AssignmentExpression 2386 // Expression ',' AssignmentExpression
2382 2387
2383 ExpressionClassifier binding_classifier; 2388 ExpressionClassifier binding_classifier;
2384 ExpressionT result = 2389 ExpressionT result =
2385 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); 2390 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
2386 classifier->Accumulate(binding_classifier, 2391 classifier->Accumulate(binding_classifier,
2387 ExpressionClassifier::AllProductions); 2392 ExpressionClassifier::AllProductions);
2393 bool is_simple_parameter_list = this->IsIdentifier(result);
2388 bool seen_rest = false; 2394 bool seen_rest = false;
2389 while (peek() == Token::COMMA) { 2395 while (peek() == Token::COMMA) {
2390 if (seen_rest) { 2396 if (seen_rest) {
2391 // At this point the production can't possibly be valid, but we don't know 2397 // At this point the production can't possibly be valid, but we don't know
2392 // which error to signal. 2398 // which error to signal.
2393 classifier->RecordArrowFormalParametersError( 2399 classifier->RecordArrowFormalParametersError(
2394 scanner()->peek_location(), MessageTemplate::kParamAfterRest); 2400 scanner()->peek_location(), MessageTemplate::kParamAfterRest);
2395 } 2401 }
2396 Consume(Token::COMMA); 2402 Consume(Token::COMMA);
2397 bool is_rest = false; 2403 bool is_rest = false;
2398 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) { 2404 if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) {
2399 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only 2405 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
2400 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a 2406 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
2401 // valid expression or binding pattern. 2407 // valid expression or binding pattern.
2402 ExpressionUnexpectedToken(classifier); 2408 ExpressionUnexpectedToken(classifier);
2403 BindingPatternUnexpectedToken(classifier); 2409 BindingPatternUnexpectedToken(classifier);
2404 Consume(Token::ELLIPSIS); 2410 Consume(Token::ELLIPSIS);
2405 seen_rest = is_rest = true; 2411 seen_rest = is_rest = true;
2406 } 2412 }
2407 int pos = position(); 2413 int pos = position();
2408 ExpressionT right = this->ParseAssignmentExpression( 2414 ExpressionT right = this->ParseAssignmentExpression(
2409 accept_IN, &binding_classifier, CHECK_OK); 2415 accept_IN, &binding_classifier, CHECK_OK);
2410 if (is_rest) right = factory()->NewSpread(right, pos); 2416 if (is_rest) right = factory()->NewSpread(right, pos);
2417 is_simple_parameter_list =
2418 is_simple_parameter_list && this->IsIdentifier(right);
2411 classifier->Accumulate(binding_classifier, 2419 classifier->Accumulate(binding_classifier,
2412 ExpressionClassifier::AllProductions); 2420 ExpressionClassifier::AllProductions);
2413 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); 2421 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2414 } 2422 }
2423 if (!is_simple_parameter_list || seen_rest) {
2424 classifier->RecordNonSimpleParameter();
2425 }
2415 return result; 2426 return result;
2416 } 2427 }
2417 2428
2418 2429
2419 template <class Traits> 2430 template <class Traits>
2420 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( 2431 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
2421 ExpressionClassifier* classifier, bool* ok) { 2432 ExpressionClassifier* classifier, bool* ok) {
2422 // ArrayLiteral :: 2433 // ArrayLiteral ::
2423 // '[' Expression? (',' Expression?)* ']' 2434 // '[' Expression? (',' Expression?)* ']'
2424 2435
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
2832 2843
2833 if (fni_ != NULL) fni_->Enter(); 2844 if (fni_ != NULL) fni_->Enter();
2834 ParserBase<Traits>::Checkpoint checkpoint(this); 2845 ParserBase<Traits>::Checkpoint checkpoint(this);
2835 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder()); 2846 ExpressionClassifier arrow_formals_classifier(classifier->duplicate_finder());
2836 bool parenthesized_formals = peek() == Token::LPAREN; 2847 bool parenthesized_formals = peek() == Token::LPAREN;
2837 if (!parenthesized_formals) { 2848 if (!parenthesized_formals) {
2838 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); 2849 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
2839 } 2850 }
2840 ExpressionT expression = this->ParseConditionalExpression( 2851 ExpressionT expression = this->ParseConditionalExpression(
2841 accept_IN, &arrow_formals_classifier, CHECK_OK); 2852 accept_IN, &arrow_formals_classifier, CHECK_OK);
2842
2843 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { 2853 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
2844 BindingPatternUnexpectedToken(classifier); 2854 BindingPatternUnexpectedToken(classifier);
2845 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, 2855 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2846 parenthesized_formals, CHECK_OK); 2856 parenthesized_formals, CHECK_OK);
2847 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); 2857 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
2848 Scope* scope = 2858 Scope* scope =
2849 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); 2859 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2850 FormalParametersT parameters(scope); 2860 FormalParametersT parameters(scope);
2861 if (!arrow_formals_classifier.is_simple_parameter_list()) {
2862 scope->SetHasNonSimpleParameters();
2863 parameters.is_simple = false;
2864 }
2851 checkpoint.Restore(&parameters.materialized_literals_count); 2865 checkpoint.Restore(&parameters.materialized_literals_count);
2852 2866
2853 scope->set_start_position(lhs_beg_pos); 2867 scope->set_start_position(lhs_beg_pos);
2854 Scanner::Location duplicate_loc = Scanner::Location::invalid(); 2868 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2855 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc, 2869 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
2856 &duplicate_loc, CHECK_OK); 2870 &duplicate_loc, CHECK_OK);
2857 if (duplicate_loc.IsValid()) { 2871 if (duplicate_loc.IsValid()) {
2858 arrow_formals_classifier.RecordDuplicateFormalParameterError( 2872 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2859 duplicate_loc); 2873 duplicate_loc);
2860 } 2874 }
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after
3655 ValidateBindingPattern(classifier, ok); 3669 ValidateBindingPattern(classifier, ok);
3656 if (!*ok) return; 3670 if (!*ok) return;
3657 3671
3658 if (!Traits::IsIdentifier(pattern)) { 3672 if (!Traits::IsIdentifier(pattern)) {
3659 if (is_rest || !allow_harmony_destructuring()) { 3673 if (is_rest || !allow_harmony_destructuring()) {
3660 ReportUnexpectedToken(next); 3674 ReportUnexpectedToken(next);
3661 *ok = false; 3675 *ok = false;
3662 return; 3676 return;
3663 } 3677 }
3664 parameters->is_simple = false; 3678 parameters->is_simple = false;
3679 classifier->RecordNonSimpleParameter();
3665 } 3680 }
3666 3681
3667 ExpressionT initializer = Traits::EmptyExpression(); 3682 ExpressionT initializer = Traits::EmptyExpression();
3668 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) { 3683 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) {
3669 ExpressionClassifier init_classifier; 3684 ExpressionClassifier init_classifier;
3670 initializer = ParseAssignmentExpression(true, &init_classifier, ok); 3685 initializer = ParseAssignmentExpression(true, &init_classifier, ok);
3671 if (!*ok) return; 3686 if (!*ok) return;
3672 ValidateExpression(&init_classifier, ok); 3687 ValidateExpression(&init_classifier, ok);
3673 if (!*ok) return; 3688 if (!*ok) return;
3674 parameters->is_simple = false; 3689 parameters->is_simple = false;
3690 classifier->RecordNonSimpleParameter();
3675 } 3691 }
3676 3692
3677 Traits::AddFormalParameter(parameters, pattern, initializer, is_rest); 3693 Traits::AddFormalParameter(parameters, pattern, initializer, is_rest);
3678 } 3694 }
3679 3695
3680 3696
3681 template <class Traits> 3697 template <class Traits>
3682 void ParserBase<Traits>::ParseFormalParameterList( 3698 void ParserBase<Traits>::ParseFormalParameterList(
3683 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { 3699 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3684 // FormalParameters[Yield,GeneratorParameter] : 3700 // FormalParameters[Yield,GeneratorParameter] :
(...skipping 20 matching lines...) Expand all
3705 return; 3721 return;
3706 } 3722 }
3707 parameters->has_rest = 3723 parameters->has_rest =
3708 allow_harmony_rest_parameters() && Check(Token::ELLIPSIS); 3724 allow_harmony_rest_parameters() && Check(Token::ELLIPSIS);
3709 ParseFormalParameter(parameters, classifier, ok); 3725 ParseFormalParameter(parameters, classifier, ok);
3710 if (!*ok) return; 3726 if (!*ok) return;
3711 } while (!parameters->has_rest && Check(Token::COMMA)); 3727 } while (!parameters->has_rest && Check(Token::COMMA));
3712 3728
3713 if (parameters->has_rest) { 3729 if (parameters->has_rest) {
3714 parameters->is_simple = false; 3730 parameters->is_simple = false;
3731 classifier->RecordNonSimpleParameter();
3715 if (peek() == Token::COMMA) { 3732 if (peek() == Token::COMMA) {
3716 ReportMessageAt(scanner()->peek_location(), 3733 ReportMessageAt(scanner()->peek_location(),
3717 MessageTemplate::kParamAfterRest); 3734 MessageTemplate::kParamAfterRest);
3718 *ok = false; 3735 *ok = false;
3719 return; 3736 return;
3720 } 3737 }
3721 } 3738 }
3722 } 3739 }
3723 3740
3724 for (int i = 0; i < parameters->Arity(); ++i) { 3741 for (int i = 0; i < parameters->Arity(); ++i) {
3725 auto parameter = parameters->at(i); 3742 auto parameter = parameters->at(i);
3726 Traits::DeclareFormalParameter( 3743 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier);
3727 parameters->scope, parameter, parameters->is_simple, classifier);
3728 } 3744 }
3729 } 3745 }
3730 3746
3731 3747
3732 template <class Traits> 3748 template <class Traits>
3733 void ParserBase<Traits>::CheckArityRestrictions( 3749 void ParserBase<Traits>::CheckArityRestrictions(
3734 int param_count, FunctionLiteral::ArityRestriction arity_restriction, 3750 int param_count, FunctionLiteral::ArityRestriction arity_restriction,
3735 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) { 3751 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) {
3736 switch (arity_restriction) { 3752 switch (arity_restriction) {
3737 case FunctionLiteral::GETTER_ARITY: 3753 case FunctionLiteral::GETTER_ARITY:
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
4060 *ok = false; 4076 *ok = false;
4061 return; 4077 return;
4062 } 4078 }
4063 has_seen_constructor_ = true; 4079 has_seen_constructor_ = true;
4064 return; 4080 return;
4065 } 4081 }
4066 } 4082 }
4067 } } // v8::internal 4083 } } // v8::internal
4068 4084
4069 #endif // V8_PREPARSER_H 4085 #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