Skip to content

Commit 166a709

Browse files
javeleonelkorchi
authored andcommitted
make sure we attempt type converters for not otherwise directly mapped target types
(cherry picked from commit f4b024a)
1 parent a165ae8 commit 166a709

File tree

2 files changed

+98
-36
lines changed

2 files changed

+98
-36
lines changed

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/interop/ToEspressoNode.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@ public Object doInternalTypeConverter(Object value, Klass targetType,
264264
public Object doGeneric(Object value, Klass targetType,
265265
@Bind("getMeta()") Meta meta,
266266
@CachedLibrary(limit = "LIMIT") InteropLibrary interop,
267+
@Cached LookupTypeConverterNode lookupTypeConverterNode,
268+
@Cached LookupInternalTypeConverterNode lookupInternalTypeConverterNode,
269+
@Cached ToReference.DynamicToReference converterToEspresso,
267270
@Cached InlinedBranchProfile unknownProfile) throws UnsupportedTypeException {
268271
ToEspressoNode uncachedToEspresso = getUncachedToEspresso(targetType, meta);
269272
if (uncachedToEspresso != null) {
@@ -272,6 +275,10 @@ public Object doGeneric(Object value, Klass targetType,
272275
unknownProfile.enter(this);
273276
// hit the unknown type case, so inline generic handling for that here
274277
if (targetType instanceof ObjectKlass) {
278+
StaticObject result = ToReference.tryConverterForUnknownTarget(value, interop, lookupTypeConverterNode, lookupInternalTypeConverterNode, converterToEspresso, meta);
279+
if (result != null) {
280+
return result;
281+
}
275282
try {
276283
checkHasAllFieldsOrThrow(value, (ObjectKlass) targetType, interop, getMeta());
277284
return StaticObject.createForeign(getLanguage(), targetType, value, interop);

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/interop/ToReference.java

Lines changed: 91 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,10 @@ public StaticObject doInternalTypeConverter(Object value, @SuppressWarnings("unu
454454
public StaticObject doGeneric(Object value, Klass targetType,
455455
@Bind("getMeta()") Meta meta,
456456
@CachedLibrary(limit = "LIMIT") InteropLibrary interop,
457+
@Cached LookupTypeConverterNode lookupTypeConverterNode,
458+
@Cached LookupInternalTypeConverterNode lookupInternalTypeConverterNode,
459+
@Cached ToReference.DynamicToReference converterToEspresso,
460+
@Cached InlinedBranchProfile noConverterProfile,
457461
@Cached InlinedBranchProfile unknownProfile) throws UnsupportedTypeException {
458462
ToReference uncachedToReference = getUncachedToReference(targetType, meta);
459463
if (uncachedToReference != null) {
@@ -462,7 +466,12 @@ public StaticObject doGeneric(Object value, Klass targetType,
462466
unknownProfile.enter(this);
463467
// hit the unknown type case, so inline generic handling for that here
464468
if (targetType instanceof ObjectKlass) {
469+
StaticObject result = ToReference.tryConverterForUnknownTarget(value, interop, lookupTypeConverterNode, lookupInternalTypeConverterNode, converterToEspresso, meta);
470+
if (result != null) {
471+
return result;
472+
}
465473
try {
474+
noConverterProfile.enter(this);
466475
checkHasAllFieldsOrThrow(value, (ObjectKlass) targetType, interop, getMeta());
467476
return StaticObject.createForeign(getLanguage(), targetType, value, interop);
468477
} catch (ClassCastException e) {
@@ -1237,45 +1246,78 @@ StaticObject doForeignObject(Object value,
12371246
StaticObject doUnsupportedType(Object value) throws UnsupportedTypeException {
12381247
throw UnsupportedTypeException.create(new Object[]{value}, "java.lang.Object");
12391248
}
1249+
}
12401250

1241-
private StaticObject tryTypeConversion(Object value, InteropLibrary interop, LookupProxyKlassNode lookupProxyKlassNode, LookupTypeConverterNode lookupTypeConverterNode,
1242-
LookupInternalTypeConverterNode lookupInternalTypeConverterNode,
1243-
ToReference.DynamicToReference converterToEspresso, BranchProfile errorProfile, Meta meta) throws UnsupportedTypeException {
1244-
try {
1245-
Object metaObject = getMetaObjectOrThrow(value, interop);
1246-
String metaName = getMetaName(metaObject, interop);
1247-
1248-
// check if there's a specific type mapping available
1249-
PolyglotTypeMappings.InternalTypeConverter internalConverter = lookupInternalTypeConverterNode.execute(metaName);
1250-
if (internalConverter != null) {
1251-
return internalConverter.convertInternal(interop, value, meta, converterToEspresso);
1252-
} else {
1253-
PolyglotTypeMappings.TypeConverter converter = lookupTypeConverterNode.execute(metaName);
1254-
if (converter != null) {
1255-
if (interop.isException(value)) {
1256-
return (StaticObject) converter.convert(StaticObject.createForeignException(getContext(), value, interop));
1257-
} else {
1258-
return (StaticObject) converter.convert(StaticObject.createForeign(getLanguage(), meta.java_lang_Object, value, interop));
1259-
}
1260-
}
1251+
static StaticObject tryTypeConversion(Object value, InteropLibrary interop, LookupProxyKlassNode lookupProxyKlassNode, LookupTypeConverterNode lookupTypeConverterNode,
1252+
LookupInternalTypeConverterNode lookupInternalTypeConverterNode,
1253+
ToReference.DynamicToReference converterToEspresso, BranchProfile errorProfile, Meta meta) throws UnsupportedTypeException {
1254+
try {
1255+
Object metaObject = getMetaObjectOrThrow(value, interop);
1256+
String metaName = getMetaName(metaObject, interop);
12611257

1262-
// check if foreign exception
1258+
// check if there's a specific type mapping available
1259+
PolyglotTypeMappings.InternalTypeConverter internalConverter = lookupInternalTypeConverterNode.execute(metaName);
1260+
if (internalConverter != null) {
1261+
return internalConverter.convertInternal(interop, value, meta, converterToEspresso);
1262+
} else {
1263+
PolyglotTypeMappings.TypeConverter converter = lookupTypeConverterNode.execute(metaName);
1264+
if (converter != null) {
12631265
if (interop.isException(value)) {
1264-
return StaticObject.createForeignException(getContext(), value, interop);
1266+
return (StaticObject) converter.convert(StaticObject.createForeignException(converterToEspresso.getContext(), value, interop));
1267+
} else {
1268+
return (StaticObject) converter.convert(StaticObject.createForeign(converterToEspresso.getLanguage(), meta.java_lang_Object, value, interop));
12651269
}
1266-
// see if a generated proxy can be used for interface mapped types
1267-
WrappedProxyKlass proxyKlass = lookupProxyKlassNode.execute(metaObject, metaName, meta.java_lang_Object);
1268-
if (proxyKlass != null) {
1269-
return proxyKlass.createProxyInstance(value, getLanguage(), interop);
1270+
}
1271+
1272+
// check if foreign exception
1273+
if (interop.isException(value)) {
1274+
return StaticObject.createForeignException(converterToEspresso.getContext(), value, interop);
1275+
}
1276+
// see if a generated proxy can be used for interface mapped types
1277+
WrappedProxyKlass proxyKlass = lookupProxyKlassNode.execute(metaObject, metaName, meta.java_lang_Object);
1278+
if (proxyKlass != null) {
1279+
return proxyKlass.createProxyInstance(value, converterToEspresso.getLanguage(), interop);
1280+
}
1281+
return StaticObject.createForeign(converterToEspresso.getLanguage(), meta.java_lang_Object, value, interop);
1282+
}
1283+
} catch (ClassCastException e) {
1284+
errorProfile.enter();
1285+
throw UnsupportedTypeException.create(new Object[]{value},
1286+
EspressoError.format("Could not cast foreign object to %s: due to: %s", meta.java_lang_Object.getNameAsString(), e.getMessage()));
1287+
}
1288+
}
1289+
1290+
static StaticObject tryConverterForUnknownTarget(Object value, InteropLibrary interop, LookupTypeConverterNode lookupTypeConverterNode,
1291+
LookupInternalTypeConverterNode lookupInternalTypeConverterNode,
1292+
ToReference.DynamicToReference converterToEspresso, Meta meta) throws UnsupportedTypeException {
1293+
try {
1294+
Object metaObject = getMetaObjectOrThrow(value, interop);
1295+
String metaName = getMetaName(metaObject, interop);
1296+
1297+
// check if there's a specific type mapping available
1298+
PolyglotTypeMappings.InternalTypeConverter internalConverter = lookupInternalTypeConverterNode.execute(metaName);
1299+
if (internalConverter != null) {
1300+
return internalConverter.convertInternal(interop, value, meta, converterToEspresso);
1301+
} else {
1302+
PolyglotTypeMappings.TypeConverter converter = lookupTypeConverterNode.execute(metaName);
1303+
// check if foreign exception
1304+
boolean isException = interop.isException(value);
1305+
StaticObject foreignWrapper = isException ? StaticObject.createForeignException(converterToEspresso.getContext(), value, interop) : null;
1306+
1307+
if (converter != null) {
1308+
if (foreignWrapper == null) {
1309+
// not exception
1310+
foreignWrapper = StaticObject.createForeign(converterToEspresso.getLanguage(), meta.java_lang_Object, value, interop);
12701311
}
1271-
return StaticObject.createForeign(getLanguage(), meta.java_lang_Object, value, interop);
1312+
return (StaticObject) converter.convert(foreignWrapper);
12721313
}
1273-
} catch (ClassCastException e) {
1274-
errorProfile.enter();
1275-
throw UnsupportedTypeException.create(new Object[]{value},
1276-
EspressoError.format("Could not cast foreign object to %s: due to: %s", meta.java_lang_Object.getNameAsString(), e.getMessage()));
1314+
return foreignWrapper;
1315+
12771316
}
1317+
} catch (ClassCastException e) {
1318+
// fall through, since there was no converter available
12781319
}
1320+
return null;
12791321
}
12801322

12811323
@NodeInfo(shortName = "j.l.String target type")
@@ -2398,14 +2440,27 @@ public StaticObject doEspresso(StaticObject value) throws UnsupportedTypeExcepti
23982440
StaticObject doForeignWrapper(Object value,
23992441
@Cached.Shared("value") @CachedLibrary(limit = "LIMIT") InteropLibrary interop,
24002442
@SuppressWarnings("unused") @Bind("getContext()") EspressoContext context,
2443+
@Cached LookupTypeConverterNode lookupTypeConverterNode,
2444+
@Cached LookupInternalTypeConverterNode lookupInternalTypeConverterNode,
2445+
@Cached ToReference.DynamicToReference converterToEspresso,
2446+
@Cached InlinedBranchProfile unknownProfile,
2447+
@Cached InlinedBranchProfile noConverterProfile,
24012448
@Bind("getMeta()") Meta meta) throws UnsupportedTypeException {
2449+
ToReference uncachedToReference = getUncachedToReference(targetType, meta);
2450+
if (uncachedToReference != null) {
2451+
return uncachedToReference.execute(value);
2452+
}
2453+
unknownProfile.enter(this);
2454+
// hit the unknown type case, so inline generic handling for that here
2455+
StaticObject result = ToReference.tryConverterForUnknownTarget(value, interop, lookupTypeConverterNode, lookupInternalTypeConverterNode, converterToEspresso, meta);
2456+
if (result != null) {
2457+
return result;
2458+
}
24022459
try {
2403-
if (targetType.isInterface()) {
2404-
throw UnsupportedTypeException.create(new Object[]{value}, targetType.getTypeAsString());
2405-
}
2406-
checkHasAllFieldsOrThrow(value, targetType, interop, meta);
2460+
noConverterProfile.enter(this);
2461+
checkHasAllFieldsOrThrow(value, targetType, interop, getMeta());
24072462
return StaticObject.createForeign(getLanguage(), targetType, value, interop);
2408-
} catch (ClassCastException ex) {
2463+
} catch (ClassCastException e) {
24092464
throw UnsupportedTypeException.create(new Object[]{value}, targetType.getTypeAsString());
24102465
}
24112466
}

0 commit comments

Comments
 (0)