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 + -
显示快捷键?