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/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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |