Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Side by Side Diff: src/parser.cc

Issue 1060883004: [strong] Implement static restrictions on binding 'undefined' in arrow functions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: linebreak Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698