71
71
import com .oracle .graal .python .builtins .objects .PythonAbstractObject .PInteropGetAttributeNode ;
72
72
import com .oracle .graal .python .builtins .objects .bytes .PByteArray ;
73
73
import com .oracle .graal .python .builtins .objects .bytes .PBytes ;
74
+ import com .oracle .graal .python .builtins .objects .cext .CExtNodes .GetSpecialSingletonPtrNode ;
75
+ import com .oracle .graal .python .builtins .objects .cext .CExtNodes .IsPointerNode ;
74
76
import com .oracle .graal .python .builtins .objects .cext .CExtNodes .PCallCapiFunction ;
77
+ import com .oracle .graal .python .builtins .objects .cext .CExtNodes .SetSpecialSingletonPtrNode ;
75
78
import com .oracle .graal .python .builtins .objects .cext .DynamicObjectNativeWrapperFactory .ReadTypeNativeMemberNodeGen ;
76
79
import com .oracle .graal .python .builtins .objects .cext .UnicodeObjectNodes .UnicodeAsWideCharNode ;
77
80
import com .oracle .graal .python .builtins .objects .common .DynamicObjectStorage ;
106
109
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetSuperClassNode ;
107
110
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetTypeFlagsNode ;
108
111
import com .oracle .graal .python .nodes .PGuards ;
109
- import com .oracle .graal .python .nodes .PNodeWithContext ;
110
112
import com .oracle .graal .python .nodes .PRaiseNode ;
111
113
import com .oracle .graal .python .nodes .SpecialAttributeNames ;
112
114
import com .oracle .graal .python .nodes .SpecialMethodNames ;
@@ -995,71 +997,78 @@ protected Object execute(Object[] arguments,
995
997
// TO NATIVE, IS POINTER, AS POINTER
996
998
@ GenerateUncached
997
999
abstract static class ToNativeNode extends Node {
998
- public abstract Object execute (PythonNativeWrapper obj );
1000
+ public abstract void execute (PythonNativeWrapper obj );
999
1001
1000
1002
protected static boolean isClassInitNativeWrapper (PythonNativeWrapper obj ) {
1001
1003
return obj instanceof PythonClassInitNativeWrapper ;
1002
1004
}
1003
1005
1004
1006
@ Specialization
1005
- public Object executeClsInit (PythonClassInitNativeWrapper obj ,
1006
- @ Cached . Shared ("toPyObjectNode" ) @ Cached DynamicObjectNativeWrapper . ToPyObjectNode toPyObjectNode ,
1007
- @ Cached . Shared ("invalidateNode" ) @ Cached InvalidateNativeObjectsAllManagedNode invalidateNode ) {
1007
+ public void executeClsInit (PythonClassInitNativeWrapper obj ,
1008
+ @ Shared ("toPyObjectNode" ) @ Cached ToPyObjectNode toPyObjectNode ,
1009
+ @ Shared ("invalidateNode" ) @ Cached InvalidateNativeObjectsAllManagedNode invalidateNode ) {
1008
1010
invalidateNode .execute ();
1009
1011
if (!obj .isNative ()) {
1010
1012
obj .setNativePointer (toPyObjectNode .execute (obj ));
1011
1013
}
1012
- return obj ;
1013
1014
}
1014
1015
1015
1016
@ Specialization (guards = "!isClassInitNativeWrapper(obj)" )
1016
- public Object execute (PythonNativeWrapper obj ,
1017
- @ Cached .Shared ("toPyObjectNode" ) @ Cached DynamicObjectNativeWrapper .ToPyObjectNode toPyObjectNode ,
1018
- @ Cached .Shared ("invalidateNode" ) @ Cached InvalidateNativeObjectsAllManagedNode invalidateNode ) {
1017
+ public void execute (PythonNativeWrapper obj ,
1018
+ @ Shared ("toPyObjectNode" ) @ Cached ToPyObjectNode toPyObjectNode ,
1019
+ @ Cached SetSpecialSingletonPtrNode setSpecialSingletonPtrNode ,
1020
+ @ Cached ("createBinaryProfile()" ) ConditionProfile profile ,
1021
+ @ Shared ("invalidateNode" ) @ Cached InvalidateNativeObjectsAllManagedNode invalidateNode ,
1022
+ @ Cached IsPointerNode isPointerNode ) {
1019
1023
invalidateNode .execute ();
1020
- if (!obj .isNative ()) {
1021
- obj .setNativePointer (toPyObjectNode .execute (obj ));
1024
+ if (!isPointerNode .execute (obj )) {
1025
+ Object ptr = toPyObjectNode .execute (obj );
1026
+ Object delegate = obj .getDelegate ();
1027
+ if (profile .profile (PythonLanguage .getSingletonNativePtrIdx (delegate ) != -1 )) {
1028
+ setSpecialSingletonPtrNode .execute (delegate , ptr );
1029
+ } else {
1030
+ obj .setNativePointer (ptr );
1031
+ }
1022
1032
}
1023
- return obj ;
1024
- }
1025
- }
1026
-
1027
- abstract static class IsPointerNode extends Node {
1028
- public abstract boolean execute (PythonNativeWrapper obj );
1029
-
1030
- @ Specialization
1031
- public boolean execute (PythonNativeWrapper obj ,
1032
- @ Cached .Exclusive @ Cached CExtNodes .IsPointerNode pIsPointerNode ) {
1033
- return pIsPointerNode .execute (obj );
1034
1033
}
1035
1034
}
1036
1035
1037
1036
@ GenerateUncached
1038
- abstract static class PAsPointerNode extends PNodeWithContext {
1037
+ abstract static class PAsPointerNode extends Node {
1039
1038
1040
1039
public abstract long execute (PythonNativeWrapper o );
1041
1040
1042
1041
@ Specialization (guards = {"obj.isBool()" , "!obj.isNative()" })
1043
- long doBoolNotNative (DynamicObjectNativeWrapper . PrimitiveNativeWrapper obj ,
1042
+ long doBoolNotNative (PrimitiveNativeWrapper obj ,
1044
1043
@ Cached CExtNodes .MaterializeDelegateNode materializeNode ,
1045
1044
@ Shared ("interopLib" ) @ CachedLibrary (limit = "1" ) InteropLibrary interopLib ) {
1046
1045
// special case for True and False singletons
1047
1046
PInt boxed = (PInt ) materializeNode .execute (obj );
1048
1047
assert obj .getNativePointer () == boxed .getNativeWrapper ().getNativePointer ();
1049
- return doFast ( obj , interopLib );
1048
+ return ensureLong ( interopLib , obj . getNativePointer () );
1050
1049
}
1051
1050
1052
1051
@ Specialization (guards = {"obj.isBool()" , "obj.isNative()" })
1053
- long doBoolNative (DynamicObjectNativeWrapper . PrimitiveNativeWrapper obj ,
1052
+ long doBoolNative (PrimitiveNativeWrapper obj ,
1054
1053
@ Shared ("interopLib" ) @ CachedLibrary (limit = "1" ) InteropLibrary interopLib ) {
1055
- return doFast ( obj , interopLib );
1054
+ return ensureLong ( interopLib , obj . getNativePointer () );
1056
1055
}
1057
1056
1058
1057
@ Specialization (guards = "!isBoolNativeWrapper(obj)" )
1059
1058
long doFast (PythonNativeWrapper obj ,
1060
- @ Shared ("interopLib" ) @ CachedLibrary (limit = "1" ) InteropLibrary interopLib ) {
1059
+ @ Shared ("interopLib" ) @ CachedLibrary (limit = "1" ) InteropLibrary interopLib ,
1060
+ @ Cached ("createBinaryProfile()" ) ConditionProfile profile ,
1061
+ @ Cached GetSpecialSingletonPtrNode getSpecialSingletonPtrNode ) {
1061
1062
// the native pointer object must either be a TruffleObject or a primitive
1062
- return ensureLong (interopLib , obj .getNativePointer ());
1063
+ Object nativePointer = obj .getNativePointer ();
1064
+ if (profile .profile (nativePointer == null )) {
1065
+ // We assume that before someone calls 'asPointer' on the wrapper, 'isPointer' was
1066
+ // checked and returned true. So, for this case we assume that it is one of the
1067
+ // special singletons where we store the pointer in the context.
1068
+ nativePointer = getSpecialSingletonPtrNode .execute (obj .getDelegate ());
1069
+ assert nativePointer != null : createAssertionMessage (obj .getDelegate ());
1070
+ }
1071
+ return ensureLong (interopLib , nativePointer );
1063
1072
}
1064
1073
1065
1074
private static long ensureLong (InteropLibrary interopLib , Object nativePointer ) {
@@ -1076,8 +1085,18 @@ private static long ensureLong(InteropLibrary interopLib, Object nativePointer)
1076
1085
}
1077
1086
1078
1087
protected static boolean isBoolNativeWrapper (Object obj ) {
1079
- return obj instanceof DynamicObjectNativeWrapper . PrimitiveNativeWrapper && ((DynamicObjectNativeWrapper . PrimitiveNativeWrapper ) obj ).isBool ();
1088
+ return obj instanceof PrimitiveNativeWrapper && ((PrimitiveNativeWrapper ) obj ).isBool ();
1080
1089
}
1090
+
1091
+ private static String createAssertionMessage (Object delegate ) {
1092
+ CompilerAsserts .neverPartOfCompilation ();
1093
+ int singletonNativePtrIdx = PythonLanguage .getSingletonNativePtrIdx (delegate );
1094
+ if (singletonNativePtrIdx == -1 ) {
1095
+ return "invalid special singleton object " + delegate ;
1096
+ }
1097
+ return "expected special singleton '" + delegate + "' to have a native pointer" ;
1098
+ }
1099
+
1081
1100
}
1082
1101
1083
1102
@ GenerateUncached
@@ -1270,7 +1289,7 @@ protected boolean isMemberReadable(String member) {
1270
1289
1271
1290
@ ExportMessage
1272
1291
protected boolean isPointer (
1273
- @ Cached . Exclusive @ Cached CExtNodes .IsPointerNode pIsPointerNode ) {
1292
+ @ Cached CExtNodes .IsPointerNode pIsPointerNode ) {
1274
1293
return pIsPointerNode .execute (this );
1275
1294
}
1276
1295
0 commit comments