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

Side by Side Diff: src/parser.cc

Issue 1234213004: [parser] use-strict directives in function body affect init block (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 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
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 4289 matching lines...) Expand 10 before | Expand all | Expand 10 after
4300 RelocInfo::kNoPosition); 4300 RelocInfo::kNoPosition);
4301 IfStatement* if_statement = factory()->NewIfStatement( 4301 IfStatement* if_statement = factory()->NewIfStatement(
4302 condition, factory()->NewExpressionStatement(throw_type_error, 4302 condition, factory()->NewExpressionStatement(throw_type_error,
4303 RelocInfo::kNoPosition), 4303 RelocInfo::kNoPosition),
4304 factory()->NewEmptyStatement(RelocInfo::kNoPosition), 4304 factory()->NewEmptyStatement(RelocInfo::kNoPosition),
4305 RelocInfo::kNoPosition); 4305 RelocInfo::kNoPosition);
4306 return if_statement; 4306 return if_statement;
4307 } 4307 }
4308 4308
4309 4309
4310 bool Parser::NeedsParameterInitializationBlock(
rossberg 2015/07/16 12:53:47 Make this into IsSimpleParameterList, to match wha
caitp (gmail) 2015/07/16 13:03:57 Acknowledged.
4311 const ParserFormalParameterParsingState& formal_parameters) {
4312 for (auto parameter : formal_parameters.params) {
4313 if (parameter.pattern != nullptr) return true;
4314 }
4315 return false;
4316 }
4317
4318
4310 Block* Parser::BuildParameterInitializationBlock( 4319 Block* Parser::BuildParameterInitializationBlock(
4311 const ParserFormalParameterParsingState& formal_parameters, bool* ok) { 4320 const ParserFormalParameterParsingState& formal_parameters, bool* ok) {
4321 DCHECK(NeedsParameterInitializationBlock(formal_parameters));
4312 DCHECK(scope_->is_function_scope()); 4322 DCHECK(scope_->is_function_scope());
4313 Block* init_block = nullptr; 4323 Block* init_block =
4324 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
4314 for (auto parameter : formal_parameters.params) { 4325 for (auto parameter : formal_parameters.params) {
4315 if (parameter.pattern == nullptr) continue; 4326 if (parameter.pattern == nullptr) continue;
4316 if (init_block == nullptr) {
4317 init_block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
4318 }
4319
4320 DeclarationDescriptor descriptor; 4327 DeclarationDescriptor descriptor;
4321 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; 4328 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
4322 descriptor.parser = this; 4329 descriptor.parser = this;
4323 descriptor.declaration_scope = scope_; 4330 descriptor.declaration_scope = scope_;
4324 descriptor.scope = scope_; 4331 descriptor.scope = scope_;
4325 descriptor.mode = LET; 4332 descriptor.mode = LET;
4326 descriptor.is_const = false; 4333 descriptor.is_const = false;
4327 descriptor.needs_init = true; 4334 descriptor.needs_init = true;
4328 descriptor.declaration_pos = parameter.pattern->position(); 4335 descriptor.declaration_pos = parameter.pattern->position();
4329 descriptor.initialization_pos = parameter.pattern->position(); 4336 descriptor.initialization_pos = parameter.pattern->position();
4330 descriptor.init_op = Token::INIT_LET; 4337 descriptor.init_op = Token::INIT_LET;
4331 DeclarationParsingResult::Declaration decl( 4338 DeclarationParsingResult::Declaration decl(
4332 parameter.pattern, parameter.pattern->position(), 4339 parameter.pattern, parameter.pattern->position(),
4333 factory()->NewVariableProxy(parameter.var)); 4340 factory()->NewVariableProxy(parameter.var));
4334 PatternRewriter::DeclareAndInitializeVariables(init_block, &descriptor, 4341 PatternRewriter::DeclareAndInitializeVariables(init_block, &descriptor,
4335 &decl, nullptr, CHECK_OK); 4342 &decl, nullptr, CHECK_OK);
4336 } 4343 }
4337 return init_block; 4344 return init_block;
4338 } 4345 }
4339 4346
4340 4347
4341 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( 4348 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
4342 const AstRawString* function_name, int pos, 4349 const AstRawString* function_name, int pos,
4343 const ParserFormalParameterParsingState& formal_parameters, Variable* fvar, 4350 const ParserFormalParameterParsingState& formal_parameters, Variable* fvar,
4344 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { 4351 Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
4345 // Everything inside an eagerly parsed function will be parsed eagerly 4352 // Everything inside an eagerly parsed function will be parsed eagerly
4346 // (see comment above). 4353 // (see comment above).
4347 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 4354 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4348 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); 4355 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
4356 Statement* init_fvar = nullptr;
4357
4349 if (fvar != NULL) { 4358 if (fvar != NULL) {
4350 VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name); 4359 VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name);
4351 fproxy->BindTo(fvar); 4360 fproxy->BindTo(fvar);
4352 result->Add(factory()->NewExpressionStatement( 4361 init_fvar = factory()->NewExpressionStatement(
4353 factory()->NewAssignment(fvar_init_op, 4362 factory()->NewAssignment(fvar_init_op, fproxy,
4354 fproxy,
4355 factory()->NewThisFunction(pos), 4363 factory()->NewThisFunction(pos),
4356 RelocInfo::kNoPosition), 4364 RelocInfo::kNoPosition),
4357 RelocInfo::kNoPosition), zone()); 4365 RelocInfo::kNoPosition);
4358 }
4359
4360
4361 // For concise constructors, check that they are constructed,
4362 // not called.
4363 if (i::IsConstructor(kind)) {
4364 AddAssertIsConstruct(result, pos);
4365 } 4366 }
4366 4367
4367 ZoneList<Statement*>* body = result; 4368 ZoneList<Statement*>* body = result;
4368 Scope* inner_scope = nullptr; 4369 Scope* inner_scope = nullptr;
4369 Block* inner_block = nullptr; 4370 Block* inner_block = nullptr;
4370 Block* init_block = 4371
4371 BuildParameterInitializationBlock(formal_parameters, CHECK_OK); 4372 bool needs_inner_block = NeedsParameterInitializationBlock(formal_parameters);
4372 if (init_block != nullptr) { 4373 if (needs_inner_block) {
4373 body->Add(init_block, zone());
4374 // Wrap the actual function body into an inner scope.
4375 inner_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition);
4376 body->Add(inner_block, zone());
4377 body = inner_block->statements();
4378 inner_scope = NewScope(scope_, BLOCK_SCOPE); 4374 inner_scope = NewScope(scope_, BLOCK_SCOPE);
4379 inner_scope->set_is_declaration_scope(); 4375 inner_scope->set_is_declaration_scope();
4380 inner_scope->set_start_position(scanner()->location().beg_pos); 4376 inner_scope->set_start_position(scanner()->location().beg_pos);
4381 } 4377 }
4382 4378
4383 { 4379 {
4384 BlockState block_state(&scope_, inner_scope ? inner_scope : scope_); 4380 BlockState block_state(&scope_, inner_scope ? inner_scope : scope_);
4385 4381
4382 if (!needs_inner_block) {
4383 if (fvar != nullptr) {
rossberg 2015/07/16 12:53:47 Hm, why do you need to move (and duplicate) fvar i
caitp (gmail) 2015/07/16 13:03:57 it seems that these need to happen before the init
rossberg 2015/07/16 13:21:05 Not sure I understand. They were happening before
caitp (gmail) 2015/07/16 14:44:31 I've refactored this, it's much cleaner now
4384 body->Add(init_fvar, zone());
4385 }
4386 // For concise constructors, check that they are constructed,
4387 // not called.
4388 if (i::IsConstructor(kind)) {
4389 AddAssertIsConstruct(body, pos);
4390 }
4391 }
4392
4386 // For generators, allocate and yield an iterator on function entry. 4393 // For generators, allocate and yield an iterator on function entry.
4387 if (IsGeneratorFunction(kind)) { 4394 if (IsGeneratorFunction(kind)) {
4388 ZoneList<Expression*>* arguments = 4395 ZoneList<Expression*>* arguments =
4389 new(zone()) ZoneList<Expression*>(0, zone()); 4396 new(zone()) ZoneList<Expression*>(0, zone());
4390 CallRuntime* allocation = factory()->NewCallRuntime( 4397 CallRuntime* allocation = factory()->NewCallRuntime(
4391 ast_value_factory()->empty_string(), 4398 ast_value_factory()->empty_string(),
4392 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), arguments, 4399 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), arguments,
4393 pos); 4400 pos);
4394 VariableProxy* init_proxy = factory()->NewVariableProxy( 4401 VariableProxy* init_proxy = factory()->NewVariableProxy(
4395 function_state_->generator_object_variable()); 4402 function_state_->generator_object_variable());
(...skipping 24 matching lines...) Expand all
4420 body->Add( 4427 body->Add(
4421 factory()->NewReturnStatement( 4428 factory()->NewReturnStatement(
4422 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition), 4429 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition),
4423 RelocInfo::kNoPosition), 4430 RelocInfo::kNoPosition),
4424 zone()); 4431 zone());
4425 } 4432 }
4426 } 4433 }
4427 4434
4428 Expect(Token::RBRACE, CHECK_OK); 4435 Expect(Token::RBRACE, CHECK_OK);
4429 scope_->set_end_position(scanner()->location().end_pos); 4436 scope_->set_end_position(scanner()->location().end_pos);
4430 if (inner_scope != nullptr) { 4437
4431 DCHECK(inner_block != nullptr); 4438 if (needs_inner_block) {
4439 DCHECK_NOT_NULL(inner_scope);
4440 scope_->SetLanguageMode(inner_scope->language_mode());
4441 Block* init_block =
4442 BuildParameterInitializationBlock(formal_parameters, CHECK_OK);
4443 DCHECK_NOT_NULL(init_block);
4444 inner_block =
4445 factory()->NewBlock(NULL, body->length(), true, RelocInfo::kNoPosition);
4446 inner_block->statements()->AddAll(*body, zone());
4432 inner_scope->set_end_position(scanner()->location().end_pos); 4447 inner_scope->set_end_position(scanner()->location().end_pos);
4433 inner_scope = inner_scope->FinalizeBlockScope(); 4448 inner_scope = inner_scope->FinalizeBlockScope();
4434 inner_block->set_scope(inner_scope); 4449 inner_block->set_scope(inner_scope);
4450
4451 result = new (zone()) ZoneList<Statement*>(8, zone());
4452 if (fvar != nullptr) {
4453 result->Add(init_fvar, zone());
4454 }
4455 // For concise constructors, check that they are constructed,
4456 // not called.
4457 if (i::IsConstructor(kind)) {
4458 AddAssertIsConstruct(result, pos);
4459 }
4460 result->Add(init_block, zone());
4461 // Wrap the actual function body into an inner scope.
4462 result->Add(inner_block, zone());
4435 } 4463 }
4436 4464
4437 return result; 4465 return result;
4438 } 4466 }
4439 4467
4440 4468
4441 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( 4469 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
4442 SingletonLogger* logger, Scanner::BookmarkScope* bookmark) { 4470 SingletonLogger* logger, Scanner::BookmarkScope* bookmark) {
4443 // This function may be called on a background thread too; record only the 4471 // This function may be called on a background thread too; record only the
4444 // main thread preparse times. 4472 // main thread preparse times.
(...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after
5977 Expression* Parser::SpreadCallNew(Expression* function, 6005 Expression* Parser::SpreadCallNew(Expression* function,
5978 ZoneList<v8::internal::Expression*>* args, 6006 ZoneList<v8::internal::Expression*>* args,
5979 int pos) { 6007 int pos) {
5980 args->InsertAt(0, function, zone()); 6008 args->InsertAt(0, function, zone());
5981 6009
5982 return factory()->NewCallRuntime( 6010 return factory()->NewCallRuntime(
5983 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 6011 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5984 } 6012 }
5985 } // namespace internal 6013 } // namespace internal
5986 } // namespace v8 6014 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698