5353import com .oracle .graal .python .builtins .objects .cext .CExtNodes .MaterializeDelegateNode ;
5454import com .oracle .graal .python .builtins .objects .cext .CExtNodes .ToJavaNode ;
5555import com .oracle .graal .python .builtins .objects .cext .CExtNodes .ToSulongNode ;
56+ import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .BoolNativeWrapper ;
5657import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .DynamicObjectNativeWrapper ;
5758import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .PySequenceArrayWrapper ;
5859import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .PyUnicodeData ;
6162import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .PythonNativeWrapper ;
6263import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .PythonObjectNativeWrapper ;
6364import com .oracle .graal .python .builtins .objects .cext .PythonObjectNativeWrapperMRFactory .PAsPointerNodeGen ;
65+ import com .oracle .graal .python .builtins .objects .cext .PythonObjectNativeWrapperMRFactory .PIsPointerNodeGen ;
6466import com .oracle .graal .python .builtins .objects .cext .PythonObjectNativeWrapperMRFactory .ReadNativeMemberNodeGen ;
6567import com .oracle .graal .python .builtins .objects .cext .PythonObjectNativeWrapperMRFactory .ToPyObjectNodeGen ;
6668import com .oracle .graal .python .builtins .objects .cext .PythonObjectNativeWrapperMRFactory .WriteNativeMemberNodeGen ;
7375import com .oracle .graal .python .builtins .objects .common .SequenceStorageNodes ;
7476import com .oracle .graal .python .builtins .objects .dict .PDict ;
7577import com .oracle .graal .python .builtins .objects .floats .PFloat ;
78+ import com .oracle .graal .python .builtins .objects .ints .PInt ;
7679import com .oracle .graal .python .builtins .objects .mappingproxy .PMappingproxy ;
7780import com .oracle .graal .python .builtins .objects .memoryview .PBuffer ;
7881import com .oracle .graal .python .builtins .objects .memoryview .PMemoryView ;
@@ -259,11 +262,13 @@ Object doObStart(PByteArray object, @SuppressWarnings("unused") String key) {
259262 }
260263
261264 @ Specialization (guards = "eq(OB_FVAL, key)" )
262- Object doObFval (PythonObject object , @ SuppressWarnings ("unused" ) String key ,
265+ Object doObFval (Object object , @ SuppressWarnings ("unused" ) String key ,
263266 @ Cached ("createClassProfile()" ) ValueProfile profile ) {
264267 Object profiled = profile .profile (object );
265268 if (profiled instanceof PFloat ) {
266269 return ((PFloat ) profiled ).getValue ();
270+ } else if (profiled instanceof Double ) {
271+ return object ;
267272 }
268273 throw UnsupportedMessageException .raise (Message .READ );
269274 }
@@ -442,7 +447,7 @@ Object doState(PString object, @SuppressWarnings("unused") String key) {
442447 }
443448
444449 @ Specialization (guards = "eq(MD_DICT, key)" )
445- Object doMdDict (PythonObject object , @ SuppressWarnings ("unused" ) String key ,
450+ Object doMdDict (Object object , @ SuppressWarnings ("unused" ) String key ,
446451 @ Cached ("create(__GETATTRIBUTE__)" ) LookupAndCallBinaryNode getDictNode ) {
447452 return getToSulongNode ().execute (getDictNode .executeObject (object , SpecialAttributeNames .__DICT__ ));
448453 }
@@ -834,29 +839,48 @@ public Object access(Object object) {
834839
835840 @ Resolve (message = "TO_NATIVE" )
836841 abstract static class ToNativeNode extends Node {
837- @ Child private ToPyObjectNode toPyObjectNode = ToPyObjectNode .create ();
838- @ Child private MaterializeDelegateNode materializeNode = MaterializeDelegateNode .create ();
842+ @ Child private ToPyObjectNode toPyObjectNode ;
843+ @ Child private MaterializeDelegateNode materializeNode ;
844+ @ Child private PIsPointerNode pIsPointerNode = PIsPointerNode .create ();
839845
840846 Object access (PythonClassInitNativeWrapper obj ) {
841- if (!obj . isNative ( )) {
842- obj .setNativePointer (toPyObjectNode .getHandleForObject (materializeNode .execute (obj ), 0 ));
847+ if (!pIsPointerNode . execute ( obj )) {
848+ obj .setNativePointer (getToPyObjectNode () .getHandleForObject (getMaterializeDelegateNode () .execute (obj ), 0 ));
843849 }
844850 return obj ;
845851 }
846852
847853 Object access (PythonNativeWrapper obj ) {
848854 assert !(obj instanceof PythonClassInitNativeWrapper );
849- if (!obj . isNative ( )) {
850- obj .setNativePointer (toPyObjectNode .execute (materializeNode .execute (obj )));
855+ if (!pIsPointerNode . execute ( obj )) {
856+ obj .setNativePointer (getToPyObjectNode () .execute (getMaterializeDelegateNode () .execute (obj )));
851857 }
852858 return obj ;
853859 }
860+
861+ private MaterializeDelegateNode getMaterializeDelegateNode () {
862+ if (materializeNode == null ) {
863+ CompilerDirectives .transferToInterpreterAndInvalidate ();
864+ materializeNode = insert (MaterializeDelegateNode .create ());
865+ }
866+ return materializeNode ;
867+ }
868+
869+ private ToPyObjectNode getToPyObjectNode () {
870+ if (toPyObjectNode == null ) {
871+ CompilerDirectives .transferToInterpreterAndInvalidate ();
872+ toPyObjectNode = insert (ToPyObjectNode .create ());
873+ }
874+ return toPyObjectNode ;
875+ }
854876 }
855877
856878 @ Resolve (message = "IS_POINTER" )
857879 abstract static class IsPointerNode extends Node {
880+ @ Child private PIsPointerNode pIsPointerNode = PIsPointerNode .create ();
881+
858882 boolean access (PythonNativeWrapper obj ) {
859- return obj . isNative ( );
883+ return pIsPointerNode . execute ( obj );
860884 }
861885 }
862886
@@ -869,16 +893,60 @@ long access(PythonNativeWrapper obj) {
869893 }
870894 }
871895
896+ abstract static class PIsPointerNode extends PBaseNode {
897+
898+ public abstract boolean execute (PythonNativeWrapper obj );
899+
900+ @ Specialization (guards = "!obj.isNative()" )
901+ boolean doBool (BoolNativeWrapper obj ) {
902+ // Special case: Booleans are singletons, so we need to check if the singletons have
903+ // native wrappers associated and if they are already native.
904+ PInt boxed = factory ().createInt (obj .getValue ());
905+ DynamicObjectNativeWrapper nativeWrapper = boxed .getNativeWrapper ();
906+ return nativeWrapper != null && nativeWrapper .isNative ();
907+ }
908+
909+ @ Fallback
910+ boolean doBool (PythonNativeWrapper obj ) {
911+ return obj .isNative ();
912+ }
913+
914+ private static PIsPointerNode create () {
915+ return PIsPointerNodeGen .create ();
916+ }
917+ }
918+
872919 abstract static class PAsPointerNode extends PBaseNode {
873920 @ Child private Node asPointerNode ;
874921
875922 public abstract long execute (PythonNativeWrapper o );
876923
877- @ Specialization (assumptions = "getSingleNativeContextAssumption()" )
924+ @ Specialization (assumptions = "getSingleNativeContextAssumption()" , guards = "!obj.isNative()" )
925+ long doBoolNotNative (BoolNativeWrapper obj ,
926+ @ Cached ("create()" ) MaterializeDelegateNode materializeNode ) {
927+ // special case for True and False singletons
928+ PInt boxed = (PInt ) materializeNode .execute (obj );
929+ assert obj .getNativePointer () == boxed .getNativeWrapper ().getNativePointer ();
930+ return doFast (obj );
931+ }
932+
933+ @ Specialization (assumptions = "getSingleNativeContextAssumption()" , guards = "obj.isNative()" )
934+ long doBoolNative (BoolNativeWrapper obj ) {
935+ return doFast (obj );
936+ }
937+
938+ @ Specialization (assumptions = "getSingleNativeContextAssumption()" , guards = "!isBoolNativeWrapper(obj)" )
878939 long doFast (PythonNativeWrapper obj ) {
879940 // the native pointer object must either be a TruffleObject or a primitive
880- Object nativePointer = obj .getNativePointer ();
881- return ensureLong (nativePointer );
941+ return ensureLong (obj .getNativePointer ());
942+ }
943+
944+ @ Specialization (replaces = {"doFast" , "doBoolNotNative" , "doBoolNative" })
945+ long doGenericSlow (PythonNativeWrapper obj ,
946+ @ Cached ("create()" ) MaterializeDelegateNode materializeNode ,
947+ @ Cached ("create()" ) ToPyObjectNode toPyObjectNode ) {
948+ Object materialized = materializeNode .execute (obj );
949+ return ensureLong (toPyObjectNode .execute (materialized ));
882950 }
883951
884952 private long ensureLong (Object nativePointer ) {
@@ -890,16 +958,15 @@ private long ensureLong(Object nativePointer) {
890958 try {
891959 return ForeignAccess .sendAsPointer (asPointerNode , (TruffleObject ) nativePointer );
892960 } catch (UnsupportedMessageException e ) {
961+ CompilerDirectives .transferToInterpreter ();
893962 throw e .raise ();
894963 }
895964 }
896965 return (long ) nativePointer ;
897966 }
898967
899- @ Specialization (replaces = "doFast" )
900- long doSlow (PythonNativeWrapper obj ,
901- @ Cached ("create()" ) ToPyObjectNode toPyObjectNode ) {
902- return ensureLong (toPyObjectNode .execute (obj ));
968+ protected static boolean isBoolNativeWrapper (Object obj ) {
969+ return obj instanceof BoolNativeWrapper ;
903970 }
904971
905972 protected Assumption getSingleNativeContextAssumption () {
@@ -909,7 +976,61 @@ protected Assumption getSingleNativeContextAssumption() {
909976 public static PAsPointerNode create () {
910977 return PAsPointerNodeGen .create ();
911978 }
979+ }
980+
981+ abstract static class PToNativeNode extends PBaseNode {
982+ @ Child private ToPyObjectNode toPyObjectNode ;
983+ @ Child private MaterializeDelegateNode materializeNode ;
984+ @ Child private PIsPointerNode pIsPointerNode = PIsPointerNode .create ();
985+
986+ public abstract PythonNativeWrapper execute (PythonNativeWrapper obj );
987+
988+ @ Specialization
989+ PythonNativeWrapper doInitClass (PythonClassInitNativeWrapper obj ) {
990+ if (!pIsPointerNode .execute (obj )) {
991+ obj .setNativePointer (getToPyObjectNode ().getHandleForObject (getMaterializeDelegateNode ().execute (obj ), 0 ));
992+ }
993+ return obj ;
994+ }
995+
996+ @ Specialization
997+ PythonNativeWrapper doBool (BoolNativeWrapper obj ) {
998+ if (!pIsPointerNode .execute (obj )) {
999+ PInt materialized = (PInt ) getMaterializeDelegateNode ().execute (obj );
1000+ obj .setNativePointer (getToPyObjectNode ().execute (materialized ));
1001+ if (!materialized .getNativeWrapper ().isNative ()) {
1002+ assert materialized .getNativeWrapper () != obj ;
1003+ materialized .getNativeWrapper ().setNativePointer (obj .getNativePointer ());
1004+ }
1005+ assert obj .getNativePointer () == materialized .getNativeWrapper ().getNativePointer ();
1006+ }
1007+ return obj ;
1008+ }
1009+
1010+ @ Fallback
1011+ PythonNativeWrapper doGeneric (PythonNativeWrapper obj ) {
1012+ assert !(obj instanceof PythonClassInitNativeWrapper );
1013+ if (!pIsPointerNode .execute (obj )) {
1014+ obj .setNativePointer (getToPyObjectNode ().execute (getMaterializeDelegateNode ().execute (obj )));
1015+ }
1016+ return obj ;
1017+ }
9121018
1019+ private MaterializeDelegateNode getMaterializeDelegateNode () {
1020+ if (materializeNode == null ) {
1021+ CompilerDirectives .transferToInterpreterAndInvalidate ();
1022+ materializeNode = insert (MaterializeDelegateNode .create ());
1023+ }
1024+ return materializeNode ;
1025+ }
1026+
1027+ private ToPyObjectNode getToPyObjectNode () {
1028+ if (toPyObjectNode == null ) {
1029+ CompilerDirectives .transferToInterpreterAndInvalidate ();
1030+ toPyObjectNode = insert (ToPyObjectNode .create ());
1031+ }
1032+ return toPyObjectNode ;
1033+ }
9131034 }
9141035
9151036 abstract static class ToPyObjectNode extends CExtBaseNode {
0 commit comments