130
130
import com .oracle .graal .python .builtins .objects .str .StringNodes .StringMaterializeNode ;
131
131
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
132
132
import com .oracle .graal .python .builtins .objects .type .PythonAbstractClass ;
133
+ import com .oracle .graal .python .builtins .objects .type .PythonClass ;
133
134
import com .oracle .graal .python .builtins .objects .type .PythonManagedClass ;
135
+ import com .oracle .graal .python .builtins .objects .type .TypeBuiltins ;
134
136
import com .oracle .graal .python .builtins .objects .type .TypeNodes ;
135
137
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetMroStorageNode ;
136
138
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetNameNode ;
203
205
import com .oracle .truffle .api .nodes .EncapsulatingNodeReference ;
204
206
import com .oracle .truffle .api .nodes .ExplodeLoop ;
205
207
import com .oracle .truffle .api .nodes .Node ;
208
+ import com .oracle .truffle .api .object .HiddenKey ;
206
209
import com .oracle .truffle .api .profiles .BranchProfile ;
207
210
import com .oracle .truffle .api .profiles .ConditionProfile ;
208
211
import com .oracle .truffle .api .source .Source ;
@@ -1718,22 +1721,31 @@ public static GetTypeMemberNode getUncached() {
1718
1721
* Use this node to lookup a native type member like {@code tp_alloc}.<br>
1719
1722
* <p>
1720
1723
* This node basically implements the native member inheritance that is done by
1721
- * {@code inherit_special} or other code in {@code PyType_Ready}.
1724
+ * {@code inherit_special} or other code in {@code PyType_Ready}. In addition, we do a special
1725
+ * case for special slots assignment that happens within {@Code type_new_alloc} for heap types.
1722
1726
* </p>
1723
1727
* <p>
1724
1728
* Since it may be that a managed types needs to emulate such members but there is no
1725
- * corresponding Python attribute (e.g. {@code tp_alloc }), such members are stored as hidden
1726
- * keys on the managed type. However, the MRO may contain native types and in this case, we need
1727
- * to access the native member.
1729
+ * corresponding Python attribute (e.g. {@code tp_vectorcall_offset }), such members are stored
1730
+ * as hidden keys on the managed type. However, the MRO may contain native types and in this
1731
+ * case, we need to access the native member.
1728
1732
* </p>
1729
1733
*/
1730
1734
@ GenerateUncached
1731
1735
public abstract static class LookupNativeMemberInMRONode extends Node {
1732
1736
1733
- public abstract Object execute (Object cls , NativeMember nativeMemberName , Object managedMemberName );
1737
+ public abstract Object execute (Object cls , NativeMember nativeMemberName , HiddenKey managedMemberName );
1734
1738
1735
- @ Specialization
1736
- static Object doSingleContext (Object cls , NativeMember nativeMemberName , Object managedMemberName ,
1739
+ static boolean isSpecialHeapSlot (Object cls , HiddenKey key ) {
1740
+ return cls instanceof PythonClass && (key == TypeBuiltins .TYPE_ALLOC || key == TypeBuiltins .TYPE_DEL );
1741
+ // mq: not supported yet
1742
+ // key == TypeBuiltins.TYPE_DEALLOC (subtype_dealloc)
1743
+ // key == TypeBuiltins.TYPE_TRAVERSE (subtype_traverse)
1744
+ // key == TypeBuiltins.TYPE_CLEAR (subtype_clear)
1745
+ }
1746
+
1747
+ @ Specialization (guards = "!isSpecialHeapSlot(cls, managedMemberName)" )
1748
+ static Object doSingleContext (Object cls , NativeMember nativeMemberName , HiddenKey managedMemberName ,
1737
1749
@ Cached GetMroStorageNode getMroNode ,
1738
1750
@ Cached SequenceStorageNodes .GetItemDynamicNode getItemNode ,
1739
1751
@ Cached ("createForceType()" ) ReadAttributeFromObjectNode readAttrNode ,
@@ -1744,6 +1756,7 @@ static Object doSingleContext(Object cls, NativeMember nativeMemberName, Object
1744
1756
1745
1757
for (int i = 0 ; i < n ; i ++) {
1746
1758
PythonAbstractClass mroCls = (PythonAbstractClass ) getItemNode .execute (mroStorage , i );
1759
+
1747
1760
Object result ;
1748
1761
if (PGuards .isManagedClass (mroCls )) {
1749
1762
result = readAttrNode .execute (mroCls , managedMemberName );
@@ -1756,7 +1769,34 @@ static Object doSingleContext(Object cls, NativeMember nativeMemberName, Object
1756
1769
}
1757
1770
}
1758
1771
1759
- return PNone .NO_VALUE ;
1772
+ return readAttrNode .execute (PythonContext .get (readAttrNode ).lookupType (PythonBuiltinClassType .PythonObject ), managedMemberName );
1773
+ }
1774
+
1775
+ @ TruffleBoundary
1776
+ static Object createSpecialHeapSlot (Object cls , HiddenKey managedMemberName , Node node ) {
1777
+ Object func ;
1778
+ if (managedMemberName == TypeBuiltins .TYPE_ALLOC || managedMemberName == TypeBuiltins .TYPE_DEL ) {
1779
+ PythonObject object = PythonContext .get (null ).lookupType (PythonBuiltinClassType .PythonObject );
1780
+ // We need to point to PyType_GenericAlloc or PyObject_GC_Del
1781
+ func = ReadAttributeFromObjectNode .getUncachedForceType ().execute (object , managedMemberName );
1782
+ WriteAttributeToObjectNode .getUncached ().execute (cls , managedMemberName , func );
1783
+ } else {
1784
+ // managedMemberName == TypeBuiltins.TYPE_DEALLOC
1785
+ // managedMemberName == TypeBuiltins.TYPE_CLEAR
1786
+ // managedMemberName == TypeBuiltins.TYPE_TRAVERSE
1787
+ throw PRaiseNode .raiseUncached (node , SystemError , tsLiteral ("not supported yet!" ));
1788
+ }
1789
+ return func ;
1790
+ }
1791
+
1792
+ @ Specialization (guards = "isSpecialHeapSlot(cls, managedMemberName)" )
1793
+ static Object doToAllocOrDelManaged (Object cls , @ SuppressWarnings ("unused" ) NativeMember nativeMemberName , HiddenKey managedMemberName ,
1794
+ @ Cached ("createForceType()" ) ReadAttributeFromObjectNode readAttrNode ) {
1795
+ Object func = readAttrNode .execute (cls , managedMemberName );
1796
+ if (func == PNone .NO_VALUE ) {
1797
+ func = createSpecialHeapSlot (cls , managedMemberName , readAttrNode );
1798
+ }
1799
+ return func ;
1760
1800
}
1761
1801
}
1762
1802
0 commit comments