@@ -1728,30 +1728,35 @@ public static GetTypeMemberNode getUncached() {
1728
1728
* Use this node to lookup a native type member like {@code tp_alloc}.<br>
1729
1729
* <p>
1730
1730
* This node basically implements the native member inheritance that is done by
1731
- * {@code inherit_special} or other code in {@code PyType_Ready}.
1731
+ * {@code inherit_special} or other code in {@code PyType_Ready}. In addition, we do a special
1732
+ * case for special slots assignment that happens within {@Code type_new_alloc} for heap types.
1732
1733
* </p>
1733
1734
* <p>
1734
1735
* Since it may be that a managed types needs to emulate such members but there is no
1735
- * corresponding Python attribute (e.g. {@code tp_alloc }), such members are stored as hidden
1736
- * keys on the managed type. However, the MRO may contain native types and in this case, we need
1737
- * to access the native member.
1736
+ * corresponding Python attribute (e.g. {@code tp_vectorcall_offset }), such members are stored
1737
+ * as hidden keys on the managed type. However, the MRO may contain native types and in this
1738
+ * case, we need to access the native member.
1738
1739
* </p>
1739
1740
*/
1740
1741
@ GenerateUncached
1741
1742
public abstract static class LookupNativeMemberInMRONode extends Node {
1742
1743
1743
1744
public abstract Object execute (Object cls , NativeMember nativeMemberName , HiddenKey managedMemberName );
1744
1745
1745
- static boolean isTpAlloc (Object cls , HiddenKey key ) {
1746
- return cls instanceof PythonClass && key == TypeBuiltins .TYPE_ALLOC ;
1746
+ static boolean isSpecialHeapSlot (Object cls , HiddenKey key ) {
1747
+ return cls instanceof PythonClass && (key == TypeBuiltins .TYPE_ALLOC || key == TypeBuiltins .TYPE_DEL );
1748
+ // mq: not supported yet
1749
+ // key == TypeBuiltins.TYPE_DEALLOC (subtype_dealloc)
1750
+ // key == TypeBuiltins.TYPE_TRAVERSE (subtype_traverse)
1751
+ // key == TypeBuiltins.TYPE_CLEAR (subtype_clear)
1747
1752
}
1748
1753
1749
- @ Specialization (guards = "!isTpAlloc (cls, managedMemberName)" )
1754
+ @ Specialization (guards = "!isSpecialHeapSlot (cls, managedMemberName)" )
1750
1755
static Object doSingleContext (Object cls , NativeMember nativeMemberName , HiddenKey managedMemberName ,
1751
- @ Cached GetMroStorageNode getMroNode ,
1752
- @ Cached SequenceStorageNodes .GetItemDynamicNode getItemNode ,
1753
- @ Cached ("createForceType()" ) ReadAttributeFromObjectNode readAttrNode ,
1754
- @ Cached GetTypeMemberNode getTypeMemberNode ) {
1756
+ @ Cached GetMroStorageNode getMroNode ,
1757
+ @ Cached SequenceStorageNodes .GetItemDynamicNode getItemNode ,
1758
+ @ Cached ("createForceType()" ) ReadAttributeFromObjectNode readAttrNode ,
1759
+ @ Cached GetTypeMemberNode getTypeMemberNode ) {
1755
1760
1756
1761
MroSequenceStorage mroStorage = getMroNode .execute (cls );
1757
1762
int n = mroStorage .length ();
@@ -1774,19 +1779,31 @@ static Object doSingleContext(Object cls, NativeMember nativeMemberName, HiddenK
1774
1779
return readAttrNode .execute (PythonContext .get (readAttrNode ).lookupType (PythonBuiltinClassType .PythonObject ), managedMemberName );
1775
1780
}
1776
1781
1777
- @ Specialization (guards = "isTpAlloc(cls, managedMemberName)" )
1778
- static Object doToAllocManaged (Object cls , @ SuppressWarnings ("unused" ) NativeMember nativeMemberName , HiddenKey managedMemberName ,
1779
- @ Cached ("createForceType()" ) ReadAttributeFromObjectNode readAttrNode ,
1780
- @ Cached WriteAttributeToObjectNode writeAttrNode ) {
1782
+ @ TruffleBoundary
1783
+ static Object createSpecialHeapSlot (Object cls , HiddenKey managedMemberName , Node node ) {
1784
+ Object func ;
1785
+ if (managedMemberName == TypeBuiltins .TYPE_ALLOC || managedMemberName == TypeBuiltins .TYPE_DEL ) {
1786
+ PythonObject object = PythonContext .get (null ).lookupType (PythonBuiltinClassType .PythonObject );
1787
+ // We need to point to PyType_GenericAlloc or PyObject_GC_Del
1788
+ func = ReadAttributeFromObjectNode .getUncachedForceType ().execute (object , managedMemberName );
1789
+ WriteAttributeToObjectNode .getUncached ().execute (cls , managedMemberName , func );
1790
+ } else {
1791
+ // managedMemberName == TypeBuiltins.TYPE_DEALLOC
1792
+ // managedMemberName == TypeBuiltins.TYPE_CLEAR
1793
+ // managedMemberName == TypeBuiltins.TYPE_TRAVERSE
1794
+ throw PRaiseNode .raiseUncached (node , SystemError , tsLiteral ("not supported yet!" ));
1795
+ }
1796
+ return func ;
1797
+ }
1781
1798
1782
- Object alloc = readAttrNode . execute (cls , managedMemberName );
1783
- if ( alloc == PNone . NO_VALUE ) {
1784
- PythonObject object = PythonContext . get ( readAttrNode ). lookupType ( PythonBuiltinClassType . PythonObject );
1785
- Object pyTypeGenericAlloc = readAttrNode .execute (object , managedMemberName );
1786
- writeAttrNode . execute ( cls , managedMemberName , pyTypeGenericAlloc );
1787
- alloc = pyTypeGenericAlloc ;
1799
+ @ Specialization ( guards = "isSpecialHeapSlot (cls, managedMemberName)" )
1800
+ static Object doToAllocOrDelManaged ( Object cls , @ SuppressWarnings ( "unused" ) NativeMember nativeMemberName , HiddenKey managedMemberName ,
1801
+ @ Cached ( "createForceType()" ) ReadAttributeFromObjectNode readAttrNode ) {
1802
+ Object func = readAttrNode .execute (cls , managedMemberName );
1803
+ if ( func == PNone . NO_VALUE ) {
1804
+ func = createSpecialHeapSlot ( cls , managedMemberName , readAttrNode ) ;
1788
1805
}
1789
- return alloc ;
1806
+ return func ;
1790
1807
}
1791
1808
}
1792
1809
0 commit comments