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 #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 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 return NULL; | 780 return NULL; |
781 } | 781 } |
782 | 782 |
783 | 783 |
784 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name, | 784 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name, |
785 int start_position, | 785 int start_position, |
786 int end_position, | 786 int end_position, |
787 Scope* scope, | 787 Scope* scope, |
788 AstNodeFactory* factory) { | 788 AstNodeFactory* factory) { |
789 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); | 789 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); |
790 return scope->NewUnresolved(factory, name, start_position, end_position); | 790 |
| 791 // Arrow function parameters are parsed as an expression. When |
| 792 // parsing lazily, it is enough to create a VariableProxy in order |
| 793 // for Traits::DeclareArrowParametersFromExpression() to be able to |
| 794 // pick the names of the parameters. |
| 795 return parser_->parsing_lazy_arrow_parameters_ |
| 796 ? factory->NewVariableProxy(name, Variable::NORMAL, start_position, |
| 797 end_position) |
| 798 : scope->NewUnresolved(factory, name, start_position, |
| 799 end_position); |
791 } | 800 } |
792 | 801 |
793 | 802 |
794 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner, | 803 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner, |
795 AstNodeFactory* factory) { | 804 AstNodeFactory* factory) { |
796 const AstRawString* symbol = GetSymbol(scanner); | 805 const AstRawString* symbol = GetSymbol(scanner); |
797 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); | 806 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
798 return factory->NewStringLiteral(symbol, pos); | 807 return factory->NewStringLiteral(symbol, pos); |
799 } | 808 } |
800 | 809 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 Parser::Parser(ParseInfo* info) | 854 Parser::Parser(ParseInfo* info) |
846 : ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(), | 855 : ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(), |
847 info->extension(), info->ast_value_factory(), | 856 info->extension(), info->ast_value_factory(), |
848 NULL, this), | 857 NULL, this), |
849 scanner_(info->unicode_cache()), | 858 scanner_(info->unicode_cache()), |
850 reusable_preparser_(NULL), | 859 reusable_preparser_(NULL), |
851 original_scope_(NULL), | 860 original_scope_(NULL), |
852 target_stack_(NULL), | 861 target_stack_(NULL), |
853 compile_options_(info->compile_options()), | 862 compile_options_(info->compile_options()), |
854 cached_parse_data_(NULL), | 863 cached_parse_data_(NULL), |
| 864 parsing_lazy_arrow_parameters_(false), |
855 total_preparse_skipped_(0), | 865 total_preparse_skipped_(0), |
856 pre_parse_timer_(NULL), | 866 pre_parse_timer_(NULL), |
857 parsing_on_main_thread_(true) { | 867 parsing_on_main_thread_(true) { |
858 // Even though we were passed ParseInfo, we should not store it in | 868 // Even though we were passed ParseInfo, we should not store it in |
859 // Parser - this makes sure that Isolate is not accidentally accessed via | 869 // Parser - this makes sure that Isolate is not accidentally accessed via |
860 // ParseInfo during background parsing. | 870 // ParseInfo during background parsing. |
861 DCHECK(!info->script().is_null() || info->source_stream() != NULL); | 871 DCHECK(!info->script().is_null() || info->source_stream() != NULL); |
862 set_allow_lazy(info->allow_lazy_parsing()); | 872 set_allow_lazy(info->allow_lazy_parsing()); |
863 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 873 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
864 set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules); | 874 set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules); |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1125 DCHECK(info->language_mode() == shared_info->language_mode()); | 1135 DCHECK(info->language_mode() == shared_info->language_mode()); |
1126 scope->SetLanguageMode(shared_info->language_mode()); | 1136 scope->SetLanguageMode(shared_info->language_mode()); |
1127 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 1137 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
1128 ? (shared_info->is_anonymous() | 1138 ? (shared_info->is_anonymous() |
1129 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1139 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
1130 : FunctionLiteral::NAMED_EXPRESSION) | 1140 : FunctionLiteral::NAMED_EXPRESSION) |
1131 : FunctionLiteral::DECLARATION; | 1141 : FunctionLiteral::DECLARATION; |
1132 bool ok = true; | 1142 bool ok = true; |
1133 | 1143 |
1134 if (shared_info->is_arrow()) { | 1144 if (shared_info->is_arrow()) { |
1135 FormalParameterErrorLocations error_locs; | 1145 // The first expression being parsed is the parameter list of the arrow |
1136 bool has_rest = false; | 1146 // function. Setting this avoids prevents ExpressionFromIdentifier() |
1137 ZoneList<const AstRawString*>* params; | 1147 // from creating unresolved variables in already-resolved scopes. |
1138 if (Check(Token::LPAREN)) { | 1148 parsing_lazy_arrow_parameters_ = true; |
1139 // '(' StrictFormalParameters ')' | 1149 Expression* expression = ParseExpression(false, &ok); |
1140 params = ParseFormalParameterList(&error_locs, &has_rest, &ok); | |
1141 if (ok) ok = Check(Token::RPAREN); | |
1142 } else { | |
1143 // BindingIdentifier | |
1144 params = NewFormalParameterList(1, zone()); | |
1145 DuplicateFinder* null_duplicate_finder = nullptr; | |
1146 const AstRawString* single_param = | |
1147 ParseFormalParameter(null_duplicate_finder, &error_locs, &ok); | |
1148 if (ok) params->Add(single_param, zone()); | |
1149 } | |
1150 | |
1151 if (ok) { | 1150 if (ok) { |
1152 Expression* expression = ParseArrowFunctionLiteral( | 1151 // Scanning must end at the same position that was recorded |
1153 shared_info->start_position(), params, error_locs, has_rest, &ok); | 1152 // previously. If not, parsing has been interrupted due to a |
1154 if (ok) { | 1153 // stack overflow, at which point the partially parsed arrow |
1155 // Scanning must end at the same position that was recorded | 1154 // function concise body happens to be a valid expression. This |
1156 // previously. If not, parsing has been interrupted due to a stack | 1155 // is a problem only for arrow functions with single statement |
1157 // overflow, at which point the partially parsed arrow function | 1156 // bodies, since there is no end token such as "}" for normal |
1158 // concise body happens to be a valid expression. This is a problem | 1157 // functions. |
1159 // only for arrow functions with single expression bodies, since there | 1158 if (scanner()->location().end_pos == shared_info->end_position()) { |
1160 // is no end token such as "}" for normal functions. | 1159 // The pre-parser saw an arrow function here, so the full parser |
1161 if (scanner()->location().end_pos == shared_info->end_position()) { | 1160 // must produce a FunctionLiteral. |
1162 // The pre-parser saw an arrow function here, so the full parser | 1161 DCHECK(expression->IsFunctionLiteral()); |
1163 // must produce a FunctionLiteral. | 1162 result = expression->AsFunctionLiteral(); |
1164 DCHECK(expression->IsFunctionLiteral()); | 1163 } else { |
1165 result = expression->AsFunctionLiteral(); | 1164 result = NULL; |
1166 } else { | 1165 ok = false; |
1167 ok = false; | |
1168 } | |
1169 } | 1166 } |
1170 } | 1167 } |
1171 } else if (shared_info->is_default_constructor()) { | 1168 } else if (shared_info->is_default_constructor()) { |
1172 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()), | 1169 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()), |
1173 scope, shared_info->start_position(), | 1170 scope, shared_info->start_position(), |
1174 shared_info->end_position()); | 1171 shared_info->end_position()); |
1175 } else { | 1172 } else { |
1176 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), | 1173 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), |
1177 false, // Strict mode name already checked. | 1174 false, // Strict mode name already checked. |
1178 shared_info->kind(), RelocInfo::kNoPosition, | 1175 shared_info->kind(), RelocInfo::kNoPosition, |
(...skipping 2551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3730 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); | 3727 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); |
3731 return static_cast<LiteralType>(literal_type->value()); | 3728 return static_cast<LiteralType>(literal_type->value()); |
3732 } | 3729 } |
3733 | 3730 |
3734 | 3731 |
3735 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { | 3732 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
3736 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); | 3733 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); |
3737 } | 3734 } |
3738 | 3735 |
3739 | 3736 |
3740 void ParserTraits::RecordArrowFunctionParameter( | 3737 bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression, |
3741 ZoneList<const AstRawString*>* params, VariableProxy* proxy, | 3738 Scope* scope, int* num_params, |
3742 FormalParameterErrorLocations* error_locs, bool* ok) { | 3739 Scanner::Location* undefined_loc, |
3743 const AstRawString* raw_name = proxy->raw_name(); | 3740 Scanner::Location* dupe_loc) { |
3744 Scanner::Location param_location(proxy->position(), | 3741 // Case for empty parameter lists: |
3745 proxy->position() + raw_name->length()); | 3742 // () => ... |
| 3743 if (expression == NULL) return true; |
3746 | 3744 |
3747 if (proxy->is_this()) { | 3745 // Too many parentheses around expression: |
3748 ReportMessageAt(param_location, "this_formal_parameter"); | 3746 // (( ... )) => ... |
3749 *ok = false; | 3747 if (expression->is_multi_parenthesized()) return false; |
3750 return; | 3748 |
| 3749 // Case for a single parameter: |
| 3750 // (foo) => ... |
| 3751 // foo => ... |
| 3752 if (expression->IsVariableProxy()) { |
| 3753 if (expression->AsVariableProxy()->is_this()) return false; |
| 3754 |
| 3755 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name(); |
| 3756 if (traits->IsEvalOrArguments(raw_name) || |
| 3757 traits->IsFutureStrictReserved(raw_name)) |
| 3758 return false; |
| 3759 if (traits->IsUndefined(raw_name) && !undefined_loc->IsValid()) { |
| 3760 *undefined_loc = Scanner::Location( |
| 3761 expression->position(), expression->position() + raw_name->length()); |
| 3762 } |
| 3763 if (scope->IsDeclared(raw_name)) { |
| 3764 *dupe_loc = Scanner::Location( |
| 3765 expression->position(), expression->position() + raw_name->length()); |
| 3766 return false; |
| 3767 } |
| 3768 |
| 3769 // When the variable was seen, it was recorded as unresolved in the outer |
| 3770 // scope. But it's really not unresolved. |
| 3771 scope->outer_scope()->RemoveUnresolved(expression->AsVariableProxy()); |
| 3772 |
| 3773 scope->DeclareParameter(raw_name, VAR); |
| 3774 ++(*num_params); |
| 3775 return true; |
3751 } | 3776 } |
3752 | 3777 |
3753 if (!error_locs->eval_or_arguments.IsValid() && IsEvalOrArguments(raw_name)) | 3778 // Case for more than one parameter: |
3754 error_locs->eval_or_arguments = param_location; | 3779 // (foo, bar [, ...]) => ... |
3755 if (!error_locs->reserved.IsValid() && IsFutureStrictReserved(raw_name)) | 3780 if (expression->IsBinaryOperation()) { |
3756 error_locs->reserved = param_location; | 3781 BinaryOperation* binop = expression->AsBinaryOperation(); |
3757 if (!error_locs->undefined.IsValid() && IsUndefined(raw_name)) | 3782 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() || |
3758 error_locs->undefined = param_location; | 3783 binop->right()->is_parenthesized()) |
| 3784 return false; |
3759 | 3785 |
3760 // TODO(wingo): Fix quadratic check. (Scope::IsDeclaredParameter has the same | 3786 return CheckAndDeclareArrowParameter(traits, binop->left(), scope, |
3761 // issue.) | 3787 num_params, undefined_loc, dupe_loc) && |
3762 for (int i = 0; i < params->length(); i++) { | 3788 CheckAndDeclareArrowParameter(traits, binop->right(), scope, |
3763 // Eagerly report the error here; duplicate formal parameter names are never | 3789 num_params, undefined_loc, dupe_loc); |
3764 // allowed in arrow functions. | |
3765 if (raw_name == params->at(i)) { | |
3766 ReportMessageAt(param_location, | |
3767 "duplicate_arrow_function_formal_parameter"); | |
3768 *ok = false; | |
3769 return; | |
3770 } | |
3771 } | 3790 } |
3772 | 3791 |
3773 // When the formal parameter was originally seen, it was parsed as a | 3792 // Any other kind of expression is not a valid parameter list. |
3774 // VariableProxy and recorded as unresolved in the scope. Here we undo that | 3793 return false; |
3775 // parse-time side-effect. | |
3776 parser_->scope_->RemoveUnresolved(proxy); | |
3777 | |
3778 params->Add(raw_name, parser_->zone()); | |
3779 } | 3794 } |
3780 | 3795 |
3781 | 3796 |
3782 // Arrow function parameter lists are parsed as StrictFormalParameters, which | 3797 int ParserTraits::DeclareArrowParametersFromExpression( |
3783 // means that they cannot have duplicates. Note that this is a subset of the | 3798 Expression* expression, Scope* scope, Scanner::Location* undefined_loc, |
3784 // restrictions placed on parameters to functions whose body is strict. | 3799 Scanner::Location* dupe_loc, bool* ok) { |
3785 ZoneList<const AstRawString*>* | 3800 int num_params = 0; |
3786 ParserTraits::ParseArrowFunctionFormalParameterList( | 3801 // Always reset the flag: It only needs to be set for the first expression |
3787 Expression* params, const Scanner::Location& params_loc, | 3802 // parsed as arrow function parameter list, because only top-level functions |
3788 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok) { | 3803 // are parsed lazily. |
3789 ZoneList<const AstRawString*>* result = | 3804 parser_->parsing_lazy_arrow_parameters_ = false; |
3790 NewFormalParameterList(4, parser_->zone()); | 3805 *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params, |
3791 | 3806 undefined_loc, dupe_loc); |
3792 DCHECK_NOT_NULL(params); | 3807 return num_params; |
3793 | |
3794 // Too many parentheses around expression: | |
3795 // (( ... )) => ... | |
3796 if (params->is_multi_parenthesized()) { | |
3797 // TODO(wingo): Make a better message. | |
3798 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
3799 *ok = false; | |
3800 return NULL; | |
3801 } | |
3802 | |
3803 // ArrowFunctionFormals :: | |
3804 // VariableProxy | |
3805 // Binary(Token::COMMA, ArrowFunctionFormals, VariableProxy) | |
3806 // | |
3807 // To stay iterative we'll process arguments in right-to-left order, then | |
3808 // reverse the list in place. | |
3809 // | |
3810 // Sadly, for the various malformed_arrow_function_parameter_list errors, we | |
3811 // can't be more specific on the error message or on the location because we | |
3812 // need to match the pre-parser's behavior. | |
3813 while (params->IsBinaryOperation()) { | |
3814 BinaryOperation* binop = params->AsBinaryOperation(); | |
3815 Expression* left = binop->left(); | |
3816 Expression* right = binop->right(); | |
3817 if (binop->op() != Token::COMMA) { | |
3818 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
3819 *ok = false; | |
3820 return NULL; | |
3821 } | |
3822 // RHS of comma expression should be an unparenthesized variable proxy. | |
3823 if (right->is_parenthesized() || !right->IsVariableProxy()) { | |
3824 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
3825 *ok = false; | |
3826 return NULL; | |
3827 } | |
3828 RecordArrowFunctionParameter(result, right->AsVariableProxy(), error_locs, | |
3829 CHECK_OK); | |
3830 // LHS of comma expression should be unparenthesized. | |
3831 params = left; | |
3832 if (params->is_parenthesized()) { | |
3833 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
3834 *ok = false; | |
3835 return NULL; | |
3836 } | |
3837 | |
3838 if (result->length() > Code::kMaxArguments) { | |
3839 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
3840 *ok = false; | |
3841 return NULL; | |
3842 } | |
3843 } | |
3844 | |
3845 if (params->IsVariableProxy()) { | |
3846 RecordArrowFunctionParameter(result, params->AsVariableProxy(), error_locs, | |
3847 CHECK_OK); | |
3848 } else { | |
3849 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
3850 *ok = false; | |
3851 return NULL; | |
3852 } | |
3853 | |
3854 // Reverse in place. | |
3855 std::reverse(result->begin(), result->end()); | |
3856 | |
3857 return result; | |
3858 } | 3808 } |
3859 | 3809 |
3860 | 3810 |
3861 int ParserTraits::DeclareFormalParameters(ZoneList<const AstRawString*>* params, | |
3862 Scope* scope, bool has_rest) { | |
3863 for (int i = 0; i < params->length(); i++) { | |
3864 const AstRawString* param_name = params->at(i); | |
3865 int is_rest = has_rest && i == params->length() - 1; | |
3866 Variable* var = scope->DeclareParameter(param_name, VAR, is_rest); | |
3867 if (is_sloppy(scope->language_mode())) { | |
3868 // TODO(sigurds) Mark every parameter as maybe assigned. This is a | |
3869 // conservative approximation necessary to account for parameters | |
3870 // that are assigned via the arguments array. | |
3871 var->set_maybe_assigned(); | |
3872 } | |
3873 } | |
3874 return params->length(); | |
3875 } | |
3876 | |
3877 | |
3878 FunctionLiteral* Parser::ParseFunctionLiteral( | 3811 FunctionLiteral* Parser::ParseFunctionLiteral( |
3879 const AstRawString* function_name, Scanner::Location function_name_location, | 3812 const AstRawString* function_name, Scanner::Location function_name_location, |
3880 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, | 3813 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, |
3881 FunctionLiteral::FunctionType function_type, | 3814 FunctionLiteral::FunctionType function_type, |
3882 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { | 3815 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { |
3883 // Function :: | 3816 // Function :: |
3884 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3817 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
3885 // | 3818 // |
3886 // Getter :: | 3819 // Getter :: |
3887 // '(' ')' '{' FunctionBody '}' | 3820 // '(' ')' '{' FunctionBody '}' |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3963 scope_->ForceContextAllocation(); | 3896 scope_->ForceContextAllocation(); |
3964 | 3897 |
3965 // Calling a generator returns a generator object. That object is stored | 3898 // Calling a generator returns a generator object. That object is stored |
3966 // in a temporary variable, a definition that is used by "yield" | 3899 // in a temporary variable, a definition that is used by "yield" |
3967 // expressions. This also marks the FunctionState as a generator. | 3900 // expressions. This also marks the FunctionState as a generator. |
3968 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3901 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
3969 ast_value_factory()->dot_generator_object_string()); | 3902 ast_value_factory()->dot_generator_object_string()); |
3970 function_state.set_generator_object_variable(temp); | 3903 function_state.set_generator_object_variable(temp); |
3971 } | 3904 } |
3972 | 3905 |
3973 FormalParameterErrorLocations error_locs; | 3906 // FormalParameterList :: |
3974 bool has_rest = false; | 3907 // '(' (Identifier)*[','] ')' |
3975 Expect(Token::LPAREN, CHECK_OK); | 3908 Expect(Token::LPAREN, CHECK_OK); |
3976 int start_position = scanner()->location().beg_pos; | 3909 scope->set_start_position(scanner()->location().beg_pos); |
3977 ZoneList<const AstRawString*>* params = | 3910 |
3978 ParseFormalParameterList(&error_locs, &has_rest, CHECK_OK); | 3911 // We don't yet know if the function will be strict, so we cannot yet |
| 3912 // produce errors for parameter names or duplicates. However, we remember |
| 3913 // the locations of these errors if they occur and produce the errors later. |
| 3914 Scanner::Location eval_args_loc = Scanner::Location::invalid(); |
| 3915 Scanner::Location dupe_loc = Scanner::Location::invalid(); |
| 3916 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 3917 |
| 3918 // Similarly for strong mode. |
| 3919 Scanner::Location undefined_loc = Scanner::Location::invalid(); |
| 3920 |
| 3921 bool is_rest = false; |
| 3922 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || |
| 3923 (peek() == Token::RPAREN && |
| 3924 arity_restriction != FunctionLiteral::SETTER_ARITY); |
| 3925 while (!done) { |
| 3926 bool is_strict_reserved = false; |
| 3927 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params(); |
| 3928 if (is_rest) { |
| 3929 Consume(Token::ELLIPSIS); |
| 3930 } |
| 3931 |
| 3932 const AstRawString* param_name = |
| 3933 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 3934 |
| 3935 // Store locations for possible future error reports. |
| 3936 if (!eval_args_loc.IsValid() && IsEvalOrArguments(param_name)) { |
| 3937 eval_args_loc = scanner()->location(); |
| 3938 } |
| 3939 if (!undefined_loc.IsValid() && IsUndefined(param_name)) { |
| 3940 undefined_loc = scanner()->location(); |
| 3941 } |
| 3942 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 3943 reserved_loc = scanner()->location(); |
| 3944 } |
| 3945 if (!dupe_loc.IsValid() && |
| 3946 scope_->IsDeclaredParameter(param_name)) { |
| 3947 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
| 3948 dupe_loc = scanner()->location(); |
| 3949 } |
| 3950 |
| 3951 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest); |
| 3952 if (is_sloppy(scope->language_mode())) { |
| 3953 // TODO(sigurds) Mark every parameter as maybe assigned. This is a |
| 3954 // conservative approximation necessary to account for parameters |
| 3955 // that are assigned via the arguments array. |
| 3956 var->set_maybe_assigned(); |
| 3957 } |
| 3958 |
| 3959 num_parameters++; |
| 3960 if (num_parameters > Code::kMaxArguments) { |
| 3961 ReportMessage("too_many_parameters"); |
| 3962 *ok = false; |
| 3963 return NULL; |
| 3964 } |
| 3965 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break; |
| 3966 done = (peek() == Token::RPAREN); |
| 3967 if (!done) { |
| 3968 if (is_rest) { |
| 3969 ReportMessageAt(scanner()->peek_location(), "param_after_rest"); |
| 3970 *ok = false; |
| 3971 return NULL; |
| 3972 } |
| 3973 Expect(Token::COMMA, CHECK_OK); |
| 3974 } |
| 3975 } |
3979 Expect(Token::RPAREN, CHECK_OK); | 3976 Expect(Token::RPAREN, CHECK_OK); |
3980 int formals_end_position = scanner()->location().end_pos; | |
3981 | |
3982 CheckArityRestrictions(params->length(), arity_restriction, start_position, | |
3983 formals_end_position, CHECK_OK); | |
3984 | |
3985 scope->set_start_position(start_position); | |
3986 | |
3987 num_parameters = DeclareFormalParameters(params, scope_, has_rest); | |
3988 if (error_locs.duplicate.IsValid()) { | |
3989 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | |
3990 } | |
3991 | |
3992 | 3977 |
3993 Expect(Token::LBRACE, CHECK_OK); | 3978 Expect(Token::LBRACE, CHECK_OK); |
3994 | 3979 |
3995 // If we have a named function expression, we add a local variable | 3980 // If we have a named function expression, we add a local variable |
3996 // declaration to the body of the function with the name of the | 3981 // declaration to the body of the function with the name of the |
3997 // function and let it refer to the function itself (closure). | 3982 // function and let it refer to the function itself (closure). |
3998 // NOTE: We create a proxy and resolve it here so that in the | 3983 // NOTE: We create a proxy and resolve it here so that in the |
3999 // future we can change the AST to only refer to VariableProxies | 3984 // future we can change the AST to only refer to VariableProxies |
4000 // instead of Variables and Proxis as is the case now. | 3985 // instead of Variables and Proxis as is the case now. |
4001 Variable* fvar = NULL; | 3986 Variable* fvar = NULL; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4063 materialized_literal_count = function_state.materialized_literal_count(); | 4048 materialized_literal_count = function_state.materialized_literal_count(); |
4064 expected_property_count = function_state.expected_property_count(); | 4049 expected_property_count = function_state.expected_property_count(); |
4065 handler_count = function_state.handler_count(); | 4050 handler_count = function_state.handler_count(); |
4066 } | 4051 } |
4067 | 4052 |
4068 // Validate name and parameter names. We can do this only after parsing the | 4053 // Validate name and parameter names. We can do this only after parsing the |
4069 // function, since the function can declare itself strict. | 4054 // function, since the function can declare itself strict. |
4070 CheckFunctionName(language_mode(), kind, function_name, | 4055 CheckFunctionName(language_mode(), kind, function_name, |
4071 name_is_strict_reserved, function_name_location, | 4056 name_is_strict_reserved, function_name_location, |
4072 CHECK_OK); | 4057 CHECK_OK); |
4073 const bool use_strict_params = has_rest || IsConciseMethod(kind); | 4058 const bool use_strict_params = is_rest || IsConciseMethod(kind); |
4074 CheckFunctionParameterNames(language_mode(), use_strict_params, error_locs, | 4059 CheckFunctionParameterNames(language_mode(), use_strict_params, |
4075 CHECK_OK); | 4060 eval_args_loc, undefined_loc, dupe_loc, |
| 4061 reserved_loc, CHECK_OK); |
4076 | 4062 |
4077 if (is_strict(language_mode())) { | 4063 if (is_strict(language_mode())) { |
4078 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 4064 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
4079 CHECK_OK); | 4065 CHECK_OK); |
4080 } | 4066 } |
4081 if (is_strict(language_mode())) { | 4067 if (is_strict(language_mode())) { |
4082 CheckConflictingVarDeclarations(scope, CHECK_OK); | 4068 CheckConflictingVarDeclarations(scope, CHECK_OK); |
4083 } | 4069 } |
4084 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { | 4070 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { |
4085 if (!function_state.super_call_location().IsValid()) { | 4071 if (!function_state.super_call_location().IsValid()) { |
(...skipping 1709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5795 | 5781 |
5796 Expression* Parser::SpreadCallNew(Expression* function, | 5782 Expression* Parser::SpreadCallNew(Expression* function, |
5797 ZoneList<v8::internal::Expression*>* args, | 5783 ZoneList<v8::internal::Expression*>* args, |
5798 int pos) { | 5784 int pos) { |
5799 args->InsertAt(0, function, zone()); | 5785 args->InsertAt(0, function, zone()); |
5800 | 5786 |
5801 return factory()->NewCallRuntime( | 5787 return factory()->NewCallRuntime( |
5802 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5788 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
5803 } | 5789 } |
5804 } } // namespace v8::internal | 5790 } } // namespace v8::internal |
OLD | NEW |