1.1 --- a/src/BytecodeCompiler.cpp Sun Aug 12 13:22:56 2012 -0700
1.2 +++ b/src/BytecodeCompiler.cpp Sun Aug 12 20:48:49 2012 -0700
1.3 @@ -971,6 +971,115 @@
1.4 __ bind(&join);
1.5 }
1.6
1.7 +bool
1.8 +BytecodeCompiler::tableswitch(SwitchStatement *node)
1.9 +{
1.10 + CaseValueList *values = node->caseValueList();
1.11 +
1.12 + if (values->length() < 3)
1.13 + return false;
1.14 +
1.15 + // Find the delta between the largest and smallest value.
1.16 + int hi = values->at(values->length() - 1).box.toInt();
1.17 + int lo = values->at(0).box.toInt();
1.18 + assert(hi > lo);
1.19 +
1.20 + unsigned tablesize = TableSwitchEntries(lo, hi);
1.21 + if (tablesize > MAX_TABLESWITCH_ENTRIES)
1.22 + return false;
1.23 +
1.24 + Label def, join;
1.25 +
1.26 + // Create the list of labels that each statement will bind to.
1.27 + Label *labels = new Label[node->cases()->length()];
1.28 +
1.29 + // Create the table of labels we'll use for each case.
1.30 + Label **table = new Label *[tablesize];
1.31 +
1.32 + // Link all cases, by default, to the default label.
1.33 + for (size_t i = 0; i < tablesize; i++)
1.34 + table[i] = &def;
1.35 +
1.36 + // Now patch actual cases to their correct labels.
1.37 + for (size_t i = 0; i < values->length(); i++) {
1.38 + CaseValue &v = values->at(i);
1.39 + assert(v.statement < node->cases()->length());
1.40 +
1.41 + unsigned index = unsigned(v.box.toInt() - lo);
1.42 + assert(index < tablesize);
1.43 +
1.44 + table[index] = &labels[v.statement];
1.45 + }
1.46 +
1.47 + // Emit the tableswitch opcode and the jump table.
1.48 + __ tableswitch(lo, hi, &def, table);
1.49 +
1.50 + // We're done with the jump table now.
1.51 + delete [] table;
1.52 +
1.53 + // Emit each statement.
1.54 + for (size_t i = 0; i < node->cases()->length(); i++) {
1.55 + Statement *stmt = node->cases()->at(i)->statement();
1.56 +
1.57 + __ bind(&labels[i]);
1.58 + stmt->accept(this);
1.59 + __ jump(&join);
1.60 + }
1.61 +
1.62 + // We're done with the statement labels.
1.63 + delete [] labels;
1.64 +
1.65 + // Emit the default case.
1.66 + __ bind(&def);
1.67 + if (node->defaultCase())
1.68 + node->defaultCase()->accept(this);
1.69 +
1.70 + __ bind(&join);
1.71 +
1.72 + return true;
1.73 +}
1.74 +
1.75 +void
1.76 +BytecodeCompiler::visit(SwitchStatement *node)
1.77 +{
1.78 + node->expression()->accept(this);
1.79 +
1.80 + if (tableswitch(node))
1.81 + return;
1.82 +
1.83 + Label join;
1.84 +
1.85 + for (size_t i = 0; i < node->cases()->length(); i++) {
1.86 + Case *c = node->cases()->at(i);
1.87 +
1.88 + Label success, fail;
1.89 + if (c->others()) {
1.90 + for (size_t j = 0; j < c->others()->length(); j++) {
1.91 + Expression *expr = c->others()->at(j);
1.92 +
1.93 + __ dup();
1.94 + expr->accept(this);
1.95 + __ j(OP_JEQ, &success);
1.96 + }
1.97 + }
1.98 +
1.99 + // The final test.
1.100 + __ dup();
1.101 + c->expression()->accept(this);
1.102 + __ j(OP_JNE, &fail);
1.103 + __ bind(&success);
1.104 + c->statement()->accept(this);
1.105 + __ jump(&join);
1.106 + __ bind(&fail);
1.107 + }
1.108 +
1.109 + if (node->defaultCase())
1.110 + node->defaultCase()->accept(this);
1.111 +
1.112 + __ drop(1);
1.113 + __ bind(&join);
1.114 +}
1.115 +
1.116 void
1.117 BytecodeCompiler::visit(FunctionStatement *node)
1.118 {