@@ -454,6 +454,10 @@ public StaticObject doInternalTypeConverter(Object value, @SuppressWarnings("unu
454
454
public StaticObject doGeneric (Object value , Klass targetType ,
455
455
@ Bind ("getMeta()" ) Meta meta ,
456
456
@ CachedLibrary (limit = "LIMIT" ) InteropLibrary interop ,
457
+ @ Cached LookupTypeConverterNode lookupTypeConverterNode ,
458
+ @ Cached LookupInternalTypeConverterNode lookupInternalTypeConverterNode ,
459
+ @ Cached ToReference .DynamicToReference converterToEspresso ,
460
+ @ Cached InlinedBranchProfile noConverterProfile ,
457
461
@ Cached InlinedBranchProfile unknownProfile ) throws UnsupportedTypeException {
458
462
ToReference uncachedToReference = getUncachedToReference (targetType , meta );
459
463
if (uncachedToReference != null ) {
@@ -462,7 +466,12 @@ public StaticObject doGeneric(Object value, Klass targetType,
462
466
unknownProfile .enter (this );
463
467
// hit the unknown type case, so inline generic handling for that here
464
468
if (targetType instanceof ObjectKlass ) {
469
+ StaticObject result = ToReference .tryConverterForUnknownTarget (value , interop , lookupTypeConverterNode , lookupInternalTypeConverterNode , converterToEspresso , meta );
470
+ if (result != null ) {
471
+ return result ;
472
+ }
465
473
try {
474
+ noConverterProfile .enter (this );
466
475
checkHasAllFieldsOrThrow (value , (ObjectKlass ) targetType , interop , getMeta ());
467
476
return StaticObject .createForeign (getLanguage (), targetType , value , interop );
468
477
} catch (ClassCastException e ) {
@@ -1237,45 +1246,78 @@ StaticObject doForeignObject(Object value,
1237
1246
StaticObject doUnsupportedType (Object value ) throws UnsupportedTypeException {
1238
1247
throw UnsupportedTypeException .create (new Object []{value }, "java.lang.Object" );
1239
1248
}
1249
+ }
1240
1250
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 );
1261
1257
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 ) {
1263
1265
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 ));
1265
1269
}
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 );
1270
1311
}
1271
- return StaticObject . createForeign ( getLanguage (), meta . java_lang_Object , value , interop );
1312
+ return ( StaticObject ) converter . convert ( foreignWrapper );
1272
1313
}
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
+
1277
1316
}
1317
+ } catch (ClassCastException e ) {
1318
+ // fall through, since there was no converter available
1278
1319
}
1320
+ return null ;
1279
1321
}
1280
1322
1281
1323
@ NodeInfo (shortName = "j.l.String target type" )
@@ -2398,14 +2440,27 @@ public StaticObject doEspresso(StaticObject value) throws UnsupportedTypeExcepti
2398
2440
StaticObject doForeignWrapper (Object value ,
2399
2441
@ Cached .Shared ("value" ) @ CachedLibrary (limit = "LIMIT" ) InteropLibrary interop ,
2400
2442
@ 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 ,
2401
2448
@ 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
+ }
2402
2459
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 ());
2407
2462
return StaticObject .createForeign (getLanguage (), targetType , value , interop );
2408
- } catch (ClassCastException ex ) {
2463
+ } catch (ClassCastException e ) {
2409
2464
throw UnsupportedTypeException .create (new Object []{value }, targetType .getTypeAsString ());
2410
2465
}
2411
2466
}
0 commit comments