* Instrument instruction list.
*/
private void patchInstructionList(InstructionList il,
Instrumentation instrumentation) {
//System.out.println(">> " + il.getDeclaringMethod());
InstructionFactory factory = il.getInstructionFactory();
if (factory == null) {
throw new NullPointerException("Got null factory");
}
int currentMethodModifiers = il.getDeclaringMethod().getModifiers();
JiapiClass clazz = getCurrentClass();
Class[] hookParams = hookMethod.getParameterTypes();
if (isDynamic) {
log.debug("Hook is dynamic");
// Obtain a field, that holds a reference to the method
// to be called.
JiapiField field = null;
try {
field = clazz.getDeclaredField(jiapiFieldName);
}
catch (NoSuchFieldException nsfe) {
throw new JiapiRuntimeException("No such field: " + nsfe.getMessage());
}
il.add(factory.getField(field));
if (Modifier.isStatic(currentMethodModifiers)) {
il.add(factory.pushConstant(clazz.getName()));
}
else {
il.add(factory.pushThis()); // First argument is 'this'
}
}
else {
log.debug("Hook is static");
// On static methods, First argument is name of the current class.
// This should be Class object.
// Runtime.forName(clazz.getName())
// factory.forName(clazz.getName())
il.add(factory.pushConstant(clazz.getName()));
}
// Skip first param (source object made above)
for (int i = 1; i < hookParams.length; i++) {
if (hookParams[i].equals(String.class)) {
// --- target name ---
String targetName = instrumentation.getTargetName();
if (targetName == null) {
targetName = "???";
}
il.add(factory.pushConstant(targetName));
}
else if (hookParams[i].equals(Object.class)) {
// --- target Object ---
InstructionList targetCode = instrumentation.getTargetCode();
if (targetCode != null) {
log.debug("Got target code: " + targetCode);
il.add(targetCode);
}
else {
log.debug("No target code");
il.add(factory.pushNull());
}
}
else if (hookParams[i].equals(Object[].class)) {
// --- target Object[] ---
log.warn("target arguments are not supported");
il.add(factory.pushNull());
}
else {
log.error("Invalid Hook method: " + hookMethod);
}
}
Loader l = new Loader();
try {
JiapiClass hClass = l.loadClass(hookClass.getName());
Class[] hpTypes = hookMethod.getParameterTypes();
String[] pTypes = new String[hpTypes.length];
for (int i = 0; i < pTypes.length; i++) {
pTypes[i] = hpTypes[i].getName();
}
JiapiMethod hMethod =hClass.getDeclaredMethod(hookMethod.getName(),
pTypes);
il.add(factory.invoke(hMethod));
}
catch(Exception e) {
log.error("Failed to add invoke instruction: " + e);
}
}