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 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1127 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1127 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
1128 : FunctionLiteral::NAMED_EXPRESSION) | 1128 : FunctionLiteral::NAMED_EXPRESSION) |
1129 : FunctionLiteral::DECLARATION; | 1129 : FunctionLiteral::DECLARATION; |
1130 bool ok = true; | 1130 bool ok = true; |
1131 | 1131 |
1132 if (shared_info->is_arrow()) { | 1132 if (shared_info->is_arrow()) { |
1133 Scope* scope = NewScope(scope_, ARROW_SCOPE); | 1133 Scope* scope = NewScope(scope_, ARROW_SCOPE); |
1134 scope->set_start_position(shared_info->start_position()); | 1134 scope->set_start_position(shared_info->start_position()); |
1135 FormalParameterErrorLocations error_locs; | 1135 FormalParameterErrorLocations error_locs; |
1136 bool has_rest = false; | 1136 bool has_rest = false; |
| 1137 bool has_initializers = false; |
| 1138 ZoneList<Expression*>* initializers = |
| 1139 new (zone()) ZoneList<Expression*>(0, zone()); |
1137 if (Check(Token::LPAREN)) { | 1140 if (Check(Token::LPAREN)) { |
1138 // '(' StrictFormalParameters ')' | 1141 // '(' StrictFormalParameters ')' |
1139 ParseFormalParameterList(scope, &error_locs, &has_rest, &ok); | 1142 ParseFormalParameterList(scope, &error_locs, initializers, |
| 1143 &has_initializers, &has_rest, &ok); |
1140 if (ok) ok = Check(Token::RPAREN); | 1144 if (ok) ok = Check(Token::RPAREN); |
1141 } else { | 1145 } else { |
1142 // BindingIdentifier | 1146 // BindingIdentifier |
1143 ParseFormalParameter(scope, &error_locs, has_rest, &ok); | 1147 ParseFormalParameter(scope, &error_locs, nullptr, nullptr, has_rest, |
| 1148 &ok); |
1144 } | 1149 } |
1145 | 1150 |
1146 if (ok) { | 1151 if (ok) { |
1147 ExpressionClassifier classifier; | 1152 ExpressionClassifier classifier; |
1148 Expression* expression = ParseArrowFunctionLiteral( | 1153 Expression* expression = ParseArrowFunctionLiteral( |
1149 scope, error_locs, has_rest, &classifier, &ok); | 1154 scope, error_locs, has_rest, &classifier, &ok); |
1150 ValidateExpression(&classifier, &ok); | 1155 ValidateExpression(&classifier, &ok); |
1151 if (ok) { | 1156 if (ok) { |
1152 // Scanning must end at the same position that was recorded | 1157 // Scanning must end at the same position that was recorded |
1153 // previously. If not, parsing has been interrupted due to a stack | 1158 // previously. If not, parsing has been interrupted due to a stack |
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1918 // truly local variable, and the scope of the variable is always the function | 1923 // truly local variable, and the scope of the variable is always the function |
1919 // scope. | 1924 // scope. |
1920 // Let/const variables in harmony mode are always added to the immediately | 1925 // Let/const variables in harmony mode are always added to the immediately |
1921 // enclosing scope. | 1926 // enclosing scope. |
1922 return DeclarationScope(mode)->NewUnresolved(factory(), name, | 1927 return DeclarationScope(mode)->NewUnresolved(factory(), name, |
1923 scanner()->location().beg_pos, | 1928 scanner()->location().beg_pos, |
1924 scanner()->location().end_pos); | 1929 scanner()->location().end_pos); |
1925 } | 1930 } |
1926 | 1931 |
1927 | 1932 |
1928 Variable* Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1933 Variable* Parser::Declare(Declaration* declaration, bool resolve, |
| 1934 bool allow_redeclaration, bool* ok) { |
1929 VariableProxy* proxy = declaration->proxy(); | 1935 VariableProxy* proxy = declaration->proxy(); |
1930 DCHECK(proxy->raw_name() != NULL); | 1936 DCHECK(proxy->raw_name() != NULL); |
1931 const AstRawString* name = proxy->raw_name(); | 1937 const AstRawString* name = proxy->raw_name(); |
1932 VariableMode mode = declaration->mode(); | 1938 VariableMode mode = declaration->mode(); |
1933 Scope* declaration_scope = DeclarationScope(mode); | 1939 Scope* declaration_scope = DeclarationScope(mode); |
1934 Variable* var = NULL; | 1940 Variable* var = NULL; |
1935 | 1941 |
1936 // If a suitable scope exists, then we can statically declare this | 1942 // If a suitable scope exists, then we can statically declare this |
1937 // variable and also set its mode. In any case, a Declaration node | 1943 // variable and also set its mode. In any case, a Declaration node |
1938 // will be added to the scope so that the declaration can be added | 1944 // will be added to the scope so that the declaration can be added |
1939 // to the corresponding activation frame at runtime if necessary. | 1945 // to the corresponding activation frame at runtime if necessary. |
1940 // For instance declarations inside an eval scope need to be added | 1946 // For instance declarations inside an eval scope need to be added |
1941 // to the calling function context. | 1947 // to the calling function context. |
1942 // Similarly, strict mode eval scope does not leak variable declarations to | 1948 // Similarly, strict mode eval scope does not leak variable declarations to |
1943 // the caller's scope so we declare all locals, too. | 1949 // the caller's scope so we declare all locals, too. |
1944 if (declaration_scope->is_function_scope() || | 1950 if (declaration_scope->is_function_scope() || |
1945 declaration_scope->is_strict_eval_scope() || | 1951 declaration_scope->is_strict_eval_scope() || |
1946 declaration_scope->is_block_scope() || | 1952 declaration_scope->is_block_scope() || |
1947 declaration_scope->is_module_scope() || | 1953 declaration_scope->is_module_scope() || |
1948 declaration_scope->is_script_scope()) { | 1954 declaration_scope->is_script_scope()) { |
1949 // Declare the variable in the declaration scope. | 1955 // Declare the variable in the declaration scope. |
1950 var = declaration_scope->LookupLocal(name); | 1956 var = declaration_scope->LookupLocal(name); |
1951 if (var == NULL) { | 1957 if (var == NULL || allow_redeclaration) { |
1952 // Declare the name. | 1958 // Declare the name. |
1953 Variable::Kind kind = Variable::NORMAL; | 1959 Variable::Kind kind = Variable::NORMAL; |
1954 int declaration_group_start = -1; | 1960 int declaration_group_start = -1; |
1955 if (declaration->IsFunctionDeclaration()) { | 1961 if (declaration->IsFunctionDeclaration()) { |
1956 kind = Variable::FUNCTION; | 1962 kind = Variable::FUNCTION; |
1957 } else if (declaration->IsVariableDeclaration() && | 1963 } else if (declaration->IsVariableDeclaration() && |
1958 declaration->AsVariableDeclaration()->is_class_declaration()) { | 1964 declaration->AsVariableDeclaration()->is_class_declaration()) { |
1959 kind = Variable::CLASS; | 1965 kind = Variable::CLASS; |
1960 declaration_group_start = | 1966 declaration_group_start = |
1961 declaration->AsVariableDeclaration()->declaration_group_start(); | 1967 declaration->AsVariableDeclaration()->declaration_group_start(); |
1962 } | 1968 } |
1963 var = declaration_scope->DeclareLocal( | 1969 if (var) { |
1964 name, mode, declaration->initialization(), kind, kNotAssigned, | 1970 DCHECK(declaration_scope->IsDeclaredParameter(name)); |
1965 declaration_group_start); | 1971 var = declaration_scope->RedeclareLocal( |
| 1972 name, mode, declaration->initialization(), kind, kNotAssigned, |
| 1973 declaration_group_start); |
| 1974 } else { |
| 1975 var = declaration_scope->DeclareLocal( |
| 1976 name, mode, declaration->initialization(), kind, kNotAssigned, |
| 1977 declaration_group_start); |
| 1978 } |
1966 } else if (IsLexicalVariableMode(mode) || | 1979 } else if (IsLexicalVariableMode(mode) || |
1967 IsLexicalVariableMode(var->mode()) || | 1980 IsLexicalVariableMode(var->mode()) || |
1968 ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && | 1981 ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && |
1969 !declaration_scope->is_script_scope())) { | 1982 !declaration_scope->is_script_scope())) { |
1970 // The name was declared in this scope before; check for conflicting | 1983 // The name was declared in this scope before; check for conflicting |
1971 // re-declarations. We have a conflict if either of the declarations is | 1984 // re-declarations. We have a conflict if either of the declarations is |
1972 // not a var (in script scope, we also have to ignore legacy const for | 1985 // not a var (in script scope, we also have to ignore legacy const for |
1973 // compatibility). There is similar code in runtime.cc in the Declare | 1986 // compatibility). There is similar code in runtime.cc in the Declare |
1974 // functions. The function CheckConflictingVarDeclarations checks for | 1987 // functions. The function CheckConflictingVarDeclarations checks for |
1975 // var and let bindings from different scopes whereas this is a check for | 1988 // var and let bindings from different scopes whereas this is a check for |
(...skipping 1947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3923 error_locs->eval_or_arguments = param_location; | 3936 error_locs->eval_or_arguments = param_location; |
3924 if (!error_locs->reserved.IsValid() && IsFutureStrictReserved(raw_name)) | 3937 if (!error_locs->reserved.IsValid() && IsFutureStrictReserved(raw_name)) |
3925 error_locs->reserved = param_location; | 3938 error_locs->reserved = param_location; |
3926 if (!error_locs->undefined.IsValid() && IsUndefined(raw_name)) | 3939 if (!error_locs->undefined.IsValid() && IsUndefined(raw_name)) |
3927 error_locs->undefined = param_location; | 3940 error_locs->undefined = param_location; |
3928 | 3941 |
3929 // When the formal parameter was originally seen, it was parsed as a | 3942 // When the formal parameter was originally seen, it was parsed as a |
3930 // VariableProxy and recorded as unresolved in the scope. Here we undo that | 3943 // VariableProxy and recorded as unresolved in the scope. Here we undo that |
3931 // parse-time side-effect. | 3944 // parse-time side-effect. |
3932 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); | 3945 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); |
3933 | 3946 int pos = expr->AsVariableProxy()->position(); |
3934 bool is_rest = false; | 3947 bool is_rest = false; |
3935 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest); | 3948 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest, pos); |
3936 | 3949 |
3937 if (is_duplicate) { | 3950 if (is_duplicate) { |
3938 // Arrow function parameter lists are parsed as StrictFormalParameters, | 3951 // Arrow function parameter lists are parsed as StrictFormalParameters, |
3939 // which means that they cannot have duplicates. Note that this is a subset | 3952 // which means that they cannot have duplicates. Note that this is a subset |
3940 // of the restrictions placed on parameters to functions whose body is | 3953 // of the restrictions placed on parameters to functions whose body is |
3941 // strict. | 3954 // strict. |
3942 ReportMessageAt(param_location, | 3955 ReportMessageAt(param_location, |
3943 "duplicate_arrow_function_formal_parameter"); | 3956 "duplicate_arrow_function_formal_parameter"); |
3944 *ok = false; | 3957 *ok = false; |
3945 return; | 3958 return; |
(...skipping 10 matching lines...) Expand all Loading... |
3956 // TODO(wingo): Make a better message. | 3969 // TODO(wingo): Make a better message. |
3957 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | 3970 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
3958 *ok = false; | 3971 *ok = false; |
3959 return; | 3972 return; |
3960 } | 3973 } |
3961 | 3974 |
3962 DeclareArrowFunctionParameters(scope, params, params_loc, error_locs, ok); | 3975 DeclareArrowFunctionParameters(scope, params, params_loc, error_locs, ok); |
3963 } | 3976 } |
3964 | 3977 |
3965 | 3978 |
| 3979 ZoneList<Statement*>* Parser::DesugarInitializeParameters( |
| 3980 Scope* scope, bool has_initializers, ZoneList<Expression*>* initializers) { |
| 3981 DCHECK(scope->is_function_scope()); |
| 3982 |
| 3983 ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(0, zone()); |
| 3984 if (has_initializers) { |
| 3985 for (int i = 0; i < initializers->length(); ++i) { |
| 3986 Expression* initializer = initializers->at(i); |
| 3987 |
| 3988 // Position of parameter VariableProxy, for hole-checking |
| 3989 int pos = scope->parameter_position(i); |
| 3990 |
| 3991 // Lexically declare the initialized variable |
| 3992 static const VariableMode mode = LET; |
| 3993 VariableProxy* proxy = |
| 3994 NewUnresolved(scope->parameter(i)->raw_name(), mode); |
| 3995 VariableDeclaration* declaration = factory()->NewVariableDeclaration( |
| 3996 proxy, mode, scope, RelocInfo::kNoPosition); |
| 3997 // BRITTLE: this illegally redeclares the variable, be careful about this |
| 3998 proxy = |
| 3999 factory()->NewVariableProxy(Declare(declaration, true, true), pos); |
| 4000 proxy->var()->set_maybe_assigned(); |
| 4001 |
| 4002 const AstRawString* fn_name = ast_value_factory()->empty_string(); |
| 4003 const Runtime::Function* arguments = |
| 4004 Runtime::FunctionForId(Runtime::kInlineArguments); |
| 4005 ZoneList<Expression*>* arguments_i0 = |
| 4006 new (zone()) ZoneList<Expression*>(0, zone()); |
| 4007 arguments_i0->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition), |
| 4008 zone()); |
| 4009 |
| 4010 // TODO(caitp): ensure proper TDZ behaviour --- need hole-check for |
| 4011 // all parameter bindings, including ones without initializers |
| 4012 if (initializer) { |
| 4013 // IS_UNDEFINED(%_Arguments(i)) ? <initializer> : %_Arguments(i); |
| 4014 ZoneList<Expression*>* arguments_i1 = |
| 4015 new (zone()) ZoneList<Expression*>(0, zone()); |
| 4016 arguments_i1->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition), |
| 4017 zone()); |
| 4018 |
| 4019 Expression* arg_or_default = factory()->NewConditional( |
| 4020 // condition: |
| 4021 factory()->NewCompareOperation( |
| 4022 Token::EQ_STRICT, |
| 4023 factory()->NewCallRuntime(fn_name, arguments, arguments_i0, |
| 4024 RelocInfo::kNoPosition), |
| 4025 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), |
| 4026 RelocInfo::kNoPosition), |
| 4027 // if true: |
| 4028 initializer, |
| 4029 // if false: |
| 4030 factory()->NewCallRuntime(fn_name, arguments, arguments_i1, |
| 4031 RelocInfo::kNoPosition), |
| 4032 RelocInfo::kNoPosition); |
| 4033 |
| 4034 Expression* assign = factory()->NewAssignment( |
| 4035 Token::INIT_LET, proxy, arg_or_default, RelocInfo::kNoPosition); |
| 4036 |
| 4037 body->Add( |
| 4038 factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition), |
| 4039 zone()); |
| 4040 proxy->var()->set_initializer_position(initializer->position()); |
| 4041 } else { |
| 4042 // let <name> = %_Arguments(i) |
| 4043 Expression* assign = factory()->NewAssignment( |
| 4044 Token::INIT_LET, proxy, |
| 4045 factory()->NewCallRuntime(fn_name, arguments, arguments_i0, |
| 4046 RelocInfo::kNoPosition), |
| 4047 RelocInfo::kNoPosition); |
| 4048 body->Add( |
| 4049 factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition), |
| 4050 zone()); |
| 4051 proxy->var()->set_initializer_position(pos); |
| 4052 } |
| 4053 } |
| 4054 } else { |
| 4055 // If hasParameterExpressions is false, remove the unnecessary parameter |
| 4056 // block scopes. The function body scope can't be safely removed at this |
| 4057 // point. |
| 4058 ZoneList<Scope*>* scopes = scope->inner_scopes(); |
| 4059 for (int i = 0; i < scopes->length(); ++i) { |
| 4060 Scope* scope = scopes->at(i); |
| 4061 if (!scope->is_function_body_scope()) { |
| 4062 DCHECK(scope->is_block_scope()); |
| 4063 scope->FinalizeBlockScope(); |
| 4064 } |
| 4065 } |
| 4066 } |
| 4067 return body; |
| 4068 } |
| 4069 |
| 4070 |
3966 FunctionLiteral* Parser::ParseFunctionLiteral( | 4071 FunctionLiteral* Parser::ParseFunctionLiteral( |
3967 const AstRawString* function_name, Scanner::Location function_name_location, | 4072 const AstRawString* function_name, Scanner::Location function_name_location, |
3968 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, | 4073 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, |
3969 FunctionLiteral::FunctionType function_type, | 4074 FunctionLiteral::FunctionType function_type, |
3970 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { | 4075 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { |
3971 // Function :: | 4076 // Function :: |
3972 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 4077 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
3973 // | 4078 // |
3974 // Getter :: | 4079 // Getter :: |
3975 // '(' ')' '{' FunctionBody '}' | 4080 // '(' ')' '{' FunctionBody '}' |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4021 // compiling a function in an inner declaration scope in the eval, e.g. a | 4126 // compiling a function in an inner declaration scope in the eval, e.g. a |
4022 // nested function, and hoisting works normally relative to that. | 4127 // nested function, and hoisting works normally relative to that. |
4023 Scope* declaration_scope = scope_->DeclarationScope(); | 4128 Scope* declaration_scope = scope_->DeclarationScope(); |
4024 Scope* original_declaration_scope = original_scope_->DeclarationScope(); | 4129 Scope* original_declaration_scope = original_scope_->DeclarationScope(); |
4025 Scope* scope = function_type == FunctionLiteral::DECLARATION && | 4130 Scope* scope = function_type == FunctionLiteral::DECLARATION && |
4026 is_sloppy(language_mode()) && | 4131 is_sloppy(language_mode()) && |
4027 (original_scope_ == original_declaration_scope || | 4132 (original_scope_ == original_declaration_scope || |
4028 declaration_scope != original_declaration_scope) | 4133 declaration_scope != original_declaration_scope) |
4029 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind) | 4134 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind) |
4030 : NewScope(scope_, FUNCTION_SCOPE, kind); | 4135 : NewScope(scope_, FUNCTION_SCOPE, kind); |
| 4136 Scope* function_body = NewScope(scope, FUNCTION_BODY_SCOPE); |
| 4137 DCHECK_EQ(scope->function_body(), function_body); |
4031 ZoneList<Statement*>* body = NULL; | 4138 ZoneList<Statement*>* body = NULL; |
4032 int materialized_literal_count = -1; | 4139 int materialized_literal_count = -1; |
4033 int expected_property_count = -1; | 4140 int expected_property_count = -1; |
4034 int handler_count = 0; | 4141 int handler_count = 0; |
4035 FormalParameterErrorLocations error_locs; | 4142 FormalParameterErrorLocations error_locs; |
4036 FunctionLiteral::EagerCompileHint eager_compile_hint = | 4143 FunctionLiteral::EagerCompileHint eager_compile_hint = |
4037 parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile | 4144 parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile |
4038 : FunctionLiteral::kShouldLazyCompile; | 4145 : FunctionLiteral::kShouldLazyCompile; |
4039 // Parse function body. | 4146 // Parse function body. |
4040 { | 4147 { |
4041 AstNodeFactory function_factory(ast_value_factory()); | 4148 AstNodeFactory function_factory(ast_value_factory()); |
4042 FunctionState function_state(&function_state_, &scope_, scope, kind, | 4149 FunctionState function_state(&function_state_, &scope_, scope, kind, |
4043 &function_factory); | 4150 &function_factory); |
4044 scope_->SetScopeName(function_name); | 4151 scope_->SetScopeName(function_name); |
| 4152 function_body->SetScopeName(function_name); |
4045 | 4153 |
4046 if (is_generator) { | 4154 if (is_generator) { |
4047 // For generators, allocating variables in contexts is currently a win | 4155 // For generators, allocating variables in contexts is currently a win |
4048 // because it minimizes the work needed to suspend and resume an | 4156 // because it minimizes the work needed to suspend and resume an |
4049 // activation. | 4157 // activation. |
4050 scope_->ForceContextAllocation(); | 4158 scope_->ForceContextAllocation(); |
4051 | 4159 |
4052 // Calling a generator returns a generator object. That object is stored | 4160 // Calling a generator returns a generator object. That object is stored |
4053 // in a temporary variable, a definition that is used by "yield" | 4161 // in a temporary variable, a definition that is used by "yield" |
4054 // expressions. This also marks the FunctionState as a generator. | 4162 // expressions. This also marks the FunctionState as a generator. |
4055 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 4163 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
4056 ast_value_factory()->dot_generator_object_string()); | 4164 ast_value_factory()->dot_generator_object_string()); |
4057 function_state.set_generator_object_variable(temp); | 4165 function_state.set_generator_object_variable(temp); |
4058 } | 4166 } |
4059 | 4167 |
4060 bool has_rest = false; | 4168 bool has_rest = false; |
4061 Expect(Token::LPAREN, CHECK_OK); | 4169 Expect(Token::LPAREN, CHECK_OK); |
4062 int start_position = scanner()->location().beg_pos; | 4170 int start_position = scanner()->location().beg_pos; |
4063 scope_->set_start_position(start_position); | 4171 scope_->set_start_position(start_position); |
| 4172 function_body->set_start_position(start_position); |
| 4173 ZoneList<Expression*>* initializers = |
| 4174 new (zone()) ZoneList<Expression*>(0, zone()); |
| 4175 bool has_initializers = false; |
4064 num_parameters = | 4176 num_parameters = |
4065 ParseFormalParameterList(scope, &error_locs, &has_rest, CHECK_OK); | 4177 ParseFormalParameterList(scope, &error_locs, initializers, |
| 4178 &has_initializers, &has_rest, CHECK_OK); |
4066 Expect(Token::RPAREN, CHECK_OK); | 4179 Expect(Token::RPAREN, CHECK_OK); |
4067 int formals_end_position = scanner()->location().end_pos; | 4180 int formals_end_position = scanner()->location().end_pos; |
4068 | 4181 |
4069 CheckArityRestrictions(num_parameters, arity_restriction, start_position, | 4182 CheckArityRestrictions(num_parameters, arity_restriction, start_position, |
4070 formals_end_position, CHECK_OK); | 4183 formals_end_position, CHECK_OK); |
4071 | 4184 |
4072 Expect(Token::LBRACE, CHECK_OK); | 4185 Expect(Token::LBRACE, CHECK_OK); |
4073 | 4186 |
4074 // If we have a named function expression, we add a local variable | 4187 // If we have a named function expression, we add a local variable |
4075 // declaration to the body of the function with the name of the | 4188 // declaration to the body of the function with the name of the |
4076 // function and let it refer to the function itself (closure). | 4189 // function and let it refer to the function itself (closure). |
4077 // NOTE: We create a proxy and resolve it here so that in the | 4190 // NOTE: We create a proxy and resolve it here so that in the |
4078 // future we can change the AST to only refer to VariableProxies | 4191 // future we can change the AST to only refer to VariableProxies |
4079 // instead of Variables and Proxis as is the case now. | 4192 // instead of Variables and Proxis as is the case now. |
4080 Variable* fvar = NULL; | 4193 Variable* fvar = NULL; |
4081 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; | 4194 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
4082 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 4195 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
4083 if (is_strict(language_mode())) { | 4196 if (is_strict(language_mode())) { |
4084 fvar_init_op = Token::INIT_CONST; | 4197 fvar_init_op = Token::INIT_CONST; |
4085 } | 4198 } |
4086 VariableMode fvar_mode = | 4199 VariableMode fvar_mode = |
4087 is_strict(language_mode()) ? CONST : CONST_LEGACY; | 4200 is_strict(language_mode()) ? CONST : CONST_LEGACY; |
4088 DCHECK(function_name != NULL); | 4201 DCHECK(function_name != NULL); |
4089 fvar = new (zone()) | 4202 fvar = new (zone()) |
4090 Variable(scope_, function_name, fvar_mode, Variable::NORMAL, | 4203 Variable(scope_, function_name, fvar_mode, Variable::NORMAL, |
4091 kCreatedInitialized, kNotAssigned); | 4204 kCreatedInitialized, kNotAssigned); |
4092 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 4205 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
4093 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 4206 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
4094 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 4207 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
| 4208 DCHECK(scope_->is_function_scope()); |
4095 scope_->DeclareFunctionVar(fvar_declaration); | 4209 scope_->DeclareFunctionVar(fvar_declaration); |
4096 } | 4210 } |
4097 | 4211 |
4098 // Determine if the function can be parsed lazily. Lazy parsing is different | 4212 // Determine if the function can be parsed lazily. Lazy parsing is different |
4099 // from lazy compilation; we need to parse more eagerly than we compile. | 4213 // from lazy compilation; we need to parse more eagerly than we compile. |
4100 | 4214 |
4101 // We can only parse lazily if we also compile lazily. The heuristics for | 4215 // We can only parse lazily if we also compile lazily. The heuristics for |
4102 // lazy compilation are: | 4216 // lazy compilation are: |
4103 // - It must not have been prohibited by the caller to Parse (some callers | 4217 // - It must not have been prohibited by the caller to Parse (some callers |
4104 // need a full AST). | 4218 // need a full AST). |
(...skipping 21 matching lines...) Expand all Loading... |
4126 // possible reference to the variable in foo's scope. However, it's possible | 4240 // possible reference to the variable in foo's scope. However, it's possible |
4127 // that it will be compiled lazily. | 4241 // that it will be compiled lazily. |
4128 | 4242 |
4129 // To make this additional case work, both Parser and PreParser implement a | 4243 // To make this additional case work, both Parser and PreParser implement a |
4130 // logic where only top-level functions will be parsed lazily. | 4244 // logic where only top-level functions will be parsed lazily. |
4131 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | 4245 bool is_lazily_parsed = (mode() == PARSE_LAZILY && |
4132 scope_->AllowsLazyCompilation() && | 4246 scope_->AllowsLazyCompilation() && |
4133 !parenthesized_function_); | 4247 !parenthesized_function_); |
4134 parenthesized_function_ = false; // The bit was set for this function only. | 4248 parenthesized_function_ = false; // The bit was set for this function only. |
4135 | 4249 |
4136 if (is_lazily_parsed) { | 4250 { |
4137 for (Scope* s = scope_->outer_scope(); | 4251 // Use the FUNCTION_BODY scope only if it's needed |
4138 s != nullptr && (s != s->DeclarationScope()); s = s->outer_scope()) { | 4252 // TODO(caitp): This is needed when ObjectBindingPatterns with |
4139 s->ForceContextAllocation(); | 4253 // computed property keys are used as well. |
| 4254 Scope* func_scope = has_initializers ? function_body : scope_; |
| 4255 if (func_scope != function_body) { |
| 4256 function_body->FinalizeBlockScope(); |
4140 } | 4257 } |
4141 SkipLazyFunctionBody(&materialized_literal_count, | |
4142 &expected_property_count, CHECK_OK); | |
4143 } else { | |
4144 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, | |
4145 kind, CHECK_OK); | |
4146 materialized_literal_count = function_state.materialized_literal_count(); | |
4147 expected_property_count = function_state.expected_property_count(); | |
4148 handler_count = function_state.handler_count(); | |
4149 | 4258 |
4150 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { | 4259 if (is_lazily_parsed) { |
4151 if (!function_state.super_location().IsValid()) { | 4260 for (Scope* s = scope_->outer_scope(); |
4152 ReportMessageAt(function_name_location, | 4261 s != nullptr && (s != s->DeclarationScope()); |
4153 "strong_super_call_missing", kReferenceError); | 4262 s = s->outer_scope()) { |
4154 *ok = false; | 4263 s->ForceContextAllocation(); |
4155 return nullptr; | 4264 } |
| 4265 { |
| 4266 BlockState function_body_state(&scope_, func_scope); |
| 4267 SkipLazyFunctionBody(&materialized_literal_count, |
| 4268 &expected_property_count, CHECK_OK); |
| 4269 } |
| 4270 } else { |
| 4271 body = |
| 4272 DesugarInitializeParameters(scope, has_initializers, initializers); |
| 4273 { |
| 4274 BlockState function_body_state(&scope_, func_scope); |
| 4275 ZoneList<Statement*>* inner_body = ParseEagerFunctionBody( |
| 4276 function_name, pos, fvar, fvar_init_op, kind, CHECK_OK); |
| 4277 body->AddAll(*inner_body, zone()); |
| 4278 } |
| 4279 materialized_literal_count = |
| 4280 function_state.materialized_literal_count(); |
| 4281 expected_property_count = function_state.expected_property_count(); |
| 4282 handler_count = function_state.handler_count(); |
| 4283 |
| 4284 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { |
| 4285 if (!function_state.super_location().IsValid()) { |
| 4286 ReportMessageAt(function_name_location, "strong_super_call_missing", |
| 4287 kReferenceError); |
| 4288 *ok = false; |
| 4289 return nullptr; |
| 4290 } |
4156 } | 4291 } |
4157 } | 4292 } |
4158 } | 4293 } |
4159 | 4294 |
4160 // Validate name and parameter names. We can do this only after parsing the | 4295 // Validate name and parameter names. We can do this only after parsing the |
4161 // function, since the function can declare itself strict. | 4296 // function, since the function can declare itself strict. |
4162 CheckFunctionName(language_mode(), kind, function_name, | 4297 CheckFunctionName(language_mode(), kind, function_name, |
4163 name_is_strict_reserved, function_name_location, | 4298 name_is_strict_reserved, function_name_location, |
4164 CHECK_OK); | 4299 CHECK_OK); |
4165 const bool use_strict_params = has_rest || IsConciseMethod(kind); | 4300 const bool use_strict_params = has_rest || IsConciseMethod(kind); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4237 return; | 4372 return; |
4238 } | 4373 } |
4239 if (logger.has_error()) { | 4374 if (logger.has_error()) { |
4240 ParserTraits::ReportMessageAt( | 4375 ParserTraits::ReportMessageAt( |
4241 Scanner::Location(logger.start(), logger.end()), logger.message(), | 4376 Scanner::Location(logger.start(), logger.end()), logger.message(), |
4242 logger.argument_opt(), logger.error_type()); | 4377 logger.argument_opt(), logger.error_type()); |
4243 *ok = false; | 4378 *ok = false; |
4244 return; | 4379 return; |
4245 } | 4380 } |
4246 scope_->set_end_position(logger.end()); | 4381 scope_->set_end_position(logger.end()); |
| 4382 if (scope_->is_function_body_scope()) { |
| 4383 DCHECK(scope_->outer_scope()->is_function_scope()); |
| 4384 scope_->outer_scope()->set_end_position(scanner()->location().end_pos); |
| 4385 } |
4247 Expect(Token::RBRACE, ok); | 4386 Expect(Token::RBRACE, ok); |
4248 if (!*ok) { | 4387 if (!*ok) { |
4249 return; | 4388 return; |
4250 } | 4389 } |
4251 total_preparse_skipped_ += scope_->end_position() - function_block_pos; | 4390 total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
4252 *materialized_literal_count = logger.literals(); | 4391 *materialized_literal_count = logger.literals(); |
4253 *expected_property_count = logger.properties(); | 4392 *expected_property_count = logger.properties(); |
4254 scope_->SetLanguageMode(logger.language_mode()); | 4393 scope_->SetLanguageMode(logger.language_mode()); |
4255 if (logger.scope_uses_super_property()) { | 4394 if (logger.scope_uses_super_property()) { |
4256 scope_->RecordSuperPropertyUsage(); | 4395 scope_->RecordSuperPropertyUsage(); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4345 if (IsSubclassConstructor(kind)) { | 4484 if (IsSubclassConstructor(kind)) { |
4346 body->Add( | 4485 body->Add( |
4347 factory()->NewReturnStatement( | 4486 factory()->NewReturnStatement( |
4348 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition), | 4487 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition), |
4349 RelocInfo::kNoPosition), | 4488 RelocInfo::kNoPosition), |
4350 zone()); | 4489 zone()); |
4351 } | 4490 } |
4352 | 4491 |
4353 Expect(Token::RBRACE, CHECK_OK); | 4492 Expect(Token::RBRACE, CHECK_OK); |
4354 scope_->set_end_position(scanner()->location().end_pos); | 4493 scope_->set_end_position(scanner()->location().end_pos); |
| 4494 if (scope_->is_function_body_scope()) { |
| 4495 DCHECK(scope_->outer_scope()->is_function_scope()); |
| 4496 scope_->outer_scope()->set_end_position(scanner()->location().end_pos); |
| 4497 } |
4355 | 4498 |
4356 return body; | 4499 return body; |
4357 } | 4500 } |
4358 | 4501 |
4359 | 4502 |
4360 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( | 4503 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
4361 SingletonLogger* logger) { | 4504 SingletonLogger* logger) { |
4362 // This function may be called on a background thread too; record only the | 4505 // This function may be called on a background thread too; record only the |
4363 // main thread preparse times. | 4506 // main thread preparse times. |
4364 if (pre_parse_timer_ != NULL) { | 4507 if (pre_parse_timer_ != NULL) { |
(...skipping 1526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5891 | 6034 |
5892 Expression* Parser::SpreadCallNew(Expression* function, | 6035 Expression* Parser::SpreadCallNew(Expression* function, |
5893 ZoneList<v8::internal::Expression*>* args, | 6036 ZoneList<v8::internal::Expression*>* args, |
5894 int pos) { | 6037 int pos) { |
5895 args->InsertAt(0, function, zone()); | 6038 args->InsertAt(0, function, zone()); |
5896 | 6039 |
5897 return factory()->NewCallRuntime( | 6040 return factory()->NewCallRuntime( |
5898 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 6041 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
5899 } | 6042 } |
5900 } } // namespace v8::internal | 6043 } } // namespace v8::internal |
OLD | NEW |