⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fieldtransformer.java

📁 好东西,hibernate-3.2.0,他是一开元的树杖hibernate-3.2.0
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		code.growStack(Descriptor.dataSize(finfo.getDescriptor()) - 1);
		// *load_1
		addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
		// invokeinterface // callback.write*(..)
		addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(),
		                            false);
		// putfield // new value of the field
		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 ((!classfile.getName().equals(className))
		    || (!readableFields.containsKey(fieldName))) {
			return pos;
		}
		String desc = "()" + (String) readableFields.get(fieldName);
		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 ((!classfile.getName().equals(className))
		    || (!writableFields.containsKey(fieldName))) {
			return pos;
		}
		String desc = "(" + (String) writableFields.get(fieldName) + ")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 + -