mirror of
https://github.com/zaaarf/lillero.git
synced 2024-11-12 18:49:23 +01:00
feat: added some more utils to InsnSequence
This commit is contained in:
parent
53c8d23cd2
commit
af259809ca
1 changed files with 69 additions and 1 deletions
|
@ -27,5 +27,73 @@ public class InsnSequence extends InsnList implements Opcodes {
|
|||
throw new InstructionMismatchException("Nodes" + getFirst() + " and " + getLast() + " are not connected.");
|
||||
}
|
||||
|
||||
//TODO replace
|
||||
/**
|
||||
* Extends the existing get function from InsnList to allow for negative indexes.
|
||||
* @param index the index of the instruction that must be returned
|
||||
* @return the instruction whose index is given
|
||||
*/
|
||||
@Override
|
||||
public AbstractInsnNode get(int index) {
|
||||
if(index >= 0)
|
||||
return super.get(index);
|
||||
index = Math.abs(index);
|
||||
if(index > size())
|
||||
throw new IndexOutOfBoundsException();
|
||||
return this.toArray()[size() - index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a node with another one. Mostly used internally.
|
||||
* @param oldNode node to replace
|
||||
* @param newNode new node
|
||||
*/
|
||||
public void replaceNode(AbstractInsnNode oldNode, AbstractInsnNode newNode) {
|
||||
super.insert(oldNode, newNode);
|
||||
super.remove(oldNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces n occurrences of said opcode with the given node.
|
||||
* @param opcode the opcode to replace
|
||||
* @param newNode the replacement node
|
||||
* @param amount how many occurrences to replace, set to 0 to replace all
|
||||
* @return true if anything was changed, false otherwise
|
||||
*/
|
||||
public boolean replace(int opcode, AbstractInsnNode newNode, int amount) {
|
||||
return replace(opcode, newNode, amount, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces n occurrences of said opcode with the given node.
|
||||
* @param opcode the opcode to replace
|
||||
* @param newNode the replacement node
|
||||
* @param reverse whether the search should be done from the end
|
||||
* @param amount how many occurrences to replace, set to 0 to replace all
|
||||
* @return true if anything was changed, false otherwise
|
||||
*/
|
||||
public boolean replace(int opcode, AbstractInsnNode newNode, int amount, boolean reverse) {
|
||||
boolean changed = false;
|
||||
for(AbstractInsnNode cur = this.getFirst();
|
||||
cur != null && cur.getPrevious() != this.getLast() && cur.getNext() != this.getFirst();
|
||||
cur = reverse ? cur.getPrevious() : cur.getNext()) {
|
||||
if(cur.getOpcode() == opcode) {
|
||||
this.replaceNode(cur, newNode);
|
||||
changed = true;
|
||||
amount--; // will go to negative if it was already 0, causing it to go on until for loop finishes
|
||||
if(amount == 0)
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cut a number of nodes from the list.
|
||||
* @param amount how many nodes to cut
|
||||
* @param reverse true if should cut from the end, false otherwise
|
||||
*/
|
||||
public void cut(int amount, boolean reverse) {
|
||||
for(int i = 0; i < amount; i++)
|
||||
this.remove(reverse ? getLast() : getFirst());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue