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;
}
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);
}
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);
}
}
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);
}
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());
}
}
Aggregations