Skip to content

Commit e14ebc0

Browse files
committed
feat: InsnListUtils as replacements for InsnSequence
1 parent 06de084 commit e14ebc0

File tree

5 files changed

+104
-5
lines changed

5 files changed

+104
-5
lines changed

src/main/java/ftbsc/lll/utils/DescriptorBuilder.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,7 @@ public DescriptorBuilder addParameter(String param, int arrayLevel) {
118118
public String build() {
119119
StringBuilder sb = new StringBuilder();
120120
sb.append('(');
121-
for(String p : params)
122-
sb.append(p);
121+
for(String p : params) sb.append(p);
123122
sb.append(')').append(returnType);
124123
return sb.toString();
125124
}
@@ -133,8 +132,7 @@ public String build() {
133132
*/
134133
public static String nameToDescriptor(String name, int arrayLevel) {
135134
StringBuilder sb = new StringBuilder();
136-
for(int i = 0; i < arrayLevel; i++)
137-
sb.append('[');
135+
for(int i = 0; i < arrayLevel; i++) sb.append('[');
138136
sb.append('L').append(name.replace('.', '/')).append(';');
139137
return sb.toString();
140138
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package ftbsc.lll.utils;
2+
3+
import ftbsc.lll.exceptions.InstructionMismatchException;
4+
import org.objectweb.asm.tree.AbstractInsnNode;
5+
import org.objectweb.asm.tree.InsnList;
6+
7+
/**
8+
* A collection of utilities for manipulating {@link InsnList}s.
9+
*/
10+
public class InsnListUtils {
11+
12+
/**
13+
* Factory method that builds an {@link InsnList} with the given nodes.
14+
* @param nodes the nodes in question
15+
* @return the resulting {@link InsnList}
16+
*/
17+
public static InsnList of(AbstractInsnNode... nodes) {
18+
InsnList list = new InsnList();
19+
for(AbstractInsnNode node : nodes) {
20+
list.add(node);
21+
}
22+
return list;
23+
}
24+
25+
/**
26+
* Creates a sublist with all the nodes between the given extremes.
27+
* @param startNode the starting node of the pattern, must be non-null
28+
* @param endNode the first node of the pattern, must be non-null
29+
* @return the resulting {@link InsnList}
30+
*/
31+
public static InsnList between(AbstractInsnNode startNode, AbstractInsnNode endNode) {
32+
InsnList list = new InsnList();
33+
for(; startNode != null; startNode = startNode.getNext()) {
34+
list.add(startNode);
35+
if(startNode == endNode) {
36+
return list;
37+
}
38+
}
39+
40+
throw new InstructionMismatchException(String.format(
41+
"Nodes %s and %s are not connected.",
42+
list.getFirst(),
43+
list.getLast()
44+
));
45+
}
46+
47+
/**
48+
* Replaces a node with another one. Mostly used internally.
49+
* @param list the list to perform the operation on
50+
* @param oldNode node to replace
51+
* @param newNode new node
52+
*/
53+
public static void replaceNode(InsnList list, AbstractInsnNode oldNode, AbstractInsnNode newNode) {
54+
list.insert(oldNode, newNode);
55+
list.remove(oldNode);
56+
}
57+
58+
/**
59+
* Replaces n occurrences of said opcode with the given node.
60+
* @param list the list to perform the operation on
61+
* @param opcode the opcode to replace
62+
* @param newNode the replacement node
63+
* @param reverse whether the search should be done from the end
64+
* @param amount how many occurrences to replace, set to 0 to replace all
65+
* @return true if anything was changed, false otherwise
66+
*/
67+
public static boolean replace(InsnList list, int opcode, AbstractInsnNode newNode, int amount, boolean reverse) {
68+
boolean changed = false;
69+
for(
70+
AbstractInsnNode cur = list.getFirst();
71+
cur != null && cur.getPrevious() != list.getLast() && cur.getNext() != list.getFirst();
72+
cur = reverse ? cur.getPrevious() : cur.getNext()
73+
) {
74+
if(cur.getOpcode() == opcode) {
75+
replaceNode(list, cur, newNode);
76+
changed = true;
77+
amount--; // will go to negative if it was already 0, causing it to go on until for loop finishes
78+
if(amount == 0) {
79+
return changed;
80+
}
81+
}
82+
}
83+
return changed;
84+
}
85+
86+
/**
87+
* Cut a number of nodes from the list.
88+
* @param amount how many nodes to cut
89+
* @param reverse true if it should cut from the end, false otherwise
90+
*/
91+
public static void cut(InsnList list, int amount, boolean reverse) {
92+
for(int i = 0; i < amount; i++) {
93+
list.remove(reverse ? list.getLast() : list.getFirst());
94+
}
95+
}
96+
}

src/main/java/ftbsc/lll/utils/InsnSequence.java

+3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
/**
1010
* Represents a sequence of instructions contained within two given nodes.
1111
* Extends {@link InsnList}, but provides additional flexibility and features.
12+
* @deprecated Riddled with bugs, poorly named and hardly useful.
13+
* Will be removed (or possibly replaced) in an upcoming release.
1214
*/
15+
@Deprecated
1316
public class InsnSequence extends InsnList {
1417
/**
1518
* Public constructor.

src/main/java/ftbsc/lll/utils/PatternMatcher.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public InsnList find(MethodNode node) {
8080
* @param node the node to start the search on
8181
* @return the {@link InsnList} object representing the matched pattern
8282
*/
83-
public InsnSequence find(AbstractInsnNode node) {
83+
public InsnList find(AbstractInsnNode node) {
8484
if(node != null) {
8585
AbstractInsnNode first, last;
8686
for(AbstractInsnNode cur = node; cur != null; cur = this.reverse ? cur.getPrevious() : cur.getNext()) {

src/main/java/ftbsc/lll/utils/StackUtils.java

+2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ public class StackUtils implements Opcodes {
2020
* @param desc the descriptor of the constructor to call
2121
* @param args nodes containing instructions to load the constructor arguments, in the right order
2222
* @return an instruction list containing the opcodes needed to create the new object and load it on the stack.
23+
* @deprecated very redundant
2324
*/
25+
@Deprecated
2426
public static InsnList instantiate(String name, String desc, AbstractInsnNode... args) {
2527
InsnSequence is = new InsnSequence();
2628
is.add(args);

0 commit comments

Comments
 (0)