case MOD:
mv.visitInsn(Opcodes.IREM);
break;
default:
// should never happen
throw new CompileException("ArithmeticExpression.compile : unexpected operator " + oper);
}
// now coerce back to appropriate type
if (type == type.B) {
mv.visitInsn(Opcodes.I2B);
} else if (type == type.S) {
mv.visitInsn(Opcodes.I2S);
} else if (type == type.C) {
mv.visitInsn(Opcodes.I2C);
} // else if (type == type.I) { do nothing }
// ok, we popped two bytes but added one
compileContext.addStackCount(-1);
} else if (type == type.J) {
expectedStack = 2;
switch (oper)
{
case MUL:
mv.visitInsn(Opcodes.LMUL);
break;
case DIV:
mv.visitInsn(Opcodes.LDIV);
break;
case PLUS:
mv.visitInsn(Opcodes.LADD);
break;
case MINUS:
mv.visitInsn(Opcodes.LSUB);
break;
case MOD:
mv.visitInsn(Opcodes.LREM);
break;
default:
// should never happen
throw new CompileException("ArithmeticExpression.compile : unexpected operator " + oper);
}
// ok, we popped four bytes but added two
compileContext.addStackCount(-2);
} else if (type == type.F) {
expectedStack = 1;
switch (oper)
{
case MUL:
mv.visitInsn(Opcodes.FMUL);
break;
case DIV:
mv.visitInsn(Opcodes.FDIV);
break;
case PLUS:
mv.visitInsn(Opcodes.FADD);
break;
case MINUS:
mv.visitInsn(Opcodes.FSUB);
break;
case MOD:
mv.visitInsn(Opcodes.FREM);
break;
default:
// should never happen
throw new CompileException("ArithmeticExpression.compile : unexpected operator " + oper);
}
// ok, we popped two bytes but added one
compileContext.addStackCount(-1);
} else if (type == type.D) {
expectedStack = 2;
switch (oper)
{
case MUL:
mv.visitInsn(Opcodes.DMUL);
break;
case DIV:
mv.visitInsn(Opcodes.DDIV);
break;
case PLUS:
mv.visitInsn(Opcodes.DADD);
break;
case MINUS:
mv.visitInsn(Opcodes.DSUB);
break;
case MOD:
mv.visitInsn(Opcodes.DREM);
break;
default:
// should never happen
throw new CompileException("ArithmeticExpression.compile : unexpected operator " + oper);
}
// ok, we popped four bytes but added two
compileContext.addStackCount(-2);
} else {
throw new CompileException("ArithmeticExpression.compile : unexpected result type " + type.getName());
}
} catch (CompileException e) {
throw e;
} catch (Exception e) {
throw new CompileException("ArithmeticExpression.compile : unexpected exception for operation " + token + getPos() + " in rule " + rule.getName(), e);
}
// check stack heights
if (compileContext.getStackCount() != currentStack + expectedStack) {
throw new CompileException("ArithmeticExpression.compile : invalid stack height " + compileContext.getStackCount() + " expecting " + (currentStack + expectedStack));
}
}