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

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: Link generator iterator definitions and uses through local variable 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()),
497 parser_(parser), 495 parser_(parser),
498 outer_function_state_(parser->current_function_state_), 496 outer_function_state_(parser->current_function_state_),
499 outer_scope_(parser->top_scope_), 497 outer_scope_(parser->top_scope_),
498 generator_iterator_variable_(NULL),
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
507 506
508 Parser::FunctionState::~FunctionState() { 507 Parser::FunctionState::~FunctionState() {
509 parser_->top_scope_ = outer_scope_; 508 parser_->top_scope_ = outer_scope_;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 scope->set_start_position(0); 636 scope->set_start_position(0);
638 scope->set_end_position(source->length()); 637 scope->set_end_position(source->length());
639 638
640 // Compute the parsing mode. 639 // Compute the parsing mode.
641 Mode mode = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY; 640 Mode mode = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
642 if (allow_natives_syntax_ || extension_ != NULL || scope->is_eval_scope()) { 641 if (allow_natives_syntax_ || extension_ != NULL || scope->is_eval_scope()) {
643 mode = PARSE_EAGERLY; 642 mode = PARSE_EAGERLY;
644 } 643 }
645 ParsingModeScope parsing_mode(this, mode); 644 ParsingModeScope parsing_mode(this, mode);
646 645
647 bool is_generator = false;
648 // Enters 'scope'. 646 // Enters 'scope'.
649 FunctionState function_state(this, scope, is_generator, isolate()); 647 FunctionState function_state(this, scope, isolate());
650 648
651 top_scope_->SetLanguageMode(info->language_mode()); 649 top_scope_->SetLanguageMode(info->language_mode());
652 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 650 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
653 bool ok = true; 651 bool ok = true;
654 int beg_loc = scanner().location().beg_pos; 652 int beg_loc = scanner().location().beg_pos;
655 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); 653 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok);
656 if (ok && !top_scope_->is_classic_mode()) { 654 if (ok && !top_scope_->is_classic_mode()) {
657 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); 655 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
658 } 656 }
659 657
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 FunctionLiteral* result = NULL; 751 FunctionLiteral* result = NULL;
754 752
755 { 753 {
756 // Parse the function literal. 754 // Parse the function literal.
757 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); 755 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
758 info()->SetGlobalScope(scope); 756 info()->SetGlobalScope(scope);
759 if (!info()->closure().is_null()) { 757 if (!info()->closure().is_null()) {
760 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, 758 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
761 zone()); 759 zone());
762 } 760 }
763 bool is_generator = false; // Top scope is not a generator. 761 FunctionState function_state(this, scope, isolate());
764 FunctionState function_state(this, scope, is_generator, isolate());
765 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); 762 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode());
766 ASSERT(scope->language_mode() != EXTENDED_MODE || 763 ASSERT(scope->language_mode() != EXTENDED_MODE ||
767 info()->is_extended_mode()); 764 info()->is_extended_mode());
768 ASSERT(info()->language_mode() == shared_info->language_mode()); 765 ASSERT(info()->language_mode() == shared_info->language_mode());
769 scope->SetLanguageMode(shared_info->language_mode()); 766 scope->SetLanguageMode(shared_info->language_mode());
770 FunctionLiteral::Type type = shared_info->is_expression() 767 FunctionLiteral::Type type = shared_info->is_expression()
771 ? (shared_info->is_anonymous() 768 ? (shared_info->is_anonymous()
772 ? FunctionLiteral::ANONYMOUS_EXPRESSION 769 ? FunctionLiteral::ANONYMOUS_EXPRESSION
773 : FunctionLiteral::NAMED_EXPRESSION) 770 : FunctionLiteral::NAMED_EXPRESSION)
774 : FunctionLiteral::DECLARATION; 771 : FunctionLiteral::DECLARATION;
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 1025
1029 1026
1030 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 1027 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1031 int end_token, 1028 int end_token,
1032 bool is_eval, 1029 bool is_eval,
1033 bool is_global, 1030 bool is_global,
1034 bool* ok) { 1031 bool* ok) {
1035 // SourceElements :: 1032 // SourceElements ::
1036 // (ModuleElement)* <end_token> 1033 // (ModuleElement)* <end_token>
1037 1034
1035 // For generators, allocate and yield an iterator on function entry.
Michael Starzinger 2013/04/08 13:14:05 As discussed offline, it scares me a little bit to
rossberg 2013/04/09 09:37:44 I think it's perfectly fine. With the more high-le
rossberg 2013/04/09 09:37:44 I don't understand, though, why this code is here
Michael Starzinger 2013/04/09 10:40:14 I am convinced, please ignore my initial comment.
1036 if (is_generator()) {
1037 ZoneList<Expression*>* arguments =
1038 new(zone()) ZoneList<Expression*>(1, zone());
1039 arguments->Add(factory()->NewThisFunction(), zone());
1040 CallRuntime* allocation = factory()->NewCallRuntime(
1041 isolate()->factory()->empty_string(),
1042 Runtime::FunctionForId(Runtime::kCreateJSGeneratorIterator),
1043 arguments);
1044 VariableProxy* init_proxy = factory()->NewVariableProxy(
1045 current_function_state_->generator_iterator_variable());
1046 Assignment* assignment = factory()->NewAssignment(
1047 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
1048 VariableProxy* get_proxy = factory()->NewVariableProxy(
1049 current_function_state_->generator_iterator_variable());
1050 Yield* yield = factory()->NewYield(
1051 get_proxy, assignment, false, RelocInfo::kNoPosition);
1052 processor->Add(factory()->NewExpressionStatement(yield), zone());
1053 }
1054
1038 // Allocate a target stack to use for this set of source 1055 // Allocate a target stack to use for this set of source
1039 // elements. This way, all scripts and functions get their own 1056 // elements. This way, all scripts and functions get their own
1040 // target stack thus avoiding illegal breaks and continues across 1057 // target stack thus avoiding illegal breaks and continues across
1041 // functions. 1058 // functions.
1042 TargetScope scope(&this->target_stack_); 1059 TargetScope scope(&this->target_stack_);
1043 1060
1044 ASSERT(processor != NULL); 1061 ASSERT(processor != NULL);
1045 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate(), 1062 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate(),
1046 zone()); 1063 zone());
1047 bool directive_prologue = true; // Parsing directive prologue. 1064 bool directive_prologue = true; // Parsing directive prologue.
(...skipping 2050 matching lines...) Expand 10 before | Expand all | Expand 10 after
3098 return factory()->NewAssignment(op, expression, right, pos); 3115 return factory()->NewAssignment(op, expression, right, pos);
3099 } 3116 }
3100 3117
3101 3118
3102 Expression* Parser::ParseYieldExpression(bool* ok) { 3119 Expression* Parser::ParseYieldExpression(bool* ok) {
3103 // YieldExpression :: 3120 // YieldExpression ::
3104 // 'yield' '*'? AssignmentExpression 3121 // 'yield' '*'? AssignmentExpression
3105 int position = scanner().peek_location().beg_pos; 3122 int position = scanner().peek_location().beg_pos;
3106 Expect(Token::YIELD, CHECK_OK); 3123 Expect(Token::YIELD, CHECK_OK);
3107 bool is_yield_star = Check(Token::MUL); 3124 bool is_yield_star = Check(Token::MUL);
3125 Expression* iterator = factory()->NewVariableProxy(
3126 current_function_state_->generator_iterator_variable());
3108 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); 3127 Expression* expression = ParseAssignmentExpression(false, CHECK_OK);
3109 return factory()->NewYield(expression, is_yield_star, position); 3128 return factory()->NewYield(iterator, expression, is_yield_star, position);
3110 } 3129 }
3111 3130
3112 3131
3113 // Precedence = 3 3132 // Precedence = 3
3114 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { 3133 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
3115 // ConditionalExpression :: 3134 // ConditionalExpression ::
3116 // LogicalOrExpression 3135 // LogicalOrExpression
3117 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 3136 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
3118 3137
3119 // We start using the binary expression parser for prec >= 4 only! 3138 // We start using the binary expression parser for prec >= 4 only!
(...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after
4383 FunctionLiteral::ParameterFlag duplicate_parameters = 4402 FunctionLiteral::ParameterFlag duplicate_parameters =
4384 FunctionLiteral::kNoDuplicateParameters; 4403 FunctionLiteral::kNoDuplicateParameters;
4385 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ 4404 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
4386 ? FunctionLiteral::kIsParenthesized 4405 ? FunctionLiteral::kIsParenthesized
4387 : FunctionLiteral::kNotParenthesized; 4406 : FunctionLiteral::kNotParenthesized;
4388 FunctionLiteral::IsGeneratorFlag generator = is_generator 4407 FunctionLiteral::IsGeneratorFlag generator = is_generator
4389 ? FunctionLiteral::kIsGenerator 4408 ? FunctionLiteral::kIsGenerator
4390 : FunctionLiteral::kNotGenerator; 4409 : FunctionLiteral::kNotGenerator;
4391 AstProperties ast_properties; 4410 AstProperties ast_properties;
4392 // Parse function body. 4411 // Parse function body.
4393 { FunctionState function_state(this, scope, is_generator, isolate()); 4412 { FunctionState function_state(this, scope, isolate());
4394 top_scope_->SetScopeName(function_name); 4413 top_scope_->SetScopeName(function_name);
4395 if (is_generator) 4414
4415 // Generators allocate their variables on the heap, to avoid copying on
4416 // suspend and resume. The iterator object also gets a local, which
4417 // indicates this FunctionState is a generator, while also connecting the
4418 // definition of the iterator with its uses in "yield" expressions.
4419 if (is_generator) {
4396 top_scope_->ForceContextAllocation(); 4420 top_scope_->ForceContextAllocation();
4421 Handle<String> tempname = isolate()->factory()->InternalizeOneByteString(
4422 STATIC_ASCII_VECTOR(".generator_iterator"));
Michael Starzinger 2013/04/08 13:14:05 The current generator instance needs to be stored
rossberg 2013/04/09 09:37:44 Again, I think this is fine. Hard-coding context s
Michael Starzinger 2013/04/09 10:40:14 I am convinced, please ignore my initial comment.
4423 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname);
4424 function_state.set_generator_iterator_variable(temp);
4425 }
4397 4426
4398 // FormalParameterList :: 4427 // FormalParameterList ::
4399 // '(' (Identifier)*[','] ')' 4428 // '(' (Identifier)*[','] ')'
4400 Expect(Token::LPAREN, CHECK_OK); 4429 Expect(Token::LPAREN, CHECK_OK);
4401 scope->set_start_position(scanner().location().beg_pos); 4430 scope->set_start_position(scanner().location().beg_pos);
4402 Scanner::Location name_loc = Scanner::Location::invalid(); 4431 Scanner::Location name_loc = Scanner::Location::invalid();
4403 Scanner::Location dupe_loc = Scanner::Location::invalid(); 4432 Scanner::Location dupe_loc = Scanner::Location::invalid();
4404 Scanner::Location reserved_loc = Scanner::Location::invalid(); 4433 Scanner::Location reserved_loc = Scanner::Location::invalid();
4405 4434
4406 bool done = (peek() == Token::RPAREN); 4435 bool done = (peek() == Token::RPAREN);
(...skipping 1597 matching lines...) Expand 10 before | Expand all | Expand 10 after
6004 ASSERT(info->isolate()->has_pending_exception()); 6033 ASSERT(info->isolate()->has_pending_exception());
6005 } else { 6034 } else {
6006 result = parser.ParseProgram(); 6035 result = parser.ParseProgram();
6007 } 6036 }
6008 } 6037 }
6009 info->SetFunction(result); 6038 info->SetFunction(result);
6010 return (result != NULL); 6039 return (result != NULL);
6011 } 6040 }
6012 6041
6013 } } // namespace v8::internal 6042 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698