use of com.oracle.truffle.espresso.impl.Method 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());
}
}
use of com.oracle.truffle.espresso.impl.Method in project graal by oracle.
the class MethodHandleIntrinsics method findIntrinsic.
private Method findIntrinsic(Method m, MethodRef methodRef) {
Method method = getIntrinsic(methodRef);
if (method != null) {
return method;
}
CompilerAsserts.neverPartOfCompilation();
method = m.createIntrinsic(methodRef.signature);
Method previous = putIntrinsic(methodRef, method);
if (previous != null) {
return previous;
}
return method;
}
use of com.oracle.truffle.espresso.impl.Method in project graal by oracle.
the class BaseInterop method toDisplayString.
@ExportMessage
@TruffleBoundary
public static Object toDisplayString(StaticObject object, boolean allowSideEffects) {
if (object.isForeignObject()) {
InteropLibrary interopLibrary = InteropLibrary.getUncached();
try {
return "Foreign object: " + interopLibrary.asString(interopLibrary.toDisplayString(object.rawForeignObject(), allowSideEffects));
} catch (UnsupportedMessageException e) {
throw EspressoError.shouldNotReachHere("Interop library failed to convert display string to string");
}
}
if (StaticObject.isNull(object)) {
return "NULL";
}
Klass thisKlass = object.getKlass();
Meta meta = thisKlass.getMeta();
if (allowSideEffects) {
// Call guest toString.
int toStringIndex = meta.java_lang_Object_toString.getVTableIndex();
Method toString = thisKlass.vtableLookup(toStringIndex);
return meta.toHostString((StaticObject) toString.invokeDirect(object));
}
// Handle some special instances without side effects.
if (thisKlass == meta.java_lang_Class) {
return "class " + thisKlass.getTypeAsString();
}
if (thisKlass == meta.java_lang_String) {
return meta.toHostString(object);
}
return thisKlass.getTypeAsString() + "@" + Integer.toHexString(System.identityHashCode(object));
}
use of com.oracle.truffle.espresso.impl.Method in project graal by oracle.
the class ClassRedefinition method detectClassChanges.
// detect all types of class changes, but return early when a change that require arbitrary
// changes
private static ClassChange detectClassChanges(ParserKlass newParserKlass, ObjectKlass oldKlass, DetectedChange collectedChanges, ParserKlass finalParserKlass) throws RedefintionNotSupportedException {
ClassChange result = ClassChange.NO_CHANGE;
ParserKlass oldParserKlass = oldKlass.getLinkedKlass().getParserKlass();
boolean isPatched = finalParserKlass != null;
// detect method changes (including constructors)
ParserMethod[] newParserMethods = newParserKlass.getMethods();
List<Method> oldMethods = new ArrayList<>(Arrays.asList(oldKlass.getDeclaredMethods()));
List<ParserMethod> newMethods = new ArrayList<>(Arrays.asList(newParserMethods));
Map<Method, ParserMethod> bodyChanges = new HashMap<>();
List<ParserMethod> newSpecialMethods = new ArrayList<>(1);
boolean constantPoolChanged = false;
if (!Arrays.equals(oldParserKlass.getConstantPool().getRawBytes(), newParserKlass.getConstantPool().getRawBytes())) {
constantPoolChanged = true;
}
Iterator<Method> oldIt = oldMethods.iterator();
Iterator<ParserMethod> newIt;
while (oldIt.hasNext()) {
Method oldMethod = oldIt.next();
ParserMethod oldParserMethod = oldMethod.getLinkedMethod().getParserMethod();
// verify that there is a new corresponding method
newIt = newMethods.iterator();
while (newIt.hasNext()) {
ParserMethod newMethod = newIt.next();
if (isSameMethod(oldParserMethod, newMethod)) {
// detect method changes
ClassChange change = detectMethodChanges(oldParserMethod, newMethod);
switch(change) {
case NO_CHANGE:
if (isPatched) {
checkForSpecialConstructor(collectedChanges, bodyChanges, newSpecialMethods, oldMethod, oldParserMethod, newMethod);
} else if (constantPoolChanged) {
if (isObsolete(oldParserMethod, newMethod, oldParserKlass.getConstantPool(), newParserKlass.getConstantPool())) {
result = ClassChange.CONSTANT_POOL_CHANGE;
collectedChanges.addMethodBodyChange(oldMethod, newMethod);
} else {
collectedChanges.addUnchangedMethod(oldMethod);
}
} else {
collectedChanges.addUnchangedMethod(oldMethod);
}
break;
case METHOD_BODY_CHANGE:
result = change;
if (isPatched) {
checkForSpecialConstructor(collectedChanges, bodyChanges, newSpecialMethods, oldMethod, oldParserMethod, newMethod);
} else {
collectedChanges.addMethodBodyChange(oldMethod, newMethod);
}
break;
default:
return change;
}
newIt.remove();
oldIt.remove();
break;
}
}
}
if (isPatched) {
ParserMethod[] finalMethods = finalParserKlass.getMethods();
// map found changed methods
for (Map.Entry<Method, ParserMethod> entry : bodyChanges.entrySet()) {
Method oldMethod = entry.getKey();
ParserMethod changed = entry.getValue();
for (int i = 0; i < newParserMethods.length; i++) {
if (newParserMethods[i] == changed) {
collectedChanges.addMethodBodyChange(oldMethod, finalMethods[i]);
break;
}
}
}
// map found new methods
newMethods.addAll(newSpecialMethods);
for (ParserMethod changed : newMethods) {
for (int i = 0; i < newParserMethods.length; i++) {
if (newParserMethods[i] == changed) {
collectedChanges.addNewMethod(finalMethods[i]);
break;
}
}
}
} else {
collectedChanges.addNewMethods(newMethods);
}
for (Method oldMethod : oldMethods) {
collectedChanges.addRemovedMethod(oldMethod.getMethodVersion());
}
if (!oldMethods.isEmpty()) {
result = ClassChange.REMOVE_METHOD;
} else if (!newMethods.isEmpty()) {
result = ClassChange.ADD_METHOD;
}
if (isPatched) {
result = ClassChange.CLASS_NAME_CHANGED;
}
// detect field changes
Field[] oldFields = oldKlass.getDeclaredFields();
ParserField[] newFields = newParserKlass.getFields();
ArrayList<Field> oldFieldsList = new ArrayList<>(Arrays.asList(oldFields));
ArrayList<ParserField> newFieldsList = new ArrayList<>(Arrays.asList(newFields));
Map<ParserField, Field> compatibleFields = new HashMap<>();
Iterator<Field> oldFieldsIt = oldFieldsList.iterator();
Iterator<ParserField> newFieldsIt;
while (oldFieldsIt.hasNext()) {
Field oldField = oldFieldsIt.next();
newFieldsIt = newFieldsList.iterator();
// search for a new corresponding field
while (newFieldsIt.hasNext()) {
ParserField newField = newFieldsIt.next();
// first look for a perfect match
if (isUnchangedField(oldField, newField, compatibleFields)) {
// A nested anonymous inner class may contain a field reference to the outer
// class instance. Since we match against the patched (inner class rename rules
// applied) if the current class was patched (renamed) the resulting outer
// field pointer will have a changed type. Hence we should mark it as a new
// field.
Matcher matcher = InnerClassRedefiner.ANON_INNER_CLASS_PATTERN.matcher(oldField.getType().toString());
if (isPatched && matcher.matches()) {
break;
}
oldFieldsIt.remove();
newFieldsIt.remove();
break;
}
}
}
if (!newFieldsList.isEmpty()) {
if (isPatched) {
ParserField[] finalFields = finalParserKlass.getFields();
// lookup the final new field based on the index in the parser field array
for (ParserField parserField : newFieldsList) {
for (int i = 0; i < newFields.length; i++) {
if (parserField == newFields[i]) {
collectedChanges.addNewField(finalFields[i]);
break;
}
}
}
} else {
collectedChanges.addNewFields(newFieldsList);
}
result = ClassChange.SCHEMA_CHANGE;
}
if (!oldFieldsList.isEmpty()) {
collectedChanges.addRemovedFields(oldFieldsList);
result = ClassChange.SCHEMA_CHANGE;
}
// detect class-level changes
if (newParserKlass.getFlags() != oldParserKlass.getFlags()) {
result = ClassChange.SCHEMA_CHANGE;
}
collectedChanges.addCompatibleFields(compatibleFields);
// detect changes to superclass and implemented interfaces
Klass superKlass = oldKlass.getSuperKlass();
if (!newParserKlass.getSuperKlass().equals(oldParserKlass.getSuperKlass())) {
result = ClassChange.CLASS_HIERARCHY_CHANGED;
superKlass = getLoadedKlass(newParserKlass.getSuperKlass(), oldKlass);
}
collectedChanges.addSuperKlass((ObjectKlass) superKlass);
ObjectKlass[] newSuperInterfaces = oldKlass.getSuperInterfaces();
if (!Arrays.equals(newParserKlass.getSuperInterfaces(), oldParserKlass.getSuperInterfaces())) {
result = ClassChange.CLASS_HIERARCHY_CHANGED;
newSuperInterfaces = new ObjectKlass[newParserKlass.getSuperInterfaces().length];
for (int i = 0; i < newParserKlass.getSuperInterfaces().length; i++) {
newSuperInterfaces[i] = (ObjectKlass) getLoadedKlass(newParserKlass.getSuperInterfaces()[i], oldKlass);
}
}
collectedChanges.addSuperInterfaces(newSuperInterfaces);
return result;
}
use of com.oracle.truffle.espresso.impl.Method in project graal by oracle.
the class EspressoInterop method asDate.
@ExportMessage
@TruffleBoundary
static LocalDate asDate(StaticObject receiver, @Shared("error") @Cached BranchProfile error) throws UnsupportedMessageException {
receiver.checkNotForeign();
if (isDate(receiver)) {
Meta meta = receiver.getKlass().getMeta();
if (instanceOf(receiver, meta.java_time_LocalDate)) {
int year = (int) meta.java_time_LocalDate_year.get(receiver);
short month = (short) meta.java_time_LocalDate_month.get(receiver);
short day = (short) meta.java_time_LocalDate_day.get(receiver);
return LocalDate.of(year, month, day);
} else if (instanceOf(receiver, meta.java_time_LocalDateTime)) {
StaticObject localDate = (StaticObject) meta.java_time_LocalDateTime_toLocalDate.invokeDirect(receiver);
assert instanceOf(localDate, meta.java_time_LocalDate);
return asDate(localDate, error);
} else if (instanceOf(receiver, meta.java_time_Instant)) {
StaticObject zoneIdUTC = (StaticObject) meta.java_time_ZoneId_of.invokeDirect(null, meta.toGuestString("UTC"));
assert instanceOf(zoneIdUTC, meta.java_time_ZoneId);
StaticObject zonedDateTime = (StaticObject) meta.java_time_Instant_atZone.invokeDirect(receiver, zoneIdUTC);
assert instanceOf(zonedDateTime, meta.java_time_ZonedDateTime);
StaticObject localDate = (StaticObject) meta.java_time_ZonedDateTime_toLocalDate.invokeDirect(zonedDateTime);
assert instanceOf(localDate, meta.java_time_LocalDate);
return asDate(localDate, error);
} else if (instanceOf(receiver, meta.java_time_ZonedDateTime)) {
StaticObject localDate = (StaticObject) meta.java_time_ZonedDateTime_toLocalDate.invokeDirect(receiver);
assert instanceOf(localDate, meta.java_time_LocalDate);
return asDate(localDate, error);
} else if (instanceOf(receiver, meta.java_util_Date)) {
// return ((Date) obj).toInstant().atZone(UTC).toLocalDate();
int index = meta.java_util_Date_toInstant.getVTableIndex();
Method virtualToInstant = receiver.getKlass().vtableLookup(index);
StaticObject instant = (StaticObject) virtualToInstant.invokeDirect(receiver);
return asDate(instant, error);
}
}
error.enter();
throw UnsupportedMessageException.create();
}
Aggregations