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

Side by Side Diff: src/parser.cc

Issue 1260053004: Create function name const assignment after parsing language mode. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: replace 0 by constant Created 5 years, 4 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/ast-literal-reindexer.h" 9 #include "src/ast-literal-reindexer.h"
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 4021 matching lines...) Expand 10 before | Expand all | Expand 10 after
4032 ParserFormalParameters formals(scope); 4032 ParserFormalParameters formals(scope);
4033 arity = ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); 4033 arity = ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
4034 Expect(Token::RPAREN, CHECK_OK); 4034 Expect(Token::RPAREN, CHECK_OK);
4035 int formals_end_position = scanner()->location().end_pos; 4035 int formals_end_position = scanner()->location().end_pos;
4036 4036
4037 CheckArityRestrictions(arity, arity_restriction, 4037 CheckArityRestrictions(arity, arity_restriction,
4038 formals.has_rest, start_position, 4038 formals.has_rest, start_position,
4039 formals_end_position, CHECK_OK); 4039 formals_end_position, CHECK_OK);
4040 Expect(Token::LBRACE, CHECK_OK); 4040 Expect(Token::LBRACE, CHECK_OK);
4041 4041
4042 // If we have a named function expression, we add a local variable
4043 // declaration to the body of the function with the name of the
4044 // function and let it refer to the function itself (closure).
4045 // NOTE: We create a proxy and resolve it here so that in the
4046 // future we can change the AST to only refer to VariableProxies
4047 // instead of Variables and Proxis as is the case now.
4048 Variable* fvar = NULL;
4049 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
4050 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
4051 bool use_strict_const = is_strict(language_mode) ||
4052 (!allow_legacy_const() && allow_harmony_sloppy());
4053 if (use_strict_const) {
4054 fvar_init_op = Token::INIT_CONST;
4055 }
4056 VariableMode fvar_mode = use_strict_const ? CONST : CONST_LEGACY;
4057 DCHECK(function_name != NULL);
4058 fvar = new (zone())
4059 Variable(scope_, function_name, fvar_mode, Variable::NORMAL,
4060 kCreatedInitialized, kNotAssigned);
4061 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
4062 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
4063 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
4064 scope_->DeclareFunctionVar(fvar_declaration);
4065 }
4066
4067 // Determine if the function can be parsed lazily. Lazy parsing is different 4042 // Determine if the function can be parsed lazily. Lazy parsing is different
4068 // from lazy compilation; we need to parse more eagerly than we compile. 4043 // from lazy compilation; we need to parse more eagerly than we compile.
4069 4044
4070 // We can only parse lazily if we also compile lazily. The heuristics for 4045 // We can only parse lazily if we also compile lazily. The heuristics for
4071 // lazy compilation are: 4046 // lazy compilation are:
4072 // - It must not have been prohibited by the caller to Parse (some callers 4047 // - It must not have been prohibited by the caller to Parse (some callers
4073 // need a full AST). 4048 // need a full AST).
4074 // - The outer scope must allow lazy compilation of inner functions. 4049 // - The outer scope must allow lazy compilation of inner functions.
4075 // - The function mustn't be a function expression with an open parenthesis 4050 // - The function mustn't be a function expression with an open parenthesis
4076 // before; we consider that a hint that the function will be called 4051 // before; we consider that a hint that the function will be called
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
4120 is_lazily_parsed = false; 4095 is_lazily_parsed = false;
4121 4096
4122 // This is probably an initialization function. Inform the compiler it 4097 // This is probably an initialization function. Inform the compiler it
4123 // should also eager-compile this function, and that we expect it to be 4098 // should also eager-compile this function, and that we expect it to be
4124 // used once. 4099 // used once.
4125 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 4100 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
4126 should_be_used_once_hint = true; 4101 should_be_used_once_hint = true;
4127 } 4102 }
4128 } 4103 }
4129 if (!is_lazily_parsed) { 4104 if (!is_lazily_parsed) {
4130 body = ParseEagerFunctionBody(function_name, pos, formals, fvar, 4105 body = ParseEagerFunctionBody(function_name, pos, formals, kind,
4131 fvar_init_op, kind, CHECK_OK); 4106 function_type, CHECK_OK);
4132 materialized_literal_count = function_state.materialized_literal_count(); 4107 materialized_literal_count = function_state.materialized_literal_count();
4133 expected_property_count = function_state.expected_property_count(); 4108 expected_property_count = function_state.expected_property_count();
4134 } 4109 }
4135 4110
4136 // Parsing the body may change the language mode in our scope. 4111 // Parsing the body may change the language mode in our scope.
4137 language_mode = scope->language_mode(); 4112 language_mode = scope->language_mode();
4138 4113
4139 if (is_strong(language_mode) && IsSubclassConstructor(kind)) { 4114 if (is_strong(language_mode) && IsSubclassConstructor(kind)) {
4140 if (!function_state.super_location().IsValid()) { 4115 if (!function_state.super_location().IsValid()) {
4141 ReportMessageAt(function_name_location, 4116 ReportMessageAt(function_name_location,
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
4337 factory()->NewVariableProxy(parameter.var)); 4312 factory()->NewVariableProxy(parameter.var));
4338 PatternRewriter::DeclareAndInitializeVariables(init_block, &descriptor, 4313 PatternRewriter::DeclareAndInitializeVariables(init_block, &descriptor,
4339 &decl, nullptr, CHECK_OK); 4314 &decl, nullptr, CHECK_OK);
4340 } 4315 }
4341 return init_block; 4316 return init_block;
4342 } 4317 }
4343 4318
4344 4319
4345 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( 4320 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
4346 const AstRawString* function_name, int pos, 4321 const AstRawString* function_name, int pos,
4347 const ParserFormalParameters& parameters, Variable* fvar, 4322 const ParserFormalParameters& parameters, FunctionKind kind,
4348 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { 4323 FunctionLiteral::FunctionType function_type, bool* ok) {
4349 // Everything inside an eagerly parsed function will be parsed eagerly 4324 // Everything inside an eagerly parsed function will be parsed eagerly
4350 // (see comment above). 4325 // (see comment above).
4351 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 4326 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4352 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); 4327 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
4353 if (fvar != NULL) { 4328
4354 VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name); 4329 static const int kFunctionNameAssignmentIndex = 0;
4355 fproxy->BindTo(fvar); 4330 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
4356 result->Add(factory()->NewExpressionStatement( 4331 DCHECK(function_name != NULL);
4357 factory()->NewAssignment(fvar_init_op, 4332 // If we have a named function expression, we add a local variable
4358 fproxy, 4333 // declaration to the body of the function with the name of the
4359 factory()->NewThisFunction(pos), 4334 // function and let it refer to the function itself (closure).
4360 RelocInfo::kNoPosition), 4335 // Not having parsed the function body, the language mode may still change,
4361 RelocInfo::kNoPosition), zone()); 4336 // so we reserve a spot and create the actual const assignment later.
4337 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
4338 result->Add(NULL, zone());
4362 } 4339 }
4363 4340
4364
4365 // For concise constructors, check that they are constructed, 4341 // For concise constructors, check that they are constructed,
4366 // not called. 4342 // not called.
4367 if (i::IsConstructor(kind)) { 4343 if (i::IsConstructor(kind)) {
4368 AddAssertIsConstruct(result, pos); 4344 AddAssertIsConstruct(result, pos);
4369 } 4345 }
4370 4346
4371 ZoneList<Statement*>* body = result; 4347 ZoneList<Statement*>* body = result;
4372 Scope* inner_scope = nullptr; 4348 Scope* inner_scope = nullptr;
4373 Block* inner_block = nullptr; 4349 Block* inner_block = nullptr;
4374 if (!parameters.is_simple) { 4350 if (!parameters.is_simple) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
4438 inner_scope->set_end_position(scanner()->location().end_pos); 4414 inner_scope->set_end_position(scanner()->location().end_pos);
4439 inner_scope = inner_scope->FinalizeBlockScope(); 4415 inner_scope = inner_scope->FinalizeBlockScope();
4440 if (inner_scope != nullptr) { 4416 if (inner_scope != nullptr) {
4441 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); 4417 CheckConflictingVarDeclarations(inner_scope, CHECK_OK);
4442 } 4418 }
4443 4419
4444 result->Add(init_block, zone()); 4420 result->Add(init_block, zone());
4445 result->Add(inner_block, zone()); 4421 result->Add(inner_block, zone());
4446 } 4422 }
4447 4423
4424 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
4425 // Now that we know the language mode, we can create the const assignment
4426 // in the previously reserved spot.
4427 // NOTE: We create a proxy and resolve it here so that in the
4428 // future we can change the AST to only refer to VariableProxies
4429 // instead of Variables and Proxies as is the case now.
4430 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
4431 bool use_strict_const = is_strict(scope_->language_mode()) ||
4432 (!allow_legacy_const() && allow_harmony_sloppy());
4433 if (use_strict_const) {
4434 fvar_init_op = Token::INIT_CONST;
4435 }
4436 VariableMode fvar_mode = use_strict_const ? CONST : CONST_LEGACY;
rossberg 2015/08/04 09:47:36 Wait, I thought the idea was that this should alwa
4437 Variable* fvar = new (zone())
4438 Variable(scope_, function_name, fvar_mode, Variable::NORMAL,
4439 kCreatedInitialized, kNotAssigned);
4440 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
4441 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
4442 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
4443 scope_->DeclareFunctionVar(fvar_declaration);
4444
4445 VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name);
4446 fproxy->BindTo(fvar);
4447 result->Set(kFunctionNameAssignmentIndex,
4448 factory()->NewExpressionStatement(
4449 factory()->NewAssignment(fvar_init_op, fproxy,
4450 factory()->NewThisFunction(pos),
4451 RelocInfo::kNoPosition),
4452 RelocInfo::kNoPosition));
4453 }
4454
4448 return result; 4455 return result;
4449 } 4456 }
4450 4457
4451 4458
4452 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( 4459 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
4453 SingletonLogger* logger, Scanner::BookmarkScope* bookmark) { 4460 SingletonLogger* logger, Scanner::BookmarkScope* bookmark) {
4454 // This function may be called on a background thread too; record only the 4461 // This function may be called on a background thread too; record only the
4455 // main thread preparse times. 4462 // main thread preparse times.
4456 if (pre_parse_timer_ != NULL) { 4463 if (pre_parse_timer_ != NULL) {
4457 pre_parse_timer_->Start(); 4464 pre_parse_timer_->Start();
(...skipping 1531 matching lines...) Expand 10 before | Expand all | Expand 10 after
5989 Expression* Parser::SpreadCallNew(Expression* function, 5996 Expression* Parser::SpreadCallNew(Expression* function,
5990 ZoneList<v8::internal::Expression*>* args, 5997 ZoneList<v8::internal::Expression*>* args,
5991 int pos) { 5998 int pos) {
5992 args->InsertAt(0, function, zone()); 5999 args->InsertAt(0, function, zone());
5993 6000
5994 return factory()->NewCallRuntime( 6001 return factory()->NewCallRuntime(
5995 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 6002 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5996 } 6003 }
5997 } // namespace internal 6004 } // namespace internal
5998 } // namespace v8 6005 } // namespace v8
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