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 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1131 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 1131 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
1132 ? (shared_info->is_anonymous() | 1132 ? (shared_info->is_anonymous() |
1133 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1133 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
1134 : FunctionLiteral::NAMED_EXPRESSION) | 1134 : FunctionLiteral::NAMED_EXPRESSION) |
1135 : FunctionLiteral::DECLARATION; | 1135 : FunctionLiteral::DECLARATION; |
1136 bool ok = true; | 1136 bool ok = true; |
1137 | 1137 |
1138 if (shared_info->is_arrow()) { | 1138 if (shared_info->is_arrow()) { |
1139 Scope* scope = NewScope(scope_, ARROW_SCOPE); | 1139 Scope* scope = NewScope(scope_, ARROW_SCOPE); |
1140 scope->set_start_position(shared_info->start_position()); | 1140 scope->set_start_position(shared_info->start_position()); |
1141 FormalParameterErrorLocations error_locs; | 1141 ExpressionClassifier formals_classifier; |
1142 bool has_rest = false; | 1142 bool has_rest = false; |
1143 if (Check(Token::LPAREN)) { | 1143 if (Check(Token::LPAREN)) { |
1144 // '(' StrictFormalParameters ')' | 1144 // '(' StrictFormalParameters ')' |
1145 ParseFormalParameterList(scope, &error_locs, &has_rest, &ok); | 1145 ParseFormalParameterList(scope, &has_rest, &formals_classifier, &ok); |
1146 if (ok) ok = Check(Token::RPAREN); | 1146 if (ok) ok = Check(Token::RPAREN); |
1147 } else { | 1147 } else { |
1148 // BindingIdentifier | 1148 // BindingIdentifier |
1149 ParseFormalParameter(scope, &error_locs, has_rest, &ok); | 1149 ParseFormalParameter(scope, has_rest, &formals_classifier, &ok); |
1150 } | 1150 } |
1151 | 1151 |
1152 if (ok) { | 1152 if (ok) { |
1153 ExpressionClassifier classifier; | 1153 Expression* expression = |
1154 Expression* expression = ParseArrowFunctionLiteral( | 1154 ParseArrowFunctionLiteral(scope, has_rest, formals_classifier, &ok); |
1155 scope, error_locs, has_rest, &classifier, &ok); | |
1156 ValidateExpression(&classifier, &ok); | |
1157 if (ok) { | 1155 if (ok) { |
1158 // Scanning must end at the same position that was recorded | 1156 // Scanning must end at the same position that was recorded |
1159 // previously. If not, parsing has been interrupted due to a stack | 1157 // previously. If not, parsing has been interrupted due to a stack |
1160 // overflow, at which point the partially parsed arrow function | 1158 // overflow, at which point the partially parsed arrow function |
1161 // concise body happens to be a valid expression. This is a problem | 1159 // concise body happens to be a valid expression. This is a problem |
1162 // only for arrow functions with single expression bodies, since there | 1160 // only for arrow functions with single expression bodies, since there |
1163 // is no end token such as "}" for normal functions. | 1161 // is no end token such as "}" for normal functions. |
1164 if (scanner()->location().end_pos == shared_info->end_position()) { | 1162 if (scanner()->location().end_pos == shared_info->end_position()) { |
1165 // The pre-parser saw an arrow function here, so the full parser | 1163 // The pre-parser saw an arrow function here, so the full parser |
1166 // must produce a FunctionLiteral. | 1164 // must produce a FunctionLiteral. |
(...skipping 2546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3713 } | 3711 } |
3714 | 3712 |
3715 | 3713 |
3716 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { | 3714 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
3717 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); | 3715 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); |
3718 } | 3716 } |
3719 | 3717 |
3720 | 3718 |
3721 void ParserTraits::DeclareArrowFunctionParameters( | 3719 void ParserTraits::DeclareArrowFunctionParameters( |
3722 Scope* scope, Expression* expr, const Scanner::Location& params_loc, | 3720 Scope* scope, Expression* expr, const Scanner::Location& params_loc, |
3723 FormalParameterErrorLocations* error_locs, bool* ok) { | 3721 Scanner::Location* duplicate_loc, bool* ok) { |
3724 if (scope->num_parameters() >= Code::kMaxArguments) { | 3722 if (scope->num_parameters() >= Code::kMaxArguments) { |
3725 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | 3723 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
3726 *ok = false; | 3724 *ok = false; |
3727 return; | 3725 return; |
3728 } | 3726 } |
3729 | 3727 |
3730 // ArrowFunctionFormals :: | 3728 // ArrowFunctionFormals :: |
3731 // Binary(Token::COMMA, ArrowFunctionFormals, VariableProxy) | 3729 // Binary(Token::COMMA, ArrowFunctionFormals, VariableProxy) |
3732 // VariableProxy | 3730 // VariableProxy |
3733 // | 3731 // |
3734 // As we need to visit the parameters in left-to-right order, we recurse on | 3732 // As we need to visit the parameters in left-to-right order, we recurse on |
3735 // the left-hand side of comma expressions. | 3733 // the left-hand side of comma expressions. |
3736 // | 3734 // |
3737 // Sadly, for the various malformed_arrow_function_parameter_list errors, we | 3735 // Sadly, for the various malformed_arrow_function_parameter_list errors, we |
3738 // can't be more specific on the error message or on the location because we | 3736 // can't be more specific on the error message or on the location because we |
3739 // need to match the pre-parser's behavior. | 3737 // need to match the pre-parser's behavior. |
3740 if (expr->IsBinaryOperation()) { | 3738 if (expr->IsBinaryOperation()) { |
3741 BinaryOperation* binop = expr->AsBinaryOperation(); | 3739 BinaryOperation* binop = expr->AsBinaryOperation(); |
3740 // TODO(wingo): These checks are now unnecessary, given the classifier. | |
3742 if (binop->op() != Token::COMMA) { | 3741 if (binop->op() != Token::COMMA) { |
3743 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | 3742 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
3744 *ok = false; | 3743 *ok = false; |
3745 return; | 3744 return; |
3746 } | 3745 } |
3747 Expression* left = binop->left(); | 3746 Expression* left = binop->left(); |
3748 Expression* right = binop->right(); | 3747 Expression* right = binop->right(); |
3749 if (left->is_single_parenthesized() || right->is_single_parenthesized()) { | 3748 if (left->is_single_parenthesized() || right->is_single_parenthesized()) { |
3750 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | 3749 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
3751 *ok = false; | 3750 *ok = false; |
3752 return; | 3751 return; |
3753 } | 3752 } |
3754 DeclareArrowFunctionParameters(scope, left, params_loc, error_locs, ok); | 3753 DeclareArrowFunctionParameters(scope, left, params_loc, duplicate_loc, ok); |
3755 if (!*ok) return; | 3754 if (!*ok) return; |
3756 // LHS of comma expression should be unparenthesized. | 3755 // LHS of comma expression should be unparenthesized. |
3757 expr = right; | 3756 expr = right; |
3758 } | 3757 } |
3759 | 3758 |
3760 // TODO(wingo): Support rest parameters. | 3759 // TODO(wingo): Support rest parameters. |
3761 if (!expr->IsVariableProxy()) { | 3760 if (!expr->IsVariableProxy()) { |
3762 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | 3761 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
3763 *ok = false; | 3762 *ok = false; |
3764 return; | 3763 return; |
3765 } | 3764 } |
3766 | 3765 |
3767 const AstRawString* raw_name = expr->AsVariableProxy()->raw_name(); | 3766 const AstRawString* raw_name = expr->AsVariableProxy()->raw_name(); |
3768 Scanner::Location param_location(expr->position(), | 3767 Scanner::Location param_location(expr->position(), |
3769 expr->position() + raw_name->length()); | 3768 expr->position() + raw_name->length()); |
3770 | 3769 |
3771 if (expr->AsVariableProxy()->is_this()) { | 3770 if (expr->AsVariableProxy()->is_this()) { |
3772 ReportMessageAt(param_location, "this_formal_parameter"); | 3771 ReportMessageAt(param_location, "this_formal_parameter"); |
3773 *ok = false; | 3772 *ok = false; |
3774 return; | 3773 return; |
3775 } | 3774 } |
3776 | 3775 |
3777 if (!error_locs->eval_or_arguments.IsValid() && IsEvalOrArguments(raw_name)) | |
3778 error_locs->eval_or_arguments = param_location; | |
3779 if (!error_locs->reserved.IsValid() && IsFutureStrictReserved(raw_name)) | |
3780 error_locs->reserved = param_location; | |
3781 if (!error_locs->undefined.IsValid() && IsUndefined(raw_name)) | |
3782 error_locs->undefined = param_location; | |
3783 | |
3784 // When the formal parameter was originally seen, it was parsed as a | 3776 // When the formal parameter was originally seen, it was parsed as a |
3785 // VariableProxy and recorded as unresolved in the scope. Here we undo that | 3777 // VariableProxy and recorded as unresolved in the scope. Here we undo that |
3786 // parse-time side-effect. | 3778 // parse-time side-effect. |
3787 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); | 3779 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); |
3788 | 3780 |
3789 bool is_rest = false; | 3781 bool is_rest = false; |
3790 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest); | 3782 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest); |
3791 | 3783 |
3792 if (is_duplicate) { | 3784 if (is_duplicate && !duplicate_loc->IsValid()) { |
3793 // Arrow function parameter lists are parsed as StrictFormalParameters, | 3785 *duplicate_loc = param_location; |
3794 // which means that they cannot have duplicates. Note that this is a subset | |
3795 // of the restrictions placed on parameters to functions whose body is | |
3796 // strict. | |
3797 ReportMessageAt(param_location, | |
3798 "duplicate_arrow_function_formal_parameter"); | |
3799 *ok = false; | |
3800 return; | |
3801 } | 3786 } |
3802 } | 3787 } |
3803 | 3788 |
3804 | 3789 |
3805 void ParserTraits::ParseArrowFunctionFormalParameters( | 3790 void ParserTraits::ParseArrowFunctionFormalParameters( |
3806 Scope* scope, Expression* params, const Scanner::Location& params_loc, | 3791 Scope* scope, Expression* params, const Scanner::Location& params_loc, |
3807 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok) { | 3792 bool* is_rest, Scanner::Location* duplicate_loc, bool* ok) { |
3808 // Too many parentheses around expression: | 3793 // Too many parentheses around expression: |
3809 // (( ... )) => ... | 3794 // (( ... )) => ... |
3810 if (params->is_multi_parenthesized()) { | 3795 if (params->is_multi_parenthesized()) { |
3811 // TODO(wingo): Make a better message. | 3796 // TODO(wingo): Make a better message. |
3812 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | 3797 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
3813 *ok = false; | 3798 *ok = false; |
3814 return; | 3799 return; |
3815 } | 3800 } |
3816 | 3801 |
3817 DeclareArrowFunctionParameters(scope, params, params_loc, error_locs, ok); | 3802 DeclareArrowFunctionParameters(scope, params, params_loc, duplicate_loc, ok); |
3818 } | 3803 } |
3819 | 3804 |
3820 | 3805 |
3821 FunctionLiteral* Parser::ParseFunctionLiteral( | 3806 FunctionLiteral* Parser::ParseFunctionLiteral( |
3822 const AstRawString* function_name, Scanner::Location function_name_location, | 3807 const AstRawString* function_name, Scanner::Location function_name_location, |
3823 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, | 3808 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, |
3824 FunctionLiteral::FunctionType function_type, | 3809 FunctionLiteral::FunctionType function_type, |
3825 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { | 3810 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { |
3826 // Function :: | 3811 // Function :: |
3827 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3812 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3880 Scope* scope = function_type == FunctionLiteral::DECLARATION && | 3865 Scope* scope = function_type == FunctionLiteral::DECLARATION && |
3881 is_sloppy(language_mode()) && | 3866 is_sloppy(language_mode()) && |
3882 (original_scope_ == original_declaration_scope || | 3867 (original_scope_ == original_declaration_scope || |
3883 declaration_scope != original_declaration_scope) | 3868 declaration_scope != original_declaration_scope) |
3884 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind) | 3869 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind) |
3885 : NewScope(scope_, FUNCTION_SCOPE, kind); | 3870 : NewScope(scope_, FUNCTION_SCOPE, kind); |
3886 ZoneList<Statement*>* body = NULL; | 3871 ZoneList<Statement*>* body = NULL; |
3887 int materialized_literal_count = -1; | 3872 int materialized_literal_count = -1; |
3888 int expected_property_count = -1; | 3873 int expected_property_count = -1; |
3889 int handler_count = 0; | 3874 int handler_count = 0; |
3890 FormalParameterErrorLocations error_locs; | 3875 ExpressionClassifier formals_classifier; |
3891 FunctionLiteral::EagerCompileHint eager_compile_hint = | 3876 FunctionLiteral::EagerCompileHint eager_compile_hint = |
3892 parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile | 3877 parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile |
3893 : FunctionLiteral::kShouldLazyCompile; | 3878 : FunctionLiteral::kShouldLazyCompile; |
3894 bool should_be_used_once_hint = false; | 3879 bool should_be_used_once_hint = false; |
3895 // Parse function body. | 3880 // Parse function body. |
3896 { | 3881 { |
3897 AstNodeFactory function_factory(ast_value_factory()); | 3882 AstNodeFactory function_factory(ast_value_factory()); |
3898 FunctionState function_state(&function_state_, &scope_, scope, kind, | 3883 FunctionState function_state(&function_state_, &scope_, scope, kind, |
3899 &function_factory); | 3884 &function_factory); |
3900 scope_->SetScopeName(function_name); | 3885 scope_->SetScopeName(function_name); |
3901 | 3886 |
3902 if (is_generator) { | 3887 if (is_generator) { |
3903 // For generators, allocating variables in contexts is currently a win | 3888 // For generators, allocating variables in contexts is currently a win |
3904 // because it minimizes the work needed to suspend and resume an | 3889 // because it minimizes the work needed to suspend and resume an |
3905 // activation. | 3890 // activation. |
3906 scope_->ForceContextAllocation(); | 3891 scope_->ForceContextAllocation(); |
3907 | 3892 |
3908 // Calling a generator returns a generator object. That object is stored | 3893 // Calling a generator returns a generator object. That object is stored |
3909 // in a temporary variable, a definition that is used by "yield" | 3894 // in a temporary variable, a definition that is used by "yield" |
3910 // expressions. This also marks the FunctionState as a generator. | 3895 // expressions. This also marks the FunctionState as a generator. |
3911 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3896 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
3912 ast_value_factory()->dot_generator_object_string()); | 3897 ast_value_factory()->dot_generator_object_string()); |
3913 function_state.set_generator_object_variable(temp); | 3898 function_state.set_generator_object_variable(temp); |
3914 } | 3899 } |
3915 | 3900 |
3916 bool has_rest = false; | 3901 bool has_rest = false; |
3917 Expect(Token::LPAREN, CHECK_OK); | 3902 Expect(Token::LPAREN, CHECK_OK); |
3918 int start_position = scanner()->location().beg_pos; | 3903 int start_position = scanner()->location().beg_pos; |
3919 scope_->set_start_position(start_position); | 3904 scope_->set_start_position(start_position); |
3920 num_parameters = | 3905 num_parameters = ParseFormalParameterList(scope, &has_rest, |
3921 ParseFormalParameterList(scope, &error_locs, &has_rest, CHECK_OK); | 3906 &formals_classifier, CHECK_OK); |
3922 Expect(Token::RPAREN, CHECK_OK); | 3907 Expect(Token::RPAREN, CHECK_OK); |
3923 int formals_end_position = scanner()->location().end_pos; | 3908 int formals_end_position = scanner()->location().end_pos; |
3924 | 3909 |
3925 CheckArityRestrictions(num_parameters, arity_restriction, start_position, | 3910 CheckArityRestrictions(num_parameters, arity_restriction, start_position, |
3926 formals_end_position, CHECK_OK); | 3911 formals_end_position, CHECK_OK); |
3927 | 3912 |
3928 Expect(Token::LBRACE, CHECK_OK); | 3913 Expect(Token::LBRACE, CHECK_OK); |
3929 | 3914 |
3930 // If we have a named function expression, we add a local variable | 3915 // If we have a named function expression, we add a local variable |
3931 // declaration to the body of the function with the name of the | 3916 // declaration to the body of the function with the name of the |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4034 } | 4019 } |
4035 } | 4020 } |
4036 } | 4021 } |
4037 | 4022 |
4038 // 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 |
4039 // function, since the function can declare itself strict. | 4024 // function, since the function can declare itself strict. |
4040 CheckFunctionName(language_mode(), kind, function_name, | 4025 CheckFunctionName(language_mode(), kind, function_name, |
4041 name_is_strict_reserved, function_name_location, | 4026 name_is_strict_reserved, function_name_location, |
4042 CHECK_OK); | 4027 CHECK_OK); |
4043 const bool use_strict_params = has_rest || IsConciseMethod(kind); | 4028 const bool use_strict_params = has_rest || IsConciseMethod(kind); |
4044 CheckFunctionParameterNames(language_mode(), use_strict_params, error_locs, | 4029 const bool allow_duplicate_parameters = |
arv (Not doing code reviews)
2015/05/13 14:13:05
Does this handle patterns?
// sloppy
function f(x
wingo
2015/05/15 12:30:30
I guess it should but it doesn't. In a similar wa
| |
4045 CHECK_OK); | 4030 is_sloppy(language_mode()) && !use_strict_params; |
4031 ValidateFormalParameters(&formals_classifier, language_mode(), | |
4032 allow_duplicate_parameters, CHECK_OK); | |
4046 | 4033 |
4047 if (is_strict(language_mode())) { | 4034 if (is_strict(language_mode())) { |
4048 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 4035 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
4049 CHECK_OK); | 4036 CHECK_OK); |
4050 CheckConflictingVarDeclarations(scope, CHECK_OK); | 4037 CheckConflictingVarDeclarations(scope, CHECK_OK); |
4051 } | 4038 } |
4052 } | 4039 } |
4053 | 4040 |
4041 bool has_duplicate_parameters = | |
4042 !formals_classifier.is_valid_formal_parameter_list_without_duplicates(); | |
4054 FunctionLiteral::ParameterFlag duplicate_parameters = | 4043 FunctionLiteral::ParameterFlag duplicate_parameters = |
4055 error_locs.duplicate.IsValid() ? FunctionLiteral::kHasDuplicateParameters | 4044 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters |
4056 : FunctionLiteral::kNoDuplicateParameters; | 4045 : FunctionLiteral::kNoDuplicateParameters; |
4057 | 4046 |
4058 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( | 4047 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( |
4059 function_name, ast_value_factory(), scope, body, | 4048 function_name, ast_value_factory(), scope, body, |
4060 materialized_literal_count, expected_property_count, handler_count, | 4049 materialized_literal_count, expected_property_count, handler_count, |
4061 num_parameters, duplicate_parameters, function_type, | 4050 num_parameters, duplicate_parameters, function_type, |
4062 FunctionLiteral::kIsFunction, eager_compile_hint, kind, pos); | 4051 FunctionLiteral::kIsFunction, eager_compile_hint, kind, pos); |
4063 function_literal->set_function_token_position(function_token_pos); | 4052 function_literal->set_function_token_position(function_token_pos); |
4064 if (should_be_used_once_hint) | 4053 if (should_be_used_once_hint) |
4065 function_literal->set_should_be_used_once_hint(); | 4054 function_literal->set_should_be_used_once_hint(); |
4066 | 4055 |
(...skipping 1708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5775 | 5764 |
5776 Expression* Parser::SpreadCallNew(Expression* function, | 5765 Expression* Parser::SpreadCallNew(Expression* function, |
5777 ZoneList<v8::internal::Expression*>* args, | 5766 ZoneList<v8::internal::Expression*>* args, |
5778 int pos) { | 5767 int pos) { |
5779 args->InsertAt(0, function, zone()); | 5768 args->InsertAt(0, function, zone()); |
5780 | 5769 |
5781 return factory()->NewCallRuntime( | 5770 return factory()->NewCallRuntime( |
5782 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5771 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
5783 } | 5772 } |
5784 } } // namespace v8::internal | 5773 } } // namespace v8::internal |
OLD | NEW |