42
42
43
43
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
44
44
import com .oracle .graal .python .builtins .objects .cext .PythonAbstractNativeObject ;
45
+ import com .oracle .graal .python .builtins .objects .cext .capi .CExtNodes ;
45
46
import com .oracle .graal .python .builtins .objects .cext .capi .CExtNodes .PCallCapiFunction ;
46
47
import com .oracle .graal .python .builtins .objects .cext .capi .NativeCAPISymbol ;
48
+ import com .oracle .graal .python .builtins .objects .cext .capi .NativeMember ;
49
+ import com .oracle .graal .python .builtins .objects .common .HashingStorageNodes .HashingStorageGetItem ;
50
+ import com .oracle .graal .python .builtins .objects .common .HashingStorageNodes .HashingStorageSetItem ;
51
+ import com .oracle .graal .python .builtins .objects .common .HashingStorageNodesFactory .HashingStorageGetItemNodeGen ;
52
+ import com .oracle .graal .python .builtins .objects .dict .PDict ;
47
53
import com .oracle .graal .python .builtins .objects .type .PythonManagedClass ;
54
+ import com .oracle .graal .python .runtime .PythonContext ;
55
+ import com .oracle .truffle .api .Assumption ;
56
+ import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
48
57
import com .oracle .truffle .api .dsl .Cached ;
49
58
import com .oracle .truffle .api .dsl .Fallback ;
50
59
import com .oracle .truffle .api .dsl .GenerateInline ;
51
60
import com .oracle .truffle .api .dsl .GenerateUncached ;
52
61
import com .oracle .truffle .api .dsl .Specialization ;
53
62
import com .oracle .truffle .api .nodes .Node ;
63
+ import com .oracle .truffle .api .object .HiddenKey ;
54
64
55
65
/**
56
66
* Retrieve slots occupation of `cls->tp_as_number`, `cls->tp_as_sequence` and `cls->tp_as_mapping`
@@ -72,13 +82,44 @@ protected static long pythonclasstype(PythonBuiltinClassType cls) {
72
82
return cls .getMethodsFlags ();
73
83
}
74
84
75
- @ Specialization
76
- static long doNative (PythonAbstractNativeObject cls ,
77
- @ Cached PCallCapiFunction callCapiFunction ) {
78
- Long flags = (Long ) callCapiFunction .call (NativeCAPISymbol .FUN_GET_METHODS_FLAGS , cls .getPtr ());
85
+ public static final HiddenKey METHODS_FLAGS = new HiddenKey ("__methods_flags__" );
86
+
87
+ @ TruffleBoundary
88
+ private static long populateMethodsFlags (PythonAbstractNativeObject cls , PDict dict ) {
89
+ Long flags = (Long ) PCallCapiFunction .getUncached ().call (NativeCAPISymbol .FUN_GET_METHODS_FLAGS , cls .getPtr ());
90
+ HashingStorageSetItem .executeUncached (dict .getDictStorage (), METHODS_FLAGS , flags );
79
91
return flags ;
80
92
}
81
93
94
+ protected static long getMethodsFlags (PythonAbstractNativeObject cls ) {
95
+ return doNative (cls , CExtNodes .GetTypeMemberNode .getUncached (), HashingStorageGetItemNodeGen .getUncached ());
96
+ }
97
+
98
+ // The assumption should hold unless `PyType_Modified` is called.
99
+ protected static Assumption nativeAssumption (PythonAbstractNativeObject cls ) {
100
+ return PythonContext .get (null ).getNativeClassStableAssumption (cls , true ).getAssumption ();
101
+ }
102
+
103
+ @ Specialization (guards = "cachedCls == cls" , limit = "5" , assumptions = "nativeAssumption(cachedCls)" )
104
+ static long doNativeCached (@ SuppressWarnings ("unused" ) PythonAbstractNativeObject cls ,
105
+ @ SuppressWarnings ("unused" ) @ Cached ("cls" ) PythonAbstractNativeObject cachedCls ,
106
+ @ Cached ("getMethodsFlags(cls)" ) long flags ) {
107
+ return flags ;
108
+ }
109
+
110
+ @ Specialization (replaces = "doNativeCached" )
111
+ static long doNative (PythonAbstractNativeObject cls ,
112
+ @ Cached CExtNodes .GetTypeMemberNode getTpDictNode ,
113
+ @ Cached HashingStorageGetItem getItem ) {
114
+ // classes must have tp_dict since they are set during PyType_Ready
115
+ PDict dict = (PDict ) getTpDictNode .execute (cls , NativeMember .TP_DICT );
116
+ Object f = getItem .execute (null , dict .getDictStorage (), METHODS_FLAGS );
117
+ if (f == null ) {
118
+ return populateMethodsFlags (cls , dict );
119
+ }
120
+ return (Long ) f ;
121
+ }
122
+
82
123
@ Fallback
83
124
protected static long zero (@ SuppressWarnings ("unused" ) Object cls ) {
84
125
return 0 ;
0 commit comments