vmreflection.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 421 行 · 第 1/2 页
JAVA
421 行
initialize(sf);
Unsafe.setLong(getStaticFieldAddress(sf), value);
} else {
final VmInstanceField inf = (VmInstanceField) field;
Unsafe.setLong(o, inf.getOffset(), value);
}
}
public static void setDouble(VmField field, Object o, double value) {
if (field.isStatic()) {
final VmStaticField sf = (VmStaticField) field;
initialize(sf);
Unsafe.setDouble(getStaticFieldAddress(sf), value);
} else {
final VmInstanceField inf = (VmInstanceField) field;
Unsafe.setDouble(o, inf.getOffset(), value);
}
}
/**
* Gets the address of the static field data (in the statics table)
*
* @param sf
* @return The address of the static field data
*/
private static final Address getStaticFieldAddress(VmStaticField sf) {
final VmProcessor proc = Unsafe.getCurrentProcessor();
final Address tablePtr = Address.addressOfArrayData(proc
.getStaticsTable());
final int offset = sf.getStaticsIndex() << 2;
return Unsafe.add(tablePtr, offset);
}
/**
* Invoke the given method, which must be static and have no arguments
*
* @param method
* @throws InvocationTargetException
*/
public static void invokeStatic(VmMethod method)
throws InvocationTargetException {
try {
Unsafe.invokeVoid(method);
} catch (Throwable ex) {
throw new InvocationTargetException(ex);
}
}
/**
* Invoke the given method on the given object with the given arguments.
*
* @param method
* @param o
* @param args
* @return Object
* @throws InvocationTargetException
*/
public static Object invoke(VmMethod method, Object o, Object[] args)
throws InvocationTargetException {
int argCount = method.getNoArguments();
int argsLength = (args == null) ? 0 : args.length;
if (argCount != argsLength) { throw new IllegalArgumentException(
"Invalid number of arguments"); }
if (!method.isStatic()) {
Unsafe.pushObject(o);
} else {
method.getDeclaringClass().initialize();
}
for (int i = 0; i < argCount; i++) {
final VmType argType = method.getArgumentType(i);
final Object arg = args[ i];
if (argType.isPrimitive()) {
int v = 0;
long lv = 0;
boolean wide = false;
if (arg == null) {
/* do nothing */
} else if (arg instanceof Boolean) {
v = ((Boolean) arg).booleanValue() ? 1 : 0;
} else if (arg instanceof Byte) {
v = ((Byte) arg).byteValue();
} else if (arg instanceof Character) {
v = ((Character) arg).charValue();
} else if (arg instanceof Short) {
v = ((Short) arg).shortValue();
} else if (arg instanceof Integer) {
v = ((Integer) arg).intValue();
} else if (arg instanceof Long) {
lv = ((Long) arg).longValue();
wide = true;
} else if (arg instanceof Float) {
v = Float.floatToRawIntBits(((Float) arg).floatValue());
} else if (arg instanceof Double) {
lv = Double.doubleToRawLongBits(((Double) arg)
.doubleValue());
wide = true;
}
final Class argClass = argType.asClass();
if ((argClass == Long.TYPE) || (argClass == Double.TYPE)) {
// Wide argument
if (wide) {
Unsafe.pushLong(lv);
} else {
Unsafe.pushLong(v);
}
} else {
// Normal argument
if (wide) {
Unsafe.pushInt((int) lv);
} else {
Unsafe.pushInt(v);
}
}
} else {
// Non-primitive argument
Unsafe.pushObject(arg);
}
}
try {
if (method.isReturnVoid()) {
Unsafe.invokeVoid(method);
return null;
} else if (method.isReturnObject()) {
return Unsafe.invokeObject(method);
} else if (method.isReturnWide()) {
long rc = Unsafe.invokeLong(method);
final Class retType = method.getReturnType().asClass();
if (Long.TYPE == retType) {
return new Long(rc);
} else {
return new Double(Double.longBitsToDouble(rc));
}
} else {
int rc = Unsafe.invokeInt(method);
final Class retType = method.getReturnType().asClass();
if (Byte.TYPE == retType) {
return new Byte((byte) rc);
} else if (Boolean.TYPE == retType) {
return Boolean.valueOf(rc != 0);
} else if (Character.TYPE == retType) {
return new Character((char) rc);
} else if (Short.TYPE == retType) {
return new Short((short) rc);
} else if (Float.TYPE == retType) {
return new Float(Float.intBitsToFloat(rc));
} else {
return new Integer(rc);
}
}
} catch (Throwable ex) {
throw new InvocationTargetException(ex);
}
}
/**
* Create and return a new object using the given constructor and arguments
*
* @param constructor
* @param args
* @return Object
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static Object newInstance(VmMethod constructor, Object[] args)
throws InstantiationException, IllegalAccessException,
InvocationTargetException {
final VmHeapManager hm = Vm.getVm().getHeapManager();
final Object obj = hm.newInstance(constructor.getDeclaringClass());
invoke(constructor, obj, args);
return obj;
}
/**
* Create and return a new object using the given constructor no arguments
*
* @param constructor
* @return Object
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public static Object newInstance(VmMethod constructor)
throws InstantiationException, IllegalAccessException,
InvocationTargetException {
final VmHeapManager hm = Vm.getVm().getHeapManager();
final Object obj = hm.newInstance(constructor.getDeclaringClass());
Unsafe.pushObject(obj);
Unsafe.invokeVoid(constructor);
return obj;
}
/**
* Initialize the class that declared this field if needed.
*
* @param sf
*/
private static void initialize(VmStaticField sf) {
final VmType declClass = sf.getDeclaringClass();
if (!declClass.isInitialized()) {
if (!(sf.isPrimitive() && sf.isFinal())) {
sf.getDeclaringClass().initialize();
}
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?