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

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 nits; generator object fields are undefined if not set 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
« no previous file with comments | « src/parser.h ('k') | src/runtime.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 // 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 1264 matching lines...) Expand 10 before | Expand all | Expand 10 after
4382 FunctionLiteral::ParameterFlag duplicate_parameters = 4382 FunctionLiteral::ParameterFlag duplicate_parameters =
4383 FunctionLiteral::kNoDuplicateParameters; 4383 FunctionLiteral::kNoDuplicateParameters;
4384 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ 4384 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
4385 ? FunctionLiteral::kIsParenthesized 4385 ? FunctionLiteral::kIsParenthesized
4386 : FunctionLiteral::kNotParenthesized; 4386 : FunctionLiteral::kNotParenthesized;
4387 FunctionLiteral::IsGeneratorFlag generator = is_generator 4387 FunctionLiteral::IsGeneratorFlag generator = is_generator
4388 ? FunctionLiteral::kIsGenerator 4388 ? FunctionLiteral::kIsGenerator
4389 : FunctionLiteral::kNotGenerator; 4389 : FunctionLiteral::kNotGenerator;
4390 AstProperties ast_properties; 4390 AstProperties ast_properties;
4391 // Parse function body. 4391 // Parse function body.
4392 { FunctionState function_state(this, scope, is_generator, isolate()); 4392 { FunctionState function_state(this, scope, isolate());
4393 top_scope_->SetScopeName(function_name); 4393 top_scope_->SetScopeName(function_name);
4394 // For generators, allocating variables in contexts is currently a win 4394
4395 // because it minimizes the work needed to suspend and resume an activation. 4395 if (is_generator) {
4396 if (is_generator) top_scope_->ForceContextAllocation(); 4396 // For generators, allocating variables in contexts is currently a win
4397 // because it minimizes the work needed to suspend and resume an
4398 // activation.
4399 top_scope_->ForceContextAllocation();
4400
4401 // Calling a generator returns a generator object. That object is stored
4402 // in a temporary variable, a definition that is used by "yield"
4403 // expressions. Presence of a variable for the generator object in the
4404 // FunctionState indicates that this function is a generator.
4405 Handle<String> tempname = isolate()->factory()->InternalizeOneByteString(
4406 STATIC_ASCII_VECTOR(".generator_object"));
4407 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname);
4408 function_state.set_generator_object_variable(temp);
4409 }
4397 4410
4398 // FormalParameterList :: 4411 // FormalParameterList ::
4399 // '(' (Identifier)*[','] ')' 4412 // '(' (Identifier)*[','] ')'
4400 Expect(Token::LPAREN, CHECK_OK); 4413 Expect(Token::LPAREN, CHECK_OK);
4401 scope->set_start_position(scanner().location().beg_pos); 4414 scope->set_start_position(scanner().location().beg_pos);
4402 Scanner::Location name_loc = Scanner::Location::invalid(); 4415 Scanner::Location name_loc = Scanner::Location::invalid();
4403 Scanner::Location dupe_loc = Scanner::Location::invalid(); 4416 Scanner::Location dupe_loc = Scanner::Location::invalid();
4404 Scanner::Location reserved_loc = Scanner::Location::invalid(); 4417 Scanner::Location reserved_loc = Scanner::Location::invalid();
4405 4418
4406 bool done = (peek() == Token::RPAREN); 4419 bool done = (peek() == Token::RPAREN);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
4544 VariableProxy* fproxy = top_scope_->NewUnresolved( 4557 VariableProxy* fproxy = top_scope_->NewUnresolved(
4545 factory(), function_name, Interface::NewConst()); 4558 factory(), function_name, Interface::NewConst());
4546 fproxy->BindTo(fvar); 4559 fproxy->BindTo(fvar);
4547 body->Add(factory()->NewExpressionStatement( 4560 body->Add(factory()->NewExpressionStatement(
4548 factory()->NewAssignment(fvar_init_op, 4561 factory()->NewAssignment(fvar_init_op,
4549 fproxy, 4562 fproxy,
4550 factory()->NewThisFunction(), 4563 factory()->NewThisFunction(),
4551 RelocInfo::kNoPosition)), 4564 RelocInfo::kNoPosition)),
4552 zone()); 4565 zone());
4553 } 4566 }
4567
4568 // For generators, allocate and yield an iterator on function entry.
4569 if (is_generator) {
4570 ZoneList<Expression*>* arguments =
4571 new(zone()) ZoneList<Expression*>(0, zone());
4572 CallRuntime* allocation = factory()->NewCallRuntime(
4573 isolate()->factory()->empty_string(),
4574 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject),
4575 arguments);
4576 VariableProxy* init_proxy = factory()->NewVariableProxy(
4577 current_function_state_->generator_object_variable());
4578 Assignment* assignment = factory()->NewAssignment(
4579 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
4580 VariableProxy* get_proxy = factory()->NewVariableProxy(
4581 current_function_state_->generator_object_variable());
4582 Yield* yield = factory()->NewYield(
4583 get_proxy, assignment, false, RelocInfo::kNoPosition);
4584 body->Add(factory()->NewExpressionStatement(yield), zone());
4585 }
4586
4554 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); 4587 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
4555 4588
4556 materialized_literal_count = function_state.materialized_literal_count(); 4589 materialized_literal_count = function_state.materialized_literal_count();
4557 expected_property_count = function_state.expected_property_count(); 4590 expected_property_count = function_state.expected_property_count();
4558 handler_count = function_state.handler_count(); 4591 handler_count = function_state.handler_count();
4559 only_simple_this_property_assignments = 4592 only_simple_this_property_assignments =
4560 function_state.only_simple_this_property_assignments(); 4593 function_state.only_simple_this_property_assignments();
4561 this_property_assignments = function_state.this_property_assignments(); 4594 this_property_assignments = function_state.this_property_assignments();
4562 4595
4563 Expect(Token::RBRACE, CHECK_OK); 4596 Expect(Token::RBRACE, CHECK_OK);
(...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after
5974 ASSERT(info()->isolate()->has_pending_exception()); 6007 ASSERT(info()->isolate()->has_pending_exception());
5975 } else { 6008 } else {
5976 result = ParseProgram(); 6009 result = ParseProgram();
5977 } 6010 }
5978 } 6011 }
5979 info()->SetFunction(result); 6012 info()->SetFunction(result);
5980 return (result != NULL); 6013 return (result != NULL);
5981 } 6014 }
5982 6015
5983 } } // namespace v8::internal 6016 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698