use of com.github.anba.es6draft.ast.StringLiteral in project es6draft by anba.
the class SwitchStatementGenerator method emitStringSwitch.
/**
* <h3>String-switch</h3>
*
* <pre>
* switch (v) {
* case "key1": ...
* case "key2": ...
* }
*
* var $v = v;
* if (typeof $v == 'string') {
* lookupswitch(hashCode($v)) {
* hashCode("key1"): goto L1
* hashCode("key2"): goto L2
* }
* L1: if (equals($v, "key1")) ...
* L2: if (equals($v, "key2")) ...
* }
* </pre>
*
* @param clauses
* the switch clauses
* @param labels
* the labels for each switch clause
* @param defaultClause
* the label for the default clause
* @param lblExit
* the exit label
* @param switchValue
* the variable which holds the switch value
* @param mv
* the code visitor
*/
private void emitStringSwitch(List<SwitchClause> clauses, Jump[] labels, Jump defaultClause, Jump lblExit, Variable<?> switchValue, CodeVisitor mv) {
Jump switchDefault = defaultClause != null ? defaultClause : lblExit;
mv.enterVariableScope();
Variable<String> switchValueString = mv.newVariable("switchValueString", String.class);
if (switchValue.getType().equals(Types.CharSequence)) {
mv.load(switchValue);
mv.invoke(Methods.CharSequence_toString);
mv.dup();
mv.store(switchValueString);
mv.invoke(Methods.String_hashCode);
} else {
assert switchValue.getType().equals(Types.Object);
// test for string: type is java.lang.CharSequence
mv.load(switchValue);
mv.instanceOf(Types.CharSequence);
mv.ifeq(switchDefault);
mv.load(switchValue);
mv.checkcast(Types.CharSequence);
mv.invoke(Methods.CharSequence_toString);
mv.dup();
mv.store(switchValueString);
mv.invoke(Methods.String_hashCode);
}
long[] entries = stringSwitchEntries(clauses, defaultClause != null);
int distinctValues = distinctValues(entries);
Jump[] switchLabels = new Jump[distinctValues];
int[] switchKeys = new int[distinctValues];
for (int i = 0, j = 0, lastValue = 0, length = entries.length; i < length; ++i) {
int value = Value(entries[i]);
if (i == 0 || value != lastValue) {
switchLabels[j] = new Jump();
switchKeys[j] = value;
j += 1;
}
lastValue = value;
}
// emit lookupswitch
mv.lookupswitch(switchDefault, switchKeys, switchLabels);
// add String.equals() calls
for (int i = 0, j = 0, lastValue = 0, length = entries.length; i < length; ++i) {
int value = Value(entries[i]);
int index = Index(entries[i]);
if (i == 0 || value != lastValue) {
if (i != 0) {
mv.goTo(switchDefault);
}
mv.mark(switchLabels[j++]);
}
String string = ((StringLiteral) clauses.get(index).getExpression()).getValue();
mv.load(switchValueString);
mv.aconst(string);
mv.invoke(Methods.String_equals);
mv.ifne(labels[index]);
lastValue = value;
}
mv.goTo(switchDefault);
mv.exitVariableScope();
}
Aggregations