Search in sources :

Example 61 with Klass

use of com.oracle.truffle.espresso.impl.Klass in project graal by oracle.

the class Target_sun_reflect_NativeMethodAccessorImpl method callMethodReflectively.

@JavaType(Object.class)
public static StaticObject callMethodReflectively(Meta meta, @JavaType(Object.class) StaticObject receiver, @JavaType(Object[].class) StaticObject args, Method m, Klass klass, @JavaType(Class[].class) StaticObject parameterTypes) {
    // Klass should be initialized if method is static, and could be delayed until method
    // invocation, according to specs. However, JCK tests that it is indeed always initialized
    // before doing anything, even if the method to be invoked is from another class.
    klass.safeInitialize();
    Method reflectedMethod = m;
    if (reflectedMethod.isRemovedByRedefition()) {
        reflectedMethod = m.getContext().getClassRedefinition().handleRemovedMethod(reflectedMethod, reflectedMethod.isStatic() ? reflectedMethod.getDeclaringKlass() : receiver.getKlass());
    }
    // actual method to invoke
    Method method;
    // target klass, receiver's klass for non-static
    Klass targetKlass;
    if (reflectedMethod.isStatic()) {
        // Ignore receiver argument;.
        method = reflectedMethod;
        targetKlass = klass;
    } else {
        if (StaticObject.isNull(receiver)) {
            throw meta.throwNullPointerException();
        }
        // Check class of receiver against class declaring method.
        if (!klass.isAssignableFrom(receiver.getKlass())) {
            throw meta.throwExceptionWithMessage(meta.java_lang_IllegalArgumentException, "object is not an instance of declaring class");
        }
        // target klass is receiver's klass
        targetKlass = receiver.getKlass();
        // no need to resolve if method is private or <init>
        if (reflectedMethod.isPrivate() || Name._init_.equals(reflectedMethod.getName())) {
            method = reflectedMethod;
        } else {
            // resolve based on the receiver
            if (reflectedMethod.getDeclaringKlass().isInterface()) {
                // resolve interface call
                // Match resolution errors with those thrown due to reflection inlining
                // Linktime resolution & IllegalAccessCheck already done by Class.getMethod()
                method = reflectedMethod;
                assert targetKlass instanceof ObjectKlass;
                method = ((ObjectKlass) targetKlass).itableLookup(method.getDeclaringKlass(), method.getITableIndex());
                if (method != null) {
                    // Check for abstract methods as well
                    if (!method.hasCode()) {
                        // new default: 65315
                        throw meta.throwExceptionWithCause(meta.java_lang_reflect_InvocationTargetException, Meta.initException(meta.java_lang_AbstractMethodError));
                    }
                }
            } else {
                // if the method can be overridden, we resolve using the vtable index.
                method = reflectedMethod;
                // VTable is live, use it
                method = targetKlass.vtableLookup(method.getVTableIndex());
                if (method != null) {
                    // Check for abstract methods as well
                    if (method.isAbstract()) {
                        // new default: 65315
                        throw meta.throwExceptionWithCause(meta.java_lang_reflect_InvocationTargetException, Meta.initException(meta.java_lang_AbstractMethodError));
                    }
                }
            }
        }
    }
    // an internal vtable bug. If you ever get this please let Karen know.
    if (method == null) {
        throw meta.throwExceptionWithMessage(meta.java_lang_NoSuchMethodError, "please let Karen know");
    }
    int argsLen = StaticObject.isNull(args) ? 0 : args.length();
    final Symbol<Type>[] signature = method.getParsedSignature();
    // Check number of arguments.
    if (Signatures.parameterCount(signature, false) != argsLen) {
        throw meta.throwExceptionWithMessage(meta.java_lang_IllegalArgumentException, "wrong number of arguments!");
    }
    Object[] adjustedArgs = new Object[argsLen];
    for (int i = 0; i < argsLen; ++i) {
        StaticObject arg = args.get(i);
        StaticObject paramTypeMirror = parameterTypes.get(i);
        Klass paramKlass = paramTypeMirror.getMirrorKlass();
        // Throws guest IllegallArgumentException if the parameter cannot be casted or widened.
        adjustedArgs[i] = checkAndWiden(meta, arg, paramKlass);
    }
    Object result;
    try {
        result = method.invokeDirect(receiver, adjustedArgs);
    } catch (EspressoException e) {
        throw meta.throwExceptionWithCause(meta.java_lang_reflect_InvocationTargetException, e.getGuestException());
    }
    if (reflectedMethod.getReturnKind() == JavaKind.Void) {
        return StaticObject.NULL;
    }
    if (reflectedMethod.getReturnKind().isPrimitive()) {
        return Meta.box(meta, result);
    }
    // Result is not void nor primitive, pass through.
    return (StaticObject) result;
}
Also used : Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) EspressoException(com.oracle.truffle.espresso.runtime.EspressoException) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) Symbol(com.oracle.truffle.espresso.descriptors.Symbol) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) Method(com.oracle.truffle.espresso.impl.Method)

Example 62 with Klass

use of com.oracle.truffle.espresso.impl.Klass in project graal by oracle.

the class Target_java_lang_reflect_Array method multiNewArray.

/**
 * Creates a new array with the specified component type and dimensions. If
 * {@code componentType} represents a non-array class or interface, the new array has
 * {@code dimensions.length} dimensions and {@code componentType} as its component type. If
 * {@code componentType} represents an array class, the number of dimensions of the new array is
 * equal to the sum of {@code dimensions.length} and the number of dimensions of
 * {@code componentType}. In this case, the component type of the new array is the component
 * type of {@code componentType}.
 *
 * <p>
 * The number of dimensions of the new array must not exceed 255.
 *
 * @param componentType the {@code Class} object representing the component type of the new
 *            array
 * @param dimensionsArray an array of {@code int} representing the dimensions of the new array
 * @return the new array
 * @exception NullPointerException if the specified {@code componentType} argument is null
 * @exception IllegalArgumentException if the specified {@code dimensions} argument is a
 *                zero-dimensional array, if componentType is {@link Void#TYPE}, or if the
 *                number of dimensions of the requested array instance exceed 255.
 * @exception NegativeArraySizeException if any of the components in the specified
 *                {@code dimensions} argument is negative.
 */
@TruffleBoundary
@Substitution
@JavaType(Object.class)
public static StaticObject multiNewArray(@JavaType(Class.class) StaticObject componentType, @JavaType(int[].class) StaticObject dimensionsArray, @Inject Meta meta) {
    if (StaticObject.isNull(componentType) || StaticObject.isNull(dimensionsArray)) {
        throw meta.throwNullPointerException();
    }
    Klass component = componentType.getMirrorKlass();
    if (component == meta._void || StaticObject.isNull(dimensionsArray)) {
        throw meta.throwException(meta.java_lang_IllegalArgumentException);
    }
    final int[] dimensions = dimensionsArray.unwrap();
    int finalDimensions = dimensions.length;
    if (component.isArray()) {
        finalDimensions += Types.getArrayDimensions(component.getType());
    }
    if (dimensions.length == 0 || finalDimensions > 255) {
        throw meta.throwException(meta.java_lang_IllegalArgumentException);
    }
    for (int d : dimensions) {
        if (d < 0) {
            throw meta.throwException(meta.java_lang_NegativeArraySizeException);
        }
    }
    if (dimensions.length == 1) {
        // getArrayClass(0) is undefined.
        return meta.getInterpreterToVM().newMultiArray(component, dimensions);
    }
    return meta.getInterpreterToVM().newMultiArray(component.getArrayClass(dimensions.length - 1), dimensions);
}
Also used : ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) Klass(com.oracle.truffle.espresso.impl.Klass) TruffleBoundary(com.oracle.truffle.api.CompilerDirectives.TruffleBoundary)

Example 63 with Klass

use of com.oracle.truffle.espresso.impl.Klass in project graal by oracle.

the class Target_sun_misc_Unsafe method arrayBaseOffset.

/**
 * Report the offset of the first element in the storage allocation of a given array class. If
 * {@link #arrayIndexScale} returns a non-zero value for the same class, you may use that scale
 * factor, together with this base offset, to form new offsets to access elements of arrays of
 * the given class.
 *
 * @see #getInt
 * @see #putInt
 */
@Substitution(hasReceiver = true, nameProvider = SharedUnsafeAppend0.class)
public static int arrayBaseOffset(@SuppressWarnings("unused") @JavaType(Unsafe.class) StaticObject self, @JavaType(Class.class) StaticObject clazz, @Inject Meta meta) {
    Unsafe unsafe = UnsafeAccess.getIfAllowed(meta);
    Klass klass = clazz.getMirrorKlass();
    assert klass.isArray();
    if (((ArrayKlass) klass).getComponentType().isPrimitive()) {
        Class<?> hostPrimitive = ((ArrayKlass) klass).getComponentType().getJavaKind().toJavaClass();
        return unsafe.arrayBaseOffset(Array.newInstance(hostPrimitive, 0).getClass());
    } else {
        // Just a reference type.
        return unsafe.arrayBaseOffset(Object[].class);
    }
}
Also used : Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) Unsafe(sun.misc.Unsafe) TruffleObject(com.oracle.truffle.api.interop.TruffleObject) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject)

Example 64 with Klass

use of com.oracle.truffle.espresso.impl.Klass in project graal by oracle.

the class Target_sun_misc_Unsafe method objectFieldOffset1.

@Substitution(hasReceiver = true, nameProvider = Unsafe11.class)
@SuppressWarnings("unused")
public static long objectFieldOffset1(@JavaType(Unsafe.class) StaticObject self, @JavaType(value = Class.class) StaticObject cl, @JavaType(value = String.class) StaticObject guestName, @Inject Meta meta) {
    Klass k = cl.getMirrorKlass();
    String hostName = meta.toHostString(guestName);
    if (k instanceof ObjectKlass) {
        ObjectKlass kl = (ObjectKlass) k;
        for (Field f : kl.getFieldTable()) {
            if (!f.isRemoved() && f.getNameAsString().equals(hostName)) {
                return SAFETY_FIELD_OFFSET + f.getSlot();
            }
        }
        for (Field f : kl.getStaticFieldTable()) {
            if (!f.isRemoved() && f.getNameAsString().equals(hostName)) {
                return SAFETY_FIELD_OFFSET + f.getSlot();
            }
        }
    }
    throw meta.throwException(meta.java_lang_InternalError);
}
Also used : Field(com.oracle.truffle.espresso.impl.Field) Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass)

Example 65 with Klass

use of com.oracle.truffle.espresso.impl.Klass in project graal by oracle.

the class Target_java_lang_invoke_MethodHandleNatives method init.

/**
 * Plants an already resolved target into a memberName.
 *
 * @param self the memberName
 * @param ref the target. Can be either a mathod or a field.
 */
@Substitution
public static void init(@JavaType(internalName = "Ljava/lang/invoke/MemberName;") StaticObject self, @JavaType(Object.class) StaticObject ref, @Inject Meta meta) {
    Klass targetKlass = ref.getKlass();
    if (targetKlass.getType() == Type.java_lang_reflect_Method) {
        // Actual planting
        Method target = Method.getHostReflectiveMethodRoot(ref, meta);
        plantResolvedMethod(self, target, target.getRefKind(), meta);
        // Finish the job
        meta.java_lang_invoke_MemberName_clazz.setObject(self, target.getDeclaringKlass().mirror());
    } else if (targetKlass.getType() == Type.java_lang_reflect_Field) {
        // Actual planting
        Field field = Field.getReflectiveFieldRoot(ref, meta);
        plantResolvedField(self, field, getRefKind(meta.java_lang_invoke_MemberName_flags.getInt(self)), meta);
        // Finish the job
        Klass fieldKlass = meta.java_lang_reflect_Field_class.getObject(ref).getMirrorKlass();
        meta.java_lang_invoke_MemberName_clazz.setObject(self, fieldKlass.mirror());
    } else if (targetKlass.getType() == Type.java_lang_reflect_Constructor) {
        Method target = Method.getHostReflectiveConstructorRoot(ref, meta);
        plantResolvedMethod(self, target, target.getRefKind(), meta);
        meta.java_lang_invoke_MemberName_clazz.setObject(self, target.getDeclaringKlass().mirror());
    } else {
        throw EspressoError.shouldNotReachHere("invalid argument for MemberName.init: ", ref.getKlass());
    }
}
Also used : REF_getField(com.oracle.truffle.espresso.classfile.Constants.REF_getField) Field(com.oracle.truffle.espresso.impl.Field) REF_putField(com.oracle.truffle.espresso.classfile.Constants.REF_putField) Klass(com.oracle.truffle.espresso.impl.Klass) Method(com.oracle.truffle.espresso.impl.Method)

Aggregations

Klass (com.oracle.truffle.espresso.impl.Klass)71 ObjectKlass (com.oracle.truffle.espresso.impl.ObjectKlass)54 ArrayKlass (com.oracle.truffle.espresso.impl.ArrayKlass)49 StaticObject (com.oracle.truffle.espresso.runtime.StaticObject)33 JavaType (com.oracle.truffle.espresso.substitutions.JavaType)24 Meta (com.oracle.truffle.espresso.meta.Meta)21 Method (com.oracle.truffle.espresso.impl.Method)19 TruffleBoundary (com.oracle.truffle.api.CompilerDirectives.TruffleBoundary)10 Name (com.oracle.truffle.espresso.descriptors.Symbol.Name)10 NoSafepoint (com.oracle.truffle.espresso.jni.NoSafepoint)10 ExportMessage (com.oracle.truffle.api.library.ExportMessage)8 Field (com.oracle.truffle.espresso.impl.Field)7 ArrayList (java.util.ArrayList)7 RuntimeConstantPool (com.oracle.truffle.espresso.classfile.RuntimeConstantPool)6 EspressoException (com.oracle.truffle.espresso.runtime.EspressoException)6 InnerClassesAttribute (com.oracle.truffle.espresso.classfile.attributes.InnerClassesAttribute)5 Type (com.oracle.truffle.espresso.descriptors.Symbol.Type)5 NativeType (com.oracle.truffle.espresso.ffi.NativeType)5 TruffleObject (com.oracle.truffle.api.interop.TruffleObject)3 EnclosingMethodAttribute (com.oracle.truffle.espresso.classfile.attributes.EnclosingMethodAttribute)3