List of usage examples for org.objectweb.asm MethodVisitor visitMethodInsn
public void visitMethodInsn(final int opcode, final String owner, final String name, final String descriptor, final boolean isInterface)
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); }