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

Side by Side Diff: src/parser.cc

Issue 13542002: Calling a generator function returns a generator object (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Fix generator construction via `new' Created 7 years, 8 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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 ~BlockState() { parser_->top_scope_ = outer_scope_; } 479 ~BlockState() { parser_->top_scope_ = outer_scope_; }
480 480
481 private: 481 private:
482 Parser* parser_; 482 Parser* parser_;
483 Scope* outer_scope_; 483 Scope* outer_scope_;
484 }; 484 };
485 485
486 486
487 Parser::FunctionState::FunctionState(Parser* parser, 487 Parser::FunctionState::FunctionState(Parser* parser,
488 Scope* scope, 488 Scope* scope,
489 bool is_generator,
490 Isolate* isolate) 489 Isolate* isolate)
491 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), 490 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
492 next_handler_index_(0), 491 next_handler_index_(0),
493 expected_property_count_(0), 492 expected_property_count_(0),
494 is_generator_(is_generator),
495 only_simple_this_property_assignments_(false), 493 only_simple_this_property_assignments_(false),
496 this_property_assignments_(isolate->factory()->empty_fixed_array()), 494 this_property_assignments_(isolate->factory()->empty_fixed_array()),
495 generator_object_variable_(NULL),
497 parser_(parser), 496 parser_(parser),
498 outer_function_state_(parser->current_function_state_), 497 outer_function_state_(parser->current_function_state_),
499 outer_scope_(parser->top_scope_), 498 outer_scope_(parser->top_scope_),
500 saved_ast_node_id_(isolate->ast_node_id()), 499 saved_ast_node_id_(isolate->ast_node_id()),
501 factory_(isolate, parser->zone()) { 500 factory_(isolate, parser->zone()) {
502 parser->top_scope_ = scope; 501 parser->top_scope_ = scope;
503 parser->current_function_state_ = this; 502 parser->current_function_state_ = this;
504 isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt()); 503 isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt());
505 } 504 }
506 505
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 634
636 // Compute the parsing mode. 635 // Compute the parsing mode.
637 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; 636 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
638 if (allow_natives_syntax() || 637 if (allow_natives_syntax() ||
639 extension_ != NULL || 638 extension_ != NULL ||
640 scope->is_eval_scope()) { 639 scope->is_eval_scope()) {
641 mode = PARSE_EAGERLY; 640 mode = PARSE_EAGERLY;
642 } 641 }
643 ParsingModeScope parsing_mode(this, mode); 642 ParsingModeScope parsing_mode(this, mode);
644 643
645 bool is_generator = false;
646 // Enters 'scope'. 644 // Enters 'scope'.
647 FunctionState function_state(this, scope, is_generator, isolate()); 645 FunctionState function_state(this, scope, isolate());
648 646
649 top_scope_->SetLanguageMode(info->language_mode()); 647 top_scope_->SetLanguageMode(info->language_mode());
650 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 648 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
651 bool ok = true; 649 bool ok = true;
652 int beg_loc = scanner().location().beg_pos; 650 int beg_loc = scanner().location().beg_pos;
653 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); 651 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok);
654 if (ok && !top_scope_->is_classic_mode()) { 652 if (ok && !top_scope_->is_classic_mode()) {
655 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); 653 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
656 } 654 }
657 655
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 FunctionLiteral* result = NULL; 749 FunctionLiteral* result = NULL;
752 750
753 { 751 {
754 // Parse the function literal. 752 // Parse the function literal.
755 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); 753 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
756 info()->SetGlobalScope(scope); 754 info()->SetGlobalScope(scope);
757 if (!info()->closure().is_null()) { 755 if (!info()->closure().is_null()) {
758 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, 756 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
759 zone()); 757 zone());
760 } 758 }
761 bool is_generator = false; // Top scope is not a generator. 759 FunctionState function_state(this, scope, isolate());
762 FunctionState function_state(this, scope, is_generator, isolate());
763 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); 760 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode());
764 ASSERT(scope->language_mode() != EXTENDED_MODE || 761 ASSERT(scope->language_mode() != EXTENDED_MODE ||
765 info()->is_extended_mode()); 762 info()->is_extended_mode());
766 ASSERT(info()->language_mode() == shared_info->language_mode()); 763 ASSERT(info()->language_mode() == shared_info->language_mode());
767 scope->SetLanguageMode(shared_info->language_mode()); 764 scope->SetLanguageMode(shared_info->language_mode());
768 FunctionLiteral::Type type = shared_info->is_expression() 765 FunctionLiteral::Type type = shared_info->is_expression()
769 ? (shared_info->is_anonymous() 766 ? (shared_info->is_anonymous()
770 ? FunctionLiteral::ANONYMOUS_EXPRESSION 767 ? FunctionLiteral::ANONYMOUS_EXPRESSION
771 : FunctionLiteral::NAMED_EXPRESSION) 768 : FunctionLiteral::NAMED_EXPRESSION)
772 : FunctionLiteral::DECLARATION; 769 : FunctionLiteral::DECLARATION;
(...skipping 2323 matching lines...) Expand 10 before | Expand all | Expand 10 after
3096 return factory()->NewAssignment(op, expression, right, pos); 3093 return factory()->NewAssignment(op, expression, right, pos);
3097 } 3094 }
3098 3095
3099 3096
3100 Expression* Parser::ParseYieldExpression(bool* ok) { 3097 Expression* Parser::ParseYieldExpression(bool* ok) {
3101 // YieldExpression :: 3098 // YieldExpression ::
3102 // 'yield' '*'? AssignmentExpression 3099 // 'yield' '*'? AssignmentExpression
3103 int position = scanner().peek_location().beg_pos; 3100 int position = scanner().peek_location().beg_pos;
3104 Expect(Token::YIELD, CHECK_OK); 3101 Expect(Token::YIELD, CHECK_OK);
3105 bool is_yield_star = Check(Token::MUL); 3102 bool is_yield_star = Check(Token::MUL);
3103 Expression* generator_object = factory()->NewVariableProxy(
3104 current_function_state_->generator_object_variable());
3106 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); 3105 Expression* expression = ParseAssignmentExpression(false, CHECK_OK);
3107 return factory()->NewYield(expression, is_yield_star, position); 3106 return factory()->NewYield(generator_object, expression, is_yield_star,
3107 position);
3108 } 3108 }
3109 3109
3110 3110
3111 // Precedence = 3 3111 // Precedence = 3
3112 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { 3112 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
3113 // ConditionalExpression :: 3113 // ConditionalExpression ::
3114 // LogicalOrExpression 3114 // LogicalOrExpression
3115 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 3115 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
3116 3116
3117 // We start using the binary expression parser for prec >= 4 only! 3117 // We start using the binary expression parser for prec >= 4 only!
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after
4340 // For function entries. 4340 // For function entries.
4341 int literals_; 4341 int literals_;
4342 int properties_; 4342 int properties_;
4343 LanguageMode mode_; 4343 LanguageMode mode_;
4344 // For error messages. 4344 // For error messages.
4345 const char* message_; 4345 const char* message_;
4346 const char* argument_opt_; 4346 const char* argument_opt_;
4347 }; 4347 };
4348 4348
4349 4349
4350 Statement* Parser::BuildGeneratorObjectInitialization() {
Michael Starzinger 2013/04/14 21:32:50 No need to have a separate builder for this, pleas
wingo 2013/04/15 09:24:57 Done.
4351 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(0, zone());
4352 CallRuntime* allocation = factory()->NewCallRuntime(
4353 isolate()->factory()->empty_string(),
4354 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject),
4355 args);
4356 VariableProxy* init_proxy = factory()->NewVariableProxy(
4357 current_function_state_->generator_object_variable());
4358 Assignment* assignment = factory()->NewAssignment(
4359 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
4360 VariableProxy* get_proxy = factory()->NewVariableProxy(
4361 current_function_state_->generator_object_variable());
4362 Yield* yield = factory()->NewYield(
4363 get_proxy, assignment, false, RelocInfo::kNoPosition);
4364 return factory()->NewExpressionStatement(yield);
4365 }
4366
4367
4350 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, 4368 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
4351 bool name_is_strict_reserved, 4369 bool name_is_strict_reserved,
4352 bool is_generator, 4370 bool is_generator,
4353 int function_token_position, 4371 int function_token_position,
4354 FunctionLiteral::Type type, 4372 FunctionLiteral::Type type,
4355 bool* ok) { 4373 bool* ok) {
4356 // Function :: 4374 // Function ::
4357 // '(' FormalParameterList? ')' '{' FunctionBody '}' 4375 // '(' FormalParameterList? ')' '{' FunctionBody '}'
4358 4376
4359 // Anonymous functions were passed either the empty symbol or a null 4377 // Anonymous functions were passed either the empty symbol or a null
(...skipping 22 matching lines...) Expand all
4382 FunctionLiteral::ParameterFlag duplicate_parameters = 4400 FunctionLiteral::ParameterFlag duplicate_parameters =
4383 FunctionLiteral::kNoDuplicateParameters; 4401 FunctionLiteral::kNoDuplicateParameters;
4384 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ 4402 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
4385 ? FunctionLiteral::kIsParenthesized 4403 ? FunctionLiteral::kIsParenthesized
4386 : FunctionLiteral::kNotParenthesized; 4404 : FunctionLiteral::kNotParenthesized;
4387 FunctionLiteral::IsGeneratorFlag generator = is_generator 4405 FunctionLiteral::IsGeneratorFlag generator = is_generator
4388 ? FunctionLiteral::kIsGenerator 4406 ? FunctionLiteral::kIsGenerator
4389 : FunctionLiteral::kNotGenerator; 4407 : FunctionLiteral::kNotGenerator;
4390 AstProperties ast_properties; 4408 AstProperties ast_properties;
4391 // Parse function body. 4409 // Parse function body.
4392 { FunctionState function_state(this, scope, is_generator, isolate()); 4410 { FunctionState function_state(this, scope, isolate());
4393 top_scope_->SetScopeName(function_name); 4411 top_scope_->SetScopeName(function_name);
4394 // For generators, allocating variables in contexts is currently a win 4412
4395 // because it minimizes the work needed to suspend and resume an activation. 4413 if (is_generator) {
4396 if (is_generator) top_scope_->ForceContextAllocation(); 4414 // For generators, allocating variables in contexts is currently a win
4415 // because it minimizes the work needed to suspend and resume an
4416 // activation.
4417 top_scope_->ForceContextAllocation();
4418
4419 // Calling a generator returns a generator object. That object is stored
4420 // in a temporary variable, a definition that is used by "yield"
4421 // expressions. Presence of a variable for the generator object in the
4422 // FunctionState indicates that this function is a generator.
4423 Handle<String> tempname = isolate()->factory()->InternalizeOneByteString(
4424 STATIC_ASCII_VECTOR(".generator_object"));
4425 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname);
4426 function_state.set_generator_object_variable(temp);
4427 }
4397 4428
4398 // FormalParameterList :: 4429 // FormalParameterList ::
4399 // '(' (Identifier)*[','] ')' 4430 // '(' (Identifier)*[','] ')'
4400 Expect(Token::LPAREN, CHECK_OK); 4431 Expect(Token::LPAREN, CHECK_OK);
4401 scope->set_start_position(scanner().location().beg_pos); 4432 scope->set_start_position(scanner().location().beg_pos);
4402 Scanner::Location name_loc = Scanner::Location::invalid(); 4433 Scanner::Location name_loc = Scanner::Location::invalid();
4403 Scanner::Location dupe_loc = Scanner::Location::invalid(); 4434 Scanner::Location dupe_loc = Scanner::Location::invalid();
4404 Scanner::Location reserved_loc = Scanner::Location::invalid(); 4435 Scanner::Location reserved_loc = Scanner::Location::invalid();
4405 4436
4406 bool done = (peek() == Token::RPAREN); 4437 bool done = (peek() == Token::RPAREN);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
4544 VariableProxy* fproxy = top_scope_->NewUnresolved( 4575 VariableProxy* fproxy = top_scope_->NewUnresolved(
4545 factory(), function_name, Interface::NewConst()); 4576 factory(), function_name, Interface::NewConst());
4546 fproxy->BindTo(fvar); 4577 fproxy->BindTo(fvar);
4547 body->Add(factory()->NewExpressionStatement( 4578 body->Add(factory()->NewExpressionStatement(
4548 factory()->NewAssignment(fvar_init_op, 4579 factory()->NewAssignment(fvar_init_op,
4549 fproxy, 4580 fproxy,
4550 factory()->NewThisFunction(), 4581 factory()->NewThisFunction(),
4551 RelocInfo::kNoPosition)), 4582 RelocInfo::kNoPosition)),
4552 zone()); 4583 zone());
4553 } 4584 }
4585
4586 // For generators, allocate and yield an iterator on function entry.
4587 if (is_generator) {
4588 body->Add(BuildGeneratorObjectInitialization(), zone());
4589 }
4590
4554 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); 4591 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
4555 4592
4556 materialized_literal_count = function_state.materialized_literal_count(); 4593 materialized_literal_count = function_state.materialized_literal_count();
4557 expected_property_count = function_state.expected_property_count(); 4594 expected_property_count = function_state.expected_property_count();
4558 handler_count = function_state.handler_count(); 4595 handler_count = function_state.handler_count();
4559 only_simple_this_property_assignments = 4596 only_simple_this_property_assignments =
4560 function_state.only_simple_this_property_assignments(); 4597 function_state.only_simple_this_property_assignments();
4561 this_property_assignments = function_state.this_property_assignments(); 4598 this_property_assignments = function_state.this_property_assignments();
4562 4599
4563 Expect(Token::RBRACE, CHECK_OK); 4600 Expect(Token::RBRACE, CHECK_OK);
(...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after
5974 ASSERT(info()->isolate()->has_pending_exception()); 6011 ASSERT(info()->isolate()->has_pending_exception());
5975 } else { 6012 } else {
5976 result = ParseProgram(); 6013 result = ParseProgram();
5977 } 6014 }
5978 } 6015 }
5979 info()->SetFunction(result); 6016 info()->SetFunction(result);
5980 return (result != NULL); 6017 return (result != NULL);
5981 } 6018 }
5982 6019
5983 } } // namespace v8::internal 6020 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698