52
52
import com .oracle .graal .python .builtins .objects .cext .CExtNodesFactory .AsPythonObjectNodeGen ;
53
53
import com .oracle .graal .python .builtins .objects .cext .CExtNodesFactory .CextUpcallNodeGen ;
54
54
import com .oracle .graal .python .builtins .objects .cext .CExtNodesFactory .GetNativeClassNodeGen ;
55
+ import com .oracle .graal .python .builtins .objects .cext .CExtNodesFactory .MaterializeDelegateNodeGen ;
55
56
import com .oracle .graal .python .builtins .objects .cext .CExtNodesFactory .ObjectUpcallNodeGen ;
56
57
import com .oracle .graal .python .builtins .objects .cext .CExtNodesFactory .ToJavaNodeGen ;
57
58
import com .oracle .graal .python .builtins .objects .cext .CExtNodesFactory .ToSulongNodeGen ;
59
+ import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .ByteNativeWrapper ;
60
+ import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .DoubleNativeWrapper ;
61
+ import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .IntNativeWrapper ;
62
+ import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .LongNativeWrapper ;
63
+ import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .PrimitiveNativeWrapper ;
58
64
import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .PythonClassNativeWrapper ;
59
65
import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .PythonNativeWrapper ;
60
66
import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .PythonObjectNativeWrapper ;
98
104
import com .oracle .truffle .api .nodes .ExplodeLoop ;
99
105
import com .oracle .truffle .api .nodes .Node ;
100
106
import com .oracle .truffle .api .profiles .BranchProfile ;
107
+ import com .oracle .truffle .api .profiles .ConditionProfile ;
101
108
102
109
public abstract class CExtNodes {
103
110
@@ -237,28 +244,31 @@ public abstract static class ToSulongNode extends CExtBaseNode {
237
244
* passed from Python into C code need to wrap Strings into PStrings.
238
245
*/
239
246
@ Specialization
240
- Object doString (String str ) {
241
- return PythonObjectNativeWrapper .wrap (factory ().createString (str ));
247
+ Object doString (String str ,
248
+ @ Cached ("createBinaryProfile()" ) ConditionProfile noWrapperProfile ) {
249
+ return PythonObjectNativeWrapper .wrap (factory ().createString (str ), noWrapperProfile );
242
250
}
243
251
244
252
@ Specialization
245
- Object doBoolean (boolean b ) {
246
- return PythonObjectNativeWrapper .wrap (factory ().createInt (b ));
253
+ Object doBoolean (boolean b ,
254
+ @ Cached ("createBinaryProfile()" ) ConditionProfile noWrapperProfile ) {
255
+ return PythonObjectNativeWrapper .wrap (factory ().createInt (b ), noWrapperProfile );
247
256
}
248
257
249
258
@ Specialization
250
259
Object doInteger (int i ) {
251
- return PythonObjectNativeWrapper . wrap ( factory (). createInt ( i ) );
260
+ return IntNativeWrapper . create ( i );
252
261
}
253
262
254
263
@ Specialization
255
264
Object doLong (long l ) {
256
- return PythonObjectNativeWrapper . wrap ( factory (). createInt ( l ) );
265
+ return LongNativeWrapper . create ( l );
257
266
}
258
267
259
268
@ Specialization
260
- Object doDouble (double d ) {
261
- return PythonObjectNativeWrapper .wrap (factory ().createFloat (d ));
269
+ Object doDouble (double d ,
270
+ @ Cached ("createBinaryProfile()" ) ConditionProfile noWrapperProfile ) {
271
+ return PythonObjectNativeWrapper .wrap (factory ().createFloat (d ), noWrapperProfile );
262
272
}
263
273
264
274
@ Specialization
@@ -278,15 +288,17 @@ Object doPythonClass(PythonClass object) {
278
288
279
289
@ Specialization (guards = {"cachedClass == object.getClass()" , "!isPythonClass(object)" , "!isNativeObject(object)" , "!isNoValue(object)" }, limit = "3" )
280
290
Object runAbstractObjectCached (PythonAbstractObject object ,
291
+ @ Cached ("createBinaryProfile()" ) ConditionProfile noWrapperProfile ,
281
292
@ Cached ("object.getClass()" ) Class <? extends PythonAbstractObject > cachedClass ) {
282
293
assert object != PNone .NO_VALUE ;
283
- return PythonObjectNativeWrapper .wrap (CompilerDirectives .castExact (object , cachedClass ));
294
+ return PythonObjectNativeWrapper .wrap (CompilerDirectives .castExact (object , cachedClass ), noWrapperProfile );
284
295
}
285
296
286
297
@ Specialization (guards = {"!isPythonClass(object)" , "!isNativeObject(object)" , "!isNoValue(object)" }, replaces = "runAbstractObjectCached" )
287
- Object runAbstractObject (PythonAbstractObject object ) {
298
+ Object runAbstractObject (PythonAbstractObject object ,
299
+ @ Cached ("createBinaryProfile()" ) ConditionProfile noWrapperProfile ) {
288
300
assert object != PNone .NO_VALUE ;
289
- return PythonObjectNativeWrapper .wrap (object );
301
+ return PythonObjectNativeWrapper .wrap (object , noWrapperProfile );
290
302
}
291
303
292
304
@ Specialization (guards = {"isForeignObject(object)" , "!isNativeWrapper(object)" })
@@ -326,13 +338,33 @@ public abstract static class AsPythonObjectNode extends CExtBaseNode {
326
338
327
339
@ Child GetClassNode getClassNode ;
328
340
329
- @ Specialization (guards = "object.getClass() == cachedClass" , limit = "3" )
341
+ @ Specialization (guards = "!isMaterialized(object)" )
342
+ byte doByteNativeWrapper (ByteNativeWrapper object ) {
343
+ return object .getValue ();
344
+ }
345
+
346
+ @ Specialization (guards = "!isMaterialized(object)" )
347
+ int doIntNativeWrapper (IntNativeWrapper object ) {
348
+ return object .getValue ();
349
+ }
350
+
351
+ @ Specialization (guards = "!isMaterialized(object)" )
352
+ long doLongNativeWrapper (LongNativeWrapper object ) {
353
+ return object .getValue ();
354
+ }
355
+
356
+ @ Specialization (guards = "!isMaterialized(object)" )
357
+ double doDoubleNativeWrapper (DoubleNativeWrapper object ) {
358
+ return object .getValue ();
359
+ }
360
+
361
+ @ Specialization (guards = {"!isPrimitiveNativeWrapper(object)" , "object.getClass() == cachedClass" }, limit = "3" )
330
362
Object doNativeWrapper (PythonNativeWrapper object ,
331
363
@ SuppressWarnings ("unused" ) @ Cached ("object.getClass()" ) Class <? extends PythonNativeWrapper > cachedClass ) {
332
364
return CompilerDirectives .castExact (object , cachedClass ).getDelegate ();
333
365
}
334
366
335
- @ Specialization (replaces = "doNativeWrapper" )
367
+ @ Specialization (guards = "!isPrimitiveNativeWrapper(object)" , replaces = "doNativeWrapper" )
336
368
Object doNativeWrapperGeneric (PythonNativeWrapper object ) {
337
369
return object .getDelegate ();
338
370
}
@@ -377,6 +409,10 @@ Object run(Object obj) {
377
409
throw raise (PythonErrorType .SystemError , "invalid object from native: %s" , obj );
378
410
}
379
411
412
+ protected static boolean isPrimitiveNativeWrapper (PythonNativeWrapper object ) {
413
+ return object instanceof PrimitiveNativeWrapper && !isMaterialized ((PrimitiveNativeWrapper ) object );
414
+ }
415
+
380
416
protected boolean isForeignObject (TruffleObject obj ) {
381
417
// TODO we could probably also just use 'PGuards.isForeignObject'
382
418
if (getClassNode == null ) {
@@ -386,6 +422,10 @@ protected boolean isForeignObject(TruffleObject obj) {
386
422
return getClassNode .execute (obj ) == getCore ().lookupType (PythonBuiltinClassType .TruffleObject );
387
423
}
388
424
425
+ protected static boolean isMaterialized (PrimitiveNativeWrapper wrapper ) {
426
+ return wrapper .getMaterializedObject () != null ;
427
+ }
428
+
389
429
@ TruffleBoundary
390
430
public static Object doSlowPath (PythonCore core , Object object ) {
391
431
if (object instanceof PythonNativeWrapper ) {
@@ -401,6 +441,63 @@ public static AsPythonObjectNode create() {
401
441
}
402
442
}
403
443
444
+ /**
445
+ * Materializes a primitive value of a primitive native wrapper to ensure pointer equality.
446
+ */
447
+ public abstract static class MaterializeDelegateNode extends CExtBaseNode {
448
+
449
+ public abstract Object execute (PythonNativeWrapper object );
450
+
451
+ @ Child GetClassNode getClassNode ;
452
+
453
+ @ Specialization
454
+ PInt doByteNativeWrapper (ByteNativeWrapper object ) {
455
+ PInt materializedInt = factory ().createInt (object .getValue ());
456
+ object .setMaterializedObject (materializedInt );
457
+ return materializedInt ;
458
+ }
459
+
460
+ @ Specialization
461
+ PInt doIntNativeWrapper (IntNativeWrapper object ) {
462
+ PInt materializedInt = factory ().createInt (object .getValue ());
463
+ object .setMaterializedObject (materializedInt );
464
+ return materializedInt ;
465
+ }
466
+
467
+ @ Specialization
468
+ PInt doLongNativeWrapper (LongNativeWrapper object ) {
469
+ PInt materializedInt = factory ().createInt (object .getValue ());
470
+ object .setMaterializedObject (materializedInt );
471
+ return materializedInt ;
472
+ }
473
+
474
+ @ Specialization
475
+ PFloat doDoubleNativeWrapper (DoubleNativeWrapper object ) {
476
+ PFloat materializedInt = factory ().createFloat (object .getValue ());
477
+ object .setMaterializedObject (materializedInt );
478
+ return materializedInt ;
479
+ }
480
+
481
+ @ Specialization (guards = {"!isPrimitiveNativeWrapper(object)" , "object.getClass() == cachedClass" }, limit = "3" )
482
+ Object doNativeWrapper (PythonNativeWrapper object ,
483
+ @ SuppressWarnings ("unused" ) @ Cached ("object.getClass()" ) Class <? extends PythonNativeWrapper > cachedClass ) {
484
+ return CompilerDirectives .castExact (object , cachedClass ).getDelegate ();
485
+ }
486
+
487
+ @ Specialization (guards = "!isPrimitiveNativeWrapper(object)" , replaces = "doNativeWrapper" )
488
+ Object doNativeWrapperGeneric (PythonNativeWrapper object ) {
489
+ return object .getDelegate ();
490
+ }
491
+
492
+ protected static boolean isPrimitiveNativeWrapper (PythonNativeWrapper object ) {
493
+ return object instanceof PrimitiveNativeWrapper ;
494
+ }
495
+
496
+ public static MaterializeDelegateNode create () {
497
+ return MaterializeDelegateNodeGen .create ();
498
+ }
499
+ }
500
+
404
501
/**
405
502
* Does the same conversion as the native function {@code to_java}. The node tries to avoid
406
503
* calling the native function for resolving native handles.
@@ -925,6 +1022,16 @@ long run(PFloat value) {
925
1022
return (long ) value .getValue ();
926
1023
}
927
1024
1025
+ @ Specialization
1026
+ long doIntNativeWrapper (IntNativeWrapper object ) {
1027
+ return object .getValue ();
1028
+ }
1029
+
1030
+ @ Specialization
1031
+ long doLongNativeWrapper (LongNativeWrapper object ) {
1032
+ return object .getValue ();
1033
+ }
1034
+
928
1035
@ Specialization
929
1036
long run (PythonNativeWrapper value ,
930
1037
@ Cached ("create()" ) AsLong recursive ) {
0 commit comments