Search in sources :

Example 26 with MethodInfo

use of javassist.bytecode.MethodInfo in project openj9 by eclipse.

the class DummyClassGenerator method modifyInvokerOperand.

/*
	 * This method is to workaround a limitation of ASM which prevents
	 * generating class file where invokeinterface and invoke[static|special]
	 * bytecodes share same constant pool entry.
	 * 
	 * To overcome this limitation, after the ASM has generated class data, the
	 * operand of invoke[static|special] bytecodes is modified to be same as the
	 * operand of invokeinterface bytecode. It uses javassist APIs to make this
	 * modification.
	 */
protected byte[] modifyInvokerOperand() throws Exception {
    int cpIndex = 0;
    ByteArrayInputStream bais = new ByteArrayInputStream(data);
    ClassFile classFile = new ClassFile(new DataInputStream(bais));
    String[] sharedInvokers = (String[]) characteristics.get(SHARED_INVOKERS);
    /* Record operand of invokeinterface in invokeInterface() */
    for (int i = 0; i < sharedInvokers.length; i++) {
        String methodName = sharedInvokers[i];
        if (methodName.equals(INVOKE_INTERFACE)) {
            MethodInfo methodInfo = classFile.getMethod(methodName);
            CodeIterator ci = methodInfo.getCodeAttribute().iterator();
            while (ci.hasNext()) {
                int bcIndex = ci.next();
                int bc = ci.byteAt(bcIndex);
                if (bc == Opcode.INVOKEINTERFACE) {
                    /* found invokeinterfce bytecode */
                    cpIndex = ci.s16bitAt(bcIndex + 1);
                    break;
                }
            }
        }
    }
    /*
		 * Modify operand of invokestatic/invokespecial to cpIndex recorded
		 * above
		 */
    for (int i = 0; i < sharedInvokers.length; i++) {
        String methodName = sharedInvokers[i];
        if (methodName.equals(INVOKE_SPECIAL) || (methodName.equals(INVOKE_STATIC))) {
            MethodInfo methodInfo = classFile.getMethod(methodName);
            CodeIterator ci = methodInfo.getCodeAttribute().iterator();
            while (ci.hasNext()) {
                int bcIndex = ci.next();
                int bc = ci.byteAt(bcIndex);
                if ((bc == Opcode.INVOKESPECIAL) || (bc == Opcode.INVOKESTATIC)) {
                    /*
						 * found invokespecial or invokestatic bytecode; update
						 * the operand constant pool index
						 */
                    ci.write16bit(cpIndex, bcIndex + 1);
                }
            }
        }
    }
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    DataOutputStream dataStream = new DataOutputStream(byteStream);
    classFile.write(dataStream);
    return byteStream.toByteArray();
}
Also used : ClassFile(javassist.bytecode.ClassFile) ByteArrayInputStream(java.io.ByteArrayInputStream) CodeIterator(javassist.bytecode.CodeIterator) DataOutputStream(java.io.DataOutputStream) MethodInfo(javassist.bytecode.MethodInfo) ByteArrayOutputStream(java.io.ByteArrayOutputStream) DataInputStream(java.io.DataInputStream)

Example 27 with MethodInfo

use of javassist.bytecode.MethodInfo in project openj9 by eclipse.

the class SharedInvokersTestGenerator method modifyInvokerOperand.

/*
	 * This method is to workaround a limitation of ASM which prevents
	 * generating class file where invokeinterface and invoke[static|special]
	 * bytecodes share same constant pool entry.
	 * 
	 * To overcome this limitation, after the ASM has generated class data, the
	 * operand of invoke[static|special] bytecodes is modified to be same as the
	 * operand of invokeinterface bytecode. It uses javassist APIs to make this
	 * modification.
	 */
public static byte[] modifyInvokerOperand(byte[] data) throws Exception {
    int cpIndex = 0;
    ByteArrayInputStream bais = new ByteArrayInputStream(data);
    ClassFile classFile = new ClassFile(new DataInputStream(bais));
    /* Record operand of invokeinterface in sharedInvokers() */
    MethodInfo methodInfo = classFile.getMethod("sharedInvokers");
    CodeIterator ci = methodInfo.getCodeAttribute().iterator();
    while (ci.hasNext()) {
        int bcIndex = ci.next();
        int bc = ci.byteAt(bcIndex);
        if (bc == Opcode.INVOKEINTERFACE) {
            /* found invokeinterfce bytecode */
            cpIndex = ci.s16bitAt(bcIndex + 1);
            break;
        }
    }
    /*
		 * Modify operand of invokestatic/invokespecial to cpIndex recorded
		 * above
		 */
    ci = methodInfo.getCodeAttribute().iterator();
    while (ci.hasNext()) {
        int bcIndex = ci.next();
        int bc = ci.byteAt(bcIndex);
        if ((bc == Opcode.INVOKESPECIAL) || (bc == Opcode.INVOKESTATIC)) {
            /*
				 * found invokespecial or invokestatic bytecode; update the
				 * operand constant pool index
				 */
            ci.write16bit(cpIndex, bcIndex + 1);
        }
    }
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    DataOutputStream dataStream = new DataOutputStream(byteStream);
    classFile.write(dataStream);
    return byteStream.toByteArray();
}
Also used : ClassFile(javassist.bytecode.ClassFile) ByteArrayInputStream(java.io.ByteArrayInputStream) CodeIterator(javassist.bytecode.CodeIterator) DataOutputStream(java.io.DataOutputStream) MethodInfo(javassist.bytecode.MethodInfo) ByteArrayOutputStream(java.io.ByteArrayOutputStream) DataInputStream(java.io.DataInputStream)

Example 28 with MethodInfo

use of javassist.bytecode.MethodInfo in project duangframework by tcrct.

the class AutoBuildServiceInterface method getLocalVariableAttributeName.

/**
 * 反射取出方法里的参数名
 * @param cc                类对象
 * @param method        方法名
 * @return      方法名集合
 * @throws Exception
 */
private static List<String> getLocalVariableAttributeName(CtClass cc, Method method) throws Exception {
    List<String> paramNames = null;
    try {
        CtMethod cm = cc.getDeclaredMethod(method.getName());
        MethodInfo methodInfo = cm.getMethodInfo();
        CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
        LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
        if (attr != null) {
            int size = cm.getParameterTypes().length;
            paramNames = new ArrayList<>(size);
            int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
            for (int i = 0; i < size; i++) {
                paramNames.add(attr.variableName(i + pos));
            }
        }
    } catch (NotFoundException e) {
        throw new RpcException(e.getMessage(), e);
    }
    return paramNames;
}
Also used : CodeAttribute(javassist.bytecode.CodeAttribute) RpcException(com.duangframework.core.exceptions.RpcException) NotFoundException(javassist.NotFoundException) MethodInfo(javassist.bytecode.MethodInfo) LocalVariableAttribute(javassist.bytecode.LocalVariableAttribute) CtMethod(javassist.CtMethod)

Example 29 with MethodInfo

use of javassist.bytecode.MethodInfo in project fakereplace by fakereplace.

the class Transformer method addConstructorForInstrumentation.

private void addConstructorForInstrumentation(ClassFile file) {
    MethodInfo ret = new MethodInfo(file.getConstPool(), "<init>", Constants.ADDED_CONSTRUCTOR_DESCRIPTOR);
    Bytecode code = new Bytecode(file.getConstPool());
    // if the class does not have a constructor return
    if (!ManipulationUtils.addBogusConstructorCall(file, code)) {
        return;
    }
    CodeAttribute ca = code.toCodeAttribute();
    ca.setMaxLocals(4);
    ret.setCodeAttribute(ca);
    ret.setAccessFlags(AccessFlag.PUBLIC | AccessFlag.SYNTHETIC);
    try {
        ca.computeMaxStack();
        file.addMethod(ret);
    } catch (DuplicateMemberException e) {
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
Also used : DuplicateMemberException(javassist.bytecode.DuplicateMemberException) CodeAttribute(javassist.bytecode.CodeAttribute) MethodInfo(javassist.bytecode.MethodInfo) BadBytecode(javassist.bytecode.BadBytecode) Bytecode(javassist.bytecode.Bytecode) IllegalClassFormatException(java.lang.instrument.IllegalClassFormatException) DuplicateMemberException(javassist.bytecode.DuplicateMemberException)

Example 30 with MethodInfo

use of javassist.bytecode.MethodInfo in project fakereplace by fakereplace.

the class Transformer method addAbstractMethodForInstrumentation.

/**
 * Adds a method to a class that re can redefine when the class is reloaded
 */
private void addAbstractMethodForInstrumentation(ClassFile file) {
    try {
        MethodInfo m = new MethodInfo(file.getConstPool(), Constants.ADDED_METHOD_NAME, Constants.ADDED_METHOD_DESCRIPTOR);
        m.setAccessFlags(AccessFlag.PUBLIC | AccessFlag.ABSTRACT | AccessFlag.SYNTHETIC);
        file.addMethod(m);
    } catch (DuplicateMemberException e) {
    // e.printStackTrace();
    }
}
Also used : DuplicateMemberException(javassist.bytecode.DuplicateMemberException) MethodInfo(javassist.bytecode.MethodInfo)

Aggregations

MethodInfo (javassist.bytecode.MethodInfo)54 Bytecode (javassist.bytecode.Bytecode)28 BadBytecode (javassist.bytecode.BadBytecode)19 CodeIterator (javassist.bytecode.CodeIterator)18 CodeAttribute (javassist.bytecode.CodeAttribute)17 ConstPool (javassist.bytecode.ConstPool)17 ClassFile (javassist.bytecode.ClassFile)12 LocalVariableAttribute (javassist.bytecode.LocalVariableAttribute)10 DuplicateMemberException (javassist.bytecode.DuplicateMemberException)9 List (java.util.List)7 ClassPool (javassist.ClassPool)7 ByteArrayOutputStream (java.io.ByteArrayOutputStream)6 DataOutputStream (java.io.DataOutputStream)6 IOException (java.io.IOException)6 CtMethod (javassist.CtMethod)6 HashMap (java.util.HashMap)5 HashSet (java.util.HashSet)5 Set (java.util.Set)5 AnnotationsAttribute (javassist.bytecode.AnnotationsAttribute)5 IllegalClassFormatException (java.lang.instrument.IllegalClassFormatException)4