softbytecodes.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 338 行
JAVA
338 行
/**
* $Id: SoftByteCodes.java,v 1.16 2004/02/24 08:04:48 epr Exp $
*/
package org.jnode.vm;
import org.jnode.util.NumberUtils;
import org.jnode.vm.classmgr.VmArrayClass;
import org.jnode.vm.classmgr.VmClassLoader;
import org.jnode.vm.classmgr.VmConstClass;
import org.jnode.vm.classmgr.VmConstFieldRef;
import org.jnode.vm.classmgr.VmConstMethodRef;
import org.jnode.vm.classmgr.VmField;
import org.jnode.vm.classmgr.VmMethod;
import org.jnode.vm.classmgr.VmType;
import org.jnode.vm.memmgr.VmHeapManager;
/**
* Class with software implementations of "difficult" java bytecodes.
*
* @author epr
*/
public class SoftByteCodes implements Uninterruptible {
public static final int EX_NULLPOINTER = 0;
public static final int EX_PAGEFAULT = 1;
public static final int EX_INDEXOUTOFBOUNDS = 2;
public static final int EX_DIV0 = 3;
public static final int EX_ABSTRACTMETHOD = 4;
public static final int EX_STACKOVERFLOW = 5;
public static final int EX_CLASSCAST = 6;
private static VmHeapManager heapManager;
/**
* Is the given object instance of the given class.
*
* @param object
* @param T
* @return boolean
* @throws PragmaUninterruptible
*/
public static boolean isInstanceof(Object object, VmType T) throws PragmaUninterruptible {
if (object == null) {
return false;
} else {
final VmType[] superClasses = Unsafe.getSuperClasses(object);
final int length = superClasses.length;
for (int i = 0; i < length; i++) {
if (superClasses[i] == T) {
return true;
}
}
return false;
}
}
/**
* Resolve a const reference to a field to the actual field, in the context of the given current method.
*
* @param currentMethod
* @param fieldRef
* @param isStatic
* @return VmField
* @throws PragmaUninterruptible
*/
public static VmField resolveField(VmMethod currentMethod, VmConstFieldRef fieldRef, boolean isStatic) throws PragmaUninterruptible {
if (!fieldRef.getConstClass().isResolved()) {
resolveClass(fieldRef.getConstClass());
}
VmField result;
if (fieldRef.isResolved()) {
result = fieldRef.getResolvedVmField();
} else {
VmType vmClass = fieldRef.getConstClass().getResolvedVmClass();
vmClass.link();
VmField field = vmClass.getField(fieldRef);
if (field == null) {
throw new NoSuchFieldError();
}
fieldRef.setResolvedVmField(field);
result = field;
}
VmType declClass = result.getDeclaringClass();
if ((isStatic) && (!declClass.isInitialized())) {
if (!(result.isPrimitive() && result.isFinal())) {
declClass.initialize();
}
}
return result;
}
/**
* Resolve a const reference to a method to the actual method, in the context of the given current method.
*
* @param currentMethod
* @param methodRef
* @return VmMethod
* @throws PragmaUninterruptible
*/
public static VmMethod resolveMethod(VmMethod currentMethod, VmConstMethodRef methodRef) throws PragmaUninterruptible {
if (!methodRef.getConstClass().isResolved()) {
resolveClass(methodRef.getConstClass());
}
if (methodRef.isResolved()) {
return methodRef.getResolvedVmMethod();
} else {
VmType vmClass = methodRef.getConstClass().getResolvedVmClass();
vmClass.link();
// NEW
VmClassLoader curLoader = currentMethod.getDeclaringClass().getLoader();
methodRef.resolve(curLoader);
return methodRef.getResolvedVmMethod();
// END NEW
/*
* VmMethod method = vmClass.getMethod(methodRef); if (method == null) { String mname = methodRef.getName(); String cname = methodRef.getClassName(); Screen.debug("method not found ");
* Screen.debug(mname); Screen.debug(" in "); Screen.debug(cname); throw new NoSuchMethodError(cname); }
*
* methodRef.setResolvedVmMethod(method);
*/
}
}
/**
* Resolve a const reference to a class to the actual class, in the context of the given current method.
*
* @param classRef
* @return VmClass
* @throws PragmaUninterruptible
*/
public static VmType resolveClass(VmConstClass classRef) throws PragmaUninterruptible {
if (classRef.isResolved()) {
return classRef.getResolvedVmClass();
} else {
VmClassLoader curLoader = VmSystem.getContextClassLoader();
String cname = classRef.getClassName();
try {
Class cls = curLoader.asClassLoader().loadClass(cname);
VmType vmClass = cls.getVmClass();
/*
* VmClass vmClass = curLoader.loadClass(cname, true); //VmClass vmClass = Main.getBootClass(classRef); if (vmClass == null) { throw new NoClassDefFoundError(cname);
*/
classRef.setResolvedVmClass(vmClass);
return vmClass;
} catch (ClassNotFoundException ex) {
//ex.printStackTrace();
//Unsafe.debug("resolve::CLASSNOTFOUND");
throw new NoClassDefFoundError(cname);
}
}
}
/**
* Allocate a new object with a given class and a given size in bytes. If size < 0, the objectsize from the given class is used. The given size does not include the length of the object
* header.
*
* @param vmClass
* @param size
* @return Object The new object
* @throws PragmaUninterruptible
*/
public static Object allocObject(VmType vmClass, int size) throws PragmaUninterruptible {
vmClass.link();
//Screen.debug("ao cls{");
//Screen.debug(vmClass.getName());
VmHeapManager hm = heapManager;
if (hm == null) {
heapManager = hm = Vm.getVm().getHeapManager();
}
Object result;
if (size < 0) {
result = hm.newInstance(vmClass);
} else {
result = hm.newInstance(vmClass, size);
}
//Screen.debug("}");
return result;
}
/**
* Allocate a multi dimensional array
*
* @param vmClass
* @param dimensions
* @return The allocated array
* @throws PragmaUninterruptible
*/
public static Object allocMultiArray(VmType vmClass, int[] dimensions) throws PragmaUninterruptible {
//Syslog.debug("allocMultiArray "); // + vmClass);
return multinewarray_helper(dimensions, dimensions.length - 1, (VmArrayClass) vmClass);
}
/**
* Allocates a multidimensional array of type a, with dimensions given in dims[ind] to dims[dims.length-1]. a must be of dimensionality at least dims.length-ind.
*
* @return allocated array object
* @param dims
* array of dimensions in reverse order
* @param ind
* start index in array dims
* @param a
* array type
* @throws NegativeArraySizeException
* if one of the array sizes in dims is negative
* @throws OutOfMemoryError
* if there is not enough memory to perform operation
* @throws PragmaUninterruptible
*/
public static Object multinewarray_helper(int[] dims, int ind, VmArrayClass a) throws OutOfMemoryError, NegativeArraySizeException, PragmaUninterruptible {
//Syslog.debug("multinewarray_helper "); //+ " cls=" + a);
a.initialize();
final int length = dims[ind];
final Object o = allocArray(a, length);
if (ind == 0) {
return o;
}
final Object[] o2 = (Object[]) o;
final VmArrayClass a2 = (VmArrayClass) a.getComponentType();
a2.initialize();
for (int i = 0; i < length; ++i) {
o2[i] = multinewarray_helper(dims, ind - 1, a2);
}
return o2;
}
/**
* Allocate a new array with a given class as component type and a given number of elements.
*
* @param currentMethod
* @param vmClass
* @param elements
* @return Object The new array
* @throws PragmaUninterruptible
*/
public static Object anewarray(VmMethod currentMethod, VmType vmClass, int elements) throws PragmaUninterruptible {
final String arrClsName = vmClass.getArrayClassName();
final VmType arrCls;
try {
final VmClassLoader curLoader = currentMethod.getDeclaringClass().getLoader();
arrCls = curLoader.loadClass(arrClsName, true);
//Screen.debug("an cls{");
//Screen.debug(vmClass.getName());
if (arrCls == null) {
throw new NoClassDefFoundError(arrClsName);
}
} catch (ClassNotFoundException ex) {
throw new NoClassDefFoundError(arrClsName);
}
VmHeapManager hm = heapManager;
if (hm == null) {
heapManager = hm = Vm.getVm().getHeapManager();
}
final Object result = hm.newArray((VmArrayClass) arrCls, elements);
//Screen.debug("}");
return result;
}
/**
* Allocate a new primivite array with a given arraytype and a given number of elements.
*
* @param atype
* @param elements
* @return Object The new array
* @throws PragmaUninterruptible
*/
public static Object allocPrimitiveArray(int atype, int elements) throws PragmaUninterruptible {
VmHeapManager hm = heapManager;
if (hm == null) {
heapManager = hm = Vm.getVm().getHeapManager();
}
final Object result = hm.newArray(VmType.getPrimitiveArrayClass(atype), elements);
return result;
}
/**
* Allocate a new array with a given class and a given number of elements.
*
* @param vmClass
* @param elements
* @return Object The new array
* @throws PragmaUninterruptible
*/
public static Object allocArray(VmType vmClass, int elements) throws PragmaUninterruptible {
VmHeapManager hm = heapManager;
if (hm == null) {
heapManager = hm = Vm.getVm().getHeapManager();
}
final Object result = hm.newArray((VmArrayClass) vmClass, elements);
return result;
}
/**
* Create an exception for a system-trapped situation.
*
* @param nr
* @param address
* @return Throwable
* @throws PragmaUninterruptible
*/
public static Throwable systemException(int nr, int address) throws PragmaUninterruptible, PragmaLoadStatics {
//Unsafe.getCurrentProcessor().getArchitecture().getStackReader().debugStackTrace();
//Unsafe.die();
Unsafe.debug(nr); Unsafe.debug(address);
final String hexAddress = NumberUtils.hex(address, 8);
final String state = " (" + Unsafe.getCurrentProcessor().getCurrentThread().getReadableErrorState() + ")";
switch (nr) {
case EX_NULLPOINTER :
return new NullPointerException("NPE at address " + hexAddress + state);
case EX_PAGEFAULT :
return new InternalError("Page fault at " + hexAddress + state);
case EX_INDEXOUTOFBOUNDS :
return new ArrayIndexOutOfBoundsException("Out of bounds at index " + address + state);
case EX_DIV0 :
return new ArithmeticException("Division by zero at address " + hexAddress + state);
case EX_ABSTRACTMETHOD :
return new AbstractMethodError("Abstract method at " + hexAddress + state);
case EX_STACKOVERFLOW :
return new StackOverflowError();
case EX_CLASSCAST :
return new ClassCastException();
default :
return new UnknownError("Unknown system-exception at " + hexAddress + state);
}
}
public static void unknownOpcode(int opcode, int pc) throws PragmaUninterruptible, PragmaLoadStatics {
throw new Error("Unknown opcode " + opcode + " at pc " + pc);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?