Search in sources :

Example 1 with InsnNode

use of org.objectweb.asm.tree.InsnNode 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;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) FrameNode(org.objectweb.asm.tree.FrameNode) FieldNode(org.objectweb.asm.tree.FieldNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) Type(org.objectweb.asm.Type) MethodNode(org.objectweb.asm.tree.MethodNode) AnnotationNode(org.objectweb.asm.tree.AnnotationNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) Event(net.minecraftforge.fml.common.eventhandler.Event) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 2 with InsnNode

use of org.objectweb.asm.tree.InsnNode in project jphp by jphp-compiler.

the class ReturnCompiler method write.

@Override
public void write(ReturnStmtToken token) {
    if (token.getValue() != null && method.getGeneratorEntity() != null) {
        env.error(token.toTraceInfo(compiler.getContext()), ErrorType.E_ERROR, "Generators cannot return values using \"return\"");
    }
    Memory result = Memory.NULL;
    boolean isImmutable = method.getEntity().isImmutable();
    if (token.getValue() != null)
        result = expr.writeExpression(token.getValue(), true, true);
    if (result != null) {
        if (isImmutable) {
            if (method.getEntity().getResult() == null)
                method.getEntity().setResult(result);
        }
        expr.writePushMemory(result);
    } else {
        method.getEntity().setImmutable(false);
    }
    if (expr.stackEmpty(false))
        expr.writePushNull();
    else
        expr.writePopBoxing(false);
    if (method.getEntity().isReturnReference()) {
        expr.writePushDup();
        expr.writePushEnv();
        expr.writePushTraceInfo(token);
        expr.writeSysStaticCall(InvokeHelper.class, "checkReturnReference", void.class, Memory.class, Environment.class, TraceInfo.class);
    } else
        expr.writePopImmutable();
    if (!method.getTryStack().empty()) {
        LocalVariable variable = method.getLocalVariable("~result~");
        if (variable == null)
            variable = method.addLocalVariable("~result~", null, Memory.class);
        expr.writeVarStore(variable, false, false);
        add(new JumpInsnNode(GOTO, method.getTryStack().peek().getReturnLabel()));
    } else {
        add(new InsnNode(ARETURN));
        //removeStackFrame();
        expr.stackPop();
    }
}
Also used : JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) Memory(php.runtime.Memory) LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode)

Example 3 with InsnNode

use of org.objectweb.asm.tree.InsnNode in project pinpoint by naver.

the class ASMMethodVariables method box.

void box(final InsnList instructions, Type type) {
    if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
        return;
    }
    if (type == Type.VOID_TYPE) {
        // push null
        instructions.add(new InsnNode(Opcodes.ACONST_NULL));
    } else {
        Type boxed = getBoxedType(type);
        // new instance.
        newInstance(instructions, boxed);
        if (type.getSize() == 2) {
            // Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o
            // dupX2
            dupX2(instructions);
            // dupX2
            dupX2(instructions);
            // pop
            pop(instructions);
        } else {
            // p -> po -> opo -> oop -> o
            // dupX1
            dupX1(instructions);
            // swap
            swap(instructions);
        }
        invokeConstructor(instructions, boxed, new Method("<init>", Type.VOID_TYPE, new Type[] { type }));
    }
}
Also used : MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) IntInsnNode(org.objectweb.asm.tree.IntInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) InterceptorType(com.navercorp.pinpoint.profiler.instrument.interceptor.InterceptorType) Type(org.objectweb.asm.Type) Method(org.objectweb.asm.commons.Method)

Example 4 with InsnNode

use of org.objectweb.asm.tree.InsnNode 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);
}
Also used : FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) Type(org.objectweb.asm.Type) MethodNode(org.objectweb.asm.tree.MethodNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) InsnList(org.objectweb.asm.tree.InsnList) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 5 with InsnNode

use of org.objectweb.asm.tree.InsnNode in project robolectric by robolectric.

the class SandboxClassLoader method box.

public static void box(final Type type, ListIterator<AbstractInsnNode> instructions) {
    if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
        return;
    }
    if (type == Type.VOID_TYPE) {
        instructions.add(new InsnNode(ACONST_NULL));
    } else {
        Type boxed = getBoxedType(type);
        instructions.add(new TypeInsnNode(NEW, boxed.getInternalName()));
        if (type.getSize() == 2) {
            // Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o
            instructions.add(new InsnNode(DUP_X2));
            instructions.add(new InsnNode(DUP_X2));
            instructions.add(new InsnNode(POP));
        } else {
            // p -> po -> opo -> oop -> o
            instructions.add(new InsnNode(DUP_X1));
            instructions.add(new InsnNode(SWAP));
        }
        instructions.add(new MethodInsnNode(INVOKESPECIAL, boxed.getInternalName(), "<init>", "(" + type.getDescriptor() + ")V"));
    }
}
Also used : FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InvokeDynamicInsnNode(org.objectweb.asm.tree.InvokeDynamicInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) Type(org.objectweb.asm.Type) MethodType.methodType(java.lang.invoke.MethodType.methodType) MethodType(java.lang.invoke.MethodType) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode)

Aggregations

InsnNode (org.objectweb.asm.tree.InsnNode)12 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)8 TypeInsnNode (org.objectweb.asm.tree.TypeInsnNode)7 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)6 Type (org.objectweb.asm.Type)5 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)5 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)5 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)4 LdcInsnNode (org.objectweb.asm.tree.LdcInsnNode)4 MethodNode (org.objectweb.asm.tree.MethodNode)4 LocalVariable (org.develnext.jphp.core.compiler.jvm.misc.LocalVariable)3 InsnList (org.objectweb.asm.tree.InsnList)3 IntInsnNode (org.objectweb.asm.tree.IntInsnNode)3 LabelNode (org.objectweb.asm.tree.LabelNode)3 InvokeDynamicInsnNode (org.objectweb.asm.tree.InvokeDynamicInsnNode)2 InterceptorType (com.navercorp.pinpoint.profiler.instrument.interceptor.InterceptorType)1 MethodType (java.lang.invoke.MethodType)1 MethodType.methodType (java.lang.invoke.MethodType.methodType)1 Event (net.minecraftforge.fml.common.eventhandler.Event)1 MethodStmtCompiler (org.develnext.jphp.core.compiler.jvm.statement.MethodStmtCompiler)1