use of net.runelite.asm.attributes.code.instructions.ArrayStore in project runelite by runelite.
the class InjectHook method run.
public void run() {
Execution e = new Execution(inject.getVanilla());
e.populateInitialMethods();
Set<Instruction> done = new HashSet<>();
Set<Instruction> doneIh = new HashSet<>();
e.addExecutionVisitor((InstructionContext ic) -> {
Instruction i = ic.getInstruction();
Instructions ins = i.getInstructions();
Code code = ins.getCode();
Method method = code.getMethod();
if (method.getName().equals(CLINIT)) {
return;
}
if (!(i instanceof SetFieldInstruction)) {
return;
}
if (!done.add(i)) {
return;
}
SetFieldInstruction sfi = (SetFieldInstruction) i;
Field fieldBeingSet = sfi.getMyField();
if (fieldBeingSet == null) {
return;
}
HookInfo hookInfo = hooked.get(fieldBeingSet);
if (hookInfo == null) {
return;
}
String hookName = hookInfo.fieldName;
assert hookName != null;
logger.trace("Found injection location for hook {} at instruction {}", hookName, sfi);
++injectedHooks;
Instruction objectInstruction = new AConstNull(ins);
StackContext objectStackContext = null;
if (sfi instanceof PutField) {
// Object being set on
StackContext objectStack = ic.getPops().get(1);
objectStackContext = objectStack;
}
int idx = ins.getInstructions().indexOf(sfi);
assert idx != -1;
try {
// idx + 1 to insert after the set
injectCallback(ins, idx + 1, hookInfo, null, objectStackContext);
} catch (InjectionException ex) {
throw new RuntimeException(ex);
}
});
// these look like:
// getfield
// iload_0
// iconst_0
// iastore
e.addExecutionVisitor((InstructionContext ic) -> {
Instruction i = ic.getInstruction();
Instructions ins = i.getInstructions();
Code code = ins.getCode();
Method method = code.getMethod();
if (method.getName().equals(CLINIT)) {
return;
}
if (!(i instanceof ArrayStore)) {
return;
}
if (!doneIh.add(i)) {
return;
}
ArrayStore as = (ArrayStore) i;
Field fieldBeingSet = as.getMyField(ic);
if (fieldBeingSet == null) {
return;
}
HookInfo hookInfo = hooked.get(fieldBeingSet);
if (hookInfo == null) {
return;
}
String hookName = hookInfo.fieldName;
// assume this is always at index 1
StackContext index = ic.getPops().get(1);
StackContext arrayReference = ic.getPops().get(2);
InstructionContext arrayReferencePushed = arrayReference.getPushed();
StackContext objectStackContext = null;
if (arrayReferencePushed.getInstruction().getType() == InstructionType.GETFIELD) {
StackContext objectReference = arrayReferencePushed.getPops().get(0);
objectStackContext = objectReference;
}
// inject hook after 'i'
logger.info("Found array injection location for hook {} at instruction {}", hookName, i);
++injectedHooks;
int idx = ins.getInstructions().indexOf(i);
assert idx != -1;
try {
injectCallback(ins, idx + 1, hookInfo, index, objectStackContext);
} catch (InjectionException ex) {
throw new RuntimeException(ex);
}
});
e.run();
}
Aggregations