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

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: minor test cleanup 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/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);
2860 bool is_simple = arrow_formals_classifier.is_simple_parameter_list();
rossberg 2015/08/24 13:11:08 Nit: avoid the extra variable by storing to parame
conradw 2015/08/25 11:31:20 Done.
2861 if (!is_simple) scope->SetHasNonSimpleParameters();
2850 FormalParametersT parameters(scope); 2862 FormalParametersT parameters(scope);
2863 parameters.is_simple = is_simple;
2851 checkpoint.Restore(&parameters.materialized_literals_count); 2864 checkpoint.Restore(&parameters.materialized_literals_count);
2852 2865
2853 scope->set_start_position(lhs_beg_pos); 2866 scope->set_start_position(lhs_beg_pos);
2854 Scanner::Location duplicate_loc = Scanner::Location::invalid(); 2867 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2855 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc, 2868 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
2856 &duplicate_loc, CHECK_OK); 2869 &duplicate_loc, CHECK_OK);
2857 if (duplicate_loc.IsValid()) { 2870 if (duplicate_loc.IsValid()) {
2858 arrow_formals_classifier.RecordDuplicateFormalParameterError( 2871 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2859 duplicate_loc); 2872 duplicate_loc);
2860 } 2873 }
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after
3654 ValidateBindingPattern(classifier, ok); 3667 ValidateBindingPattern(classifier, ok);
3655 if (!*ok) return; 3668 if (!*ok) return;
3656 3669
3657 if (!Traits::IsIdentifier(pattern)) { 3670 if (!Traits::IsIdentifier(pattern)) {
3658 if (is_rest || !allow_harmony_destructuring()) { 3671 if (is_rest || !allow_harmony_destructuring()) {
3659 ReportUnexpectedToken(next); 3672 ReportUnexpectedToken(next);
3660 *ok = false; 3673 *ok = false;
3661 return; 3674 return;
3662 } 3675 }
3663 parameters->is_simple = false; 3676 parameters->is_simple = false;
3677 classifier->RecordNonSimpleParameter();
3664 } 3678 }
3665 3679
3666 ExpressionT initializer = Traits::EmptyExpression(); 3680 ExpressionT initializer = Traits::EmptyExpression();
3667 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) { 3681 if (!is_rest && allow_harmony_default_parameters() && Check(Token::ASSIGN)) {
3668 ExpressionClassifier init_classifier; 3682 ExpressionClassifier init_classifier;
3669 initializer = ParseAssignmentExpression(true, &init_classifier, ok); 3683 initializer = ParseAssignmentExpression(true, &init_classifier, ok);
3670 if (!*ok) return; 3684 if (!*ok) return;
3671 ValidateExpression(&init_classifier, ok); 3685 ValidateExpression(&init_classifier, ok);
3672 if (!*ok) return; 3686 if (!*ok) return;
3673 parameters->is_simple = false; 3687 parameters->is_simple = false;
3688 classifier->RecordNonSimpleParameter();
3674 } 3689 }
3675 3690
3676 Traits::AddFormalParameter(parameters, pattern, initializer, is_rest); 3691 Traits::AddFormalParameter(parameters, pattern, initializer, is_rest);
3677 } 3692 }
3678 3693
3679 3694
3680 template <class Traits> 3695 template <class Traits>
3681 void ParserBase<Traits>::ParseFormalParameterList( 3696 void ParserBase<Traits>::ParseFormalParameterList(
3682 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { 3697 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
3683 // FormalParameters[Yield,GeneratorParameter] : 3698 // FormalParameters[Yield,GeneratorParameter] :
(...skipping 20 matching lines...) Expand all
3704 return; 3719 return;
3705 } 3720 }
3706 parameters->has_rest = 3721 parameters->has_rest =
3707 allow_harmony_rest_parameters() && Check(Token::ELLIPSIS); 3722 allow_harmony_rest_parameters() && Check(Token::ELLIPSIS);
3708 ParseFormalParameter(parameters, classifier, ok); 3723 ParseFormalParameter(parameters, classifier, ok);
3709 if (!*ok) return; 3724 if (!*ok) return;
3710 } while (!parameters->has_rest && Check(Token::COMMA)); 3725 } while (!parameters->has_rest && Check(Token::COMMA));
3711 3726
3712 if (parameters->has_rest) { 3727 if (parameters->has_rest) {
3713 parameters->is_simple = false; 3728 parameters->is_simple = false;
3729 classifier->RecordNonSimpleParameter();
3714 if (peek() == Token::COMMA) { 3730 if (peek() == Token::COMMA) {
3715 ReportMessageAt(scanner()->peek_location(), 3731 ReportMessageAt(scanner()->peek_location(),
3716 MessageTemplate::kParamAfterRest); 3732 MessageTemplate::kParamAfterRest);
3717 *ok = false; 3733 *ok = false;
3718 return; 3734 return;
3719 } 3735 }
3720 } 3736 }
3721 } 3737 }
3722 3738
3723 for (int i = 0; i < parameters->Arity(); ++i) { 3739 for (int i = 0; i < parameters->Arity(); ++i) {
3724 auto parameter = parameters->at(i); 3740 auto parameter = parameters->at(i);
3725 Traits::DeclareFormalParameter( 3741 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier);
3726 parameters->scope, parameter, parameters->is_simple, classifier);
3727 } 3742 }
3728 } 3743 }
3729 3744
3730 3745
3731 template <class Traits> 3746 template <class Traits>
3732 void ParserBase<Traits>::CheckArityRestrictions( 3747 void ParserBase<Traits>::CheckArityRestrictions(
3733 int param_count, FunctionLiteral::ArityRestriction arity_restriction, 3748 int param_count, FunctionLiteral::ArityRestriction arity_restriction,
3734 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) { 3749 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) {
3735 switch (arity_restriction) { 3750 switch (arity_restriction) {
3736 case FunctionLiteral::GETTER_ARITY: 3751 case FunctionLiteral::GETTER_ARITY:
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
4059 *ok = false; 4074 *ok = false;
4060 return; 4075 return;
4061 } 4076 }
4062 has_seen_constructor_ = true; 4077 has_seen_constructor_ = true;
4063 return; 4078 return;
4064 } 4079 }
4065 } 4080 }
4066 } } // v8::internal 4081 } } // v8::internal
4067 4082
4068 #endif // V8_PREPARSER_H 4083 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698