use of com.oracle.svm.core.annotate.RecomputeFieldValue.CustomFieldValueComputer in project graal by oracle.
the class ComputedValueField method readValue.
@Override
public JavaConstant readValue(JavaConstant receiver) {
if (constantValue != null) {
return constantValue;
}
if (kind == RecomputeFieldValue.Kind.None || kind == RecomputeFieldValue.Kind.Manual) {
return ReadableJavaField.readFieldValue(GraalAccess.getOriginalProviders().getConstantReflection(), original, receiver);
}
JavaConstant result = valueCache.get(receiver);
if (result != null) {
return result;
}
SnippetReflectionProvider originalSnippetReflection = GraalAccess.getOriginalSnippetReflection();
switch(kind) {
case ArrayBaseOffset:
constantValue = asConstant(ConfigurationValues.getObjectLayout().getArrayBaseOffset(JavaKind.fromJavaClass(targetClass.getComponentType())));
return constantValue;
case ArrayIndexScale:
constantValue = asConstant(ConfigurationValues.getObjectLayout().getArrayIndexScale(JavaKind.fromJavaClass(targetClass.getComponentType())));
return constantValue;
case ArrayIndexShift:
constantValue = asConstant(ConfigurationValues.getObjectLayout().getArrayIndexShift(JavaKind.fromJavaClass(targetClass.getComponentType())));
return constantValue;
case NewInstance:
try {
Constructor<?> constructor = targetClass.getDeclaredConstructor();
constructor.setAccessible(true);
result = originalSnippetReflection.forObject(constructor.newInstance());
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException ex) {
throw shouldNotReachHere("Error performing field recomputation for alias " + annotated.format("%H.%n"), ex);
}
break;
case AtomicFieldUpdaterOffset:
result = computeAtomicFieldUpdaterOffset(receiver);
break;
case TranslateFieldOffset:
result = translateFieldOffset(receiver, targetClass);
break;
case Custom:
try {
Constructor<?>[] constructors = targetClass.getDeclaredConstructors();
if (constructors.length != 1) {
throw shouldNotReachHere("The " + CustomFieldValueComputer.class.getSimpleName() + " class " + targetClass.getName() + " has more than one constructor");
}
Constructor<?> constructor = constructors[0];
Object[] constructorArgs = new Object[constructor.getParameterCount()];
for (int i = 0; i < constructorArgs.length; i++) {
constructorArgs[i] = configurationValue(constructor.getParameterTypes()[i]);
}
constructor.setAccessible(true);
CustomFieldValueComputer computer = (CustomFieldValueComputer) constructor.newInstance(constructorArgs);
Object receiverValue = receiver == null ? null : originalSnippetReflection.asObject(Object.class, receiver);
result = originalSnippetReflection.forBoxed(annotated.getJavaKind(), computer.compute(original, annotated, receiverValue));
assert result.getJavaKind() == annotated.getJavaKind();
} catch (InvocationTargetException | InstantiationException | IllegalAccessException ex) {
throw shouldNotReachHere("Error performing field recomputation for alias " + annotated.format("%H.%n"), ex);
}
break;
default:
throw shouldNotReachHere("Field recomputation of kind " + kind + " specified by alias " + annotated.format("%H.%n") + " not yet supported");
}
valueCache.put(receiver, result);
return result;
}
Aggregations