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 3688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3699 } | 3699 } |
3700 | 3700 |
3701 | 3701 |
3702 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { | 3702 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
3703 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); | 3703 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); |
3704 } | 3704 } |
3705 | 3705 |
3706 | 3706 |
3707 bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression, | 3707 bool CheckAndDeclareArrowParameter(ParserTraits* traits, Expression* expression, |
3708 Scope* scope, int* num_params, | 3708 Scope* scope, int* num_params, |
3709 Scanner::Location* undefined_loc, | 3709 FormalParameterErrorLocations* locs) { |
3710 Scanner::Location* dupe_loc) { | |
3711 // Case for empty parameter lists: | 3710 // Case for empty parameter lists: |
3712 // () => ... | 3711 // () => ... |
3713 if (expression == NULL) return true; | 3712 if (expression == NULL) return true; |
3714 | 3713 |
3715 // Too many parentheses around expression: | 3714 // Too many parentheses around expression: |
3716 // (( ... )) => ... | 3715 // (( ... )) => ... |
3717 if (expression->is_multi_parenthesized()) return false; | 3716 if (expression->is_multi_parenthesized()) return false; |
3718 | 3717 |
3719 // Case for a single parameter: | 3718 // Case for a single parameter: |
3720 // (foo) => ... | 3719 // (foo) => ... |
3721 // foo => ... | 3720 // foo => ... |
3722 if (expression->IsVariableProxy()) { | 3721 if (expression->IsVariableProxy()) { |
3723 if (expression->AsVariableProxy()->is_this()) return false; | 3722 if (expression->AsVariableProxy()->is_this()) return false; |
3724 | 3723 |
3725 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name(); | 3724 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name(); |
3726 if (traits->IsEvalOrArguments(raw_name) || | 3725 if (traits->IsEvalOrArguments(raw_name) || |
3727 traits->IsFutureStrictReserved(raw_name)) | 3726 traits->IsFutureStrictReserved(raw_name)) |
3728 return false; | 3727 return false; |
3729 if (traits->IsUndefined(raw_name) && !undefined_loc->IsValid()) { | 3728 if (traits->IsUndefined(raw_name) && !locs->undefined_.IsValid()) { |
3730 *undefined_loc = Scanner::Location( | 3729 locs->undefined_ = Scanner::Location( |
3731 expression->position(), expression->position() + raw_name->length()); | 3730 expression->position(), expression->position() + raw_name->length()); |
3732 } | 3731 } |
3733 if (scope->IsDeclared(raw_name)) { | 3732 if (scope->IsDeclared(raw_name)) { |
3734 *dupe_loc = Scanner::Location( | 3733 locs->duplicate_ = Scanner::Location( |
3735 expression->position(), expression->position() + raw_name->length()); | 3734 expression->position(), expression->position() + raw_name->length()); |
3736 return false; | 3735 return false; |
3737 } | 3736 } |
3738 | 3737 |
3739 // When the variable was seen, it was recorded as unresolved in the outer | 3738 // When the variable was seen, it was recorded as unresolved in the outer |
3740 // scope. But it's really not unresolved. | 3739 // scope. But it's really not unresolved. |
3741 scope->outer_scope()->RemoveUnresolved(expression->AsVariableProxy()); | 3740 scope->outer_scope()->RemoveUnresolved(expression->AsVariableProxy()); |
3742 | 3741 |
3743 scope->DeclareParameter(raw_name, VAR); | 3742 scope->DeclareParameter(raw_name, VAR); |
3744 ++(*num_params); | 3743 ++(*num_params); |
3745 return true; | 3744 return true; |
3746 } | 3745 } |
3747 | 3746 |
3748 // Case for more than one parameter: | 3747 // Case for more than one parameter: |
3749 // (foo, bar [, ...]) => ... | 3748 // (foo, bar [, ...]) => ... |
3750 if (expression->IsBinaryOperation()) { | 3749 if (expression->IsBinaryOperation()) { |
3751 BinaryOperation* binop = expression->AsBinaryOperation(); | 3750 BinaryOperation* binop = expression->AsBinaryOperation(); |
3752 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() || | 3751 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() || |
3753 binop->right()->is_parenthesized()) | 3752 binop->right()->is_parenthesized()) |
3754 return false; | 3753 return false; |
3755 | 3754 |
3756 return CheckAndDeclareArrowParameter(traits, binop->left(), scope, | 3755 return CheckAndDeclareArrowParameter(traits, binop->left(), scope, |
3757 num_params, undefined_loc, dupe_loc) && | 3756 num_params, locs) && |
3758 CheckAndDeclareArrowParameter(traits, binop->right(), scope, | 3757 CheckAndDeclareArrowParameter(traits, binop->right(), scope, |
3759 num_params, undefined_loc, dupe_loc); | 3758 num_params, locs); |
3760 } | 3759 } |
3761 | 3760 |
3762 // Any other kind of expression is not a valid parameter list. | 3761 // Any other kind of expression is not a valid parameter list. |
3763 return false; | 3762 return false; |
3764 } | 3763 } |
3765 | 3764 |
3766 | 3765 |
3767 int ParserTraits::DeclareArrowParametersFromExpression( | 3766 int ParserTraits::DeclareArrowParametersFromExpression( |
3768 Expression* expression, Scope* scope, Scanner::Location* undefined_loc, | 3767 Expression* expression, Scope* scope, FormalParameterErrorLocations* locs, |
3769 Scanner::Location* dupe_loc, bool* ok) { | 3768 bool* ok) { |
3770 int num_params = 0; | 3769 int num_params = 0; |
3771 // Always reset the flag: It only needs to be set for the first expression | 3770 // Always reset the flag: It only needs to be set for the first expression |
3772 // parsed as arrow function parameter list, because only top-level functions | 3771 // parsed as arrow function parameter list, because only top-level functions |
3773 // are parsed lazily. | 3772 // are parsed lazily. |
3774 parser_->parsing_lazy_arrow_parameters_ = false; | 3773 parser_->parsing_lazy_arrow_parameters_ = false; |
3775 *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params, | 3774 *ok = |
3776 undefined_loc, dupe_loc); | 3775 CheckAndDeclareArrowParameter(this, expression, scope, &num_params, locs); |
3777 return num_params; | 3776 return num_params; |
3778 } | 3777 } |
3779 | 3778 |
3780 | 3779 |
3781 FunctionLiteral* Parser::ParseFunctionLiteral( | 3780 FunctionLiteral* Parser::ParseFunctionLiteral( |
3782 const AstRawString* function_name, Scanner::Location function_name_location, | 3781 const AstRawString* function_name, Scanner::Location function_name_location, |
3783 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, | 3782 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, |
3784 FunctionLiteral::FunctionType function_type, | 3783 FunctionLiteral::FunctionType function_type, |
3785 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { | 3784 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { |
3786 // Function :: | 3785 // Function :: |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3866 scope_->ForceContextAllocation(); | 3865 scope_->ForceContextAllocation(); |
3867 | 3866 |
3868 // Calling a generator returns a generator object. That object is stored | 3867 // Calling a generator returns a generator object. That object is stored |
3869 // in a temporary variable, a definition that is used by "yield" | 3868 // in a temporary variable, a definition that is used by "yield" |
3870 // expressions. This also marks the FunctionState as a generator. | 3869 // expressions. This also marks the FunctionState as a generator. |
3871 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3870 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
3872 ast_value_factory()->dot_generator_object_string()); | 3871 ast_value_factory()->dot_generator_object_string()); |
3873 function_state.set_generator_object_variable(temp); | 3872 function_state.set_generator_object_variable(temp); |
3874 } | 3873 } |
3875 | 3874 |
3876 // We don't yet know if the function will be strict, so we cannot yet | 3875 FormalParameterErrorLocations error_locs; |
3877 // produce errors for parameter names or duplicates. However, we remember | |
3878 // the locations of these errors if they occur and produce the errors later. | |
3879 Scanner::Location eval_args_loc = Scanner::Location::invalid(); | |
3880 Scanner::Location dupe_loc = Scanner::Location::invalid(); | |
3881 Scanner::Location reserved_loc = Scanner::Location::invalid(); | |
3882 | |
3883 // Similarly for strong mode. | |
3884 Scanner::Location undefined_loc = Scanner::Location::invalid(); | |
3885 | |
3886 bool has_rest = false; | 3876 bool has_rest = false; |
3887 Expect(Token::LPAREN, CHECK_OK); | 3877 Expect(Token::LPAREN, CHECK_OK); |
3888 int start_position = scanner()->location().beg_pos; | 3878 int start_position = scanner()->location().beg_pos; |
3889 ZoneList<const AstRawString*>* params = | 3879 ZoneList<const AstRawString*>* params = |
3890 ParseFormalParameterList(&eval_args_loc, &undefined_loc, &dupe_loc, | 3880 ParseFormalParameterList(&error_locs, &has_rest, CHECK_OK); |
3891 &reserved_loc, &has_rest, CHECK_OK); | |
3892 Expect(Token::RPAREN, CHECK_OK); | 3881 Expect(Token::RPAREN, CHECK_OK); |
3893 int formals_end_position = scanner()->location().end_pos; | 3882 int formals_end_position = scanner()->location().end_pos; |
3894 | 3883 |
3895 CheckArityRestrictions(params->length(), arity_restriction, start_position, | 3884 CheckArityRestrictions(params->length(), arity_restriction, start_position, |
3896 formals_end_position, CHECK_OK); | 3885 formals_end_position, CHECK_OK); |
3897 | 3886 |
3898 scope->set_start_position(start_position); | 3887 scope->set_start_position(start_position); |
3899 | 3888 |
3900 num_parameters = params->length(); | 3889 num_parameters = params->length(); |
3901 if (dupe_loc.IsValid()) { | 3890 if (error_locs.duplicate_.IsValid()) { |
3902 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | 3891 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
3903 } | 3892 } |
3904 | 3893 |
3905 for (int i = 0; i < params->length(); i++) { | 3894 for (int i = 0; i < params->length(); i++) { |
3906 const AstRawString* param_name = params->at(i); | 3895 const AstRawString* param_name = params->at(i); |
3907 int is_rest = has_rest && i == params->length() - 1; | 3896 int is_rest = has_rest && i == params->length() - 1; |
3908 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest); | 3897 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest); |
3909 if (is_sloppy(scope->language_mode())) { | 3898 if (is_sloppy(scope->language_mode())) { |
3910 // TODO(sigurds) Mark every parameter as maybe assigned. This is a | 3899 // TODO(sigurds) Mark every parameter as maybe assigned. This is a |
3911 // conservative approximation necessary to account for parameters | 3900 // conservative approximation necessary to account for parameters |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3988 expected_property_count = function_state.expected_property_count(); | 3977 expected_property_count = function_state.expected_property_count(); |
3989 handler_count = function_state.handler_count(); | 3978 handler_count = function_state.handler_count(); |
3990 } | 3979 } |
3991 | 3980 |
3992 // Validate name and parameter names. We can do this only after parsing the | 3981 // Validate name and parameter names. We can do this only after parsing the |
3993 // function, since the function can declare itself strict. | 3982 // function, since the function can declare itself strict. |
3994 CheckFunctionName(language_mode(), kind, function_name, | 3983 CheckFunctionName(language_mode(), kind, function_name, |
3995 name_is_strict_reserved, function_name_location, | 3984 name_is_strict_reserved, function_name_location, |
3996 CHECK_OK); | 3985 CHECK_OK); |
3997 const bool use_strict_params = has_rest || IsConciseMethod(kind); | 3986 const bool use_strict_params = has_rest || IsConciseMethod(kind); |
3998 CheckFunctionParameterNames(language_mode(), use_strict_params, | 3987 CheckFunctionParameterNames(language_mode(), use_strict_params, error_locs, |
3999 eval_args_loc, undefined_loc, dupe_loc, | 3988 CHECK_OK); |
4000 reserved_loc, CHECK_OK); | |
4001 | 3989 |
4002 if (is_strict(language_mode())) { | 3990 if (is_strict(language_mode())) { |
4003 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 3991 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
4004 CHECK_OK); | 3992 CHECK_OK); |
4005 } | 3993 } |
4006 if (is_strict(language_mode())) { | 3994 if (is_strict(language_mode())) { |
4007 CheckConflictingVarDeclarations(scope, CHECK_OK); | 3995 CheckConflictingVarDeclarations(scope, CHECK_OK); |
4008 } | 3996 } |
4009 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { | 3997 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { |
4010 if (!function_state.super_call_location().IsValid()) { | 3998 if (!function_state.super_call_location().IsValid()) { |
(...skipping 1717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5728 | 5716 |
5729 Expression* Parser::SpreadCallNew(Expression* function, | 5717 Expression* Parser::SpreadCallNew(Expression* function, |
5730 ZoneList<v8::internal::Expression*>* args, | 5718 ZoneList<v8::internal::Expression*>* args, |
5731 int pos) { | 5719 int pos) { |
5732 args->InsertAt(0, function, zone()); | 5720 args->InsertAt(0, function, zone()); |
5733 | 5721 |
5734 return factory()->NewCallRuntime( | 5722 return factory()->NewCallRuntime( |
5735 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5723 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
5736 } | 5724 } |
5737 } } // namespace v8::internal | 5725 } } // namespace v8::internal |
OLD | NEW |