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

Side by Side Diff: src/parser.cc

Issue 1104223002: [es6] implement optional parameters via desugaring (with scoping) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add a debugger test Created 5 years, 7 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 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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