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

Side by Side Diff: src/parser.cc

Issue 1100713002: Factor formal argument parsing into ParserBase (Closed) Base URL: https://chromium.googlesource.com/v8/v8@master
Patch Set: Avoid DuplicateFinder creation in the full parser Created 5 years, 8 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.h ('k') | src/preparser.h » ('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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 3716 matching lines...) Expand 10 before | Expand all | Expand 10 after
3727 } 3727 }
3728 3728
3729 3729
3730 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { 3730 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3731 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); 3731 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3732 } 3732 }
3733 3733
3734 3734
3735 bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression, 3735 bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression,
3736 Scope* scope, int* num_params, 3736 Scope* scope, int* num_params,
3737 Scanner::Location* undefined_loc, 3737 FormalParameterErrorLocations* locs) {
3738 Scanner::Location* dupe_loc) {
3739 // Case for empty parameter lists: 3738 // Case for empty parameter lists:
3740 // () => ... 3739 // () => ...
3741 if (expression == NULL) return true; 3740 if (expression == NULL) return true;
3742 3741
3743 // Too many parentheses around expression: 3742 // Too many parentheses around expression:
3744 // (( ... )) => ... 3743 // (( ... )) => ...
3745 if (expression->is_multi_parenthesized()) return false; 3744 if (expression->is_multi_parenthesized()) return false;
3746 3745
3747 // Case for a single parameter: 3746 // Case for a single parameter:
3748 // (foo) => ... 3747 // (foo) => ...
3749 // foo => ... 3748 // foo => ...
3750 if (expression->IsVariableProxy()) { 3749 if (expression->IsVariableProxy()) {
3751 if (expression->AsVariableProxy()->is_this()) return false; 3750 if (expression->AsVariableProxy()->is_this()) return false;
3752 3751
3753 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name(); 3752 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name();
3754 if (traits->IsEvalOrArguments(raw_name) || 3753 if (traits->IsEvalOrArguments(raw_name) ||
3755 traits->IsFutureStrictReserved(raw_name)) 3754 traits->IsFutureStrictReserved(raw_name))
3756 return false; 3755 return false;
3757 if (traits->IsUndefined(raw_name) && !undefined_loc->IsValid()) { 3756 if (traits->IsUndefined(raw_name) && !locs->undefined.IsValid()) {
3758 *undefined_loc = Scanner::Location( 3757 locs->undefined = Scanner::Location(
3759 expression->position(), expression->position() + raw_name->length()); 3758 expression->position(), expression->position() + raw_name->length());
3760 } 3759 }
3761 if (scope->IsDeclared(raw_name)) {
3762 *dupe_loc = Scanner::Location(
3763 expression->position(), expression->position() + raw_name->length());
3764 return false;
3765 }
3766 3760
3767 // When the variable was seen, it was recorded as unresolved in the outer 3761 // When the variable was seen, it was recorded as unresolved in the outer
3768 // scope. But it's really not unresolved. 3762 // scope. But it's really not unresolved.
3769 scope->outer_scope()->RemoveUnresolved(expression->AsVariableProxy()); 3763 scope->outer_scope()->RemoveUnresolved(expression->AsVariableProxy());
3770 3764
3771 scope->DeclareParameter(raw_name, VAR); 3765 bool is_rest = false;
3766 bool is_duplicate = false;
3767 scope->DeclareParameter(raw_name, VAR, is_rest, &is_duplicate);
3768 if (is_duplicate) {
3769 locs->duplicate = Scanner::Location(
3770 expression->position(), expression->position() + raw_name->length());
3771 return false;
3772 }
3773
3772 ++(*num_params); 3774 ++(*num_params);
3773 return true; 3775 return true;
3774 } 3776 }
3775 3777
3776 // Case for more than one parameter: 3778 // Case for more than one parameter:
3777 // (foo, bar [, ...]) => ... 3779 // (foo, bar [, ...]) => ...
3778 if (expression->IsBinaryOperation()) { 3780 if (expression->IsBinaryOperation()) {
3779 BinaryOperation* binop = expression->AsBinaryOperation(); 3781 BinaryOperation* binop = expression->AsBinaryOperation();
3780 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() || 3782 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() ||
3781 binop->right()->is_parenthesized()) 3783 binop->right()->is_parenthesized())
3782 return false; 3784 return false;
3783 3785
3784 return CheckAndDeclareArrowParameter(traits, binop->left(), scope, 3786 return CheckAndDeclareArrowParameter(traits, binop->left(), scope,
3785 num_params, undefined_loc, dupe_loc) && 3787 num_params, locs) &&
3786 CheckAndDeclareArrowParameter(traits, binop->right(), scope, 3788 CheckAndDeclareArrowParameter(traits, binop->right(), scope,
3787 num_params, undefined_loc, dupe_loc); 3789 num_params, locs);
3788 } 3790 }
3789 3791
3790 // Any other kind of expression is not a valid parameter list. 3792 // Any other kind of expression is not a valid parameter list.
3791 return false; 3793 return false;
3792 } 3794 }
3793 3795
3794 3796
3795 int ParserTraits::DeclareArrowParametersFromExpression( 3797 int ParserTraits::DeclareArrowParametersFromExpression(
3796 Expression* expression, Scope* scope, Scanner::Location* undefined_loc, 3798 Expression* expression, Scope* scope, FormalParameterErrorLocations* locs,
3797 Scanner::Location* dupe_loc, bool* ok) { 3799 bool* ok) {
3798 int num_params = 0; 3800 int num_params = 0;
3799 // Always reset the flag: It only needs to be set for the first expression 3801 // Always reset the flag: It only needs to be set for the first expression
3800 // parsed as arrow function parameter list, because only top-level functions 3802 // parsed as arrow function parameter list, because only top-level functions
3801 // are parsed lazily. 3803 // are parsed lazily.
3802 parser_->parsing_lazy_arrow_parameters_ = false; 3804 parser_->parsing_lazy_arrow_parameters_ = false;
3803 *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params, 3805 *ok =
3804 undefined_loc, dupe_loc); 3806 CheckAndDeclareArrowParameter(this, expression, scope, &num_params, locs);
3805 return num_params; 3807 return num_params;
3806 } 3808 }
3807 3809
3808 3810
3809 FunctionLiteral* Parser::ParseFunctionLiteral( 3811 FunctionLiteral* Parser::ParseFunctionLiteral(
3810 const AstRawString* function_name, Scanner::Location function_name_location, 3812 const AstRawString* function_name, Scanner::Location function_name_location,
3811 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, 3813 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
3812 FunctionLiteral::FunctionType function_type, 3814 FunctionLiteral::FunctionType function_type,
3813 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { 3815 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
3814 // Function :: 3816 // Function ::
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3868 Scope* scope = function_type == FunctionLiteral::DECLARATION && 3870 Scope* scope = function_type == FunctionLiteral::DECLARATION &&
3869 is_sloppy(language_mode()) && 3871 is_sloppy(language_mode()) &&
3870 (original_scope_ == original_declaration_scope || 3872 (original_scope_ == original_declaration_scope ||
3871 declaration_scope != original_declaration_scope) 3873 declaration_scope != original_declaration_scope)
3872 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind) 3874 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind)
3873 : NewScope(scope_, FUNCTION_SCOPE, kind); 3875 : NewScope(scope_, FUNCTION_SCOPE, kind);
3874 ZoneList<Statement*>* body = NULL; 3876 ZoneList<Statement*>* body = NULL;
3875 int materialized_literal_count = -1; 3877 int materialized_literal_count = -1;
3876 int expected_property_count = -1; 3878 int expected_property_count = -1;
3877 int handler_count = 0; 3879 int handler_count = 0;
3878 FunctionLiteral::ParameterFlag duplicate_parameters = 3880 FormalParameterErrorLocations error_locs;
3879 FunctionLiteral::kNoDuplicateParameters;
3880 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ 3881 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
3881 ? FunctionLiteral::kIsParenthesized 3882 ? FunctionLiteral::kIsParenthesized
3882 : FunctionLiteral::kNotParenthesized; 3883 : FunctionLiteral::kNotParenthesized;
3883 // Parse function body. 3884 // Parse function body.
3884 { 3885 {
3885 AstNodeFactory function_factory(ast_value_factory()); 3886 AstNodeFactory function_factory(ast_value_factory());
3886 FunctionState function_state(&function_state_, &scope_, scope, kind, 3887 FunctionState function_state(&function_state_, &scope_, scope, kind,
3887 &function_factory); 3888 &function_factory);
3888 scope_->SetScopeName(function_name); 3889 scope_->SetScopeName(function_name);
3889 3890
3890 if (is_generator) { 3891 if (is_generator) {
3891 // For generators, allocating variables in contexts is currently a win 3892 // For generators, allocating variables in contexts is currently a win
3892 // because it minimizes the work needed to suspend and resume an 3893 // because it minimizes the work needed to suspend and resume an
3893 // activation. 3894 // activation.
3894 scope_->ForceContextAllocation(); 3895 scope_->ForceContextAllocation();
3895 3896
3896 // Calling a generator returns a generator object. That object is stored 3897 // Calling a generator returns a generator object. That object is stored
3897 // in a temporary variable, a definition that is used by "yield" 3898 // in a temporary variable, a definition that is used by "yield"
3898 // expressions. This also marks the FunctionState as a generator. 3899 // expressions. This also marks the FunctionState as a generator.
3899 Variable* temp = scope_->DeclarationScope()->NewTemporary( 3900 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3900 ast_value_factory()->dot_generator_object_string()); 3901 ast_value_factory()->dot_generator_object_string());
3901 function_state.set_generator_object_variable(temp); 3902 function_state.set_generator_object_variable(temp);
3902 } 3903 }
3903 3904
3904 // FormalParameterList :: 3905 bool has_rest = false;
3905 // '(' (Identifier)*[','] ')'
3906 Expect(Token::LPAREN, CHECK_OK); 3906 Expect(Token::LPAREN, CHECK_OK);
3907 scope->set_start_position(scanner()->location().beg_pos); 3907 int start_position = scanner()->location().beg_pos;
3908 scope_->set_start_position(start_position);
3909 num_parameters =
3910 ParseFormalParameterList(scope, &error_locs, &has_rest, CHECK_OK);
3911 Expect(Token::RPAREN, CHECK_OK);
3912 int formals_end_position = scanner()->location().end_pos;
3908 3913
3909 // We don't yet know if the function will be strict, so we cannot yet 3914 CheckArityRestrictions(num_parameters, arity_restriction, start_position,
3910 // produce errors for parameter names or duplicates. However, we remember 3915 formals_end_position, CHECK_OK);
3911 // the locations of these errors if they occur and produce the errors later.
3912 Scanner::Location eval_args_loc = Scanner::Location::invalid();
3913 Scanner::Location dupe_loc = Scanner::Location::invalid();
3914 Scanner::Location reserved_loc = Scanner::Location::invalid();
3915
3916 // Similarly for strong mode.
3917 Scanner::Location undefined_loc = Scanner::Location::invalid();
3918
3919 bool is_rest = false;
3920 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
3921 (peek() == Token::RPAREN &&
3922 arity_restriction != FunctionLiteral::SETTER_ARITY);
3923 while (!done) {
3924 bool is_strict_reserved = false;
3925 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params();
3926 if (is_rest) {
3927 Consume(Token::ELLIPSIS);
3928 }
3929
3930 const AstRawString* param_name =
3931 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
3932
3933 // Store locations for possible future error reports.
3934 if (!eval_args_loc.IsValid() && IsEvalOrArguments(param_name)) {
3935 eval_args_loc = scanner()->location();
3936 }
3937 if (!undefined_loc.IsValid() && IsUndefined(param_name)) {
3938 undefined_loc = scanner()->location();
3939 }
3940 if (!reserved_loc.IsValid() && is_strict_reserved) {
3941 reserved_loc = scanner()->location();
3942 }
3943 if (!dupe_loc.IsValid() &&
3944 scope_->IsDeclaredParameter(param_name)) {
3945 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3946 dupe_loc = scanner()->location();
3947 }
3948
3949 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest);
3950 if (is_sloppy(scope->language_mode())) {
3951 // TODO(sigurds) Mark every parameter as maybe assigned. This is a
3952 // conservative approximation necessary to account for parameters
3953 // that are assigned via the arguments array.
3954 var->set_maybe_assigned();
3955 }
3956
3957 num_parameters++;
3958 if (num_parameters > Code::kMaxArguments) {
3959 ReportMessage("too_many_parameters");
3960 *ok = false;
3961 return NULL;
3962 }
3963 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
3964 done = (peek() == Token::RPAREN);
3965 if (!done) {
3966 if (is_rest) {
3967 ReportMessageAt(scanner()->peek_location(), "param_after_rest");
3968 *ok = false;
3969 return NULL;
3970 }
3971 Expect(Token::COMMA, CHECK_OK);
3972 }
3973 }
3974 Expect(Token::RPAREN, CHECK_OK);
3975 3916
3976 Expect(Token::LBRACE, CHECK_OK); 3917 Expect(Token::LBRACE, CHECK_OK);
3977 3918
3978 // If we have a named function expression, we add a local variable 3919 // If we have a named function expression, we add a local variable
3979 // declaration to the body of the function with the name of the 3920 // declaration to the body of the function with the name of the
3980 // function and let it refer to the function itself (closure). 3921 // function and let it refer to the function itself (closure).
3981 // NOTE: We create a proxy and resolve it here so that in the 3922 // NOTE: We create a proxy and resolve it here so that in the
3982 // future we can change the AST to only refer to VariableProxies 3923 // future we can change the AST to only refer to VariableProxies
3983 // instead of Variables and Proxis as is the case now. 3924 // instead of Variables and Proxis as is the case now.
3984 Variable* fvar = NULL; 3925 Variable* fvar = NULL;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
4046 materialized_literal_count = function_state.materialized_literal_count(); 3987 materialized_literal_count = function_state.materialized_literal_count();
4047 expected_property_count = function_state.expected_property_count(); 3988 expected_property_count = function_state.expected_property_count();
4048 handler_count = function_state.handler_count(); 3989 handler_count = function_state.handler_count();
4049 } 3990 }
4050 3991
4051 // Validate name and parameter names. We can do this only after parsing the 3992 // Validate name and parameter names. We can do this only after parsing the
4052 // function, since the function can declare itself strict. 3993 // function, since the function can declare itself strict.
4053 CheckFunctionName(language_mode(), kind, function_name, 3994 CheckFunctionName(language_mode(), kind, function_name,
4054 name_is_strict_reserved, function_name_location, 3995 name_is_strict_reserved, function_name_location,
4055 CHECK_OK); 3996 CHECK_OK);
4056 const bool use_strict_params = is_rest || IsConciseMethod(kind); 3997 const bool use_strict_params = has_rest || IsConciseMethod(kind);
4057 CheckFunctionParameterNames(language_mode(), use_strict_params, 3998 CheckFunctionParameterNames(language_mode(), use_strict_params, error_locs,
4058 eval_args_loc, undefined_loc, dupe_loc, 3999 CHECK_OK);
4059 reserved_loc, CHECK_OK);
4060 4000
4061 if (is_strict(language_mode())) { 4001 if (is_strict(language_mode())) {
4062 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), 4002 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
4063 CHECK_OK); 4003 CHECK_OK);
4064 } 4004 }
4065 if (is_strict(language_mode())) { 4005 if (is_strict(language_mode())) {
4066 CheckConflictingVarDeclarations(scope, CHECK_OK); 4006 CheckConflictingVarDeclarations(scope, CHECK_OK);
4067 } 4007 }
4068 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { 4008 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
4069 if (!function_state.super_call_location().IsValid()) { 4009 if (!function_state.super_call_location().IsValid()) {
4070 ReportMessageAt(function_name_location, "strong_super_call_missing", 4010 ReportMessageAt(function_name_location, "strong_super_call_missing",
4071 kReferenceError); 4011 kReferenceError);
4072 *ok = false; 4012 *ok = false;
4073 return nullptr; 4013 return nullptr;
4074 } 4014 }
4075 } 4015 }
4076 } 4016 }
4077 4017
4018 FunctionLiteral::ParameterFlag duplicate_parameters =
4019 error_locs.duplicate.IsValid() ? FunctionLiteral::kHasDuplicateParameters
4020 : FunctionLiteral::kNoDuplicateParameters;
4021
4078 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 4022 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
4079 function_name, ast_value_factory(), scope, body, 4023 function_name, ast_value_factory(), scope, body,
4080 materialized_literal_count, expected_property_count, handler_count, 4024 materialized_literal_count, expected_property_count, handler_count,
4081 num_parameters, duplicate_parameters, function_type, 4025 num_parameters, duplicate_parameters, function_type,
4082 FunctionLiteral::kIsFunction, parenthesized, kind, pos); 4026 FunctionLiteral::kIsFunction, parenthesized, kind, pos);
4083 function_literal->set_function_token_position(function_token_pos); 4027 function_literal->set_function_token_position(function_token_pos);
4084 4028
4085 if (scope->has_rest_parameter()) { 4029 if (scope->has_rest_parameter()) {
4086 // TODO(caitp): enable optimization of functions with rest params 4030 // TODO(caitp): enable optimization of functions with rest params
4087 function_literal->set_dont_optimize_reason(kRestParameter); 4031 function_literal->set_dont_optimize_reason(kRestParameter);
(...skipping 1691 matching lines...) Expand 10 before | Expand all | Expand 10 after
5779 5723
5780 Expression* Parser::SpreadCallNew(Expression* function, 5724 Expression* Parser::SpreadCallNew(Expression* function,
5781 ZoneList<v8::internal::Expression*>* args, 5725 ZoneList<v8::internal::Expression*>* args,
5782 int pos) { 5726 int pos) {
5783 args->InsertAt(0, function, zone()); 5727 args->InsertAt(0, function, zone());
5784 5728
5785 return factory()->NewCallRuntime( 5729 return factory()->NewCallRuntime(
5786 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5730 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5787 } 5731 }
5788 } } // namespace v8::internal 5732 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698