155
155
import com .oracle .graal .python .builtins .objects .dict .PDict ;
156
156
import com .oracle .graal .python .builtins .objects .function .BuiltinMethodDescriptor ;
157
157
import com .oracle .graal .python .builtins .objects .function .PBuiltinFunction ;
158
+ import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetBaseClassNode ;
158
159
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetMroStorageNode ;
159
160
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetSubclassesNode ;
161
+ import com .oracle .graal .python .builtins .objects .type .TypeNodes .LookupNewNode ;
160
162
import com .oracle .graal .python .nodes .attributes .LookupAttributeInMRONode ;
161
163
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromDynamicObjectNode ;
162
164
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
@@ -297,6 +299,15 @@ static class Flags {
297
299
}
298
300
299
301
public static final SpecialMethodSlot [] VALUES = values ();
302
+ public static final SpecialMethodSlot [] MRO_INHERITED_SLOTS = new SpecialMethodSlot [VALUES .length - 1 ];
303
+ static {
304
+ for (int i = 0 , j = 0 ; i < VALUES .length ; i ++) {
305
+ if (i == New .ordinal ()) {
306
+ continue ;
307
+ }
308
+ MRO_INHERITED_SLOTS [j ++] = VALUES [i ];
309
+ }
310
+ }
300
311
private final TruffleString name ;
301
312
@ CompilationFinal private SpecialMethodSlot reverse ;
302
313
/**
@@ -532,6 +543,7 @@ private static Object[] initializeSpecialMethodsSlots(PythonManagedClass klass,
532
543
if (isMroSubtype (mro , managedBase )) {
533
544
Object [] result = PythonUtils .arrayCopyOf (managedBase .specialMethodSlots , managedBase .specialMethodSlots .length );
534
545
setSlotsFromManaged (result , klass , language );
546
+ setNewSlot (result , klass );
535
547
setMethodsFlags (result , klass );
536
548
return result ;
537
549
}
@@ -573,6 +585,7 @@ private static Object[] initializeSpecialMethodsSlots(PythonManagedClass klass,
573
585
setSlotsFromGeneric (slots , base , language );
574
586
}
575
587
}
588
+ setNewSlot (slots , klass );
576
589
setMethodsFlags (slots , klass );
577
590
return slots ;
578
591
}
@@ -613,20 +626,29 @@ private static void setMethodsFlags(Object[] slots, PythonManagedClass klass) {
613
626
}
614
627
}
615
628
629
+ private static void setNewSlot (Object [] slots , Object type ) {
630
+ Object newMethod = ReadAttributeFromObjectNode .getUncachedForceType ().execute (type , New .name );
631
+ if (newMethod == PNone .NO_VALUE ) {
632
+ Object base = GetBaseClassNode .executeUncached (type );
633
+ newMethod = LookupNewNode .executeUncached (base );
634
+ }
635
+ slots [New .ordinal ()] = newMethod ;
636
+ }
637
+
616
638
private static void setSlotsFromManaged (Object [] slots , PythonManagedClass source , PythonLanguage language ) {
617
639
PDict dict = GetDictIfExistsNode .getUncached ().execute (source );
618
640
if (dict == null ) {
619
641
DynamicObject storage = source .getStorage ();
620
642
DynamicObjectLibrary domLib = DynamicObjectLibrary .getFactory ().getUncached (storage );
621
- for (SpecialMethodSlot slot : VALUES ) {
643
+ for (SpecialMethodSlot slot : MRO_INHERITED_SLOTS ) {
622
644
final Object value = domLib .getOrDefault (source , slot .getName (), PNone .NO_VALUE );
623
645
if (value != PNone .NO_VALUE ) {
624
646
slots [slot .ordinal ()] = asSlotValue (slot , value , language );
625
647
}
626
648
}
627
649
} else {
628
650
HashingStorage storage = dict .getDictStorage ();
629
- for (SpecialMethodSlot slot : VALUES ) {
651
+ for (SpecialMethodSlot slot : MRO_INHERITED_SLOTS ) {
630
652
final Object value = HashingStorageGetItem .executeUncached (storage , slot .getName ());
631
653
if (value != null ) {
632
654
slots [slot .ordinal ()] = asSlotValue (slot , value , language );
@@ -637,7 +659,7 @@ private static void setSlotsFromManaged(Object[] slots, PythonManagedClass sourc
637
659
638
660
private static void setSlotsFromGeneric (Object [] slots , PythonAbstractClass base , PythonLanguage language ) {
639
661
ReadAttributeFromObjectNode readAttNode = ReadAttributeFromObjectNode .getUncachedForceType ();
640
- for (SpecialMethodSlot slot : VALUES ) {
662
+ for (SpecialMethodSlot slot : MRO_INHERITED_SLOTS ) {
641
663
Object value = readAttNode .execute (base , slot .getName ());
642
664
if (value != PNone .NO_VALUE ) {
643
665
slots [slot .ordinal ()] = asSlotValue (slot , value , language );
@@ -651,7 +673,11 @@ public static void fixupSpecialMethodSlot(PythonNativeClass klass, SpecialMethod
651
673
if (value == PNone .NO_VALUE ) {
652
674
// We are removing the value: find the new value for the class that is being updated and
653
675
// proceed with that
654
- newValue = LookupAttributeInMRONode .lookupSlowPath (klass , slot .getName ());
676
+ if (slot == New ) {
677
+ newValue = LookupNewNode .executeUncached (GetBaseClassNode .executeUncached (klass ));
678
+ } else {
679
+ newValue = LookupAttributeInMRONode .lookupSlowPath (klass , slot .getName ());
680
+ }
655
681
}
656
682
fixupSpecialMethodInSubClasses (GetSubclassesNode .executeUncached (klass ), slot , newValue , PythonContext .get (null ));
657
683
}
@@ -675,7 +701,11 @@ public static void fixupSpecialMethodSlot(PythonManagedClass klass, SpecialMetho
675
701
if (value == PNone .NO_VALUE ) {
676
702
// We are removing the value: find the new value for the class that is being updated and
677
703
// proceed with that
678
- newValue = LookupAttributeInMRONode .lookupSlowPath (klass , slot .getName ());
704
+ if (slot == New ) {
705
+ newValue = LookupNewNode .executeUncached (GetBaseClassNode .executeUncached (klass ));
706
+ } else {
707
+ newValue = LookupAttributeInMRONode .lookupSlowPath (klass , slot .getName ());
708
+ }
679
709
}
680
710
681
711
PythonContext context = PythonContext .get (null );
@@ -1215,7 +1245,7 @@ public static boolean validateSlots(Object klassIn) {
1215
1245
if (type .getSpecialMethodSlots () == null ) {
1216
1246
return true ;
1217
1247
}
1218
- for (SpecialMethodSlot slot : VALUES ) {
1248
+ for (SpecialMethodSlot slot : MRO_INHERITED_SLOTS ) {
1219
1249
Object actual = LookupAttributeInMRONode .findAttr (core , type , slot .getName (), uncachedReadAttrNode );
1220
1250
Object expected = slot .getValue (type );
1221
1251
if (expected instanceof BuiltinMethodDescriptor ) {
@@ -1230,7 +1260,7 @@ public static boolean validateSlots(Object klassIn) {
1230
1260
}
1231
1261
if (klass instanceof PythonManagedClass ) {
1232
1262
PythonManagedClass managed = (PythonManagedClass ) klass ;
1233
- for (SpecialMethodSlot slot : VALUES ) {
1263
+ for (SpecialMethodSlot slot : MRO_INHERITED_SLOTS ) {
1234
1264
Object actual = LookupAttributeInMRONode .lookupSlowPath (managed , slot .getName ());
1235
1265
Object expected = slot .getValue (managed );
1236
1266
if (expected instanceof NodeFactory <?>) {
0 commit comments