extraParams += 1;
}
for (int i = 0; i < argCount; i++) {
Expression argument = arguments.get(i);
Type argType = argumentTypes.get(i);
Type paramType = paramTypes.get(i);
// compile code to stack argument and type convert if necessary
argument.compile(mv, compileContext);
compileTypeConversion(argType, paramType, mv, compileContext);
// allow for stacked paramType value
extraParams += (paramType.getNBytes() > 4 ? 2 : 1);
}
// enable triggering before we call the method
// this adds an extra value to the stack so modify the compile context to ensure
// we increase the maximum height if necessary
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/jboss/byteman/rule/Rule", "enableTriggersInternal", "()Z");
compileContext.addStackCount(1);
mv.visitInsn(Opcodes.POP);
compileContext.addStackCount(-1);
// ok, now just call the method -- removes extraParams words
String ownerName = Type.internalName(method.getDeclaringClass());
if (recipient == null) {
mv.visitMethodInsn(Opcodes.INVOKESTATIC, ownerName, method.getName(), getDescriptor());
} else if (recipient.getClass().isInterface()) {
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, ownerName, method.getName(), getDescriptor());
} else {
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, ownerName, method.getName(), getDescriptor());
}
// decrement the stack height to account for stacked param values (removed) and return value (added)
compileContext.addStackCount(expected - extraParams);
// now disable triggering again
// this temporarily adds an extra value to the stack -- no need to increment and
// then decrement the stack height as we will already have bumped the max last time
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/jboss/byteman/rule/Rule", "disableTriggersInternal", "()Z");
mv.visitInsn(Opcodes.POP);
} else {
// if we are calling a method by reflection then we need to stack the current helper then
// the recipient or null if there is none and then build an object array on the stack
mv.visitVarInsn(Opcodes.ALOAD, 0);
compileContext.addStackCount(1);
if (recipient != null) {
// compile code for recipient
recipient.compile(mv, compileContext);
} else {
mv.visitInsn(Opcodes.ACONST_NULL);
compileContext.addStackCount(1);
}
// stack arg count then create a new array
mv.visitLdcInsn(argCount);
compileContext.addStackCount(1);
// this just swaps one word for another
mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
// duplicate the array, stack the index, compile code to generate the arg and the do an array put
for (int i = 0; i < argCount; i++) {
mv.visitInsn(Opcodes.DUP);
mv.visitLdcInsn(i);
// that was two extra words
compileContext.addStackCount(2);
Expression argument = arguments.get(i);
Type argType = argumentTypes.get(i);
Type paramType = paramTypes.get(i);
// compile code to stack argument and type convert/box if necessary
argument.compile(mv, compileContext);
compileTypeConversion(argType, paramType, mv, compileContext);
compileBox(paramType, mv, compileContext);
// that's 3 extra words which now get removed