Chromium Code Reviews| 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 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1133 DCHECK(info->language_mode() == shared_info->language_mode()); | 1123 DCHECK(info->language_mode() == shared_info->language_mode()); |
| 1134 scope->SetLanguageMode(shared_info->language_mode()); | 1124 scope->SetLanguageMode(shared_info->language_mode()); |
| 1135 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 1125 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
| 1136 ? (shared_info->is_anonymous() | 1126 ? (shared_info->is_anonymous() |
| 1137 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1127 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 1138 : FunctionLiteral::NAMED_EXPRESSION) | 1128 : FunctionLiteral::NAMED_EXPRESSION) |
| 1139 : FunctionLiteral::DECLARATION; | 1129 : FunctionLiteral::DECLARATION; |
| 1140 bool ok = true; | 1130 bool ok = true; |
| 1141 | 1131 |
| 1142 if (shared_info->is_arrow()) { | 1132 if (shared_info->is_arrow()) { |
| 1143 // The first expression being parsed is the parameter list of the arrow | 1133 FormalParameterErrorLocations error_locs; |
| 1144 // function. Setting this avoids prevents ExpressionFromIdentifier() | 1134 bool has_rest = false; |
| 1145 // from creating unresolved variables in already-resolved scopes. | 1135 ZoneList<const AstRawString*>* params; |
| 1146 parsing_lazy_arrow_parameters_ = true; | 1136 if (Check(Token::LPAREN)) { |
| 1147 Expression* expression = ParseExpression(false, &ok); | 1137 // '(' StrictFormalParameters ')' |
| 1138 params = ParseFormalParameterList(&error_locs, &has_rest, &ok); | |
|
arv (Not doing code reviews)
2015/04/13 18:26:38
Nice.
| |
| 1139 if (ok) ok = Check(Token::RPAREN); | |
| 1140 } else { | |
| 1141 // BindingIdentifier | |
| 1142 params = NewFormalParameterList(1, zone()); | |
| 1143 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | |
|
arv (Not doing code reviews)
2015/04/13 18:26:38
Is it worth refactoring to not create a duplicate_
marja
2015/04/14 07:38:26
+1, this is unnecessary...
wingo
2015/04/14 08:23:28
Done by passing a null pointer.
| |
| 1144 const AstRawString* single_param = | |
| 1145 ParseFormalParameter(&duplicate_finder, &error_locs, &ok); | |
| 1146 if (ok) params->Add(single_param, zone()); | |
| 1147 } | |
| 1148 | |
| 1148 if (ok) { | 1149 if (ok) { |
| 1149 // Scanning must end at the same position that was recorded | 1150 Expression* expression = ParseArrowFunctionLiteral( |
| 1150 // previously. If not, parsing has been interrupted due to a | 1151 shared_info->start_position(), params, error_locs, has_rest, &ok); |
| 1151 // stack overflow, at which point the partially parsed arrow | 1152 if (ok) { |
| 1152 // function concise body happens to be a valid expression. This | 1153 // Scanning must end at the same position that was recorded |
| 1153 // is a problem only for arrow functions with single statement | 1154 // previously. If not, parsing has been interrupted due to a stack |
| 1154 // bodies, since there is no end token such as "}" for normal | 1155 // overflow, at which point the partially parsed arrow function |
| 1155 // functions. | 1156 // concise body happens to be a valid expression. This is a problem |
| 1156 if (scanner()->location().end_pos == shared_info->end_position()) { | 1157 // only for arrow functions with single statement bodies, since there |
|
arv (Not doing code reviews)
2015/04/13 18:26:38
single statement bodies
->
single expression bod
| |
| 1157 // The pre-parser saw an arrow function here, so the full parser | 1158 // is no end token such as "}" for normal functions. |
| 1158 // must produce a FunctionLiteral. | 1159 if (scanner()->location().end_pos == shared_info->end_position()) { |
| 1159 DCHECK(expression->IsFunctionLiteral()); | 1160 // The pre-parser saw an arrow function here, so the full parser |
| 1160 result = expression->AsFunctionLiteral(); | 1161 // must produce a FunctionLiteral. |
| 1161 } else { | 1162 DCHECK(expression->IsFunctionLiteral()); |
| 1162 result = NULL; | 1163 result = expression->AsFunctionLiteral(); |
| 1163 ok = false; | 1164 } else { |
| 1165 ok = false; | |
| 1166 } | |
| 1164 } | 1167 } |
| 1165 } | 1168 } |
| 1166 } else if (shared_info->is_default_constructor()) { | 1169 } else if (shared_info->is_default_constructor()) { |
| 1167 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()), | 1170 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()), |
| 1168 scope, shared_info->start_position(), | 1171 scope, shared_info->start_position(), |
| 1169 shared_info->end_position()); | 1172 shared_info->end_position()); |
| 1170 } else { | 1173 } else { |
| 1171 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), | 1174 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), |
| 1172 false, // Strict mode name already checked. | 1175 false, // Strict mode name already checked. |
| 1173 shared_info->kind(), RelocInfo::kNoPosition, | 1176 shared_info->kind(), RelocInfo::kNoPosition, |
| (...skipping 2523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3697 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); | 3700 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); |
| 3698 return static_cast<LiteralType>(literal_type->value()); | 3701 return static_cast<LiteralType>(literal_type->value()); |
| 3699 } | 3702 } |
| 3700 | 3703 |
| 3701 | 3704 |
| 3702 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { | 3705 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
| 3703 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); | 3706 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); |
| 3704 } | 3707 } |
| 3705 | 3708 |
| 3706 | 3709 |
| 3707 bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression, | 3710 void ParserTraits::RecordArrowFunctionParameter( |
| 3708 Scope* scope, int* num_params, | 3711 ZoneList<const v8::internal::AstRawString*>* result, VariableProxy* proxy, |
| 3709 FormalParameterErrorLocations* locs) { | 3712 FormalParameterErrorLocations* error_locs, bool* ok) { |
| 3713 const AstRawString* raw_name = proxy->raw_name(); | |
| 3714 Scanner::Location param_location(proxy->position(), | |
| 3715 proxy->position() + raw_name->length()); | |
| 3716 | |
| 3717 if (proxy->is_this()) { | |
| 3718 ReportMessageAt(param_location, "this_formal_parameter"); | |
| 3719 *ok = false; | |
| 3720 return; | |
| 3721 } | |
| 3722 | |
| 3723 if (IsEvalOrArguments(raw_name) && !error_locs->eval_or_arguments_.IsValid()) | |
|
arv (Not doing code reviews)
2015/04/13 18:26:38
Maybe check IsValid first?
| |
| 3724 error_locs->eval_or_arguments_ = param_location; | |
| 3725 if (IsFutureStrictReserved(raw_name) && !error_locs->reserved_.IsValid()) | |
| 3726 error_locs->reserved_ = param_location; | |
| 3727 if (IsUndefined(raw_name) && !error_locs->undefined_.IsValid()) | |
| 3728 error_locs->undefined_ = param_location; | |
| 3729 | |
| 3730 // TODO(wingo): Fix quadratic check. (Scope::IsDeclaredParameter has the same | |
| 3731 // issue.) | |
| 3732 for (int i = 0; i < result->length(); i++) { | |
| 3733 // Eagerly report the error here; duplicate formal parameter names are never | |
| 3734 // allowed in arrow functions. | |
| 3735 if (raw_name == result->at(i)) { | |
| 3736 ReportMessageAt(param_location, | |
| 3737 "duplicate_arrow_function_formal_parameter"); | |
| 3738 *ok = false; | |
| 3739 return; | |
| 3740 } | |
| 3741 } | |
| 3742 | |
| 3743 // When the formal parameter was originally seen, it was parsed as a | |
| 3744 // VariableProxy and recorded as unresolved in the outer scope. But it's | |
| 3745 // really not unresolved. | |
| 3746 parser_->scope_->RemoveUnresolved(proxy); | |
| 3747 result->Add(raw_name, parser_->zone()); | |
| 3748 } | |
| 3749 | |
| 3750 | |
| 3751 // Arrow function parameter lists are parsed as StrictFormalParameters, which | |
| 3752 // means that they cannot have duplicates. Note that this is a subset of the | |
| 3753 // restrictions placed on parameters to functions whose body is strict. | |
| 3754 ZoneList<const v8::internal::AstRawString*>* | |
| 3755 ParserTraits::ParseArrowFunctionFormalParameterList( | |
| 3756 Expression* params, const Scanner::Location& params_loc, | |
| 3757 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok) { | |
| 3758 ZoneList<const v8::internal::AstRawString*>* result = | |
| 3759 NewFormalParameterList(4, parser_->zone()); | |
| 3760 | |
| 3710 // Case for empty parameter lists: | 3761 // Case for empty parameter lists: |
| 3711 // () => ... | 3762 // () => ... |
| 3712 if (expression == NULL) return true; | 3763 if (params == NULL) return result; |
| 3713 | 3764 |
| 3714 // Too many parentheses around expression: | 3765 // Too many parentheses around expression: |
| 3715 // (( ... )) => ... | 3766 // (( ... )) => ... |
| 3716 if (expression->is_multi_parenthesized()) return false; | 3767 if (params != nullptr && params->is_multi_parenthesized()) { |
|
arv (Not doing code reviews)
2015/04/13 18:26:38
Change params != nullptr to DCHECK_NOT_NULL.
| |
| 3768 // TODO(wingo): Make a better message. | |
| 3769 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
| 3770 *ok = false; | |
| 3771 return NULL; | |
| 3772 } | |
| 3717 | 3773 |
| 3718 // Case for a single parameter: | 3774 // ArrowFunctionFormals :: |
| 3719 // (foo) => ... | 3775 // VariableProxy |
| 3720 // foo => ... | 3776 // Binary(Token::COMMA, ArrowFunctionFormals, VariableProxy) |
| 3721 if (expression->IsVariableProxy()) { | 3777 // |
| 3722 if (expression->AsVariableProxy()->is_this()) return false; | 3778 // To stay iterative we'll process arguments in right-to-left order, then |
| 3723 | 3779 // reverse the list in place. |
| 3724 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name(); | 3780 // |
| 3725 if (traits->IsEvalOrArguments(raw_name) || | 3781 // Sadly, for the various malformed_arrow_function_parameter_list errors, we |
|
arv (Not doing code reviews)
2015/04/13 18:26:38
An idea to fixing the preparser would be to:
- P
| |
| 3726 traits->IsFutureStrictReserved(raw_name)) | 3782 // can't be more specific on the error message or on the location because we |
| 3727 return false; | 3783 // need to match the pre-parser's behavior. |
| 3728 if (traits->IsUndefined(raw_name) && !locs->undefined_.IsValid()) { | 3784 while (params->IsBinaryOperation()) { |
| 3729 locs->undefined_ = Scanner::Location( | 3785 BinaryOperation* binop = params->AsBinaryOperation(); |
| 3730 expression->position(), expression->position() + raw_name->length()); | 3786 Expression* left = binop->left(); |
| 3787 Expression* right = binop->right(); | |
| 3788 if (binop->op() != Token::COMMA) { | |
| 3789 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
| 3790 *ok = false; | |
| 3791 return NULL; | |
| 3731 } | 3792 } |
| 3732 if (scope->IsDeclared(raw_name)) { | 3793 // RHS of comma expression should be an unparenthesized variable proxy. |
| 3733 locs->duplicate_ = Scanner::Location( | 3794 if (right->is_parenthesized() || !right->IsVariableProxy()) { |
| 3734 expression->position(), expression->position() + raw_name->length()); | 3795 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
| 3735 return false; | 3796 *ok = false; |
| 3797 return NULL; | |
| 3798 } | |
| 3799 RecordArrowFunctionParameter(result, right->AsVariableProxy(), error_locs, | |
| 3800 CHECK_OK); | |
| 3801 // LHS of comma expression should be unparenthesized. | |
| 3802 params = left; | |
| 3803 if (params->is_parenthesized()) { | |
| 3804 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
| 3805 *ok = false; | |
| 3806 return NULL; | |
| 3736 } | 3807 } |
| 3737 | 3808 |
| 3738 // When the variable was seen, it was recorded as unresolved in the outer | 3809 if (result->length() > Code::kMaxArguments) { |
| 3739 // scope. But it's really not unresolved. | 3810 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
| 3740 scope->outer_scope()->RemoveUnresolved(expression->AsVariableProxy()); | 3811 *ok = false; |
| 3741 | 3812 return NULL; |
| 3742 scope->DeclareParameter(raw_name, VAR); | 3813 } |
| 3743 ++(*num_params); | |
| 3744 return true; | |
| 3745 } | 3814 } |
| 3746 | 3815 |
| 3747 // Case for more than one parameter: | 3816 if (params->IsVariableProxy()) { |
| 3748 // (foo, bar [, ...]) => ... | 3817 RecordArrowFunctionParameter(result, params->AsVariableProxy(), error_locs, |
| 3749 if (expression->IsBinaryOperation()) { | 3818 CHECK_OK); |
| 3750 BinaryOperation* binop = expression->AsBinaryOperation(); | 3819 } else { |
| 3751 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() || | 3820 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
| 3752 binop->right()->is_parenthesized()) | 3821 *ok = false; |
| 3753 return false; | 3822 return NULL; |
| 3754 | |
| 3755 return CheckAndDeclareArrowParameter(traits, binop->left(), scope, | |
| 3756 num_params, locs) && | |
| 3757 CheckAndDeclareArrowParameter(traits, binop->right(), scope, | |
| 3758 num_params, locs); | |
| 3759 } | 3823 } |
| 3760 | 3824 |
| 3761 // Any other kind of expression is not a valid parameter list. | 3825 // Reverse in place. |
| 3762 return false; | 3826 std::reverse(result->begin(), result->end()); |
| 3827 | |
| 3828 return result; | |
| 3763 } | 3829 } |
| 3764 | 3830 |
| 3765 | 3831 |
| 3766 int ParserTraits::DeclareArrowParametersFromExpression( | 3832 int ParserTraits::DeclareFormalParameters(ZoneList<const AstRawString*>* params, |
| 3767 Expression* expression, Scope* scope, FormalParameterErrorLocations* locs, | 3833 Scope* scope, bool has_rest, |
| 3768 bool* ok) { | 3834 bool* ok) { |
|
marja
2015/04/14 07:38:25
The bool ok seems unnecessary now as this cannot f
wingo
2015/04/14 08:23:28
Good catch, thanks.
| |
| 3769 int num_params = 0; | 3835 for (int i = 0; i < params->length(); i++) { |
| 3770 // Always reset the flag: It only needs to be set for the first expression | 3836 const AstRawString* param_name = params->at(i); |
| 3771 // parsed as arrow function parameter list, because only top-level functions | 3837 int is_rest = has_rest && i == params->length() - 1; |
| 3772 // are parsed lazily. | 3838 Variable* var = scope->DeclareParameter(param_name, VAR, is_rest); |
| 3773 parser_->parsing_lazy_arrow_parameters_ = false; | 3839 if (is_sloppy(scope->language_mode())) { |
| 3774 *ok = | 3840 // TODO(sigurds) Mark every parameter as maybe assigned. This is a |
| 3775 CheckAndDeclareArrowParameter(this, expression, scope, &num_params, locs); | 3841 // conservative approximation necessary to account for parameters |
| 3776 return num_params; | 3842 // that are assigned via the arguments array. |
| 3843 var->set_maybe_assigned(); | |
| 3844 } | |
| 3845 } | |
| 3846 return params->length(); | |
| 3777 } | 3847 } |
| 3778 | 3848 |
| 3779 | 3849 |
| 3780 FunctionLiteral* Parser::ParseFunctionLiteral( | 3850 FunctionLiteral* Parser::ParseFunctionLiteral( |
| 3781 const AstRawString* function_name, Scanner::Location function_name_location, | 3851 const AstRawString* function_name, Scanner::Location function_name_location, |
| 3782 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, | 3852 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, |
| 3783 FunctionLiteral::FunctionType function_type, | 3853 FunctionLiteral::FunctionType function_type, |
| 3784 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { | 3854 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { |
| 3785 // Function :: | 3855 // Function :: |
| 3786 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3856 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3879 ZoneList<const AstRawString*>* params = | 3949 ZoneList<const AstRawString*>* params = |
| 3880 ParseFormalParameterList(&error_locs, &has_rest, CHECK_OK); | 3950 ParseFormalParameterList(&error_locs, &has_rest, CHECK_OK); |
| 3881 Expect(Token::RPAREN, CHECK_OK); | 3951 Expect(Token::RPAREN, CHECK_OK); |
| 3882 int formals_end_position = scanner()->location().end_pos; | 3952 int formals_end_position = scanner()->location().end_pos; |
| 3883 | 3953 |
| 3884 CheckArityRestrictions(params->length(), arity_restriction, start_position, | 3954 CheckArityRestrictions(params->length(), arity_restriction, start_position, |
| 3885 formals_end_position, CHECK_OK); | 3955 formals_end_position, CHECK_OK); |
| 3886 | 3956 |
| 3887 scope->set_start_position(start_position); | 3957 scope->set_start_position(start_position); |
| 3888 | 3958 |
| 3889 num_parameters = params->length(); | 3959 num_parameters = |
| 3960 DeclareFormalParameters(params, scope_, has_rest, CHECK_OK); | |
| 3890 if (error_locs.duplicate_.IsValid()) { | 3961 if (error_locs.duplicate_.IsValid()) { |
| 3891 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | 3962 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
| 3892 } | 3963 } |
| 3893 | 3964 |
| 3894 for (int i = 0; i < params->length(); i++) { | |
| 3895 const AstRawString* param_name = params->at(i); | |
| 3896 int is_rest = has_rest && i == params->length() - 1; | |
| 3897 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest); | |
| 3898 if (is_sloppy(scope->language_mode())) { | |
| 3899 // TODO(sigurds) Mark every parameter as maybe assigned. This is a | |
| 3900 // conservative approximation necessary to account for parameters | |
| 3901 // that are assigned via the arguments array. | |
| 3902 var->set_maybe_assigned(); | |
| 3903 } | |
| 3904 } | |
| 3905 | 3965 |
| 3906 Expect(Token::LBRACE, CHECK_OK); | 3966 Expect(Token::LBRACE, CHECK_OK); |
| 3907 | 3967 |
| 3908 // If we have a named function expression, we add a local variable | 3968 // If we have a named function expression, we add a local variable |
| 3909 // declaration to the body of the function with the name of the | 3969 // declaration to the body of the function with the name of the |
| 3910 // function and let it refer to the function itself (closure). | 3970 // function and let it refer to the function itself (closure). |
| 3911 // NOTE: We create a proxy and resolve it here so that in the | 3971 // NOTE: We create a proxy and resolve it here so that in the |
| 3912 // future we can change the AST to only refer to VariableProxies | 3972 // future we can change the AST to only refer to VariableProxies |
| 3913 // instead of Variables and Proxis as is the case now. | 3973 // instead of Variables and Proxis as is the case now. |
| 3914 Variable* fvar = NULL; | 3974 Variable* fvar = NULL; |
| (...skipping 1801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5716 | 5776 |
| 5717 Expression* Parser::SpreadCallNew(Expression* function, | 5777 Expression* Parser::SpreadCallNew(Expression* function, |
| 5718 ZoneList<v8::internal::Expression*>* args, | 5778 ZoneList<v8::internal::Expression*>* args, |
| 5719 int pos) { | 5779 int pos) { |
| 5720 args->InsertAt(0, function, zone()); | 5780 args->InsertAt(0, function, zone()); |
| 5721 | 5781 |
| 5722 return factory()->NewCallRuntime( | 5782 return factory()->NewCallRuntime( |
| 5723 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5783 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
| 5724 } | 5784 } |
| 5725 } } // namespace v8::internal | 5785 } } // namespace v8::internal |
| OLD | NEW |