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

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

Issue 1415093006: [Interpreter] Add switch support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_wideidx
Patch Set: Created 5 years, 1 month 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 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/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/control-flow-builders.h" 8 #include "src/interpreter/control-flow-builders.h"
9 #include "src/objects.h" 9 #include "src/objects.h"
10 #include "src/parser.h" 10 #include "src/parser.h"
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 ControlScope* outer() const { return outer_; } 97 ControlScope* outer() const { return outer_; }
98 98
99 private: 99 private:
100 BytecodeGenerator* generator_; 100 BytecodeGenerator* generator_;
101 ControlScope* outer_; 101 ControlScope* outer_;
102 102
103 DISALLOW_COPY_AND_ASSIGN(ControlScope); 103 DISALLOW_COPY_AND_ASSIGN(ControlScope);
104 }; 104 };
105 105
106 106
107 // Scoped class for enabling 'break' in switch statements.
108 class BytecodeGenerator::ControlScopeForSwitch
oth 2015/10/30 10:10:04 Nit - suggest putting ControlScopeForSwitch after
rmcilroy 2015/10/30 11:46:59 Done.
109 : public BytecodeGenerator::ControlScope {
110 public:
111 ControlScopeForSwitch(BytecodeGenerator* generator,
112 SwitchStatement* statement,
113 SwitchBuilder* switch_builder)
114 : ControlScope(generator),
115 statement_(statement),
116 switch_builder_(switch_builder) {}
117
118 protected:
119 virtual bool Execute(Command command, Statement* statement) {
120 if (statement != statement_) return false;
121 switch (command) {
122 case CMD_BREAK:
123 switch_builder_->Break();
124 return true;
125 case CMD_CONTINUE:
126 break;
127 }
128 return false;
129 }
130
131 private:
132 Statement* statement_;
133 SwitchBuilder* switch_builder_;
134 };
135
136
107 // Scoped class for enabling 'break' and 'continue' in iteration 137 // Scoped class for enabling 'break' and 'continue' in iteration
108 // constructs, e.g. do...while, while..., for... 138 // constructs, e.g. do...while, while..., for...
109 class BytecodeGenerator::ControlScopeForIteration 139 class BytecodeGenerator::ControlScopeForIteration
110 : public BytecodeGenerator::ControlScope { 140 : public BytecodeGenerator::ControlScope {
111 public: 141 public:
112 ControlScopeForIteration(BytecodeGenerator* generator, 142 ControlScopeForIteration(BytecodeGenerator* generator,
113 IterationStatement* statement, 143 IterationStatement* statement,
114 LoopBuilder* loop_builder) 144 LoopBuilder* loop_builder)
115 : ControlScope(generator), 145 : ControlScope(generator),
116 statement_(statement), 146 statement_(statement),
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 builder()->Return(); 562 builder()->Return();
533 } 563 }
534 564
535 565
536 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { 566 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
537 UNIMPLEMENTED(); 567 UNIMPLEMENTED();
538 } 568 }
539 569
540 570
541 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 571 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
542 UNIMPLEMENTED(); 572 ZoneList<CaseClause*>* clauses = stmt->cases();
573 SwitchBuilder switch_builder(builder(), clauses->length());
574 ControlScopeForSwitch scope(this, stmt, &switch_builder);
575 int default_index = -1;
576
577 // Keep the switch value in a register until a case matches.
578 Register tag = VisitForRegisterValue(stmt->tag());
579
580 // Iterate over all cases and create nodes for label comparison.
581 BytecodeLabel done_label;
582 for (int i = 0; i < clauses->length(); i++) {
583 CaseClause* clause = clauses->at(i);
584
585 // The default is not a test, remember index.
586 if (clause->is_default()) {
587 default_index = i;
588 continue;
589 }
590
591 // Perform label comparison as if via '===' with tag.
592 VisitForAccumulatorValue(clause->label());
593 builder()->CompareOperation(Token::Value::EQ_STRICT, tag,
594 language_mode_strength());
595 switch_builder.Case(i);
596 }
597
598 if (default_index >= 0) {
599 // Emit default jump if there is a default case.
600 switch_builder.DefaultAt(default_index);
601 } else {
602 // Otherwise if we have reached here none of the cases matched, so jump to
603 // done.
604 builder()->Jump(&done_label);
605 }
606
607 // Iterate over all cases and create the case bodies.
608 for (int i = 0; i < clauses->length(); i++) {
609 CaseClause* clause = clauses->at(i);
610 switch_builder.SetCaseTarget(i);
611 VisitStatements(clause->statements());
612 }
613 builder()->Bind(&done_label);
614
615 switch_builder.SetBreakTarget(done_label);
543 } 616 }
544 617
545 618
546 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); } 619 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
620 // Handled entirely in VisitSwitchStatement.
621 UNREACHABLE();
622 }
547 623
548 624
549 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 625 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
550 LoopBuilder loop_builder(builder()); 626 LoopBuilder loop_builder(builder());
551 ControlScopeForIteration execution_control(this, stmt, &loop_builder); 627 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
552 628
553 BytecodeLabel body_label, condition_label, done_label; 629 BytecodeLabel body_label, condition_label, done_label;
554 builder()->Bind(&body_label); 630 builder()->Bind(&body_label);
555 Visit(stmt->body()); 631 Visit(stmt->body());
556 builder()->Bind(&condition_label); 632 builder()->Bind(&condition_label);
(...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after
2055 } 2131 }
2056 2132
2057 2133
2058 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 2134 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
2059 return info()->feedback_vector()->GetIndex(slot); 2135 return info()->feedback_vector()->GetIndex(slot);
2060 } 2136 }
2061 2137
2062 } // namespace interpreter 2138 } // namespace interpreter
2063 } // namespace internal 2139 } // namespace internal
2064 } // namespace v8 2140 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698