@@ -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