Skip to content

Commit

Permalink
make sure we attempt type converters for not otherwise directly mappe…
Browse files Browse the repository at this point in the history
…d target types

(cherry picked from commit f4b024a)
  • Loading branch information
javeleon authored and elkorchi committed Jun 26, 2024
1 parent a165ae8 commit 166a709
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ public Object doInternalTypeConverter(Object value, Klass targetType,
public Object doGeneric(Object value, Klass targetType,
@Bind("getMeta()") Meta meta,
@CachedLibrary(limit = "LIMIT") InteropLibrary interop,
@Cached LookupTypeConverterNode lookupTypeConverterNode,
@Cached LookupInternalTypeConverterNode lookupInternalTypeConverterNode,
@Cached ToReference.DynamicToReference converterToEspresso,
@Cached InlinedBranchProfile unknownProfile) throws UnsupportedTypeException {
ToEspressoNode uncachedToEspresso = getUncachedToEspresso(targetType, meta);
if (uncachedToEspresso != null) {
Expand All @@ -272,6 +275,10 @@ public Object doGeneric(Object value, Klass targetType,
unknownProfile.enter(this);
// hit the unknown type case, so inline generic handling for that here
if (targetType instanceof ObjectKlass) {
StaticObject result = ToReference.tryConverterForUnknownTarget(value, interop, lookupTypeConverterNode, lookupInternalTypeConverterNode, converterToEspresso, meta);
if (result != null) {
return result;
}
try {
checkHasAllFieldsOrThrow(value, (ObjectKlass) targetType, interop, getMeta());
return StaticObject.createForeign(getLanguage(), targetType, value, interop);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,10 @@ public StaticObject doInternalTypeConverter(Object value, @SuppressWarnings("unu
public StaticObject doGeneric(Object value, Klass targetType,
@Bind("getMeta()") Meta meta,
@CachedLibrary(limit = "LIMIT") InteropLibrary interop,
@Cached LookupTypeConverterNode lookupTypeConverterNode,
@Cached LookupInternalTypeConverterNode lookupInternalTypeConverterNode,
@Cached ToReference.DynamicToReference converterToEspresso,
@Cached InlinedBranchProfile noConverterProfile,
@Cached InlinedBranchProfile unknownProfile) throws UnsupportedTypeException {
ToReference uncachedToReference = getUncachedToReference(targetType, meta);
if (uncachedToReference != null) {
Expand All @@ -462,7 +466,12 @@ public StaticObject doGeneric(Object value, Klass targetType,
unknownProfile.enter(this);
// hit the unknown type case, so inline generic handling for that here
if (targetType instanceof ObjectKlass) {
StaticObject result = ToReference.tryConverterForUnknownTarget(value, interop, lookupTypeConverterNode, lookupInternalTypeConverterNode, converterToEspresso, meta);
if (result != null) {
return result;
}
try {
noConverterProfile.enter(this);
checkHasAllFieldsOrThrow(value, (ObjectKlass) targetType, interop, getMeta());
return StaticObject.createForeign(getLanguage(), targetType, value, interop);
} catch (ClassCastException e) {
Expand Down Expand Up @@ -1237,45 +1246,78 @@ StaticObject doForeignObject(Object value,
StaticObject doUnsupportedType(Object value) throws UnsupportedTypeException {
throw UnsupportedTypeException.create(new Object[]{value}, "java.lang.Object");
}
}

private StaticObject tryTypeConversion(Object value, InteropLibrary interop, LookupProxyKlassNode lookupProxyKlassNode, LookupTypeConverterNode lookupTypeConverterNode,
LookupInternalTypeConverterNode lookupInternalTypeConverterNode,
ToReference.DynamicToReference converterToEspresso, BranchProfile errorProfile, Meta meta) throws UnsupportedTypeException {
try {
Object metaObject = getMetaObjectOrThrow(value, interop);
String metaName = getMetaName(metaObject, interop);

// check if there's a specific type mapping available
PolyglotTypeMappings.InternalTypeConverter internalConverter = lookupInternalTypeConverterNode.execute(metaName);
if (internalConverter != null) {
return internalConverter.convertInternal(interop, value, meta, converterToEspresso);
} else {
PolyglotTypeMappings.TypeConverter converter = lookupTypeConverterNode.execute(metaName);
if (converter != null) {
if (interop.isException(value)) {
return (StaticObject) converter.convert(StaticObject.createForeignException(getContext(), value, interop));
} else {
return (StaticObject) converter.convert(StaticObject.createForeign(getLanguage(), meta.java_lang_Object, value, interop));
}
}
static StaticObject tryTypeConversion(Object value, InteropLibrary interop, LookupProxyKlassNode lookupProxyKlassNode, LookupTypeConverterNode lookupTypeConverterNode,
LookupInternalTypeConverterNode lookupInternalTypeConverterNode,
ToReference.DynamicToReference converterToEspresso, BranchProfile errorProfile, Meta meta) throws UnsupportedTypeException {
try {
Object metaObject = getMetaObjectOrThrow(value, interop);
String metaName = getMetaName(metaObject, interop);

// check if foreign exception
// check if there's a specific type mapping available
PolyglotTypeMappings.InternalTypeConverter internalConverter = lookupInternalTypeConverterNode.execute(metaName);
if (internalConverter != null) {
return internalConverter.convertInternal(interop, value, meta, converterToEspresso);
} else {
PolyglotTypeMappings.TypeConverter converter = lookupTypeConverterNode.execute(metaName);
if (converter != null) {
if (interop.isException(value)) {
return StaticObject.createForeignException(getContext(), value, interop);
return (StaticObject) converter.convert(StaticObject.createForeignException(converterToEspresso.getContext(), value, interop));
} else {
return (StaticObject) converter.convert(StaticObject.createForeign(converterToEspresso.getLanguage(), meta.java_lang_Object, value, interop));
}
// see if a generated proxy can be used for interface mapped types
WrappedProxyKlass proxyKlass = lookupProxyKlassNode.execute(metaObject, metaName, meta.java_lang_Object);
if (proxyKlass != null) {
return proxyKlass.createProxyInstance(value, getLanguage(), interop);
}

// check if foreign exception
if (interop.isException(value)) {
return StaticObject.createForeignException(converterToEspresso.getContext(), value, interop);
}
// see if a generated proxy can be used for interface mapped types
WrappedProxyKlass proxyKlass = lookupProxyKlassNode.execute(metaObject, metaName, meta.java_lang_Object);
if (proxyKlass != null) {
return proxyKlass.createProxyInstance(value, converterToEspresso.getLanguage(), interop);
}
return StaticObject.createForeign(converterToEspresso.getLanguage(), meta.java_lang_Object, value, interop);
}
} catch (ClassCastException e) {
errorProfile.enter();
throw UnsupportedTypeException.create(new Object[]{value},
EspressoError.format("Could not cast foreign object to %s: due to: %s", meta.java_lang_Object.getNameAsString(), e.getMessage()));
}
}

static StaticObject tryConverterForUnknownTarget(Object value, InteropLibrary interop, LookupTypeConverterNode lookupTypeConverterNode,
LookupInternalTypeConverterNode lookupInternalTypeConverterNode,
ToReference.DynamicToReference converterToEspresso, Meta meta) throws UnsupportedTypeException {
try {
Object metaObject = getMetaObjectOrThrow(value, interop);
String metaName = getMetaName(metaObject, interop);

// check if there's a specific type mapping available
PolyglotTypeMappings.InternalTypeConverter internalConverter = lookupInternalTypeConverterNode.execute(metaName);
if (internalConverter != null) {
return internalConverter.convertInternal(interop, value, meta, converterToEspresso);
} else {
PolyglotTypeMappings.TypeConverter converter = lookupTypeConverterNode.execute(metaName);
// check if foreign exception
boolean isException = interop.isException(value);
StaticObject foreignWrapper = isException ? StaticObject.createForeignException(converterToEspresso.getContext(), value, interop) : null;

if (converter != null) {
if (foreignWrapper == null) {
// not exception
foreignWrapper = StaticObject.createForeign(converterToEspresso.getLanguage(), meta.java_lang_Object, value, interop);
}
return StaticObject.createForeign(getLanguage(), meta.java_lang_Object, value, interop);
return (StaticObject) converter.convert(foreignWrapper);
}
} catch (ClassCastException e) {
errorProfile.enter();
throw UnsupportedTypeException.create(new Object[]{value},
EspressoError.format("Could not cast foreign object to %s: due to: %s", meta.java_lang_Object.getNameAsString(), e.getMessage()));
return foreignWrapper;

}
} catch (ClassCastException e) {
// fall through, since there was no converter available
}
return null;
}

@NodeInfo(shortName = "j.l.String target type")
Expand Down Expand Up @@ -2398,14 +2440,27 @@ public StaticObject doEspresso(StaticObject value) throws UnsupportedTypeExcepti
StaticObject doForeignWrapper(Object value,
@Cached.Shared("value") @CachedLibrary(limit = "LIMIT") InteropLibrary interop,
@SuppressWarnings("unused") @Bind("getContext()") EspressoContext context,
@Cached LookupTypeConverterNode lookupTypeConverterNode,
@Cached LookupInternalTypeConverterNode lookupInternalTypeConverterNode,
@Cached ToReference.DynamicToReference converterToEspresso,
@Cached InlinedBranchProfile unknownProfile,
@Cached InlinedBranchProfile noConverterProfile,
@Bind("getMeta()") Meta meta) throws UnsupportedTypeException {
ToReference uncachedToReference = getUncachedToReference(targetType, meta);
if (uncachedToReference != null) {
return uncachedToReference.execute(value);
}
unknownProfile.enter(this);
// hit the unknown type case, so inline generic handling for that here
StaticObject result = ToReference.tryConverterForUnknownTarget(value, interop, lookupTypeConverterNode, lookupInternalTypeConverterNode, converterToEspresso, meta);
if (result != null) {
return result;
}
try {
if (targetType.isInterface()) {
throw UnsupportedTypeException.create(new Object[]{value}, targetType.getTypeAsString());
}
checkHasAllFieldsOrThrow(value, targetType, interop, meta);
noConverterProfile.enter(this);
checkHasAllFieldsOrThrow(value, targetType, interop, getMeta());
return StaticObject.createForeign(getLanguage(), targetType, value, interop);
} catch (ClassCastException ex) {
} catch (ClassCastException e) {
throw UnsupportedTypeException.create(new Object[]{value}, targetType.getTypeAsString());
}
}
Expand Down

0 comments on commit 166a709

Please sign in to comment.