📄 fieldtransformer.java
字号:
code.addOpcode(Opcode.PUTFIELD); code.addIndex(base_field_index); code.growStack(-Descriptor.dataSize(finfo.getDescriptor())); // return code.addOpcode(Opcode.RETURN); minfo.setCodeAttribute(code.toCodeAttribute()); minfo.setAccessFlags(AccessFlag.PUBLIC); classfile.addMethod(minfo); } private void transformInvokevirtualsIntoPutAndGetfields(ClassFile classfile) throws CannotCompileException { List methods = classfile.getMethods(); for (Iterator method_iter = methods.iterator(); method_iter.hasNext();) { MethodInfo minfo = (MethodInfo) method_iter.next(); String methodName = minfo.getName(); if (methodName.startsWith(EACH_READ_METHOD_PREFIX) || methodName.startsWith(EACH_WRITE_METHOD_PREFIX) || methodName.equals(GETFIELDHANDLER_METHOD_NAME) || methodName.equals(SETFIELDHANDLER_METHOD_NAME)) { continue; } CodeAttribute codeAttr = minfo.getCodeAttribute(); if (codeAttr == null) { return; } CodeIterator iter = codeAttr.iterator(); while (iter.hasNext()) { try { int pos = iter.next(); pos = transformInvokevirtualsIntoGetfields(classfile, iter, pos); pos = transformInvokevirtualsIntoPutfields(classfile, iter, pos); } catch (BadBytecode e) { throw new CannotCompileException(e); } } } } private int transformInvokevirtualsIntoGetfields(ClassFile classfile, CodeIterator iter, int pos) { ConstPool cp = classfile.getConstPool(); int c = iter.byteAt(pos); if (c != Opcode.GETFIELD) { return pos; } int index = iter.u16bitAt(pos + 1); String fieldName = cp.getFieldrefName(index); String className = cp.getFieldrefClassName(index); if ( !filter.handleReadAccess( className, fieldName ) ) { return pos; } String desc = "()" + cp.getFieldrefType( index ); int read_method_index = cp.addMethodrefInfo( cp.getThisClassInfo(), EACH_READ_METHOD_PREFIX + fieldName, desc ); iter.writeByte(Opcode.INVOKEVIRTUAL, pos); iter.write16bit(read_method_index, pos + 1); return pos; } private int transformInvokevirtualsIntoPutfields( ClassFile classfile, CodeIterator iter, int pos) { ConstPool cp = classfile.getConstPool(); int c = iter.byteAt(pos); if (c != Opcode.PUTFIELD) { return pos; } int index = iter.u16bitAt(pos + 1); String fieldName = cp.getFieldrefName(index); String className = cp.getFieldrefClassName(index); if ( !filter.handleWriteAccess( className, fieldName ) ) { return pos; } String desc = "(" + cp.getFieldrefType( index ) + ")V"; int write_method_index = cp.addMethodrefInfo( cp.getThisClassInfo(), EACH_WRITE_METHOD_PREFIX + fieldName, desc ); iter.writeByte(Opcode.INVOKEVIRTUAL, pos); iter.write16bit(write_method_index, pos + 1); return pos; } private static void addInvokeFieldHandlerMethod(ClassFile classfile, Bytecode code, String typeName, boolean isReadMethod) { ConstPool cp = classfile.getConstPool(); // invokeinterface int callback_type_index = cp.addClassInfo(FIELD_HANDLER_TYPE_NAME); if ((typeName.charAt(0) == 'L') && (typeName.charAt(typeName.length() - 1) == ';') || (typeName.charAt(0) == '[')) { // reference type int indexOfL = typeName.indexOf('L'); String type; if (indexOfL == 0) { // not array type = typeName.substring(1, typeName.length() - 1); type = type.replace('/', '.'); } else if (indexOfL == -1) { // array of primitive type // do nothing type = typeName; } else { // array of reference type type = typeName.replace('/', '.'); } if (isReadMethod) { code .addInvokeinterface( callback_type_index, "readObject", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", 4); // checkcast code.addCheckcast(type); } else { code .addInvokeinterface( callback_type_index, "writeObject", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 5); // checkcast code.addCheckcast(type); } } else if (typeName.equals("Z")) { // boolean if (isReadMethod) { code.addInvokeinterface(callback_type_index, "readBoolean", "(Ljava/lang/Object;Ljava/lang/String;Z)Z", 4); } else { code.addInvokeinterface(callback_type_index, "writeBoolean", "(Ljava/lang/Object;Ljava/lang/String;ZZ)Z", 5); } } else if (typeName.equals("B")) { // byte if (isReadMethod) { code.addInvokeinterface(callback_type_index, "readByte", "(Ljava/lang/Object;Ljava/lang/String;B)B", 4); } else { code.addInvokeinterface(callback_type_index, "writeByte", "(Ljava/lang/Object;Ljava/lang/String;BB)B", 5); } } else if (typeName.equals("C")) { // char if (isReadMethod) { code.addInvokeinterface(callback_type_index, "readChar", "(Ljava/lang/Object;Ljava/lang/String;C)C", 4); } else { code.addInvokeinterface(callback_type_index, "writeChar", "(Ljava/lang/Object;Ljava/lang/String;CC)C", 5); } } else if (typeName.equals("I")) { // int if (isReadMethod) { code.addInvokeinterface(callback_type_index, "readInt", "(Ljava/lang/Object;Ljava/lang/String;I)I", 4); } else { code.addInvokeinterface(callback_type_index, "writeInt", "(Ljava/lang/Object;Ljava/lang/String;II)I", 5); } } else if (typeName.equals("S")) { // short if (isReadMethod) { code.addInvokeinterface(callback_type_index, "readShort", "(Ljava/lang/Object;Ljava/lang/String;S)S", 4); } else { code.addInvokeinterface(callback_type_index, "writeShort", "(Ljava/lang/Object;Ljava/lang/String;SS)S", 5); } } else if (typeName.equals("D")) { // double if (isReadMethod) { code.addInvokeinterface(callback_type_index, "readDouble", "(Ljava/lang/Object;Ljava/lang/String;D)D", 5); } else { code.addInvokeinterface(callback_type_index, "writeDouble", "(Ljava/lang/Object;Ljava/lang/String;DD)D", 7); } } else if (typeName.equals("F")) { // float if (isReadMethod) { code.addInvokeinterface(callback_type_index, "readFloat", "(Ljava/lang/Object;Ljava/lang/String;F)F", 4); } else { code.addInvokeinterface(callback_type_index, "writeFloat", "(Ljava/lang/Object;Ljava/lang/String;FF)F", 5); } } else if (typeName.equals("J")) { // long if (isReadMethod) { code.addInvokeinterface(callback_type_index, "readLong", "(Ljava/lang/Object;Ljava/lang/String;J)J", 5); } else { code.addInvokeinterface(callback_type_index, "writeLong", "(Ljava/lang/Object;Ljava/lang/String;JJ)J", 7); } } else { // bad type throw new RuntimeException("bad type: " + typeName); } } private static void addTypeDependDataLoad(Bytecode code, String typeName, int i) { if ((typeName.charAt(0) == 'L') && (typeName.charAt(typeName.length() - 1) == ';') || (typeName.charAt(0) == '[')) { // reference type code.addAload(i); } else if (typeName.equals("Z") || typeName.equals("B") || typeName.equals("C") || typeName.equals("I") || typeName.equals("S")) { // boolean, byte, char, int, short code.addIload(i); } else if (typeName.equals("D")) { // double code.addDload(i); } else if (typeName.equals("F")) { // float code.addFload(i); } else if (typeName.equals("J")) { // long code.addLload(i); } else { // bad type throw new RuntimeException("bad type: " + typeName); } } private static void addTypeDependDataStore(Bytecode code, String typeName, int i) { if ((typeName.charAt(0) == 'L') && (typeName.charAt(typeName.length() - 1) == ';') || (typeName.charAt(0) == '[')) { // reference type code.addAstore(i); } else if (typeName.equals("Z") || typeName.equals("B") || typeName.equals("C") || typeName.equals("I") || typeName.equals("S")) { // boolean, byte, char, int, short code.addIstore(i); } else if (typeName.equals("D")) { // double code.addDstore(i); } else if (typeName.equals("F")) { // float code.addFstore(i); } else if (typeName.equals("J")) { // long code.addLstore(i); } else { // bad type throw new RuntimeException("bad type: " + typeName); } } private static void addTypeDependDataReturn(Bytecode code, String typeName) { if ((typeName.charAt(0) == 'L') && (typeName.charAt(typeName.length() - 1) == ';') || (typeName.charAt(0) == '[')) { // reference type code.addOpcode(Opcode.ARETURN); } else if (typeName.equals("Z") || typeName.equals("B") || typeName.equals("C") || typeName.equals("I") || typeName.equals("S")) { // boolean, byte, char, int, short code.addOpcode(Opcode.IRETURN); } else if (typeName.equals("D")) { // double code.addOpcode(Opcode.DRETURN); } else if (typeName.equals("F")) { // float code.addOpcode(Opcode.FRETURN); } else if (typeName.equals("J")) { // long code.addOpcode(Opcode.LRETURN); } else { // bad type throw new RuntimeException("bad type: " + typeName); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -