vmnormalclass.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 145 行

JAVA
145
字号
/*
 * $Id: VmNormalClass.java,v 1.3 2004/02/19 10:09:13 epr Exp $
 */
package org.jnode.vm.classmgr;

/**
 * @author epr
 */
public class VmNormalClass extends VmClassType {

	/** The offsets of all reference variables in this class */
	private int[] referenceOffsets;
	/** The size (in bytes) of an instance of this class */
	private int objectSize = 0;

	/**
	 * @param name
	 * @param superClass
	 * @param loader
	 * @param typeSize
	 */
	protected VmNormalClass(String name, VmNormalClass superClass, VmClassLoader loader, int typeSize) {
		super(name, superClass, loader, typeSize);
		testClassType();
	}

	/**
	 * @param name
	 * @param superClassName
	 * @param loader
	 * @param accessFlags
	 */
	public VmNormalClass(String name, String superClassName, VmClassLoader loader, int accessFlags) {
		super(name, superClassName, loader, accessFlags);
		testClassType();
	}

	/**
	 * Return the size in bytes of instantiations of this class
	 * 
	 * @return The object size
	 */
	public final int getObjectSize() {
		if (!isPrepared()) {
			throw new IllegalStateException("Not initialized yet");
		}
		return objectSize;
	}

	/**
	 * Sets the objectSize.
	 * 
	 * @param objectSize
	 *            The objectSize to set
	 */
	protected final void setObjectSize(int objectSize) {
		if (this.objectSize == 0) {
			this.objectSize = objectSize;
		} else {
			throw new IllegalArgumentException("Cannot overwrite object size");
		}
	}

	/**
	 * Gets the offsets within an instance of this class of all reference non-static member variables.
	 * 
	 * @return The reference offsets
	 */
	public final int[] getReferenceOffsets() {
		if (!isPrepared()) {
			throw new IllegalStateException("Not initialized yet");
		}
		return referenceOffsets;
	}

	/**
	 * Do the prepare action required to instantiate this object
	 */
	protected void prepareForInstantiation() {
		// Step 3: Calculate the object size
		final VmNormalClass superCls = getSuperClass();
		int sc_size = (superCls != null) ? superCls.getObjectSize() : 0;
		objectSize += sc_size;

		//System.out.println(getName() + " objsz:" + objectSize + " sc_size:" + sc_size);

		// Step 4a: Fix the offset for all declared non-static fields
		final int cnt = getNoDeclaredFields();
		final int[] superRefOffsets = (superCls != null) ? superCls.getReferenceOffsets() : null;
		int refOffsetsSize = (superCls != null) ? superRefOffsets.length : 0;
		int startRefIdx = refOffsetsSize;
		for (int i = 0; i < cnt; i++) {
			final VmField field = getDeclaredField(i);
			//fs.resolve(loader);
			if (!field.isStatic()) {
				final VmInstanceField inf = (VmInstanceField) field;
				inf.resolveOffset(sc_size);
				if (!field.isPrimitive()) {
					if (!field.isAddressType()) {
						refOffsetsSize++;
					} else {
						//System.out.println("Found address in field " + fs.getName());
					}
				}
			}
		}

		// Step 4b: Create the referenceOffsets field
		referenceOffsets = new int[refOffsetsSize];
		if (superCls != null) {
			System.arraycopy(superRefOffsets, 0, referenceOffsets, 0, startRefIdx);
		}
		for (int i = 0; i < cnt; i++) {
			final VmField field = getDeclaredField(i);
			if (!field.isStatic()) {
				final VmInstanceField inf = (VmInstanceField) field;
				if (!field.isPrimitive()) {
					if (!field.isAddressType()) {
						referenceOffsets[startRefIdx++] = inf.getOffset();
					}
				}
				final int off = inf.getOffset();
				if (off + 4 > objectSize) {
					throw new Error("Invalid offset in class " + getName() + " ofs " + off + " size " + objectSize);
				}
			}
		}

	}

	/**
	 * Test if this class is using the right modifiers
	 * 
	 * @throws RuntimeException
	 */
	private final void testClassType() throws RuntimeException {
		if (isArray()) {
			throw new RuntimeException("Not a normal class (array-class)");
		}
		if (isInterface()) {
			throw new RuntimeException("Not a normal class (interface-class)");
		}
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?