// modify the stack height to account for the removed exception and params
compileContext.addStackCount(-(extraParams+1));
if (compileContext.getStackCount() != currentStack + expected) {
throw new CompileException("ThrowExpression.compile : invalid stack height " + compileContext.getStackCount() + " expecting " + (currentStack + expected));
}
// now create a ThrowException to wrap the user exception
// create the thrown exception instance -- adds 1 to stack [UE] --> [UE, THE]
exceptionClassName = "org/jboss/byteman/rule/exception/ThrowException";
mv.visitTypeInsn(Opcodes.NEW, exceptionClassName);
compileContext.addStackCount(1);
// copy the ThrowException so we can init it [UE, THE] --> [THE, UE, THE]
mv.visitInsn(Opcodes.DUP_X1);
compileContext.addStackCount(1);
// reverse the order of the top two words [THE, UE, THE] --> [THE, THE, UE]
mv.visitInsn(Opcodes.SWAP);
// construct the exception [THE, THE, UE] --> [UE]
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, exceptionClassName, "<init>", "(Ljava/lang/Throwable;)V");
// we should now have just the ThrowException on the stack
compileContext.addStackCount(-2);
if (compileContext.getStackCount() != currentStack + expected) {
throw new CompileException("ThrowExpression.compile : invalid stack height " + compileContext.getStackCount() + " expecting " + (currentStack + expected));
}
// now throw the exception and decrement the stack height
mv.visitInsn(Opcodes.ATHROW);