40
40
*/
41
41
package com .oracle .graal .python .builtins .objects .type ;
42
42
43
+ import static com .oracle .graal .python .builtins .objects .cext .structs .CFields .PyTypeObject__tp_dict ;
43
44
import static com .oracle .graal .python .builtins .objects .type .MethodsFlags .NB_ADD ;
44
45
import static com .oracle .graal .python .builtins .objects .type .MethodsFlags .NB_AND ;
45
46
import static com .oracle .graal .python .builtins .objects .type .MethodsFlags .NB_BOOL ;
60
61
import static com .oracle .graal .python .builtins .objects .type .MethodsFlags .NB_TRUE_DIVIDE ;
61
62
import static com .oracle .graal .python .builtins .objects .type .MethodsFlags .NB_XOR ;
62
63
import static com .oracle .graal .python .builtins .objects .type .SpecialMethodSlot .Flags .NO_BUILTIN_DESCRIPTORS ;
64
+ import static com .oracle .graal .python .lib .GetMethodsFlagsNode .METHODS_FLAGS ;
63
65
import static com .oracle .graal .python .nodes .SpecialAttributeNames .T___DICT__ ;
64
66
import static com .oracle .graal .python .nodes .SpecialMethodNames .T___ADD__ ;
65
67
import static com .oracle .graal .python .nodes .SpecialMethodNames .T___AENTER__ ;
150
152
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
151
153
import com .oracle .graal .python .builtins .objects .PNone ;
152
154
import com .oracle .graal .python .builtins .objects .cext .PythonNativeClass ;
155
+ import com .oracle .graal .python .builtins .objects .cext .structs .CStructAccess ;
153
156
import com .oracle .graal .python .builtins .objects .common .HashingStorage ;
154
157
import com .oracle .graal .python .builtins .objects .common .HashingStorageNodes .HashingStorageGetItem ;
158
+ import com .oracle .graal .python .builtins .objects .common .HashingStorageNodes .HashingStorageSetItem ;
155
159
import com .oracle .graal .python .builtins .objects .dict .PDict ;
156
160
import com .oracle .graal .python .builtins .objects .function .BuiltinMethodDescriptor ;
157
161
import com .oracle .graal .python .builtins .objects .function .PBuiltinFunction ;
158
162
import com .oracle .graal .python .builtins .objects .method .PBuiltinMethod ;
159
163
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetBaseClassNode ;
160
164
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetMroStorageNode ;
161
165
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetSubclassesNode ;
166
+ import com .oracle .graal .python .lib .GetMethodsFlagsNodeGen ;
162
167
import com .oracle .graal .python .nodes .attributes .LookupAttributeInMRONode ;
163
168
import com .oracle .graal .python .nodes .attributes .LookupCallableSlotInMRONode ;
164
169
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromDynamicObjectNode ;
175
180
import com .oracle .truffle .api .object .DynamicObject ;
176
181
import com .oracle .truffle .api .object .DynamicObjectLibrary ;
177
182
import com .oracle .truffle .api .strings .TruffleString ;
183
+ import com .oracle .truffle .api .utilities .CyclicAssumption ;
178
184
179
185
/**
180
186
* Subset of special methods that is cached in {@link PythonManagedClass} and
@@ -601,6 +607,32 @@ private static boolean isMroSubtype(MroSequenceStorage superTypeMro, PythonManag
601
607
return isMroSubtype ;
602
608
}
603
609
610
+ private static void setMethodsFlag (PythonManagedClass klass , long flag , PythonContext context ) {
611
+ if (flag == 0 ) {
612
+ return ;
613
+ }
614
+
615
+ long isHeaptype = context .isCoreInitialized () ? MethodsFlags .SLOT1BINFULL : 0L ;
616
+ klass .setMethodsFlags (flag | isHeaptype );
617
+ }
618
+
619
+ private static void setMethodsFlag (PythonNativeClass cls , long flag , PythonContext context ) {
620
+ if (flag == 0 ) {
621
+ return ;
622
+ }
623
+
624
+ long flags = GetMethodsFlagsNodeGen .getUncached ().execute (null , cls );
625
+ if ((flags & flag ) == 0 ) {
626
+ // mq: We should put a wrapped function in the native slot.
627
+ CyclicAssumption assumption = context .getNativeClassStableAssumption (cls , false );
628
+ if (assumption != null && assumption .getAssumption ().isValid ()) {
629
+ assumption .invalidate ("methods flags have changed after class creation" );
630
+ }
631
+ PDict dict = (PDict ) CStructAccess .ReadObjectNode .getUncached ().readFromObj (cls , PyTypeObject__tp_dict );
632
+ dict .setDictStorage (HashingStorageSetItem .executeUncached (dict .getDictStorage (), METHODS_FLAGS , flags | flag ));
633
+ }
634
+ }
635
+
604
636
private static void setMethodsFlags (Object [] slots , PythonManagedClass klass ) {
605
637
long methodsFlags = 0 ;
606
638
for (SpecialMethodSlot slot : VALUES ) {
@@ -613,10 +645,7 @@ private static void setMethodsFlags(Object[] slots, PythonManagedClass klass) {
613
645
methodsFlags |= builtinClass .getMethodsFlags ();
614
646
}
615
647
616
- if (methodsFlags != 0 ) {
617
- long isHeaptype = PythonContext .get (null ).isCoreInitialized () ? MethodsFlags .SLOT1BINFULL : 0L ;
618
- klass .setMethodsFlags (methodsFlags | isHeaptype );
619
- }
648
+ setMethodsFlag (klass , methodsFlags , PythonContext .get (null ));
620
649
}
621
650
622
651
/**
@@ -738,9 +767,8 @@ public static void fixupSpecialMethodSlot(PythonManagedClass klass, SpecialMetho
738
767
739
768
PythonContext context = PythonContext .get (null );
740
769
slot .setValue (klass , newValue , context );
741
- if (oldValue == PNone .NO_VALUE && slot .getMethodsFlag () != 0 ) {
742
- long isHeaptype = context .isCoreInitialized () ? MethodsFlags .SLOT1BINFULL : 0L ;
743
- klass .setMethodsFlags (isHeaptype | slot .getMethodsFlag ());
770
+ if (oldValue == PNone .NO_VALUE ) {
771
+ setMethodsFlag (klass , slot .getMethodsFlag (), context );
744
772
}
745
773
fixupSpecialMethodInSubClasses (klass .getSubClasses (), slot , value , context );
746
774
}
@@ -768,9 +796,11 @@ private static void fixupSpecialMethodSlotInternal(PythonManagedClass klass, Spe
768
796
}
769
797
770
798
private static void fixupSpecialMethodSlot (Object klass , SpecialMethodSlot slot , Object newValue , PythonContext context ) {
771
- if (klass instanceof PythonManagedClass ) {
799
+ if (klass instanceof PythonManagedClass clazz ) {
800
+ setMethodsFlag (clazz , slot .getMethodsFlag (), context );
772
801
fixupSpecialMethodSlotInternal ((PythonManagedClass ) klass , slot , newValue , context );
773
- } else if (klass instanceof PythonNativeClass ) {
802
+ } else if (klass instanceof PythonNativeClass clazz ) {
803
+ setMethodsFlag (clazz , slot .getMethodsFlag (), context );
774
804
fixupSpecialMethodInSubClasses (GetSubclassesNode .executeUncached (klass ), slot , newValue , context );
775
805
} else {
776
806
throw new AssertionError (Objects .toString (klass ));
@@ -780,7 +810,6 @@ private static void fixupSpecialMethodSlot(Object klass, SpecialMethodSlot slot,
780
810
private static void fixupSpecialMethodInSubClasses (java .util .Set <PythonAbstractClass > subClasses , SpecialMethodSlot slot , Object newValue , PythonContext context ) {
781
811
for (PythonAbstractClass subClass : subClasses ) {
782
812
fixupSpecialMethodSlot (subClass , slot , newValue , context );
783
- // mq: TODO: we might need to update methods flags for subclasses
784
813
}
785
814
}
786
815
0 commit comments