Search in sources :

Example 1 with TypeInsnNode

use of org.objectweb.asm.tree.TypeInsnNode in project enumerable by hraberg.

the class ExpressionInterpreter method newOperation.

public Value newOperation(final AbstractInsnNode insn) throws AnalyzerException {
    switch(insn.getOpcode()) {
        case ACONST_NULL:
            return new ExpressionValue(createClassOrInterfaceType(Object.class.getName()), new NullLiteralExpr());
        case ICONST_M1:
            return new ExpressionValue(PRIMITIVE_INT, new UnaryExpr(new IntegerLiteralExpr("1"), UnaryExpr.Operator.negative));
        case ICONST_0:
            return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("0"));
        case ICONST_1:
            return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("1"));
        case ICONST_2:
            return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("2"));
        case ICONST_3:
            return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("3"));
        case ICONST_4:
            return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("4"));
        case ICONST_5:
            return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("5"));
        case LCONST_0:
            return new ExpressionValue(PRIMITIVE_LONG, new LongLiteralExpr("0L"));
        case LCONST_1:
            return new ExpressionValue(PRIMITIVE_LONG, new LongLiteralExpr("1L"));
        case FCONST_0:
            return new ExpressionValue(PRIMITIVE_FLOAT, new DoubleLiteralExpr("0.0f"));
        case FCONST_1:
            return new ExpressionValue(PRIMITIVE_FLOAT, new DoubleLiteralExpr("1.0f"));
        case FCONST_2:
            return new ExpressionValue(PRIMITIVE_FLOAT, new DoubleLiteralExpr("2.0f"));
        case DCONST_0:
            return new ExpressionValue(PRIMITIVE_DOUBLE, new DoubleLiteralExpr("0.0"));
        case DCONST_1:
            return new ExpressionValue(PRIMITIVE_DOUBLE, new DoubleLiteralExpr("1.0"));
        case BIPUSH:
        case SIPUSH:
            int operand = ((IntInsnNode) insn).operand;
            if (operand < 0)
                return new ExpressionValue(PRIMITIVE_INT, new UnaryExpr(new IntegerLiteralExpr("" + Math.abs(operand)), UnaryExpr.Operator.negative));
            return new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr("" + operand));
        case LDC:
            Object cst = ((LdcInsnNode) insn).cst;
            if (cst instanceof Number) {
                ExpressionValue value = null;
                if (cst instanceof Integer) {
                    value = new ExpressionValue(PRIMITIVE_INT, new IntegerLiteralExpr(cst.toString()));
                } else if (cst instanceof Float) {
                    value = new ExpressionValue(PRIMITIVE_FLOAT, new DoubleLiteralExpr(cst.toString() + "f"));
                } else if (cst instanceof Long) {
                    value = new ExpressionValue(PRIMITIVE_LONG, new LongLiteralExpr(cst.toString() + "L"));
                } else if (cst instanceof Double) {
                    value = new ExpressionValue(PRIMITIVE_DOUBLE, new DoubleLiteralExpr(cst.toString()));
                }
                if (((Number) cst).intValue() < 0) {
                    StringLiteralExpr expr = (StringLiteralExpr) value.expression;
                    expr.setValue(expr.getValue().substring("-".length()));
                    value.expression = new UnaryExpr(expr, UnaryExpr.Operator.negative);
                }
                return value;
            } else if (cst instanceof Type) {
                ClassExpr classExpr = new ClassExpr(new ReferenceType(createClassOrInterfaceType(((Type) cst).getClassName())));
                return new ExpressionValue(createClassOrInterfaceType(Class.class.getName()), classExpr);
            } else {
                return new ExpressionValue(createClassOrInterfaceType(String.class.getName()), new StringLiteralExpr(cst.toString()));
            }
        case JSR:
            throw new UnsupportedOperationException(AbstractVisitor.OPCODES[insn.getOpcode()]);
        case GETSTATIC:
            FieldInsnNode fieldNode = (FieldInsnNode) insn;
            ExpressionValue getField = (ExpressionValue) newValue(getType(fieldNode.desc));
            getField.expression = new FieldAccessExpr(new NameExpr(removeJavaLang(getObjectType(fieldNode.owner).getClassName())), fieldNode.name);
            return getField;
        case NEW:
            return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
        default:
            throw new Error("Internal error.");
    }
}
Also used : IntInsnNode(org.objectweb.asm.tree.IntInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) ReferenceType(japa.parser.ast.type.ReferenceType) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) Type(org.objectweb.asm.Type) ClassOrInterfaceType(japa.parser.ast.type.ClassOrInterfaceType) ReferenceType(japa.parser.ast.type.ReferenceType) PrimitiveType(japa.parser.ast.type.PrimitiveType)

Example 2 with TypeInsnNode

use of org.objectweb.asm.tree.TypeInsnNode 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 3 with TypeInsnNode

use of org.objectweb.asm.tree.TypeInsnNode 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)

Example 4 with TypeInsnNode

use of org.objectweb.asm.tree.TypeInsnNode in project evosuite by EvoSuite.

the class Instrumenter method transformWrapperCalls.

@SuppressWarnings("unchecked")
private void transformWrapperCalls(MethodNode mn) {
    Iterator<AbstractInsnNode> iterator = mn.instructions.iterator();
    List<Class<?>> wrapperClasses = getWrapperClasses();
    while (iterator.hasNext()) {
        AbstractInsnNode insn = iterator.next();
        if (insn instanceof MethodInsnNode) {
            MethodInsnNode methodInsnNode = (MethodInsnNode) insn;
            if (methodInsnNode.name.equals("<init>")) {
                String ownerName = methodInsnNode.owner.replace('/', '.');
                for (Class<?> wrapperClass : wrapperClasses) {
                    if (wrapperClass.getName().equals(ownerName)) {
                        logger.debug("Replacing call " + methodInsnNode.name);
                        methodInsnNode.owner = "org/evosuite/testcarver/wrapper/" + methodInsnNode.owner;
                        break;
                    }
                }
            } else {
                String ownerName = methodInsnNode.owner.replace('/', '.');
                for (Class<?> wrapperClass : wrapperClasses) {
                    if (wrapperClass.getName().equals(ownerName)) {
                        if (methodInsnNode.getOpcode() == Opcodes.INVOKESTATIC) {
                            logger.debug("Replacing call " + methodInsnNode.name);
                            methodInsnNode.owner = PackageInfo.getEvoSuitePackageWithSlash() + "/testcarver/wrapper/" + methodInsnNode.owner;
                        }
                        Type[] parameterTypes = Type.getArgumentTypes(methodInsnNode.desc);
                        try {
                            Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
                            int pos = 0;
                            for (Type parameter : parameterTypes) {
                                switch(parameter.getSort()) {
                                    case Type.OBJECT:
                                        parameterClasses[pos++] = Class.forName(parameter.getClassName());
                                        break;
                                    case Type.BOOLEAN:
                                        parameterClasses[pos++] = boolean.class;
                                        break;
                                    case Type.BYTE:
                                        parameterClasses[pos++] = byte.class;
                                        break;
                                    case Type.CHAR:
                                        parameterClasses[pos++] = char.class;
                                        break;
                                    case Type.DOUBLE:
                                        parameterClasses[pos++] = double.class;
                                        break;
                                    case Type.FLOAT:
                                        parameterClasses[pos++] = float.class;
                                        break;
                                    case Type.INT:
                                        parameterClasses[pos++] = int.class;
                                        break;
                                    case Type.LONG:
                                        parameterClasses[pos++] = long.class;
                                        break;
                                    case Type.SHORT:
                                        parameterClasses[pos++] = short.class;
                                        break;
                                }
                            }
                            Method method = wrapperClass.getMethod(methodInsnNode.name, parameterClasses);
                            if (Modifier.isFinal(method.getModifiers())) {
                                if (methodInsnNode.getOpcode() != Opcodes.INVOKESTATIC) {
                                    methodInsnNode.setOpcode(Opcodes.INVOKESTATIC);
                                    Type[] args = Type.getArgumentTypes(methodInsnNode.desc);
                                    Type returnType = Type.getReturnType(methodInsnNode.desc);
                                    Type[] newargs = new Type[args.length + 1];
                                    newargs[0] = Type.getObjectType(methodInsnNode.owner);
                                    for (int i = 0; i < args.length; i++) newargs[i + 1] = args[i];
                                    methodInsnNode.desc = Type.getMethodDescriptor(returnType, newargs);
                                    methodInsnNode.owner = PackageInfo.getEvoSuitePackageWithSlash() + "/testcarver/wrapper/" + methodInsnNode.owner;
                                } else {
                                    methodInsnNode.name += "_final";
                                }
                                logger.debug("Method is final: " + methodInsnNode.owner + "." + methodInsnNode.name);
                            } else {
                                logger.debug("Method is not final: " + methodInsnNode.owner + "." + methodInsnNode.name);
                            }
                        } catch (Exception e) {
                            logger.warn("Error while instrumenting: " + e);
                        }
                        break;
                    }
                }
            // } else if(methodInsnNode.name.equals("getTime")) {
            // if(methodInsnNode.owner.equals("java/util/Calendar")) {
            // logger.debug("Replacing call "+methodInsnNode.name);
            // methodInsnNode.owner = "org/evosuite/testcarver/wrapper/java/util/Calendar";
            // methodInsnNode.name = "getTime";
            // methodInsnNode.desc = "(Ljava/util/Calendar;)Ljava/util/Date;";
            // methodInsnNode.setOpcode(Opcodes.INVOKESTATIC);
            // }
            // }
            }
        } else if (insn.getOpcode() == Opcodes.NEW || insn.getOpcode() == Opcodes.CHECKCAST) {
            TypeInsnNode typeInsnNode = (TypeInsnNode) insn;
            Type generatedType = Type.getType(typeInsnNode.desc);
            String name = generatedType.getInternalName().replace('/', '.');
            logger.debug("Checking for replacement of " + name);
            for (Class<?> wrapperClass : wrapperClasses) {
                if (wrapperClass.getName().equals(name)) {
                    logger.debug("Replacing new " + name);
                    typeInsnNode.desc = PackageInfo.getEvoSuitePackageWithSlash() + "/testcarver/wrapper/" + generatedType.getInternalName();
                    break;
                }
            }
        }
    }
}
Also used : Method(java.lang.reflect.Method) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) IllegalClassFormatException(java.lang.instrument.IllegalClassFormatException) Type(org.objectweb.asm.Type) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode)

Example 5 with TypeInsnNode

use of org.objectweb.asm.tree.TypeInsnNode in project evosuite by EvoSuite.

the class Instrumenter method addFieldRegistryRegisterCall.

@SuppressWarnings("unchecked")
private void addFieldRegistryRegisterCall(final MethodNode methodNode) {
    AbstractInsnNode ins = null;
    ListIterator<AbstractInsnNode> iter = methodNode.instructions.iterator();
    // number of invokespecial calls before actual constructor call
    int numInvokeSpecials = 0;
    while (iter.hasNext()) {
        ins = iter.next();
        if (ins instanceof MethodInsnNode) {
            MethodInsnNode mins = (MethodInsnNode) ins;
            if (ins.getOpcode() == Opcodes.INVOKESPECIAL) {
                if (mins.name.startsWith("<init>")) {
                    if (numInvokeSpecials == 0) {
                        break;
                    } else {
                        numInvokeSpecials--;
                    }
                }
            }
        } else if (ins instanceof TypeInsnNode) {
            TypeInsnNode typeIns = (TypeInsnNode) ins;
            if (typeIns.getOpcode() == Opcodes.NEW || typeIns.getOpcode() == Opcodes.NEWARRAY) {
                numInvokeSpecials++;
            }
        }
    }
    final InsnList instructions = new InsnList();
    instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, PackageInfo.getNameWithSlash(FieldRegistry.class), "register", "(Ljava/lang/Object;)V"));
    methodNode.instructions.insert(ins, instructions);
}
Also used : MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnList(org.objectweb.asm.tree.InsnList) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Aggregations

TypeInsnNode (org.objectweb.asm.tree.TypeInsnNode)29 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)18 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)14 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)13 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)12 InsnNode (org.objectweb.asm.tree.InsnNode)11 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)9 IntInsnNode (org.objectweb.asm.tree.IntInsnNode)8 LdcInsnNode (org.objectweb.asm.tree.LdcInsnNode)8 MethodNode (org.objectweb.asm.tree.MethodNode)8 Type (org.objectweb.asm.Type)7 InsnList (org.objectweb.asm.tree.InsnList)7 LabelNode (org.objectweb.asm.tree.LabelNode)7 ClassNode (org.objectweb.asm.tree.ClassNode)5 FieldNode (org.objectweb.asm.tree.FieldNode)4 MultiANewArrayInsnNode (org.objectweb.asm.tree.MultiANewArrayInsnNode)3 JsonObject (com.google.gson.JsonObject)2 ClassWriter (org.objectweb.asm.ClassWriter)2 FrameNode (org.objectweb.asm.tree.FrameNode)2 IincInsnNode (org.objectweb.asm.tree.IincInsnNode)2