Skip to content

Commit aa592c8

Browse files
authored
Final ASMAPI cleanup, NumberType enum change, and new insertInsnList method (#54)
1 parent 0a44e31 commit aa592c8

File tree

1 file changed

+67
-34
lines changed
  • src/main/java/net/minecraftforge/coremod/api

1 file changed

+67
-34
lines changed

src/main/java/net/minecraftforge/coremod/api/ASMAPI.java

+67-34
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.io.PrintWriter;
2020
import java.io.StringWriter;
2121
import java.lang.reflect.Modifier;
22-
import java.util.Iterator;
2322
import java.util.ListIterator;
2423
import java.util.Objects;
2524
import java.util.Optional;
@@ -33,17 +32,29 @@ public static MethodNode getMethodNode() {
3332
return new MethodNode(Opcodes.ASM9);
3433
}
3534

36-
// Terribly named method. Should be called "prependMethodCall" or something similar.
3735
/**
3836
* Injects a method call to the beginning of the given method.
3937
*
4038
* @param node The method to inject the call into
4139
* @param methodCall The method call to inject
4240
*/
43-
public static void appendMethodCall(MethodNode node, MethodInsnNode methodCall) {
41+
public static void injectMethodCall(MethodNode node, MethodInsnNode methodCall) {
4442
node.instructions.insertBefore(node.instructions.getFirst(), methodCall);
4543
}
4644

45+
/**
46+
* Injects a method call to the beginning of the given method.
47+
*
48+
* @param node The method to inject the call into
49+
* @param methodCall The method call to inject
50+
*
51+
* @deprecated Renamed to {@link #injectMethodCall(MethodNode, MethodInsnNode)}
52+
*/
53+
@Deprecated(forRemoval = true, since = "5.1")
54+
public static void appendMethodCall(MethodNode node, MethodInsnNode methodCall) {
55+
injectMethodCall(node, methodCall);
56+
}
57+
4758
/**
4859
* Signifies the method invocation type. Mirrors "INVOKE-" opcodes from ASM.
4960
*/
@@ -80,17 +91,17 @@ public static MethodInsnNode buildMethodCall(final String ownerName, final Strin
8091
}
8192

8293
/**
83-
* Signifies the type of number constant for a {@link LdcNumberType}.
94+
* Signifies the type of number constant for a {@link NumberType}.
8495
*/
85-
public enum LdcNumberType {
96+
public enum NumberType {
8697
INTEGER(Number::intValue),
8798
FLOAT(Number::floatValue),
8899
LONG(Number::longValue),
89100
DOUBLE(Number::doubleValue);
90101

91102
private final Function<Number, Object> mapper;
92103

93-
LdcNumberType(Function<Number, Object> mapper) {
104+
NumberType(Function<Number, Object> mapper) {
94105
this.mapper = mapper;
95106
}
96107

@@ -100,14 +111,29 @@ public Object map(Number number) {
100111
}
101112

102113
/**
103-
* Builds a new {@link LdcInsnNode} with the given number value and type.
114+
* Casts a given number to a given specific {@link NumberType}. This helps elliviate the problems that comes with JavaScript's
115+
* ambiguous number system.
116+
* <p>
117+
* The result is returned as an {@link Object} so it can be used as a value in various instructions that require
118+
* values.
119+
*
120+
* @param value The number to cast
121+
* @param type The type of number to cast to
122+
* @return The casted number
123+
*/
124+
public static Object castNumber(final Number value, final NumberType type) {
125+
return type.map(value);
126+
}
127+
128+
/**
129+
* Builds a new {@link LdcInsnNode} with the given number value and {@link NumberType}.
104130
*
105131
* @param value The number value
106132
* @param type The type of the number
107133
* @return The built LDC node
108134
*/
109-
public static LdcInsnNode buildNumberLdcInsnNode(final Number value, final LdcNumberType type) {
110-
return new LdcInsnNode(type.map(value));
135+
public static LdcInsnNode buildNumberLdcInsnNode(final Number value, final NumberType type) {
136+
return new LdcInsnNode(castNumber(value, type));
111137
}
112138

113139
/**
@@ -361,35 +387,42 @@ public static MethodInsnNode findFirstMethodCallBefore(MethodNode method, Method
361387
* in the method provided. Only the first node matching is targeted, all other matches are ignored.
362388
*
363389
* @param method The method where you want to find the node
364-
* @param type The type of the old method node.
365-
* @param owner The owner of the old method node.
366-
* @param name The name of the old method node. You may want to use {@link #mapMethod(String)} if this is a srg
367-
* name
368-
* @param desc The desc of the old method node.
390+
* @param type The type of the old method node
391+
* @param owner The owner of the old method node
392+
* @param name The name of the old method node (you may want to use {@link #mapMethod(String)} if this is a srg
393+
* name)
394+
* @param desc The desc of the old method node
369395
* @param list The list that should be inserted
370396
* @param mode How the given code should be inserted
371-
* @return True if the node was found, false otherwise
397+
* @return True if the node was found and the list was inserted, false otherwise
372398
*/
373399
public static boolean insertInsnList(MethodNode method, MethodType type, String owner, String name, String desc, InsnList list, InsertMode mode) {
374-
Iterator<AbstractInsnNode> nodeIterator = method.instructions.iterator();
375-
int opcode = type.toOpcode();
376-
while (nodeIterator.hasNext()) {
377-
AbstractInsnNode next = nodeIterator.next();
378-
if (next.getOpcode() == opcode) {
379-
MethodInsnNode castedNode = (MethodInsnNode) next;
380-
if (castedNode.owner.equals(owner) && castedNode.name.equals(name) && castedNode.desc.equals(desc)) {
381-
if (mode == InsertMode.INSERT_BEFORE)
382-
method.instructions.insertBefore(next, list);
383-
else
384-
method.instructions.insert(next, list);
385-
386-
if (mode == InsertMode.REMOVE_ORIGINAL)
387-
nodeIterator.remove();
388-
return true;
389-
}
390-
}
391-
}
392-
return false;
400+
var insn = findFirstMethodCall(method, type, owner, name, desc);
401+
if (insn == null) return false;
402+
403+
return insertInsnList(method, insn, list, mode);
404+
}
405+
406+
/**
407+
* Inserts/replaces a list after/before the given instruction.
408+
*
409+
* @param method The method where you want to insert the list
410+
* @param list The list that should be inserted
411+
* @param mode How the given code should be inserted
412+
* @return True if the list was inserted, false otherwise
413+
*/
414+
public static boolean insertInsnList(MethodNode method, AbstractInsnNode insn, InsnList list, InsertMode mode) {
415+
if (!method.instructions.contains(insn)) return false;
416+
417+
if (mode == InsertMode.INSERT_BEFORE)
418+
method.instructions.insertBefore(insn, list);
419+
else
420+
method.instructions.insert(insn, list);
421+
422+
if (mode == InsertMode.REMOVE_ORIGINAL)
423+
method.instructions.remove(insn);
424+
425+
return true;
393426
}
394427

395428
/**

0 commit comments

Comments
 (0)