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

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 1927943003: Assign yield ids in ast-numbering rather than in bytecode-generator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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
« src/ast/ast.h ('K') | « src/interpreter/bytecode-generator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler.h" 8 #include "src/compiler.h"
9 #include "src/interpreter/bytecode-register-allocator.h" 9 #include "src/interpreter/bytecode-register-allocator.h"
10 #include "src/interpreter/control-flow-builders.h" 10 #include "src/interpreter/control-flow-builders.h"
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 info->scope()->num_stack_slots(), info->literal())), 563 info->scope()->num_stack_slots(), info->literal())),
564 info_(info), 564 info_(info),
565 scope_(info->scope()), 565 scope_(info->scope()),
566 globals_(0, info->zone()), 566 globals_(0, info->zone()),
567 execution_control_(nullptr), 567 execution_control_(nullptr),
568 execution_context_(nullptr), 568 execution_context_(nullptr),
569 execution_result_(nullptr), 569 execution_result_(nullptr),
570 register_allocator_(nullptr), 570 register_allocator_(nullptr),
571 generator_resume_points_(info->literal()->yield_count(), info->zone()), 571 generator_resume_points_(info->literal()->yield_count(), info->zone()),
572 generator_state_(), 572 generator_state_(),
573 generator_yields_seen_(0),
574 try_catch_nesting_level_(0), 573 try_catch_nesting_level_(0),
575 try_finally_nesting_level_(0) { 574 try_finally_nesting_level_(0) {
576 InitializeAstVisitor(isolate()); 575 InitializeAstVisitor(isolate());
577 } 576 }
578 577
579 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() { 578 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() {
580 // Initialize the incoming context. 579 // Initialize the incoming context.
581 ContextScope incoming_context(this, scope(), false); 580 ContextScope incoming_context(this, scope(), false);
582 581
583 // Initialize control scope. 582 // Initialize control scope.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 659
661 void BytecodeGenerator::VisitIterationHeader(IterationStatement* stmt, 660 void BytecodeGenerator::VisitIterationHeader(IterationStatement* stmt,
662 LoopBuilder* loop_builder) { 661 LoopBuilder* loop_builder) {
663 // Recall that stmt->yield_count() is always zero inside ordinary 662 // Recall that stmt->yield_count() is always zero inside ordinary
664 // (i.e. non-generator) functions. 663 // (i.e. non-generator) functions.
665 664
666 // Collect all labels for generator resume points within the loop (if any) so 665 // Collect all labels for generator resume points within the loop (if any) so
667 // that they can be bound to the loop header below. Also create fresh labels 666 // that they can be bound to the loop header below. Also create fresh labels
668 // for these resume points, to be used inside the loop. 667 // for these resume points, to be used inside the loop.
669 ZoneVector<BytecodeLabel> resume_points_in_loop(zone()); 668 ZoneVector<BytecodeLabel> resume_points_in_loop(zone());
670 for (size_t id = generator_yields_seen_; 669 size_t first = stmt->first_yield_id();
Jarin 2016/04/28 16:31:18 I am mildly surprised this works is not first_yiel
neis 2016/04/29 07:52:24 signed to unsigned is always "fine" as far as I kn
671 id < generator_yields_seen_ + stmt->yield_count(); id++) { 670 for (size_t id = first; id < first + stmt->yield_count(); id++) {
672 DCHECK(0 <= id && id < generator_resume_points_.size()); 671 DCHECK(0 <= id && id < generator_resume_points_.size());
673 auto& label = generator_resume_points_[id]; 672 auto& label = generator_resume_points_[id];
674 resume_points_in_loop.push_back(label); 673 resume_points_in_loop.push_back(label);
675 generator_resume_points_[id] = BytecodeLabel(); 674 generator_resume_points_[id] = BytecodeLabel();
676 } 675 }
677 676
678 loop_builder->LoopHeader(&resume_points_in_loop); 677 loop_builder->LoopHeader(&resume_points_in_loop);
679 678
680 if (stmt->yield_count() > 0) { 679 if (stmt->yield_count() > 0) {
681 // If we are not resuming, fall through to loop body. 680 // If we are not resuming, fall through to loop body.
682 // If we are resuming, perform state dispatch. 681 // If we are resuming, perform state dispatch.
683 BytecodeLabel not_resuming; 682 BytecodeLabel not_resuming;
684 builder() 683 builder()
685 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)) 684 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
686 .CompareOperation(Token::Value::EQ, generator_state_) 685 .CompareOperation(Token::Value::EQ, generator_state_)
687 .JumpIfTrue(&not_resuming); 686 .JumpIfTrue(&not_resuming);
688 BuildIndexedJump(generator_state_, generator_yields_seen_, 687 BuildIndexedJump(
689 stmt->yield_count(), generator_resume_points_); 688 generator_state_, first, stmt->yield_count(), generator_resume_points_);
690 builder()->Bind(&not_resuming); 689 builder()->Bind(&not_resuming);
691 } 690 }
692 } 691 }
693 692
694 void BytecodeGenerator::VisitGeneratorPrologue() { 693 void BytecodeGenerator::VisitGeneratorPrologue() {
695 // The generator resume trampoline abuses the new.target register both to 694 // The generator resume trampoline abuses the new.target register both to
696 // indicate that this is a resume call and to pass in the generator object. 695 // indicate that this is a resume call and to pass in the generator object.
697 // In ordinary calls, new.target is always undefined because generator 696 // In ordinary calls, new.target is always undefined because generator
698 // functions are non-constructable. 697 // functions are non-constructable.
699 Register generator_object = Register::new_target(); 698 Register generator_object = Register::new_target();
(...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after
2259 case KEYED_SUPER_PROPERTY: { 2258 case KEYED_SUPER_PROPERTY: {
2260 builder()->StoreAccumulatorInRegister(value); 2259 builder()->StoreAccumulatorInRegister(value);
2261 BuildKeyedSuperPropertyStore(object, home_object, key, value); 2260 BuildKeyedSuperPropertyStore(object, home_object, key, value);
2262 break; 2261 break;
2263 } 2262 }
2264 } 2263 }
2265 execution_result()->SetResultInAccumulator(); 2264 execution_result()->SetResultInAccumulator();
2266 } 2265 }
2267 2266
2268 void BytecodeGenerator::VisitYield(Yield* expr) { 2267 void BytecodeGenerator::VisitYield(Yield* expr) {
2269 size_t id = generator_yields_seen_++;
2270
2271 builder()->SetExpressionPosition(expr); 2268 builder()->SetExpressionPosition(expr);
2272 Register value = VisitForRegisterValue(expr->expression()); 2269 Register value = VisitForRegisterValue(expr->expression());
2273 2270
2274 Register generator = VisitForRegisterValue(expr->generator_object()); 2271 Register generator = VisitForRegisterValue(expr->generator_object());
2275 2272
2276 // Save context, registers, and state. Then return. 2273 // Save context, registers, and state. Then return.
2277 builder() 2274 builder()
2278 ->LoadLiteral(Smi::FromInt(static_cast<int>(id))) 2275 ->LoadLiteral(Smi::FromInt(expr->id()))
2279 .SuspendGenerator(generator) 2276 .SuspendGenerator(generator)
2280 .LoadAccumulatorWithRegister(value) 2277 .LoadAccumulatorWithRegister(value)
2281 .Return(); // Hard return (ignore any finally blocks). 2278 .Return(); // Hard return (ignore any finally blocks).
2282 2279
2283 builder()->Bind(&(generator_resume_points_[id])); 2280 builder()->Bind(&(generator_resume_points_[expr->id()]));
2284 // Upon resume, we continue here. 2281 // Upon resume, we continue here.
2285 2282
2286 { 2283 {
2287 RegisterAllocationScope register_scope(this); 2284 RegisterAllocationScope register_scope(this);
2288 2285
2289 // Update state to indicate that we have finished resuming. Loop headers 2286 // Update state to indicate that we have finished resuming. Loop headers
2290 // rely on this. 2287 // rely on this.
2291 builder() 2288 builder()
2292 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)) 2289 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
2293 .StoreAccumulatorInRegister(generator_state_); 2290 .StoreAccumulatorInRegister(generator_state_);
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after
3271 } 3268 }
3272 3269
3273 3270
3274 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 3271 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
3275 return info()->shared_info()->feedback_vector()->GetIndex(slot); 3272 return info()->shared_info()->feedback_vector()->GetIndex(slot);
3276 } 3273 }
3277 3274
3278 } // namespace interpreter 3275 } // namespace interpreter
3279 } // namespace internal 3276 } // namespace internal
3280 } // namespace v8 3277 } // namespace v8
OLDNEW
« src/ast/ast.h ('K') | « src/interpreter/bytecode-generator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698