use of com.github.anba.es6draft.ast.SwitchClause in project es6draft by anba.
the class SwitchStatementGenerator method Entries.
private static long[] Entries(List<SwitchClause> clauses, ToIntFunction<Expression> value) {
boolean hasDefault = hasDefaultClause(clauses);
long[] entries = new long[clauses.size() - (hasDefault ? 1 : 0)];
for (int i = 0, j = 0, size = clauses.size(); i < size; ++i) {
SwitchClause switchClause = clauses.get(i);
if (!switchClause.isDefaultClause()) {
entries[j++] = Entry(value.applyAsInt(switchClause.getExpression()), i);
}
}
// sort values in ascending order
Arrays.sort(entries);
return entries;
}
use of com.github.anba.es6draft.ast.SwitchClause in project es6draft by anba.
the class SwitchStatementGenerator method emitGenericSwitch.
/**
* <h3>Generic-switch</h3>
*
* <pre>
* switch (v) {
* case key1: ...
* case key2: ...
* }
*
* var $v = v;
* if (strictEquals($v, key1)) goto L1
* if (strictEquals($v, key2)) goto L2
* goTo (default | break)
* L1: ...
* L2: ...
* </pre>
*
* @param clauses
* the switch clauses
* @param switchValue
* the variable which holds the switch value
* @param labels
* the labels for each switch clause
* @param defaultOrExit
* the default clause or exit label
* @param mv
* the code visitor
*/
private void emitGenericSwitch(List<SwitchClause> clauses, Variable<?> switchValue, Jump[] labels, Jump defaultOrExit, CodeVisitor mv) {
assert switchValue.getType().equals(Types.Object);
int index = 0;
for (SwitchClause switchClause : clauses) {
Jump caseLabel = labels[index++];
if (!switchClause.isDefaultClause()) {
mv.load(switchValue);
// 13.11.10 Runtime Semantics: CaseSelectorEvaluation
expressionBoxed(switchClause.getExpression(), mv);
invokeDynamicOperator(BinaryExpression.Operator.SHEQ, mv);
mv.ifne(caseLabel);
}
}
mv.goTo(defaultOrExit);
}
use of com.github.anba.es6draft.ast.SwitchClause in project es6draft by anba.
the class SwitchStatementGenerator method caseBlock.
/**
* Generates a case-block method.
*
* @param caseBlock
* the case-block
* @param mv
* the code visitor
* @return the outlined-call object
*/
private OutlinedCall caseBlock(SwitchStatementGenerator.CaseBlock caseBlock, CodeVisitor mv) {
SwitchClause firstClause = caseBlock.clauses.get(0);
MethodTypeDescriptor methodDescriptor = SwitchBlockCodeVisitor.methodDescriptor(mv);
MethodCode method = codegen.method(mv, "case", methodDescriptor);
return outlined(new SwitchBlockCodeVisitor(firstClause, method, mv), body -> {
Variable<Integer> switchTarget = body.getSwitchTargetParameter();
List<SwitchClause> clauses = caseBlock.clauses;
int[] switchTargets = caseBlock.switchTargets;
int numTargets = caseBlock.numTargets();
Completion lastResult = Completion.Normal;
if (numTargets > 1) {
Jump[] labels = new Jump[numTargets];
for (int i = 0; i < labels.length; ++i) {
labels[i] = new Jump();
}
Jump defaultInstr = new Jump();
body.load(switchTarget);
body.tableswitch(1, numTargets, defaultInstr, labels);
body.mark(defaultInstr);
for (int i = 0, lastTarget = 0; i < clauses.size(); ++i) {
if (lastTarget != switchTargets[i]) {
lastTarget = switchTargets[i];
body.mark(labels[lastTarget - 1]);
}
lastResult = clauses.get(i).accept(this, body);
}
} else {
for (SwitchClause clause : clauses) {
lastResult = clause.accept(this, body);
}
}
return lastResult;
});
}
Aggregations