53
53
import com .oracle .graal .python .builtins .objects .cext .CExtNodes .MaterializeDelegateNode ;
54
54
import com .oracle .graal .python .builtins .objects .cext .CExtNodes .ToJavaNode ;
55
55
import com .oracle .graal .python .builtins .objects .cext .CExtNodes .ToSulongNode ;
56
+ import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .BoolNativeWrapper ;
56
57
import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .DynamicObjectNativeWrapper ;
57
58
import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .PySequenceArrayWrapper ;
58
59
import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .PyUnicodeData ;
61
62
import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .PythonNativeWrapper ;
62
63
import com .oracle .graal .python .builtins .objects .cext .NativeWrappers .PythonObjectNativeWrapper ;
63
64
import com .oracle .graal .python .builtins .objects .cext .PythonObjectNativeWrapperMRFactory .PAsPointerNodeGen ;
65
+ import com .oracle .graal .python .builtins .objects .cext .PythonObjectNativeWrapperMRFactory .PIsPointerNodeGen ;
64
66
import com .oracle .graal .python .builtins .objects .cext .PythonObjectNativeWrapperMRFactory .ReadNativeMemberNodeGen ;
65
67
import com .oracle .graal .python .builtins .objects .cext .PythonObjectNativeWrapperMRFactory .ToPyObjectNodeGen ;
66
68
import com .oracle .graal .python .builtins .objects .cext .PythonObjectNativeWrapperMRFactory .WriteNativeMemberNodeGen ;
73
75
import com .oracle .graal .python .builtins .objects .common .SequenceStorageNodes ;
74
76
import com .oracle .graal .python .builtins .objects .dict .PDict ;
75
77
import com .oracle .graal .python .builtins .objects .floats .PFloat ;
78
+ import com .oracle .graal .python .builtins .objects .ints .PInt ;
76
79
import com .oracle .graal .python .builtins .objects .mappingproxy .PMappingproxy ;
77
80
import com .oracle .graal .python .builtins .objects .memoryview .PBuffer ;
78
81
import com .oracle .graal .python .builtins .objects .memoryview .PMemoryView ;
@@ -259,11 +262,13 @@ Object doObStart(PByteArray object, @SuppressWarnings("unused") String key) {
259
262
}
260
263
261
264
@ Specialization (guards = "eq(OB_FVAL, key)" )
262
- Object doObFval (PythonObject object , @ SuppressWarnings ("unused" ) String key ,
265
+ Object doObFval (Object object , @ SuppressWarnings ("unused" ) String key ,
263
266
@ Cached ("createClassProfile()" ) ValueProfile profile ) {
264
267
Object profiled = profile .profile (object );
265
268
if (profiled instanceof PFloat ) {
266
269
return ((PFloat ) profiled ).getValue ();
270
+ } else if (profiled instanceof Double ) {
271
+ return object ;
267
272
}
268
273
throw UnsupportedMessageException .raise (Message .READ );
269
274
}
@@ -442,7 +447,7 @@ Object doState(PString object, @SuppressWarnings("unused") String key) {
442
447
}
443
448
444
449
@ Specialization (guards = "eq(MD_DICT, key)" )
445
- Object doMdDict (PythonObject object , @ SuppressWarnings ("unused" ) String key ,
450
+ Object doMdDict (Object object , @ SuppressWarnings ("unused" ) String key ,
446
451
@ Cached ("create(__GETATTRIBUTE__)" ) LookupAndCallBinaryNode getDictNode ) {
447
452
return getToSulongNode ().execute (getDictNode .executeObject (object , SpecialAttributeNames .__DICT__ ));
448
453
}
@@ -834,29 +839,48 @@ public Object access(Object object) {
834
839
835
840
@ Resolve (message = "TO_NATIVE" )
836
841
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 ();
839
845
840
846
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 ));
843
849
}
844
850
return obj ;
845
851
}
846
852
847
853
Object access (PythonNativeWrapper obj ) {
848
854
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 )));
851
857
}
852
858
return obj ;
853
859
}
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
+ }
854
876
}
855
877
856
878
@ Resolve (message = "IS_POINTER" )
857
879
abstract static class IsPointerNode extends Node {
880
+ @ Child private PIsPointerNode pIsPointerNode = PIsPointerNode .create ();
881
+
858
882
boolean access (PythonNativeWrapper obj ) {
859
- return obj . isNative ( );
883
+ return pIsPointerNode . execute ( obj );
860
884
}
861
885
}
862
886
@@ -869,16 +893,60 @@ long access(PythonNativeWrapper obj) {
869
893
}
870
894
}
871
895
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
+
872
919
abstract static class PAsPointerNode extends PBaseNode {
873
920
@ Child private Node asPointerNode ;
874
921
875
922
public abstract long execute (PythonNativeWrapper o );
876
923
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)" )
878
939
long doFast (PythonNativeWrapper obj ) {
879
940
// 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 ));
882
950
}
883
951
884
952
private long ensureLong (Object nativePointer ) {
@@ -890,16 +958,15 @@ private long ensureLong(Object nativePointer) {
890
958
try {
891
959
return ForeignAccess .sendAsPointer (asPointerNode , (TruffleObject ) nativePointer );
892
960
} catch (UnsupportedMessageException e ) {
961
+ CompilerDirectives .transferToInterpreter ();
893
962
throw e .raise ();
894
963
}
895
964
}
896
965
return (long ) nativePointer ;
897
966
}
898
967
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 ;
903
970
}
904
971
905
972
protected Assumption getSingleNativeContextAssumption () {
@@ -909,7 +976,61 @@ protected Assumption getSingleNativeContextAssumption() {
909
976
public static PAsPointerNode create () {
910
977
return PAsPointerNodeGen .create ();
911
978
}
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
+ }
912
1018
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
+ }
913
1034
}
914
1035
915
1036
abstract static class ToPyObjectNode extends CExtBaseNode {
0 commit comments