if ("<clinit>".equals(jm.getName())) {
return;
}
InstructionFactory factory = il.getInstructionFactory();
JiapiClass ii = getEventProducer();
JiapiMethod invokeMethod = null;
try {
invokeMethod =
ii.getDeclaredMethod("invokeMethod",
new String[] { "java.lang.Object",
"java.lang.String",
"java.lang.Object[]",
"java.lang.String"});
}
catch(Exception e) {
e.printStackTrace();
}
int idx = -1;
while ((idx = il.indexOf(OpcodeGroups.INVOKE_INSTRUCTIONS, idx+1)) != -1) {
Invocation ins = (Invocation)il.get(idx);
if (!match(ins.getClassName() + "." + ins.getMethodName())) {
continue;
}
// if (System.getProperty("no-lfix") == null) {
// // --- bug workaround for long/doubles in method params
// boolean bailOutForLongDoubleSyndrome = false;
// String[] i_params = ins.getParameterTypes();
// for (int i = 0; i < i_params.length; i++) {
// if ("double".equals(i_params[i]) ||
// "long".equals(i_params[i])) {
// bailOutForLongDoubleSyndrome = true;
// break;
// }
// }
// if (bailOutForLongDoubleSyndrome) {
// log.warn("Will not instrument invocations to methods with long or double as parameter: In " + jm.getDeclaringClass().getName() + "#" + jm +
// ", a call to " + ins + ". This is a workaround for bug in jiapi.");
// continue;
// }
// // --- bug workaround for long/doubles in method params
// }
// We support only these methods at the moment.
if (ins.getOpcode() != Opcodes.INVOKESTATIC &&
ins.getOpcode() != Opcodes.INVOKEVIRTUAL) {
continue;
}
JiapiField interceptor = getEventProducerField();
// InstructionList nList = il.createEmptyList();
InstructionList nList = new InstructionList();
// each entry in pList holds creation of one argument
// to method invocation
// InstructionList[] pLists = createArgumentLists(il, idx);
ArgumentList al = createArgumentLists(il, idx);
InstructionList[] pLists = al.arguments;
int paramIdx = al.paramIndex;
short opCode = ins.getOpcode();
if (opCode == Opcodes.INVOKEVIRTUAL ||
opCode == Opcodes.INVOKESPECIAL) {
paramIdx--; // Include object ref
}
// Generate code, that replaces invocation with a new
// invocation to InvokeHandler
switch(opCode) {
case Opcodes.INVOKEVIRTUAL:
case Opcodes.INVOKESTATIC:
nList.add(factory.getField(interceptor)); // Interceptor
if (opCode == Opcodes.INVOKESTATIC) {
// addClassForNameInstructions(jm.getDeclaringClass().getName(), nList);
addClassForNameInstructions(ins.getClassName(), nList);
}
else {
nList.add(il.get(paramIdx)); // objref
}
String mName = ins.getMethodName();
//nList.add(factory.getField(rField));
nList.add(factory.pushConstant(mName));
nList.add(factory.newArray("java.lang.Object",
ins.getParameterTypes().length));
String[] i_params = ins.getParameterTypes();
// Populate Object array with call parameters
for (int i = 0; i < pLists.length; i++) {
if ("long".equals(i_params[i])) {
nList.add(factory.dup());
}
else if ("double".equals(i_params[i])) {
nList.add(factory.dup());
}
else {
nList.add(factory.dup());
}
nList.add(factory.pushConstant(i));
nList.add(pLists[i]);
nList.add(factory.aastore());
}
// Add Methods signature
// nList.add(factory.pushConstant(ins.getDescriptor()));
// Add cache-key
nList.add(factory.pushConstant(ins.getClassName() + ins.getMethodName() + ins.getDescriptor()));
// call Interceptor
nList.add(factory.invoke(invokeMethod));
handleReturnValue(nList, ins);
// Replace invocation and its parameters with new