| 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 Scanner::Location* dupe_loc) { | 3710 Scanner::Location* dupe_loc) { |
| 3710 // Case for empty parameter lists: | 3711 // Case for empty parameter lists: |
| 3711 // () => ... | 3712 // () => ... |
| 3712 if (expression == NULL) return true; | 3713 if (expression == NULL) return true; |
| 3713 | 3714 |
| 3714 // Too many parentheses around expression: | 3715 // Too many parentheses around expression: |
| 3715 // (( ... )) => ... | 3716 // (( ... )) => ... |
| 3716 if (expression->is_multi_parenthesized()) return false; | 3717 if (expression->is_multi_parenthesized()) return false; |
| 3717 | 3718 |
| 3718 // Case for a single parameter: | 3719 // Case for a single parameter: |
| 3719 // (foo) => ... | 3720 // (foo) => ... |
| 3720 // foo => ... | 3721 // foo => ... |
| 3721 if (expression->IsVariableProxy()) { | 3722 if (expression->IsVariableProxy()) { |
| 3722 if (expression->AsVariableProxy()->is_this()) return false; | 3723 if (expression->AsVariableProxy()->is_this()) return false; |
| 3723 | 3724 |
| 3724 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name(); | 3725 const AstRawString* raw_name = expression->AsVariableProxy()->raw_name(); |
| 3725 if (traits->IsEvalOrArguments(raw_name) || | 3726 if (traits->IsEvalOrArguments(raw_name) || |
| 3726 traits->IsFutureStrictReserved(raw_name)) | 3727 traits->IsFutureStrictReserved(raw_name)) |
| 3727 return false; | 3728 return false; |
| 3728 | 3729 if (traits->IsUndefined(raw_name) && !undefined_loc->IsValid()) { |
| 3730 *undefined_loc = Scanner::Location( |
| 3731 expression->position(), expression->position() + raw_name->length()); |
| 3732 } |
| 3729 if (scope->IsDeclared(raw_name)) { | 3733 if (scope->IsDeclared(raw_name)) { |
| 3730 *dupe_loc = Scanner::Location( | 3734 *dupe_loc = Scanner::Location( |
| 3731 expression->position(), expression->position() + raw_name->length()); | 3735 expression->position(), expression->position() + raw_name->length()); |
| 3732 return false; | 3736 return false; |
| 3733 } | 3737 } |
| 3734 | 3738 |
| 3735 // When the variable was seen, it was recorded as unresolved in the outer | 3739 // When the variable was seen, it was recorded as unresolved in the outer |
| 3736 // scope. But it's really not unresolved. | 3740 // scope. But it's really not unresolved. |
| 3737 scope->outer_scope()->RemoveUnresolved(expression->AsVariableProxy()); | 3741 scope->outer_scope()->RemoveUnresolved(expression->AsVariableProxy()); |
| 3738 | 3742 |
| 3739 scope->DeclareParameter(raw_name, VAR); | 3743 scope->DeclareParameter(raw_name, VAR); |
| 3740 ++(*num_params); | 3744 ++(*num_params); |
| 3741 return true; | 3745 return true; |
| 3742 } | 3746 } |
| 3743 | 3747 |
| 3744 // Case for more than one parameter: | 3748 // Case for more than one parameter: |
| 3745 // (foo, bar [, ...]) => ... | 3749 // (foo, bar [, ...]) => ... |
| 3746 if (expression->IsBinaryOperation()) { | 3750 if (expression->IsBinaryOperation()) { |
| 3747 BinaryOperation* binop = expression->AsBinaryOperation(); | 3751 BinaryOperation* binop = expression->AsBinaryOperation(); |
| 3748 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() || | 3752 if (binop->op() != Token::COMMA || binop->left()->is_parenthesized() || |
| 3749 binop->right()->is_parenthesized()) | 3753 binop->right()->is_parenthesized()) |
| 3750 return false; | 3754 return false; |
| 3751 | 3755 |
| 3752 return CheckAndDeclareArrowParameter(traits, binop->left(), scope, | 3756 return CheckAndDeclareArrowParameter(traits, binop->left(), scope, |
| 3753 num_params, dupe_loc) && | 3757 num_params, undefined_loc, dupe_loc) && |
| 3754 CheckAndDeclareArrowParameter(traits, binop->right(), scope, | 3758 CheckAndDeclareArrowParameter(traits, binop->right(), scope, |
| 3755 num_params, dupe_loc); | 3759 num_params, undefined_loc, dupe_loc); |
| 3756 } | 3760 } |
| 3757 | 3761 |
| 3758 // Any other kind of expression is not a valid parameter list. | 3762 // Any other kind of expression is not a valid parameter list. |
| 3759 return false; | 3763 return false; |
| 3760 } | 3764 } |
| 3761 | 3765 |
| 3762 | 3766 |
| 3763 int ParserTraits::DeclareArrowParametersFromExpression( | 3767 int ParserTraits::DeclareArrowParametersFromExpression( |
| 3764 Expression* expression, Scope* scope, Scanner::Location* dupe_loc, | 3768 Expression* expression, Scope* scope, Scanner::Location* undefined_loc, |
| 3765 bool* ok) { | 3769 Scanner::Location* dupe_loc, bool* ok) { |
| 3766 int num_params = 0; | 3770 int num_params = 0; |
| 3767 // Always reset the flag: It only needs to be set for the first expression | 3771 // Always reset the flag: It only needs to be set for the first expression |
| 3768 // parsed as arrow function parameter list, becauseonly top-level functions | 3772 // parsed as arrow function parameter list, because only top-level functions |
| 3769 // are parsed lazily. | 3773 // are parsed lazily. |
| 3770 parser_->parsing_lazy_arrow_parameters_ = false; | 3774 parser_->parsing_lazy_arrow_parameters_ = false; |
| 3771 *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params, | 3775 *ok = CheckAndDeclareArrowParameter(this, expression, scope, &num_params, |
| 3772 dupe_loc); | 3776 undefined_loc, dupe_loc); |
| 3773 return num_params; | 3777 return num_params; |
| 3774 } | 3778 } |
| 3775 | 3779 |
| 3776 | 3780 |
| 3777 FunctionLiteral* Parser::ParseFunctionLiteral( | 3781 FunctionLiteral* Parser::ParseFunctionLiteral( |
| 3778 const AstRawString* function_name, Scanner::Location function_name_location, | 3782 const AstRawString* function_name, Scanner::Location function_name_location, |
| 3779 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, | 3783 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, |
| 3780 FunctionLiteral::FunctionType function_type, | 3784 FunctionLiteral::FunctionType function_type, |
| 3781 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { | 3785 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { |
| 3782 // Function :: | 3786 // Function :: |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3870 } | 3874 } |
| 3871 | 3875 |
| 3872 // FormalParameterList :: | 3876 // FormalParameterList :: |
| 3873 // '(' (Identifier)*[','] ')' | 3877 // '(' (Identifier)*[','] ')' |
| 3874 Expect(Token::LPAREN, CHECK_OK); | 3878 Expect(Token::LPAREN, CHECK_OK); |
| 3875 scope->set_start_position(scanner()->location().beg_pos); | 3879 scope->set_start_position(scanner()->location().beg_pos); |
| 3876 | 3880 |
| 3877 // We don't yet know if the function will be strict, so we cannot yet | 3881 // We don't yet know if the function will be strict, so we cannot yet |
| 3878 // produce errors for parameter names or duplicates. However, we remember | 3882 // produce errors for parameter names or duplicates. However, we remember |
| 3879 // the locations of these errors if they occur and produce the errors later. | 3883 // the locations of these errors if they occur and produce the errors later. |
| 3880 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); | 3884 Scanner::Location eval_args_loc = Scanner::Location::invalid(); |
| 3881 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 3885 Scanner::Location dupe_loc = Scanner::Location::invalid(); |
| 3882 Scanner::Location reserved_error_loc = Scanner::Location::invalid(); | 3886 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 3883 | 3887 |
| 3884 // Similarly for strong mode. | 3888 // Similarly for strong mode. |
| 3885 Scanner::Location undefined_error_loc = Scanner::Location::invalid(); | 3889 Scanner::Location undefined_loc = Scanner::Location::invalid(); |
| 3886 | 3890 |
| 3887 bool is_rest = false; | 3891 bool is_rest = false; |
| 3888 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || | 3892 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || |
| 3889 (peek() == Token::RPAREN && | 3893 (peek() == Token::RPAREN && |
| 3890 arity_restriction != FunctionLiteral::SETTER_ARITY); | 3894 arity_restriction != FunctionLiteral::SETTER_ARITY); |
| 3891 while (!done) { | 3895 while (!done) { |
| 3892 bool is_strict_reserved = false; | 3896 bool is_strict_reserved = false; |
| 3893 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params(); | 3897 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params(); |
| 3894 if (is_rest) { | 3898 if (is_rest) { |
| 3895 Consume(Token::ELLIPSIS); | 3899 Consume(Token::ELLIPSIS); |
| 3896 } | 3900 } |
| 3897 | 3901 |
| 3898 const AstRawString* param_name = | 3902 const AstRawString* param_name = |
| 3899 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 3903 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 3900 | 3904 |
| 3901 // Store locations for possible future error reports. | 3905 // Store locations for possible future error reports. |
| 3902 if (!eval_args_error_loc.IsValid() && IsEvalOrArguments(param_name)) { | 3906 if (!eval_args_loc.IsValid() && IsEvalOrArguments(param_name)) { |
| 3903 eval_args_error_loc = scanner()->location(); | 3907 eval_args_loc = scanner()->location(); |
| 3904 } | 3908 } |
| 3905 if (!undefined_error_loc.IsValid() && IsUndefined(param_name)) { | 3909 if (!undefined_loc.IsValid() && IsUndefined(param_name)) { |
| 3906 undefined_error_loc = scanner()->location(); | 3910 undefined_loc = scanner()->location(); |
| 3907 } | 3911 } |
| 3908 if (!reserved_error_loc.IsValid() && is_strict_reserved) { | 3912 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 3909 reserved_error_loc = scanner()->location(); | 3913 reserved_loc = scanner()->location(); |
| 3910 } | 3914 } |
| 3911 if (!dupe_error_loc.IsValid() && | 3915 if (!dupe_loc.IsValid() && |
| 3912 scope_->IsDeclaredParameter(param_name)) { | 3916 scope_->IsDeclaredParameter(param_name)) { |
| 3913 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | 3917 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
| 3914 dupe_error_loc = scanner()->location(); | 3918 dupe_loc = scanner()->location(); |
| 3915 } | 3919 } |
| 3916 | 3920 |
| 3917 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest); | 3921 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest); |
| 3918 if (is_sloppy(scope->language_mode())) { | 3922 if (is_sloppy(scope->language_mode())) { |
| 3919 // TODO(sigurds) Mark every parameter as maybe assigned. This is a | 3923 // TODO(sigurds) Mark every parameter as maybe assigned. This is a |
| 3920 // conservative approximation necessary to account for parameters | 3924 // conservative approximation necessary to account for parameters |
| 3921 // that are assigned via the arguments array. | 3925 // that are assigned via the arguments array. |
| 3922 var->set_maybe_assigned(); | 3926 var->set_maybe_assigned(); |
| 3923 } | 3927 } |
| 3924 | 3928 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4016 handler_count = function_state.handler_count(); | 4020 handler_count = function_state.handler_count(); |
| 4017 } | 4021 } |
| 4018 | 4022 |
| 4019 // Validate name and parameter names. We can do this only after parsing the | 4023 // Validate name and parameter names. We can do this only after parsing the |
| 4020 // function, since the function can declare itself strict. | 4024 // function, since the function can declare itself strict. |
| 4021 CheckFunctionName(language_mode(), kind, function_name, | 4025 CheckFunctionName(language_mode(), kind, function_name, |
| 4022 name_is_strict_reserved, function_name_location, | 4026 name_is_strict_reserved, function_name_location, |
| 4023 CHECK_OK); | 4027 CHECK_OK); |
| 4024 const bool use_strict_params = is_rest || IsConciseMethod(kind); | 4028 const bool use_strict_params = is_rest || IsConciseMethod(kind); |
| 4025 CheckFunctionParameterNames(language_mode(), use_strict_params, | 4029 CheckFunctionParameterNames(language_mode(), use_strict_params, |
| 4026 eval_args_error_loc, undefined_error_loc, | 4030 eval_args_loc, undefined_loc, dupe_loc, |
| 4027 dupe_error_loc, reserved_error_loc, CHECK_OK); | 4031 reserved_loc, CHECK_OK); |
| 4028 | 4032 |
| 4029 if (is_strict(language_mode())) { | 4033 if (is_strict(language_mode())) { |
| 4030 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 4034 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
| 4031 CHECK_OK); | 4035 CHECK_OK); |
| 4032 } | 4036 } |
| 4033 if (is_strict(language_mode())) { | 4037 if (is_strict(language_mode())) { |
| 4034 CheckConflictingVarDeclarations(scope, CHECK_OK); | 4038 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 4035 } | 4039 } |
| 4036 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { | 4040 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { |
| 4037 if (!function_state.super_call_location().IsValid()) { | 4041 if (!function_state.super_call_location().IsValid()) { |
| (...skipping 1717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5755 | 5759 |
| 5756 Expression* Parser::SpreadCallNew(Expression* function, | 5760 Expression* Parser::SpreadCallNew(Expression* function, |
| 5757 ZoneList<v8::internal::Expression*>* args, | 5761 ZoneList<v8::internal::Expression*>* args, |
| 5758 int pos) { | 5762 int pos) { |
| 5759 args->InsertAt(0, function, zone()); | 5763 args->InsertAt(0, function, zone()); |
| 5760 | 5764 |
| 5761 return factory()->NewCallRuntime( | 5765 return factory()->NewCallRuntime( |
| 5762 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5766 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
| 5763 } | 5767 } |
| 5764 } } // namespace v8::internal | 5768 } } // namespace v8::internal |
| OLD | NEW |