push(new NoOp(fCounter));
int switchStart = fCounter;
node.getExpression().accept(this);
ArrayList<Statement> statementsDefault = null;
Jump jumpDefault = null;
ArrayList<slot> jumpsStatements = new ArrayList<slot>();
slot currentslot = new slot();
jumpsStatements.add(currentslot);
for (Iterator<Statement> iter = node.statements().iterator(); iter.hasNext();) {
Statement statement = iter.next();
if (statement instanceof SwitchCase) {
SwitchCase switchCase = (SwitchCase) statement;
if (switchCase.isDefault()) {
jumpDefault = new Jump();
push(jumpDefault);
storeInstruction(); // jump
statementsDefault = new ArrayList<Statement>();
} else {
if (switchCase.getExpression() instanceof StringLiteral) {
push(new SendMessage(
"equals", "(Ljava/lang/Object;)Z", 1, null, fCounter)); //$NON-NLS-1$ //$NON-NLS-2$
} else {
push(new EqualEqualOperator(Instruction.T_int,
Instruction.T_int, true, fCounter));
}
push(new Dup());
storeInstruction(); // dupe
switchCase.getExpression().accept(this);
storeInstruction(); // equal-equal
ConditionalJump condJump = new ConditionalJump(true);
push(condJump);
storeInstruction(); // conditional jump
if (currentslot.stmts != null) {
currentslot = new slot();
jumpsStatements.add(currentslot);
}
currentslot.jumps.add(condJump);
}
} else {
if (statementsDefault != null) {
statementsDefault.add(statement);
} else {
if (currentslot.stmts == null) {
currentslot.stmts = new ArrayList<Statement>();
}
currentslot.stmts.add(statement);
}
}
}
Jump jumpEnd = null;
if (jumpDefault == null) {
push(new Pop(0));
storeInstruction(); // pop
jumpEnd = new Jump();
push(jumpEnd);
storeInstruction(); // jump
}
for (Iterator<slot> iter = jumpsStatements.iterator(); iter.hasNext();) {
currentslot = iter.next();
for (Iterator<ConditionalJump> iterator = currentslot.jumps.iterator(); iterator.hasNext();) {
ConditionalJump condJump = iterator.next();
condJump.setOffset((fCounter - fInstructions.indexOf(condJump)) - 1);
}
if (currentslot.stmts != null) {
push(new Pop(0));
storeInstruction(); // pop
for (Iterator<Statement> iterator = currentslot.stmts.iterator(); iterator.hasNext();) {
iterator.next().accept(this);
}
}
}
// default case
if (jumpDefault != null) {
jumpDefault.setOffset((fCounter - fInstructions.indexOf(jumpDefault)) - 1);
push(new Pop(0));
storeInstruction(); // pop
for (Iterator<Statement> iterator = statementsDefault.iterator(); iterator.hasNext();) {
iterator.next().accept(this);
}
} else if(jumpEnd != null){
jumpEnd.setOffset((fCounter - fInstructions.indexOf(jumpEnd)) - 1);
}
// for each pending break or continue instruction which are related to
// this loop, set the offset of the corresponding jump.
String label = getLabel(node);
for (Iterator<CompleteInstruction> iter = fCompleteInstructions.iterator(); iter.hasNext();) {
CompleteInstruction instruction = iter.next();
Jump jumpInstruction = instruction.fInstruction;
int instructionAddress = fInstructions.indexOf(jumpInstruction);
if (instructionAddress > switchStart && (instruction.fLabel == null || instruction.fLabel.equals(label))) {
iter.remove();
if (instruction.fIsBreak) {
// jump to the instruction after the last instruction of the
// switch
jumpInstruction.setOffset((fCounter - instructionAddress) - 1);
}
}
}
return false;
}