use of org.objectweb.asm.tree.VarInsnNode in project MinecraftForge by MinecraftForge.
the class EventSubscriptionTransformer method buildEvents.
private boolean buildEvents(ClassNode classNode) throws Exception {
// Yes, this recursively loads classes until we get this base class. THIS IS NOT A ISSUE. Coremods should handle re-entry just fine.
// If they do not this a COREMOD issue NOT a Forge/LaunchWrapper issue.
Class<?> parent = this.getClass().getClassLoader().loadClass(classNode.superName.replace('/', '.'));
if (!Event.class.isAssignableFrom(parent)) {
return false;
}
//Class<?> listenerListClazz = Class.forName("net.minecraftforge.fml.common.eventhandler.ListenerList", false, getClass().getClassLoader());
Type tList = Type.getType("Lnet/minecraftforge/fml/common/eventhandler/ListenerList;");
boolean edited = false;
boolean hasSetup = false;
boolean hasGetListenerList = false;
boolean hasDefaultCtr = false;
boolean hasCancelable = false;
boolean hasResult = false;
String voidDesc = Type.getMethodDescriptor(VOID_TYPE);
String boolDesc = Type.getMethodDescriptor(BOOLEAN_TYPE);
String listDesc = tList.getDescriptor();
String listDescM = Type.getMethodDescriptor(tList);
for (MethodNode method : classNode.methods) {
if (method.name.equals("setup") && method.desc.equals(voidDesc) && (method.access & ACC_PROTECTED) == ACC_PROTECTED)
hasSetup = true;
if ((method.access & ACC_PUBLIC) == ACC_PUBLIC) {
if (method.name.equals("getListenerList") && method.desc.equals(listDescM))
hasGetListenerList = true;
if (method.name.equals("isCancelable") && method.desc.equals(boolDesc))
hasCancelable = true;
if (method.name.equals("hasResult") && method.desc.equals(boolDesc))
hasResult = true;
}
if (method.name.equals("<init>") && method.desc.equals(voidDesc))
hasDefaultCtr = true;
}
if (classNode.visibleAnnotations != null) {
for (AnnotationNode node : classNode.visibleAnnotations) {
if (!hasResult && node.desc.equals("Lnet/minecraftforge/fml/common/eventhandler/Event$HasResult;")) {
/* Add:
* public boolean hasResult()
* {
* return true;
* }
*/
MethodNode method = new MethodNode(ACC_PUBLIC, "hasResult", boolDesc, null, null);
method.instructions.add(new InsnNode(ICONST_1));
method.instructions.add(new InsnNode(IRETURN));
classNode.methods.add(method);
edited = true;
} else if (!hasCancelable && node.desc.equals("Lnet/minecraftforge/fml/common/eventhandler/Cancelable;")) {
/* Add:
* public boolean isCancelable()
* {
* return true;
* }
*/
MethodNode method = new MethodNode(ACC_PUBLIC, "isCancelable", boolDesc, null, null);
method.instructions.add(new InsnNode(ICONST_1));
method.instructions.add(new InsnNode(IRETURN));
classNode.methods.add(method);
edited = true;
}
}
}
if (hasSetup) {
if (!hasGetListenerList)
throw new RuntimeException("Event class defines setup() but does not define getListenerList! " + classNode.name);
else
return edited;
}
Type tSuper = Type.getType(classNode.superName);
//Add private static ListenerList LISTENER_LIST
classNode.fields.add(new FieldNode(ACC_PRIVATE | ACC_STATIC, "LISTENER_LIST", listDesc, null, null));
/*Add:
* public <init>()
* {
* super();
* }
*/
if (!hasDefaultCtr) {
MethodNode method = new MethodNode(ACC_PUBLIC, "<init>", voidDesc, null, null);
method.instructions.add(new VarInsnNode(ALOAD, 0));
method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "<init>", voidDesc, false));
method.instructions.add(new InsnNode(RETURN));
classNode.methods.add(method);
}
/*Add:
* protected void setup()
* {
* super.setup();
* if (LISTENER_LIST != NULL)
* {
* return;
* }
* LISTENER_LIST = new ListenerList(super.getListenerList());
* }
*/
MethodNode method = new MethodNode(ACC_PROTECTED, "setup", voidDesc, null, null);
method.instructions.add(new VarInsnNode(ALOAD, 0));
method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "setup", voidDesc, false));
method.instructions.add(new FieldInsnNode(GETSTATIC, classNode.name, "LISTENER_LIST", listDesc));
LabelNode initListener = new LabelNode();
method.instructions.add(new JumpInsnNode(IFNULL, initListener));
method.instructions.add(new InsnNode(RETURN));
method.instructions.add(initListener);
method.instructions.add(new FrameNode(F_SAME, 0, null, 0, null));
method.instructions.add(new TypeInsnNode(NEW, tList.getInternalName()));
method.instructions.add(new InsnNode(DUP));
method.instructions.add(new VarInsnNode(ALOAD, 0));
method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "getListenerList", listDescM, false));
method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tList.getInternalName(), "<init>", getMethodDescriptor(VOID_TYPE, tList), false));
method.instructions.add(new FieldInsnNode(PUTSTATIC, classNode.name, "LISTENER_LIST", listDesc));
method.instructions.add(new InsnNode(RETURN));
classNode.methods.add(method);
/*Add:
* public ListenerList getListenerList()
* {
* return this.LISTENER_LIST;
* }
*/
method = new MethodNode(ACC_PUBLIC, "getListenerList", listDescM, null, null);
method.instructions.add(new FieldInsnNode(GETSTATIC, classNode.name, "LISTENER_LIST", listDesc));
method.instructions.add(new InsnNode(ARETURN));
classNode.methods.add(method);
return true;
}
use of org.objectweb.asm.tree.VarInsnNode in project enumerable by hraberg.
the class ExpressionInterpreter method copyOperation.
public Value copyOperation(final AbstractInsnNode insn, final Value value) throws AnalyzerException {
ExpressionValue expressionValue = (ExpressionValue) value;
if (insn instanceof VarInsnNode) {
VarInsnNode node = (VarInsnNode) insn;
if (isStoreInstruction(node)) {
AssignExpr.Operator op = AssignExpr.Operator.assign;
NameExpr target = new NameExpr(getLocalVariable(node.var).name);
Expression assignmentValue = expressionValue.expression;
if (expressionValue.expression instanceof BinaryExpr) {
BinaryExpr binary = (BinaryExpr) expressionValue.expression;
if (binary.getLeft().equals(target)) {
if (binary.getOperator() == BinaryExpr.Operator.plus)
op = AssignExpr.Operator.plus;
if (binary.getOperator() == BinaryExpr.Operator.minus)
op = AssignExpr.Operator.minus;
if (binary.getOperator() == BinaryExpr.Operator.times)
op = AssignExpr.Operator.star;
if (binary.getOperator() == BinaryExpr.Operator.divide)
op = AssignExpr.Operator.slash;
if (binary.getOperator() == BinaryExpr.Operator.binAnd)
op = AssignExpr.Operator.and;
if (binary.getOperator() == BinaryExpr.Operator.binOr)
op = AssignExpr.Operator.or;
if (binary.getOperator() == BinaryExpr.Operator.xor)
op = AssignExpr.Operator.xor;
if (binary.getOperator() == BinaryExpr.Operator.remainder)
op = AssignExpr.Operator.rem;
if (binary.getOperator() == BinaryExpr.Operator.lShift)
op = AssignExpr.Operator.lShift;
if (binary.getOperator() == BinaryExpr.Operator.rSignedShift)
op = AssignExpr.Operator.rSignedShift;
if (binary.getOperator() == BinaryExpr.Operator.rUnsignedShift)
op = AssignExpr.Operator.rUnsignedShift;
if (op != AssignExpr.Operator.assign)
assignmentValue = binary.getRight();
}
}
if (expressionValue.expression instanceof UnaryExpr)
assign = expressionValue;
else
assign = new ExpressionValue(expressionValue.type, new AssignExpr(target, assignmentValue, op));
} else {
if (node.var == 0)
return new ExpressionValue(expressionValue.type, new ThisExpr());
return new ExpressionValue(expressionValue.type, new NameExpr(getLocalVariable(node.var).name));
}
}
if (expressionValue.expression == null)
return expressionValue;
return new ExpressionValue(expressionValue.type, LambdaExpressionTrees.parseExpression(expressionValue.expression.toString()));
}
use of org.objectweb.asm.tree.VarInsnNode in project pinpoint by naver.
the class ASMMethodVariables method loadArg.
void loadArg(final InsnList instructions, Type[] argumentTypes, int i) {
final int index = getArgIndex(argumentTypes, i);
final Type type = argumentTypes[i];
instructions.add(new VarInsnNode(type.getOpcode(Opcodes.ILOAD), index));
}
use of org.objectweb.asm.tree.VarInsnNode in project pinpoint by naver.
the class ASMClassNodeAdapter method addSetterMethod.
public void addSetterMethod(final String methodName, final ASMFieldNodeAdapter fieldNode) {
if (methodName == null || fieldNode == null) {
throw new IllegalArgumentException("method name or fieldNode annotation must not be null.");
}
// void is V.
final String desc = "(" + fieldNode.getDesc() + ")V";
final MethodNode methodNode = new MethodNode(Opcodes.ACC_PUBLIC, methodName, desc, null, null);
if (methodNode.instructions == null) {
methodNode.instructions = new InsnList();
}
final InsnList instructions = methodNode.instructions;
// load this.
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
final Type type = Type.getType(fieldNode.getDesc());
// put field.
instructions.add(new VarInsnNode(type.getOpcode(Opcodes.ILOAD), 1));
instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, fieldNode.getName(), fieldNode.getDesc()));
// return.
instructions.add(new InsnNode(Opcodes.RETURN));
if (this.classNode.methods == null) {
this.classNode.methods = new ArrayList<MethodNode>();
}
this.classNode.methods.add(methodNode);
}
use of org.objectweb.asm.tree.VarInsnNode in project pinpoint by naver.
the class ASMClassNodeAdapter method addGetterMethod.
public void addGetterMethod(final String methodName, final ASMFieldNodeAdapter fieldNode) {
if (methodName == null || fieldNode == null) {
throw new IllegalArgumentException("method name or fieldNode annotation must not be null.");
}
// no argument is ().
final String desc = "()" + fieldNode.getDesc();
final MethodNode methodNode = new MethodNode(Opcodes.ACC_PUBLIC, methodName, desc, null, null);
if (methodNode.instructions == null) {
methodNode.instructions = new InsnList();
}
final InsnList instructions = methodNode.instructions;
// load this.
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
// get fieldNode.
instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldNode.getName(), fieldNode.getDesc()));
// return of type.
final Type type = Type.getType(fieldNode.getDesc());
instructions.add(new InsnNode(type.getOpcode(Opcodes.IRETURN)));
if (this.classNode.methods == null) {
this.classNode.methods = new ArrayList<MethodNode>();
}
this.classNode.methods.add(methodNode);
}
Aggregations