@@ -838,6 +838,7 @@ public abstract static class CheckCompatibleForAssigmentNode extends PNodeWithCo
838838 @ Child private PRaiseNode raiseNode ;
839839 @ Child private GetNameNode getTypeNameNode ;
840840 @ Child private ReadAttributeFromObjectNode readAttr ;
841+ @ Child private InstancesOfTypeHaveDictNode instancesHaveDictNode ;
841842
842843 public abstract boolean execute (VirtualFrame frame , Object oldBase , Object newBase );
843844
@@ -968,6 +969,14 @@ private Object getSlotsFromType(Object type) {
968969 return slots != PNone .NO_VALUE ? slots : null ;
969970 }
970971
972+ private boolean instancesHaveDict (Object type ) {
973+ if (instancesHaveDictNode == null ) {
974+ CompilerDirectives .transferToInterpreterAndInvalidate ();
975+ instancesHaveDictNode = insert (InstancesOfTypeHaveDictNode .create ());
976+ }
977+ return instancesHaveDictNode .execute (type );
978+ }
979+
971980 private GetObjectArrayNode getObjectArrayNode () {
972981 if (getObjectArrayNode == null ) {
973982 CompilerDirectives .transferToInterpreterAndInvalidate ();
@@ -1017,6 +1026,39 @@ private PRaiseNode getRaiseNode() {
10171026 }
10181027 }
10191028
1029+ /**
1030+ * Equivalent of checking type->tp_dictoffset != 0 in CPython
1031+ */
1032+ abstract static class InstancesOfTypeHaveDictNode extends PNodeWithContext {
1033+ public abstract boolean execute (Object type );
1034+
1035+ @ Specialization
1036+ static boolean doPBCT (PythonBuiltinClassType type ) {
1037+ return type .isBuiltinWithDict ();
1038+ }
1039+
1040+ @ Specialization
1041+ static boolean doPythonClass (PythonManagedClass type ) {
1042+ return (type .getInstanceShape ().getFlags () & PythonObject .HAS_SLOTS_BUT_NO_DICT_FLAG ) == 0 ;
1043+ }
1044+
1045+ @ Specialization
1046+ static boolean doNativeObject (PythonAbstractNativeObject type ,
1047+ @ Cached GetTypeMemberNode getMember ,
1048+ @ Cached CastToJavaIntExactNode cast ) {
1049+ return cast .execute (getMember .execute (type , NativeMember .TP_DICTOFFSET )) != 0 ;
1050+ }
1051+
1052+ @ Fallback
1053+ static boolean doOther (@ SuppressWarnings ("unused" ) Object type ) {
1054+ return true ;
1055+ }
1056+
1057+ public static InstancesOfTypeHaveDictNode create () {
1058+ return TypeNodesFactory .InstancesOfTypeHaveDictNodeGen .create ();
1059+ }
1060+ }
1061+
10201062 @ TruffleBoundary
10211063 private static boolean compareSortedSlots (Object aSlots , Object bSlots , GetObjectArrayNode getObjectArrayNode ) {
10221064 Object [] aArray = getObjectArrayNode .execute (aSlots );
@@ -1644,18 +1686,4 @@ private static long getBuiltinTypeItemsize(PythonBuiltinClassType cls) {
16441686 }
16451687 }
16461688 }
1647-
1648- // Equivalent of checking type->tp_dictoffset != 0 in CPython
1649- private static boolean instancesHaveDict (Object type ) {
1650- if (type instanceof PythonBuiltinClassType ) {
1651- return ((PythonBuiltinClassType ) type ).isBuiltinWithDict ();
1652- }
1653- if (type instanceof PythonClass ) {
1654- return (((PythonClass ) type ).getInstanceShape ().getFlags () & PythonObject .HAS_SLOTS_BUT_NO_DICT_FLAG ) == 0 ;
1655- }
1656- if (type instanceof PythonAbstractNativeObject ) {
1657- return CastToJavaIntExactNode .getUncached ().execute (GetTypeMemberNode .getUncached ().execute (type , NativeMember .TP_DICTOFFSET )) != 0 ;
1658- }
1659- return true ;
1660- }
16611689}
0 commit comments