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 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1006 // background thread. We should not access anything Isolate / heap dependent | 1006 // background thread. We should not access anything Isolate / heap dependent |
1007 // via ParseInfo, and also not pass it forward. | 1007 // via ParseInfo, and also not pass it forward. |
1008 DCHECK(scope_ == NULL); | 1008 DCHECK(scope_ == NULL); |
1009 DCHECK(target_stack_ == NULL); | 1009 DCHECK(target_stack_ == NULL); |
1010 | 1010 |
1011 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY; | 1011 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY; |
1012 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY; | 1012 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY; |
1013 | 1013 |
1014 FunctionLiteral* result = NULL; | 1014 FunctionLiteral* result = NULL; |
1015 { | 1015 { |
1016 // TODO(wingo): Add an outer GLOBAL_SCOPE corresponding to the native | 1016 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native |
1017 // context, which will have the "this" binding for script scopes. | 1017 // context, which will have the "this" binding for script scopes. |
1018 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); | 1018 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); |
1019 info->set_script_scope(scope); | 1019 info->set_script_scope(scope); |
1020 if (!info->context().is_null() && !info->context()->IsNativeContext()) { | 1020 if (!info->context().is_null() && !info->context()->IsNativeContext()) { |
1021 scope = Scope::DeserializeScopeChain(info->isolate(), zone(), | 1021 scope = Scope::DeserializeScopeChain(info->isolate(), zone(), |
1022 *info->context(), scope); | 1022 *info->context(), scope); |
1023 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this | 1023 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this |
1024 // means the Parser cannot operate independent of the V8 heap. Tell the | 1024 // means the Parser cannot operate independent of the V8 heap. Tell the |
1025 // string table to internalize strings and values right after they're | 1025 // string table to internalize strings and values right after they're |
1026 // created. This kind of parsing can only be done in the main thread. | 1026 // created. This kind of parsing can only be done in the main thread. |
(...skipping 3302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4329 } | 4329 } |
4330 | 4330 |
4331 | 4331 |
4332 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 4332 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
4333 const AstRawString* function_name, int pos, | 4333 const AstRawString* function_name, int pos, |
4334 const ParserFormalParameterParsingState& formal_parameters, Variable* fvar, | 4334 const ParserFormalParameterParsingState& formal_parameters, Variable* fvar, |
4335 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { | 4335 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
4336 // Everything inside an eagerly parsed function will be parsed eagerly | 4336 // Everything inside an eagerly parsed function will be parsed eagerly |
4337 // (see comment above). | 4337 // (see comment above). |
4338 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 4338 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
4339 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); | 4339 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); |
4340 if (fvar != NULL) { | 4340 if (fvar != NULL) { |
4341 VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name); | 4341 VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name); |
4342 fproxy->BindTo(fvar); | 4342 fproxy->BindTo(fvar); |
4343 body->Add(factory()->NewExpressionStatement( | 4343 result->Add(factory()->NewExpressionStatement( |
4344 factory()->NewAssignment(fvar_init_op, | 4344 factory()->NewAssignment(fvar_init_op, |
4345 fproxy, | 4345 fproxy, |
4346 factory()->NewThisFunction(pos), | 4346 factory()->NewThisFunction(pos), |
4347 RelocInfo::kNoPosition), | 4347 RelocInfo::kNoPosition), |
4348 RelocInfo::kNoPosition), zone()); | 4348 RelocInfo::kNoPosition), zone()); |
4349 } | 4349 } |
4350 | 4350 |
4351 | 4351 |
4352 // For concise constructors, check that they are constructed, | 4352 // For concise constructors, check that they are constructed, |
4353 // not called. | 4353 // not called. |
4354 if (i::IsConstructor(kind)) { | 4354 if (i::IsConstructor(kind)) { |
4355 AddAssertIsConstruct(body, pos); | 4355 AddAssertIsConstruct(result, pos); |
4356 } | 4356 } |
4357 | 4357 |
4358 auto init_block = | 4358 ZoneList<Statement*>* body = result; |
| 4359 Scope* inner_scope = nullptr; |
| 4360 Block* inner_block = nullptr; |
| 4361 Block* init_block = |
4359 BuildParameterInitializationBlock(formal_parameters, CHECK_OK); | 4362 BuildParameterInitializationBlock(formal_parameters, CHECK_OK); |
4360 if (init_block != nullptr) { | 4363 if (init_block != nullptr) { |
4361 body->Add(init_block, zone()); | 4364 body->Add(init_block, zone()); |
| 4365 // Wrap the actual function body into an inner scope. |
| 4366 inner_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition); |
| 4367 body->Add(inner_block, zone()); |
| 4368 body = inner_block->statements(); |
| 4369 inner_scope = NewScope(scope_, BLOCK_SCOPE); |
| 4370 inner_scope->set_is_declaration_scope(); |
| 4371 inner_scope->set_start_position(scanner()->location().beg_pos); |
4362 } | 4372 } |
4363 | 4373 |
4364 // For generators, allocate and yield an iterator on function entry. | 4374 { |
4365 if (IsGeneratorFunction(kind)) { | 4375 BlockState block_state(&scope_, inner_scope ? inner_scope : scope_); |
4366 ZoneList<Expression*>* arguments = | |
4367 new(zone()) ZoneList<Expression*>(0, zone()); | |
4368 CallRuntime* allocation = factory()->NewCallRuntime( | |
4369 ast_value_factory()->empty_string(), | |
4370 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), arguments, | |
4371 pos); | |
4372 VariableProxy* init_proxy = factory()->NewVariableProxy( | |
4373 function_state_->generator_object_variable()); | |
4374 Assignment* assignment = factory()->NewAssignment( | |
4375 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | |
4376 VariableProxy* get_proxy = factory()->NewVariableProxy( | |
4377 function_state_->generator_object_variable()); | |
4378 Yield* yield = factory()->NewYield( | |
4379 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); | |
4380 body->Add(factory()->NewExpressionStatement( | |
4381 yield, RelocInfo::kNoPosition), zone()); | |
4382 } | |
4383 | 4376 |
4384 ParseStatementList(body, Token::RBRACE, CHECK_OK); | 4377 // For generators, allocate and yield an iterator on function entry. |
| 4378 if (IsGeneratorFunction(kind)) { |
| 4379 ZoneList<Expression*>* arguments = |
| 4380 new(zone()) ZoneList<Expression*>(0, zone()); |
| 4381 CallRuntime* allocation = factory()->NewCallRuntime( |
| 4382 ast_value_factory()->empty_string(), |
| 4383 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), arguments, |
| 4384 pos); |
| 4385 VariableProxy* init_proxy = factory()->NewVariableProxy( |
| 4386 function_state_->generator_object_variable()); |
| 4387 Assignment* assignment = factory()->NewAssignment( |
| 4388 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
| 4389 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 4390 function_state_->generator_object_variable()); |
| 4391 Yield* yield = factory()->NewYield( |
| 4392 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); |
| 4393 body->Add(factory()->NewExpressionStatement( |
| 4394 yield, RelocInfo::kNoPosition), zone()); |
| 4395 } |
4385 | 4396 |
4386 if (IsGeneratorFunction(kind)) { | 4397 ParseStatementList(body, Token::RBRACE, CHECK_OK); |
4387 VariableProxy* get_proxy = factory()->NewVariableProxy( | |
4388 function_state_->generator_object_variable()); | |
4389 Expression* undefined = | |
4390 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); | |
4391 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, | |
4392 RelocInfo::kNoPosition); | |
4393 body->Add(factory()->NewExpressionStatement( | |
4394 yield, RelocInfo::kNoPosition), zone()); | |
4395 } | |
4396 | 4398 |
4397 if (IsSubclassConstructor(kind)) { | 4399 if (IsGeneratorFunction(kind)) { |
4398 body->Add( | 4400 VariableProxy* get_proxy = factory()->NewVariableProxy( |
4399 factory()->NewReturnStatement( | 4401 function_state_->generator_object_variable()); |
4400 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition), | 4402 Expression* undefined = |
4401 RelocInfo::kNoPosition), | 4403 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); |
4402 zone()); | 4404 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, |
| 4405 RelocInfo::kNoPosition); |
| 4406 body->Add(factory()->NewExpressionStatement( |
| 4407 yield, RelocInfo::kNoPosition), zone()); |
| 4408 } |
| 4409 |
| 4410 if (IsSubclassConstructor(kind)) { |
| 4411 body->Add( |
| 4412 factory()->NewReturnStatement( |
| 4413 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition), |
| 4414 RelocInfo::kNoPosition), |
| 4415 zone()); |
| 4416 } |
4403 } | 4417 } |
4404 | 4418 |
4405 Expect(Token::RBRACE, CHECK_OK); | 4419 Expect(Token::RBRACE, CHECK_OK); |
4406 scope_->set_end_position(scanner()->location().end_pos); | 4420 scope_->set_end_position(scanner()->location().end_pos); |
| 4421 if (inner_scope != nullptr) { |
| 4422 DCHECK(inner_block != nullptr); |
| 4423 inner_scope->set_end_position(scanner()->location().end_pos); |
| 4424 inner_scope = inner_scope->FinalizeBlockScope(); |
| 4425 inner_block->set_scope(inner_scope); |
| 4426 } |
4407 | 4427 |
4408 return body; | 4428 return result; |
4409 } | 4429 } |
4410 | 4430 |
4411 | 4431 |
4412 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( | 4432 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
4413 SingletonLogger* logger, Scanner::BookmarkScope* bookmark) { | 4433 SingletonLogger* logger, Scanner::BookmarkScope* bookmark) { |
4414 // This function may be called on a background thread too; record only the | 4434 // This function may be called on a background thread too; record only the |
4415 // main thread preparse times. | 4435 // main thread preparse times. |
4416 if (pre_parse_timer_ != NULL) { | 4436 if (pre_parse_timer_ != NULL) { |
4417 pre_parse_timer_->Start(); | 4437 pre_parse_timer_->Start(); |
4418 } | 4438 } |
(...skipping 1529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5948 Expression* Parser::SpreadCallNew(Expression* function, | 5968 Expression* Parser::SpreadCallNew(Expression* function, |
5949 ZoneList<v8::internal::Expression*>* args, | 5969 ZoneList<v8::internal::Expression*>* args, |
5950 int pos) { | 5970 int pos) { |
5951 args->InsertAt(0, function, zone()); | 5971 args->InsertAt(0, function, zone()); |
5952 | 5972 |
5953 return factory()->NewCallRuntime( | 5973 return factory()->NewCallRuntime( |
5954 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5974 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
5955 } | 5975 } |
5956 } // namespace internal | 5976 } // namespace internal |
5957 } // namespace v8 | 5977 } // namespace v8 |
OLD | NEW |