| 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 |