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

Unified 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, 2 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/interpreter/bytecode-generator.cc
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
index 8e6c9c53295a530ed45649645f7dc1f0a7953282..3eb010510da19f6ed3571002885791c878bb6f63 100644
--- a/src/interpreter/bytecode-generator.cc
+++ b/src/interpreter/bytecode-generator.cc
@@ -136,6 +136,36 @@ class BytecodeGenerator::ControlScopeForIteration
};
+// Scoped class for enabling 'break' in switch statements.
+class BytecodeGenerator::ControlScopeForSwitch
+ : public BytecodeGenerator::ControlScope {
+ public:
+ ControlScopeForSwitch(BytecodeGenerator* generator,
+ SwitchStatement* statement,
+ SwitchBuilder* switch_builder)
+ : ControlScope(generator),
+ statement_(statement),
+ switch_builder_(switch_builder) {}
+
+ protected:
+ virtual bool Execute(Command command, Statement* statement) {
+ if (statement != statement_) return false;
+ switch (command) {
+ case CMD_BREAK:
+ switch_builder_->Break();
+ return true;
+ case CMD_CONTINUE:
+ break;
+ }
+ return false;
+ }
+
+ private:
+ Statement* statement_;
+ SwitchBuilder* switch_builder_;
+};
+
+
void BytecodeGenerator::ControlScope::PerformCommand(Command command,
Statement* statement) {
ControlScope* current = this;
@@ -539,11 +569,57 @@ void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
- UNIMPLEMENTED();
+ ZoneList<CaseClause*>* clauses = stmt->cases();
+ SwitchBuilder switch_builder(builder(), clauses->length());
+ ControlScopeForSwitch scope(this, stmt, &switch_builder);
+ int default_index = -1;
+
+ // Keep the switch value in a register until a case matches.
+ Register tag = VisitForRegisterValue(stmt->tag());
+
+ // Iterate over all cases and create nodes for label comparison.
+ BytecodeLabel done_label;
+ for (int i = 0; i < clauses->length(); i++) {
+ CaseClause* clause = clauses->at(i);
+
+ // The default is not a test, remember index.
+ if (clause->is_default()) {
+ default_index = i;
+ continue;
+ }
+
+ // Perform label comparison as if via '===' with tag.
+ VisitForAccumulatorValue(clause->label());
+ builder()->CompareOperation(Token::Value::EQ_STRICT, tag,
+ language_mode_strength());
+ switch_builder.Case(i);
+ }
+
+ if (default_index >= 0) {
+ // Emit default jump if there is a default case.
+ switch_builder.DefaultAt(default_index);
+ } else {
+ // Otherwise if we have reached here none of the cases matched, so jump to
+ // done.
+ builder()->Jump(&done_label);
+ }
+
+ // Iterate over all cases and create the case bodies.
+ for (int i = 0; i < clauses->length(); i++) {
+ CaseClause* clause = clauses->at(i);
+ switch_builder.SetCaseTarget(i);
+ VisitStatements(clause->statements());
+ }
+ builder()->Bind(&done_label);
+
+ switch_builder.SetBreakTarget(done_label);
}
-void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); }
+void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
+ // Handled entirely in VisitSwitchStatement.
+ UNREACHABLE();
+}
void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
« 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