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

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: Rebased 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
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/control-flow-builders.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 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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 } 129 }
130 return false; 130 return false;
131 } 131 }
132 132
133 private: 133 private:
134 Statement* statement_; 134 Statement* statement_;
135 LoopBuilder* loop_builder_; 135 LoopBuilder* loop_builder_;
136 }; 136 };
137 137
138 138
139 // Scoped class for enabling 'break' in switch statements.
140 class BytecodeGenerator::ControlScopeForSwitch
141 : public BytecodeGenerator::ControlScope {
142 public:
143 ControlScopeForSwitch(BytecodeGenerator* generator,
144 SwitchStatement* statement,
145 SwitchBuilder* switch_builder)
146 : ControlScope(generator),
147 statement_(statement),
148 switch_builder_(switch_builder) {}
149
150 protected:
151 virtual bool Execute(Command command, Statement* statement) {
152 if (statement != statement_) return false;
153 switch (command) {
154 case CMD_BREAK:
155 switch_builder_->Break();
156 return true;
157 case CMD_CONTINUE:
158 break;
159 }
160 return false;
161 }
162
163 private:
164 Statement* statement_;
165 SwitchBuilder* switch_builder_;
166 };
167
168
139 void BytecodeGenerator::ControlScope::PerformCommand(Command command, 169 void BytecodeGenerator::ControlScope::PerformCommand(Command command,
140 Statement* statement) { 170 Statement* statement) {
141 ControlScope* current = this; 171 ControlScope* current = this;
142 do { 172 do {
143 if (current->Execute(command, statement)) return; 173 if (current->Execute(command, statement)) return;
144 current = current->outer(); 174 current = current->outer();
145 } while (current != nullptr); 175 } while (current != nullptr);
146 UNREACHABLE(); 176 UNREACHABLE();
147 } 177 }
148 178
(...skipping 383 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
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/control-flow-builders.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698