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 | 790 return scope->NewUnresolved(factory, name, start_position, end_position); |
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); | |
800 } | 791 } |
801 | 792 |
802 | 793 |
803 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner, | 794 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner, |
804 AstNodeFactory* factory) { | 795 AstNodeFactory* factory) { |
805 const AstRawString* symbol = GetSymbol(scanner); | 796 const AstRawString* symbol = GetSymbol(scanner); |
806 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); | 797 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
807 return factory->NewStringLiteral(symbol, pos); | 798 return factory->NewStringLiteral(symbol, pos); |
808 } | 799 } |
809 | 800 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
854 Parser::Parser(ParseInfo* info) | 845 Parser::Parser(ParseInfo* info) |
855 : ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(), | 846 : ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(), |
856 info->extension(), info->ast_value_factory(), | 847 info->extension(), info->ast_value_factory(), |
857 NULL, this), | 848 NULL, this), |
858 scanner_(info->unicode_cache()), | 849 scanner_(info->unicode_cache()), |
859 reusable_preparser_(NULL), | 850 reusable_preparser_(NULL), |
860 original_scope_(NULL), | 851 original_scope_(NULL), |
861 target_stack_(NULL), | 852 target_stack_(NULL), |
862 compile_options_(info->compile_options()), | 853 compile_options_(info->compile_options()), |
863 cached_parse_data_(NULL), | 854 cached_parse_data_(NULL), |
864 parsing_lazy_arrow_parameters_(false), | |
865 total_preparse_skipped_(0), | 855 total_preparse_skipped_(0), |
866 pre_parse_timer_(NULL), | 856 pre_parse_timer_(NULL), |
867 parsing_on_main_thread_(true) { | 857 parsing_on_main_thread_(true) { |
868 // Even though we were passed ParseInfo, we should not store it in | 858 // Even though we were passed ParseInfo, we should not store it in |
869 // Parser - this makes sure that Isolate is not accidentally accessed via | 859 // Parser - this makes sure that Isolate is not accidentally accessed via |
870 // ParseInfo during background parsing. | 860 // ParseInfo during background parsing. |
871 DCHECK(!info->script().is_null() || info->source_stream() != NULL); | 861 DCHECK(!info->script().is_null() || info->source_stream() != NULL); |
872 set_allow_lazy(info->allow_lazy_parsing()); | 862 set_allow_lazy(info->allow_lazy_parsing()); |
873 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 863 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
874 set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules); | 864 set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules); |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1135 DCHECK(info->language_mode() == shared_info->language_mode()); | 1125 DCHECK(info->language_mode() == shared_info->language_mode()); |
1136 scope->SetLanguageMode(shared_info->language_mode()); | 1126 scope->SetLanguageMode(shared_info->language_mode()); |
1137 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 1127 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
1138 ? (shared_info->is_anonymous() | 1128 ? (shared_info->is_anonymous() |
1139 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1129 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
1140 : FunctionLiteral::NAMED_EXPRESSION) | 1130 : FunctionLiteral::NAMED_EXPRESSION) |
1141 : FunctionLiteral::DECLARATION; | 1131 : FunctionLiteral::DECLARATION; |
1142 bool ok = true; | 1132 bool ok = true; |
1143 | 1133 |
1144 if (shared_info->is_arrow()) { | 1134 if (shared_info->is_arrow()) { |
1145 // The first expression being parsed is the parameter list of the arrow | 1135 Scope* scope = NewScope(scope_, ARROW_SCOPE); |
1146 // function. Setting this avoids prevents ExpressionFromIdentifier() | 1136 scope->set_start_position(shared_info->start_position()); |
1147 // from creating unresolved variables in already-resolved scopes. | 1137 FormalParameterErrorLocations error_locs; |
1148 parsing_lazy_arrow_parameters_ = true; | 1138 bool has_rest = false; |
1149 Expression* expression = ParseExpression(false, &ok); | 1139 if (Check(Token::LPAREN)) { |
1140 // '(' StrictFormalParameters ')' | |
1141 ParseFormalParameterList(scope, &error_locs, &has_rest, &ok); | |
1142 if (ok) ok = Check(Token::RPAREN); | |
1143 } else { | |
1144 // BindingIdentifier | |
1145 DuplicateFinder* null_duplicate_finder = nullptr; | |
1146 const AstRawString* single_param = | |
1147 ParseFormalParameter(null_duplicate_finder, &error_locs, &ok); | |
1148 ParserTraits::DeclareFormalParameter(scope, single_param, has_rest); | |
1149 } | |
1150 | |
1150 if (ok) { | 1151 if (ok) { |
1151 // Scanning must end at the same position that was recorded | 1152 Expression* expression = |
1152 // previously. If not, parsing has been interrupted due to a | 1153 ParseArrowFunctionLiteral(scope, error_locs, has_rest, &ok); |
1153 // stack overflow, at which point the partially parsed arrow | 1154 if (ok) { |
1154 // function concise body happens to be a valid expression. This | 1155 // Scanning must end at the same position that was recorded |
1155 // is a problem only for arrow functions with single statement | 1156 // previously. If not, parsing has been interrupted due to a stack |
1156 // bodies, since there is no end token such as "}" for normal | 1157 // overflow, at which point the partially parsed arrow function |
1157 // functions. | 1158 // concise body happens to be a valid expression. This is a problem |
1158 if (scanner()->location().end_pos == shared_info->end_position()) { | 1159 // only for arrow functions with single expression bodies, since there |
1159 // The pre-parser saw an arrow function here, so the full parser | 1160 // is no end token such as "}" for normal functions. |
1160 // must produce a FunctionLiteral. | 1161 if (scanner()->location().end_pos == shared_info->end_position()) { |
1161 DCHECK(expression->IsFunctionLiteral()); | 1162 // The pre-parser saw an arrow function here, so the full parser |
1162 result = expression->AsFunctionLiteral(); | 1163 // must produce a FunctionLiteral. |
1163 } else { | 1164 DCHECK(expression->IsFunctionLiteral()); |
1164 result = NULL; | 1165 result = expression->AsFunctionLiteral(); |
1165 ok = false; | 1166 } else { |
1167 ok = false; | |
1168 } | |
1166 } | 1169 } |
1167 } | 1170 } |
1168 } else if (shared_info->is_default_constructor()) { | 1171 } else if (shared_info->is_default_constructor()) { |
1169 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()), | 1172 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()), |
1170 scope, shared_info->start_position(), | 1173 scope, shared_info->start_position(), |
1171 shared_info->end_position()); | 1174 shared_info->end_position()); |
1172 } else { | 1175 } else { |
1173 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), | 1176 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), |
1174 false, // Strict mode name already checked. | 1177 false, // Strict mode name already checked. |
1175 shared_info->kind(), RelocInfo::kNoPosition, | 1178 shared_info->kind(), RelocInfo::kNoPosition, |
(...skipping 2549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3725 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); | 3728 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); |
3726 return static_cast<LiteralType>(literal_type->value()); | 3729 return static_cast<LiteralType>(literal_type->value()); |
3727 } | 3730 } |
3728 | 3731 |
3729 | 3732 |
3730 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { | 3733 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
3731 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); | 3734 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); |
3732 } | 3735 } |
3733 | 3736 |
3734 | 3737 |
3735 bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression, | 3738 void ParserTraits::DeclareArrowFunctionParameters( |
3736 Scope* scope, int* num_params, | 3739 Scope* scope, Expression* expr, const Scanner::Location& params_loc, |
3737 Scanner::Location* undefined_loc, | 3740 FormalParameterErrorLocations* error_locs, bool* ok) { |
3738 Scanner::Location* dupe_loc) { | 3741 if (scope->num_parameters() >= Code::kMaxArguments) { |
3739 // Case for empty parameter lists: | 3742 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
3740 // () => ... | 3743 *ok = false; |
3741 if (expression == NULL) return true; | 3744 return; |
3742 | |
3743 // Too many parentheses around expression: | |
3744 // (( ... )) => ... | |
3745 if (expression->is_multi_parenthesized()) return false; | |
3746 | |
3747 // Case for a single parameter: | |
3748 // (foo) => ... | |
3749 // foo => ... | |
3750 if (expression->IsVariableProxy()) { | |
3751 if (expression->AsVariableProxy()->is_this()) return false; | |
3752 | |
3753 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name(); | |
3754 if (traits->IsEvalOrArguments(raw_name) || | |
3755 traits->IsFutureStrictReserved(raw_name)) | |
3756 return false; | |
3757 if (traits->IsUndefined(raw_name) && !undefined_loc->IsValid()) { | |
3758 *undefined_loc = Scanner::Location( | |
3759 expression->position(), expression->position() + raw_name->length()); | |
3760 } | |
3761 if (scope->IsDeclared(raw_name)) { | |
3762 *dupe_loc = Scanner::Location( | |
3763 expression->position(), expression->position() + raw_name->length()); | |
3764 return false; | |
3765 } | |
3766 | |
3767 // When the variable was seen, it was recorded as unresolved in the outer | |
3768 // scope. But it's really not unresolved. | |
3769 scope->outer_scope()->RemoveUnresolved(expression->AsVariableProxy()); | |
3770 | |
3771 scope->DeclareParameter(raw_name, VAR); | |
3772 ++(*num_params); | |
3773 return true; | |
3774 } | 3745 } |
3775 | 3746 |
3776 // Case for more than one parameter: | 3747 // ArrowFunctionFormals :: |
3777 // (foo, bar [, ...]) => ... | 3748 // Binary(Token::COMMA, ArrowFunctionFormals, VariableProxy) |
3778 if (expression->IsBinaryOperation()) { | 3749 // VariableProxy |
3779 BinaryOperation* binop = expression->AsBinaryOperation(); | 3750 // |
3780 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() || | 3751 // As we need to visit the parameters in left-to-right order, we recurse on |
3781 binop->right()->is_parenthesized()) | 3752 // the left-hand side of comma expressions. |
3782 return false; | 3753 // |
3783 | 3754 // Sadly, for the various malformed_arrow_function_parameter_list errors, we |
3784 return CheckAndDeclareArrowParameter(traits, binop->left(), scope, | 3755 // can't be more specific on the error message or on the location because we |
3785 num_params, undefined_loc, dupe_loc) && | 3756 // need to match the pre-parser's behavior. |
3786 CheckAndDeclareArrowParameter(traits, binop->right(), scope, | 3757 if (expr->IsBinaryOperation()) { |
3787 num_params, undefined_loc, dupe_loc); | 3758 BinaryOperation* binop = expr->AsBinaryOperation(); |
3759 if (binop->op() != Token::COMMA) { | |
3760 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
3761 *ok = false; | |
3762 return; | |
3763 } | |
3764 Expression* left = binop->left(); | |
3765 Expression* right = binop->right(); | |
3766 if (left->is_parenthesized() || right->is_parenthesized()) { | |
3767 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
3768 *ok = false; | |
3769 return; | |
3770 } | |
3771 DeclareArrowFunctionParameters(scope, left, params_loc, error_locs, ok); | |
3772 if (!*ok) return; | |
3773 // LHS of comma expression should be unparenthesized. | |
3774 expr = right; | |
3788 } | 3775 } |
3789 | 3776 |
3790 // Any other kind of expression is not a valid parameter list. | 3777 // TODO(wingo): Support rest parameters. |
3791 return false; | 3778 if (!expr->IsVariableProxy()) { |
3779 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
3780 *ok = false; | |
3781 return; | |
3782 } | |
3783 | |
3784 const AstRawString* raw_name = expr->AsVariableProxy()->raw_name(); | |
3785 Scanner::Location param_location(expr->position(), | |
3786 expr->position() + raw_name->length()); | |
3787 | |
3788 if (expr->AsVariableProxy()->is_this()) { | |
3789 ReportMessageAt(param_location, "this_formal_parameter"); | |
3790 *ok = false; | |
3791 return; | |
3792 } | |
3793 | |
3794 if (!error_locs->eval_or_arguments.IsValid() && IsEvalOrArguments(raw_name)) | |
3795 error_locs->eval_or_arguments = param_location; | |
3796 if (!error_locs->reserved.IsValid() && IsFutureStrictReserved(raw_name)) | |
3797 error_locs->reserved = param_location; | |
3798 if (!error_locs->undefined.IsValid() && IsUndefined(raw_name)) | |
3799 error_locs->undefined = param_location; | |
3800 | |
3801 // Arrow function parameter lists are parsed as StrictFormalParameters, which | |
3802 // means that they cannot have duplicates. Note that this is a subset of the | |
3803 // restrictions placed on parameters to functions whose body is strict. | |
3804 if (scope->IsDeclared(raw_name)) { | |
3805 ReportMessageAt(param_location, | |
3806 "duplicate_arrow_function_formal_parameter"); | |
3807 *ok = false; | |
3808 return; | |
3809 } | |
3810 | |
3811 // When the formal parameter was originally seen, it was parsed as a | |
3812 // VariableProxy and recorded as unresolved in the scope. Here we undo that | |
3813 // parse-time side-effect. | |
3814 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); | |
3815 | |
3816 bool is_rest = false; | |
3817 scope->DeclareParameter(raw_name, VAR, is_rest); | |
3792 } | 3818 } |
3793 | 3819 |
3794 | 3820 |
3795 int ParserTraits::DeclareArrowParametersFromExpression( | 3821 void ParserTraits::ParseArrowFunctionFormalParameters( |
3796 Expression* expression, Scope* scope, Scanner::Location* undefined_loc, | 3822 Scope* scope, Expression* params, const Scanner::Location& params_loc, |
3797 Scanner::Location* dupe_loc, bool* ok) { | 3823 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok) { |
3798 int num_params = 0; | 3824 // Too many parentheses around expression: |
3799 // Always reset the flag: It only needs to be set for the first expression | 3825 // (( ... )) => ... |
3800 // parsed as arrow function parameter list, because only top-level functions | 3826 if (params->is_multi_parenthesized()) { |
3801 // are parsed lazily. | 3827 // TODO(wingo): Make a better message. |
3802 parser_->parsing_lazy_arrow_parameters_ = false; | 3828 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
3803 *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params, | 3829 *ok = false; |
3804 undefined_loc, dupe_loc); | 3830 return; |
3805 return num_params; | 3831 } |
3832 | |
3833 DeclareArrowFunctionParameters(scope, params, params_loc, error_locs, ok); | |
3806 } | 3834 } |
3807 | 3835 |
3808 | 3836 |
3809 FunctionLiteral* Parser::ParseFunctionLiteral( | 3837 FunctionLiteral* Parser::ParseFunctionLiteral( |
3810 const AstRawString* function_name, Scanner::Location function_name_location, | 3838 const AstRawString* function_name, Scanner::Location function_name_location, |
3811 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, | 3839 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, |
3812 FunctionLiteral::FunctionType function_type, | 3840 FunctionLiteral::FunctionType function_type, |
3813 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { | 3841 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { |
3814 // Function :: | 3842 // Function :: |
3815 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3843 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3894 scope_->ForceContextAllocation(); | 3922 scope_->ForceContextAllocation(); |
3895 | 3923 |
3896 // Calling a generator returns a generator object. That object is stored | 3924 // Calling a generator returns a generator object. That object is stored |
3897 // in a temporary variable, a definition that is used by "yield" | 3925 // in a temporary variable, a definition that is used by "yield" |
3898 // expressions. This also marks the FunctionState as a generator. | 3926 // expressions. This also marks the FunctionState as a generator. |
3899 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3927 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
3900 ast_value_factory()->dot_generator_object_string()); | 3928 ast_value_factory()->dot_generator_object_string()); |
3901 function_state.set_generator_object_variable(temp); | 3929 function_state.set_generator_object_variable(temp); |
3902 } | 3930 } |
3903 | 3931 |
3904 // FormalParameterList :: | 3932 FormalParameterErrorLocations error_locs; |
3905 // '(' (Identifier)*[','] ')' | 3933 bool has_rest = false; |
3906 Expect(Token::LPAREN, CHECK_OK); | 3934 Expect(Token::LPAREN, CHECK_OK); |
3907 scope->set_start_position(scanner()->location().beg_pos); | 3935 int start_position = scanner()->location().beg_pos; |
3936 scope_->set_start_position(start_position); | |
3937 num_parameters = ParseFormalParameterList(scope, &error_locs, &has_rest, | |
3938 CHECK_OK); | |
3939 Expect(Token::RPAREN, CHECK_OK); | |
3940 int formals_end_position = scanner()->location().end_pos; | |
3908 | 3941 |
3909 // We don't yet know if the function will be strict, so we cannot yet | 3942 CheckArityRestrictions(num_parameters, arity_restriction, start_position, |
3910 // produce errors for parameter names or duplicates. However, we remember | 3943 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 | 3944 |
3916 // Similarly for strong mode. | 3945 if (error_locs.duplicate.IsValid()) { |
marja
2015/04/20 12:31:02
Nit: duplicate_parameters is really far from its u
wingo
2015/04/20 13:26:54
I did so, though I had to move the error_locs decl
| |
3917 Scanner::Location undefined_loc = Scanner::Location::invalid(); | 3946 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
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 } | 3947 } |
3974 Expect(Token::RPAREN, CHECK_OK); | |
3975 | 3948 |
3976 Expect(Token::LBRACE, CHECK_OK); | 3949 Expect(Token::LBRACE, CHECK_OK); |
3977 | 3950 |
3978 // If we have a named function expression, we add a local variable | 3951 // 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 | 3952 // declaration to the body of the function with the name of the |
3980 // function and let it refer to the function itself (closure). | 3953 // function and let it refer to the function itself (closure). |
3981 // NOTE: We create a proxy and resolve it here so that in the | 3954 // 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 | 3955 // future we can change the AST to only refer to VariableProxies |
3983 // instead of Variables and Proxis as is the case now. | 3956 // instead of Variables and Proxis as is the case now. |
3984 Variable* fvar = NULL; | 3957 Variable* fvar = NULL; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4046 materialized_literal_count = function_state.materialized_literal_count(); | 4019 materialized_literal_count = function_state.materialized_literal_count(); |
4047 expected_property_count = function_state.expected_property_count(); | 4020 expected_property_count = function_state.expected_property_count(); |
4048 handler_count = function_state.handler_count(); | 4021 handler_count = function_state.handler_count(); |
4049 } | 4022 } |
4050 | 4023 |
4051 // Validate name and parameter names. We can do this only after parsing the | 4024 // Validate name and parameter names. We can do this only after parsing the |
4052 // function, since the function can declare itself strict. | 4025 // function, since the function can declare itself strict. |
4053 CheckFunctionName(language_mode(), kind, function_name, | 4026 CheckFunctionName(language_mode(), kind, function_name, |
4054 name_is_strict_reserved, function_name_location, | 4027 name_is_strict_reserved, function_name_location, |
4055 CHECK_OK); | 4028 CHECK_OK); |
4056 const bool use_strict_params = is_rest || IsConciseMethod(kind); | 4029 const bool use_strict_params = has_rest || IsConciseMethod(kind); |
4057 CheckFunctionParameterNames(language_mode(), use_strict_params, | 4030 CheckFunctionParameterNames(language_mode(), use_strict_params, error_locs, |
4058 eval_args_loc, undefined_loc, dupe_loc, | 4031 CHECK_OK); |
4059 reserved_loc, CHECK_OK); | |
4060 | 4032 |
4061 if (is_strict(language_mode())) { | 4033 if (is_strict(language_mode())) { |
4062 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 4034 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
4063 CHECK_OK); | 4035 CHECK_OK); |
4064 } | 4036 } |
4065 if (is_strict(language_mode())) { | 4037 if (is_strict(language_mode())) { |
4066 CheckConflictingVarDeclarations(scope, CHECK_OK); | 4038 CheckConflictingVarDeclarations(scope, CHECK_OK); |
4067 } | 4039 } |
4068 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { | 4040 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { |
4069 if (!function_state.super_call_location().IsValid()) { | 4041 if (!function_state.super_call_location().IsValid()) { |
(...skipping 1709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5779 | 5751 |
5780 Expression* Parser::SpreadCallNew(Expression* function, | 5752 Expression* Parser::SpreadCallNew(Expression* function, |
5781 ZoneList<v8::internal::Expression*>* args, | 5753 ZoneList<v8::internal::Expression*>* args, |
5782 int pos) { | 5754 int pos) { |
5783 args->InsertAt(0, function, zone()); | 5755 args->InsertAt(0, function, zone()); |
5784 | 5756 |
5785 return factory()->NewCallRuntime( | 5757 return factory()->NewCallRuntime( |
5786 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5758 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
5787 } | 5759 } |
5788 } } // namespace v8::internal | 5760 } } // namespace v8::internal |
OLD | NEW |