Example usage for org.objectweb.asm MethodVisitor visitMethodInsn

List of usage examples for org.objectweb.asm MethodVisitor visitMethodInsn

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitMethodInsn.

Prototype

public void visitMethodInsn(final int opcode, final String owner, final String name, final String descriptor,
        final boolean isInterface) 

Source Link

Document

Visits a method instruction.

Usage

From source file:ch.eiafr.cojac.Agent.java

License:Apache License

/**
* This method works only with the FloatReplacerClasses class
* It instruments it to create a static initializer block to set
* all the static variables used by the agent and injected in the 
* instrumented application./*from  w  ww . j  ava 2  s  . com*/
* Warning: this is not the only place to set these variables, see class
* "CojacReferences" !
* This is used when there is more than one classloader in the application
*/
private byte[] setGlobalFields(byte[] byteCode, ClassLoader loader) {
    ClassReader cr = new ClassReader(byteCode);
    ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
    ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) {
        @Override
        public void visit(int version, int access, String name, String signature, String superName,
                String[] interfaces) {
            super.visit(version, access, name, signature, superName, interfaces);
            MethodVisitor mv = cv.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
            mv.visitLdcInsn(references.getDoubleWrapper());
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, "setNgWrapper", "(Ljava/lang/String;)V", false);
            mv.visitLdcInsn(references.getNgWrapper());
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, "setDoubleWrapper", "(Ljava/lang/String;)V", false);
            mv.visitLdcInsn(references.getFloatWrapper());
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, "setFloatWrapper", "(Ljava/lang/String;)V", false);
            mv.visitLdcInsn(references.getBigDecimalPrecision());
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, "setBigDecimalPrecision", "(I)V", false);
            mv.visitLdcInsn(references.getStabilityThreshold());
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, "setStabilityThreshold", "(D)V", false);
            mv.visitLdcInsn(references.getCheckUnstableComparisons() ? 1 : 0);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, "setCheckUnstableComparisons", "(Z)V", false);
            mv.visitInsn(Opcodes.RETURN);
            mv.visitMaxs(0, 0);
        }
    };
    cr.accept(cv, ClassReader.EXPAND_FRAMES);
    return cw.toByteArray();
}

From source file:ch.eiafr.cojac.instrumenters.FloatProxyMethod.java

License:Apache License

public void nativeCall(MethodVisitor mv, int access, String owner, String name, String desc) {
    boolean isStatic = (access & ACC_STATIC) > 0;
    String newDesc = replaceFloatMethodDescription(desc);
    MethodVisitor newMv = ccv.addProxyMethod(access & ~ACC_NATIVE, name, newDesc, null, null);
    int varIndex = 0;
    int opcode = INVOKESTATIC;
    if (!isStatic) {
        newMv.visitVarInsn(ALOAD, 0);/*from ww w.j a v  a 2 s. c  o m*/
        varIndex = 1;
        opcode = INVOKEVIRTUAL;
    }
    ConversionContext cc = new ConversionContext(opcode, owner, name, desc);
    Type args[] = Type.getArgumentTypes(newDesc);
    for (Type type : args) {
        newMv.visitVarInsn(getLoadOpcode(type), varIndex);
        varIndex += type.getSize();
    }
    convertArgumentsToReal(mv, cc);
    // stack >> [target] allParamsArr [target] allParamsArr
    maybeConvertTarget(mv, cc.opcode, cc.owner);
    // stack >> [target] allParamsArr [newTarget] allParamsArr
    explodeOnStack(mv, cc, true);
    // stack >> [target] allParamsArr [newTarget] nprm0 nprm1 nprm2...
    newMv.visitMethodInsn(opcode, owner, name, desc, false);
    // stack >> [target] allParamsArr [possibleResult]
    checkArraysAfterCall(newMv, cc.convertedArrays, desc);
    // stack >> [target] [possibleResult]
    convertReturnType(newMv, desc);
    // stack >> [target] [newPossibleResult]
    newMv.visitInsn(afterFloatReplacement(Type.getReturnType(desc)).getOpcode(IRETURN));
    // stack >> [target]       // left on the stack... not a problem!
    newMv.visitMaxs(0, 0);
}

From source file:ch.eiafr.cojac.instrumenters.FloatProxyMethod.java

License:Apache License

public void proxyCall(MethodVisitor mv, ConversionContext cc, boolean tryUnproxied) {
    if (tryUnproxied && cc.opcode == INVOKEVIRTUAL || cc.opcode == INVOKEINTERFACE) { //|| opcode==INVOKEINTERFACE  false && 
        //proxyCallAndStupidVars(mv, opcode, owner, name, desc);
        proxyCallBetterWithVars(mv, cc);
        return;//from  w ww .  j  a v a 2  s  .  co m
    }
    // stack >> [target] nprm0 nprm1 nprm2...
    convertArgumentsToReal(mv, cc);
    // stack >> [target] allParamsArr [target] allParamsArr
    maybeConvertTarget(mv, cc.opcode, cc.owner);
    // stack >> [target] allParamsArr [newTarget] allParamsArr
    explodeOnStack(mv, cc, true);
    // stack >> [target] allParamsArr [newTarget] nprm0 nprm1 nprm2...
    mv.visitMethodInsn(cc.opcode, cc.owner, cc.name, cc.jDesc, (cc.opcode == INVOKEINTERFACE));
    // stack >> [target] allParamsArr [possibleResult]
    checkArraysAfterCall(mv, cc.convertedArrays, cc.jDesc);
    // stack >> [target] [possibleResult]
    int resultWidth = Type.getReturnType(cc.jDesc).getSize();
    if (hasTarget(cc.opcode)) {
        if (resultWidth == 0) {
            mv.visitInsn(POP);
        } else if (resultWidth == 1) {
            mv.visitInsn(SWAP);
            mv.visitInsn(POP);
        } else { // resultWidth==2) 
            mv.visitInsn(DUP2_X1);
            // stack >> possibleResult target possibleResult
            mv.visitInsn(POP2);
            // stack >> possibleResult target
            mv.visitInsn(POP);
            // stack >> possibleResult
        }
    }
    // stack >> [possibleResult]
    convertReturnType(mv, cc.jDesc);
    // stack >> [newPossibleResult]
}

From source file:ch.eiafr.cojac.instrumenters.FloatProxyMethod.java

License:Apache License

public void proxyCallBetterWithVars(MethodVisitor mv, ConversionContext cc) {
    final String pm = "possibleMethod";
    final String pmDesc = "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/reflect/Method;";
    final String myInvoke = "myInvoke";
    final String myInvokeDesc = "(Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;";
    // checkNotNullStack();
    // int paramArrayVar = mla.paramArrayVar();
    // int targetVar = mla.targetVar();
    // Label lEndTry = new Label(); 
    Label lBeginHandler = new Label(), lEndHandler = new Label();
    Type cojReturnType = Type.getReturnType(cc.cDesc);
    // stack >> target prm0 prm1 prm2...
    convertArgumentsToReal(mv, cc);// w w  w  .j a  va 2s.  c  om
    // stack >> target allParamsArr target allParamsArr
    // {
    //            mv.visitVarInsn(ASTORE, paramArrayVar);
    //            // stack >> target allParamsArr target
    //            //--------- String targetType=stackTopClass();
    //            mv.visitVarInsn(ASTORE, targetVar);
    // }
    mv.visitInsn(POP);
    mv.visitInsn(POP);
    // stack >> target allParamsArr
    Object[] localsInFrame = aaAfter.locals.toArray();
    mv.visitInsn(SWAP);
    // stack >> allParamsArr target
    mv.visitInsn(DUP_X1);
    // stack >> target allParamsArr target
    mv.visitLdcInsn(cc.name);
    // stack >> target allParamsArr target methName
    mv.visitLdcInsn(cc.cDesc);
    // stack >> target allParamsArr target methName methDesc
    mv.visitMethodInsn(INVOKESTATIC, DN_NAME, pm, pmDesc, false);
    // stack >> target allParamsArr nullOrMeth
    mv.visitInsn(DUP);
    // stack >> target allParamsArr nullOrMeth nullOrMeth

    ArrayList<Object> scl = new ArrayList<Object>(aaAfter.stack);
    scl.remove(scl.size() - 1); // remove the last nullOrMeth
    Object[] stackContent = scl.toArray(); //target allParamsArr nullOrMeth

    mv.visitJumpInsn(IFNULL, lBeginHandler);
    aaAfter.visitFrame(F_NEW, localsInFrame.length, localsInFrame, stackContent.length, stackContent);
    // stack >> target allParamsArr meth
    mv.visitInsn(DUP_X2);
    // stack >> meth target allParamsArr meth
    mv.visitInsn(POP);
    // stack >> meth target allParamsArr
    mv.visitLdcInsn(cc.inArgs.length);
    // stack >> meth target allParamsArr n
    mv.visitInsn(AALOAD);
    // stack >> meth target asObjPrm
    mv.visitTypeInsn(CHECKCAST, "[" + OBJ_TYPE.getDescriptor());
    // stack >> meth target appropriatePrmArr 
    mv.visitMethodInsn(INVOKESTATIC, DN_NAME, myInvoke, myInvokeDesc, false);
    // stack >> [ResultOrNull]
    if (cc.hasReturn()) {
        if (cc.hasPrimitiveResultInCojacVersion()) {
            String jWrapperName = getJWrapper(cojReturnType).getInternalName();
            mv.visitTypeInsn(CHECKCAST, jWrapperName);
            mv.visitMethodInsn(INVOKEVIRTUAL, jWrapperName, getWrapperToPrimitiveMethod(cojReturnType),
                    "()" + cojReturnType.getDescriptor(), false);
        } else {
            mv.visitTypeInsn(CHECKCAST, cojReturnType.getInternalName());
        }
    } else {
        mv.visitInsn(POP); // discard the dummy null result
    }
    // stack >> [possibleResult]
    //;; mv.visitLabel(lEndTry);
    mv.visitJumpInsn(GOTO, lEndHandler); // and we're done !

    ;
    ;
    mv.visitLabel(lBeginHandler);
    // stack >> target allParamsArr null
    // CAUTION: we bypass 'mv' and directly talk to the AnalyzerAdapter!
    aaAfter.visitFrame(F_NEW, localsInFrame.length, localsInFrame, stackContent.length, stackContent);
    //checkNotNullStack();  //was during debugging - removed
    mv.visitInsn(POP); // we drop the null (no-method) slot
    maybeConvertTarget(mv, cc.opcode, cc.owner);
    // stack >> newTarget allParamsArr
    mv.visitInsn(DUP_X1);
    // stack >> allParamsArr newTarget allParamsArr
    explodeOnStack(mv, cc, true);
    // stack >> allParamsArr newTarget nprm0 nprm1 nprm2...
    mv.visitMethodInsn(cc.opcode, cc.owner, cc.name, cc.jDesc, (cc.opcode == INVOKEINTERFACE));
    // stack >> allParamsArr [possibleResult]
    checkArraysAfterCall(mv, cc.convertedArrays, cc.jDesc);
    // stack >> [possibleResult]
    convertReturnType(mv, cc.jDesc);
    // stack >> [newPossibleResult]
    ;
    ;
    mv.visitLabel(lEndHandler);
    scl.remove(scl.size() - 1); // remove 3 slots: target allParamsArr nullOrMeth
    scl.remove(scl.size() - 1);
    scl.remove(scl.size() - 1);
    stackContent = scl.toArray();
    stackContent = addReturnTypeTo(stackContent, cojReturnType);
    aaAfter.visitFrame(F_NEW, localsInFrame.length, localsInFrame, stackContent.length, stackContent);
}

From source file:ch.eiafr.cojac.instrumenters.FloatProxyMethod.java

License:Apache License

private void convertArgumentsToReal(MethodVisitor mv, ConversionContext cc) {
    String convertDesc = Type.getMethodDescriptor(OBJ_ARRAY_TYPE, cc.inArgs);
    createConvertMethod(convertDesc, cc);
    // stack >> [target] prm0 prm1 prm2...
    mv.visitMethodInsn(INVOKESTATIC, crtClassName, COJAC_TYPE_CONVERT_NAME, convertDesc, false);
    // stack >> [target] allParamsArr
    // We'll need a reference to converted arrays (for merging purposes)
    // and a copy of the target (trying first without proxy)...
    if (hasTarget(cc.opcode)) {
        mv.visitInsn(DUP2);/*from w  w w.j a  va  2s.  c  o m*/
    } else {
        mv.visitInsn(DUP);
    }
    // stack >> [target] allParamsArr [target] allParamsArr
}

From source file:ch.eiafr.cojac.instrumenters.FloatProxyMethod.java

License:Apache License

private static void explodeOnStack(MethodVisitor mv, ConversionContext cc, boolean wantTheConversion) {
    Type[] args = wantTheConversion ? cc.outArgs : cc.inArgs;
    // stack >> ... allParamsArr
    for (int i = 0; i < args.length; i++) {
        // stack >> ... allParamsArr
        Type oa = args[i];/*w ww .ja  va 2s.  c  om*/
        int oaSort = oa.getSort();
        mv.visitInsn(DUP);
        mv.visitLdcInsn(i);
        mv.visitInsn(AALOAD);
        boolean keepBothVersions = (oa.getSort() == Type.ARRAY);
        if (keepBothVersions) {
            mv.visitTypeInsn(CHECKCAST, "[" + OBJ_TYPE.getDescriptor());
            mv.visitLdcInsn(wantTheConversion ? 1 : 0);
            mv.visitInsn(AALOAD);
        }

        if (oaSort == Type.ARRAY || oaSort == Type.OBJECT) { // else: primitive type
            mv.visitTypeInsn(CHECKCAST, oa.getInternalName());
        } else {
            String jWrapperName = getJWrapper(oa).getInternalName();
            mv.visitTypeInsn(CHECKCAST, jWrapperName);
            mv.visitMethodInsn(INVOKEVIRTUAL, jWrapperName, getWrapperToPrimitiveMethod(oa),
                    "()" + oa.getDescriptor(), false);
        }

        if (oa.getSize() == 2) { //    Object DD  Swap when double or long
            mv.visitInsn(DUP2_X1); // DD Object DD
            mv.visitInsn(POP2); // DD Object
        } else {
            mv.visitInsn(SWAP);
        }
        // stack >> ... nprmI allParamsArr
    }
    mv.visitInsn(POP);
    // stack >> ... nprm0 nprm1 nprm2...
}

From source file:ch.eiafr.cojac.instrumenters.FloatProxyMethod.java

License:Apache License

private static void checkArraysAfterCall(MethodVisitor mv, Map<Integer, Type> convertedArrays, String desc) {
    // stack >> allParamsArr [possibleResult]
    Type returnType = Type.getReturnType(desc);
    int returnTypeSize = returnType.getSize();
    if (returnTypeSize == 1) {
        mv.visitInsn(SWAP);/*  w w w.  j  a va2 s  . c om*/
    } else if (returnTypeSize == 2) {
        // mv.visitInsn(NOP); just a marker as a debugging helper
        mv.visitInsn(DUP2_X1); // D D Object D D
        mv.visitInsn(POP2); // D D Object
    }
    // stack >> [possibleResult] allParamsArr
    for (int pos : convertedArrays.keySet()) {
        // Type type = convertedArrays.get(pos);
        mv.visitInsn(DUP);
        // stack >> [possibleResult] allParamsArr allParamsArr
        mv.visitLdcInsn(pos);
        // stack >> [possibleResult] allParamsArr allParamsArr i
        mv.visitInsn(AALOAD);
        // stack >> [possibleResult] allParamsArr allParamsArr[i]
        mv.visitTypeInsn(CHECKCAST, "[" + OBJ_TYPE.getDescriptor());
        // stack >> [possibleResult] allParamsArr allParamsArr[i]  (of type Object[])
        mv.visitInsn(DUP);
        // stack >> [possibleResult] allParamsArr allParamsArr[i]  allParamsArr[i]
        mv.visitLdcInsn(0);
        // stack >> [possibleResult] allParamsArr allParamsArr[i]  allParamsArr[i] 0  
        mv.visitInsn(AALOAD);
        // stack >> [possibleResult] allParamsArr allParamsArr[i]  allParamsArr[i][0]    
        mv.visitInsn(SWAP);
        // stack >> [possibleResult] allParamsArr allParamsArr[i][0] allParamsArr[i]
        mv.visitLdcInsn(1);
        // stack >> [possibleResult] allParamsArr allParamsArr[i][0] allParamsArr[i] 1
        mv.visitInsn(AALOAD);
        // stack >> [possibleResult] allParamsArr allParamsArr[i][0] allParamsArr[i][1]
        // mergeOriginalArrayIntoCojac
        mv.visitMethodInsn(INVOKESTATIC, DN_NAME, "mergeOriginalArrayIntoCojac",
                "(" + OBJ_DESC + OBJ_DESC + ")V", false);
        // stack >> [possibleResult] allParamsArr
    }
    // stack >> [possibleResult] allParamsArr
    mv.visitInsn(POP);
    // stack >> [possibleResult]
}

From source file:ch.eiafr.cojac.instrumenters.FloatProxyMethod.java

License:Apache License

public static void convertRealToCojacType(Type realType, MethodVisitor mv) {
    // WRAPPER SPEC: FW.fromFloat(float) -> FW,  FW.fromRealFloatWrapper(Float) -> FW
    // WRAPPER SPEC: DW.fromDouble(double) -> DW, DW.fromRealDoubleWrapper(Double) -> DW
    if (realType.equals(Type.FLOAT_TYPE)) {
        mv.visitMethodInsn(INVOKESTATIC, COJAC_FLOAT_WRAPPER_INTERNAL_NAME, "fromFloat",
                "(F)" + COJAC_FLOAT_WRAPPER_TYPE_DESCR, false);
    } else if (realType.equals(JWRAPPER_FLOAT_TYPE)) {
        mv.visitMethodInsn(INVOKESTATIC, COJAC_FLOAT_WRAPPER_INTERNAL_NAME, "fromRealFloatWrapper",
                "(" + JWRAPPER_FLOAT_TYPE.getDescriptor() + ")" + COJAC_FLOAT_WRAPPER_TYPE_DESCR, false);
    } else if (realType.equals(Type.DOUBLE_TYPE)) {
        mv.visitMethodInsn(INVOKESTATIC, COJAC_DOUBLE_WRAPPER_INTERNAL_NAME, "fromDouble",
                "(D)" + COJAC_DOUBLE_WRAPPER_TYPE_DESCR, false);
    } else if (realType.equals(JWRAPPER_DOUBLE_TYPE)) {
        mv.visitMethodInsn(INVOKESTATIC, COJAC_DOUBLE_WRAPPER_INTERNAL_NAME, "fromRealDoubleWrapper",
                "(" + JWRAPPER_DOUBLE_TYPE.getDescriptor() + ")" + COJAC_DOUBLE_WRAPPER_TYPE_DESCR, false);
    } else if (isPrimitiveFloatOrDoubleArray(realType)) {
        mv.visitTypeInsn(CHECKCAST, OBJ_TYPE.getInternalName());
        mv.visitLdcInsn(realType.getDimensions());
        if (realType.getElementType().equals(Type.FLOAT_TYPE)) {
            mv.visitMethodInsn(INVOKESTATIC, FN_NAME, "convertPrimitiveArrayToCojac",
                    "(" + OBJ_DESC + "I)" + OBJ_DESC, false);
        } else if (realType.getElementType().equals(Type.DOUBLE_TYPE)) {
            mv.visitMethodInsn(INVOKESTATIC, DN_NAME, "convertPrimitiveArrayToCojac",
                    "(" + OBJ_DESC + "I)" + OBJ_DESC, false);
        }/*  w  w w  . j  ava2  s  .co m*/
        mv.visitTypeInsn(CHECKCAST, afterFloatReplacement(realType).getInternalName());
    }
}

From source file:ch.eiafr.cojac.instrumenters.FloatProxyMethod.java

License:Apache License

public static void convertCojacToRealType(Type realType, MethodVisitor mv) {
    if (realType.equals(Type.FLOAT_TYPE)) {
        mv.visitMethodInsn(INVOKESTATIC, COJAC_FLOAT_WRAPPER_INTERNAL_NAME, "toFloat",
                "(" + COJAC_FLOAT_WRAPPER_TYPE_DESCR + ")F", false);
    } else if (realType.equals(JWRAPPER_FLOAT_TYPE)) {
        mv.visitMethodInsn(INVOKESTATIC, COJAC_FLOAT_WRAPPER_INTERNAL_NAME, "toRealFloatWrapper",
                "(" + COJAC_FLOAT_WRAPPER_TYPE_DESCR + ")" + FL_DESCR, false);
    } else if (realType.equals(Type.DOUBLE_TYPE)) {
        mv.visitMethodInsn(INVOKESTATIC, COJAC_DOUBLE_WRAPPER_INTERNAL_NAME, "toDouble",
                "(" + COJAC_DOUBLE_WRAPPER_TYPE_DESCR + ")D", false);
    } else if (realType.equals(JWRAPPER_DOUBLE_TYPE)) {
        mv.visitMethodInsn(INVOKESTATIC, COJAC_DOUBLE_WRAPPER_INTERNAL_NAME, "toRealDoubleWrapper",
                "(" + COJAC_DOUBLE_WRAPPER_TYPE_DESCR + ")" + DL_DESCR, false);
    } else if (isPrimitiveFloatOrDoubleArray(realType) || isJWrapperFloatOrDoubleArray(realType)) {
        mv.visitTypeInsn(CHECKCAST, OBJ_TYPE.getInternalName());
        mv.visitLdcInsn(realType.getDimensions());
        Type eType = realType.getElementType();
        if (eType.equals(Type.FLOAT_TYPE)) {
            mv.visitMethodInsn(INVOKESTATIC, FN_NAME, "convertArrayToPrimitive",
                    "(" + OBJ_DESC + "I)" + OBJ_DESC, false);
        } else if (eType.equals(Type.DOUBLE_TYPE)) {
            mv.visitMethodInsn(INVOKESTATIC, DN_NAME, "convertArrayToPrimitive",
                    "(" + OBJ_DESC + "I)" + OBJ_DESC, false);
        } else if (eType.equals(JWRAPPER_FLOAT_TYPE)) {
            mv.visitMethodInsn(INVOKESTATIC, FN_NAME, "convertArrayToJWrapper",
                    "(" + OBJ_DESC + "I)" + OBJ_DESC, false);
        } else if (eType.equals(JWRAPPER_DOUBLE_TYPE)) {
            mv.visitMethodInsn(INVOKESTATIC, DN_NAME, "convertArrayToJWrapper",
                    "(" + OBJ_DESC + "I)" + OBJ_DESC, false);
        }/*from w  ww  .j a  va 2s .  c  o  m*/
        mv.visitTypeInsn(CHECKCAST, realType.getInternalName());
    }
}

From source file:ch.eiafr.cojac.instrumenters.FloatProxyMethod.java

License:Apache License

private static void convertPrimitiveToObject(MethodVisitor newMv, Type type) {
    if (type.getSort() == Type.ARRAY || type.getSort() == Type.OBJECT)
        return;/*from   ww  w  . j  a  v  a 2  s. co m*/
    Type wrapper = getJWrapper(type);
    newMv.visitMethodInsn(INVOKESTATIC, wrapper.getInternalName(), "valueOf",
            "(" + type.getDescriptor() + ")" + wrapper.getDescriptor(), false);
}