Skip to content

Commit 54cd95b

Browse files
committed
[GR-23218] Make test_descr pass - class bases layout check.
PullRequest: graalpython/1257
2 parents 4c45900 + 625da95 commit 54cd95b

File tree

5 files changed

+26
-19
lines changed

5 files changed

+26
-19
lines changed

graalpython/com.oracle.graal.python.cext/src/capi.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,11 @@ PyObject* get_tp_dict(PyTypeObject* obj) {
300300
return native_to_java(obj->tp_dict);
301301
}
302302

303+
/** to be used from Java code only; reads native 'tp_base' field */
304+
PyObject* get_tp_base(PyTypeObject* obj) {
305+
return native_to_java(obj->tp_base);
306+
}
307+
303308
/** to be used from Java code only; reads native 'tp_bases' field */
304309
PyObject* get_tp_bases(PyTypeObject* obj) {
305310
return native_to_java(obj->tp_bases);

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_descr.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_dir
2222
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_doc_descriptor
2323
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_dynamics
24+
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_errors
2425
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_evil_type_name
2526
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_ex5_from_c3_switch
2627
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_file_fault
@@ -38,6 +39,7 @@
3839
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_methods
3940
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_methods_in_c
4041
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_mixing_slot_wrappers
42+
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_module_subclasses
4143
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_monotonicity
4244
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_mro_disagreement
4345
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_multiple_inheritance

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@
165165
import com.oracle.graal.python.builtins.objects.type.PythonClass;
166166
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
167167
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
168+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBestBaseClassNode;
168169
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroNode;
169170
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
170171
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsAcceptableBaseNode;
@@ -2076,7 +2077,8 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
20762077
@Cached CastToJavaStringNode castStr,
20772078
@Cached CallNode callSetNameNode,
20782079
@Cached CallNode callInitSubclassNode,
2079-
@Cached CallNode callNewFuncNode) {
2080+
@Cached CallNode callNewFuncNode,
2081+
@Cached GetBestBaseClassNode getBestBaseNode) {
20802082
// Determine the proper metatype to deal with this
20812083
String name = castStr.execute(wName);
20822084
Object metaclass = calculate_metaclass(frame, cls, bases, lib);
@@ -2091,7 +2093,7 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
20912093
}
20922094

20932095
try {
2094-
PythonClass newType = typeMetaclass(frame, name, bases, namespace, metaclass, nslib);
2096+
PythonClass newType = typeMetaclass(frame, name, bases, namespace, metaclass, nslib, getBestBaseNode);
20952097

20962098
for (DictEntry entry : nslib.entries(namespace.getDictStorage())) {
20972099
Object setName = getSetNameNode.execute(entry.value);
@@ -2176,8 +2178,8 @@ private String getModuleNameFromGlobals(PythonObject globals, HashingStorageLibr
21762178
}
21772179
}
21782180

2179-
private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases, PDict namespace, Object metaclass, HashingStorageLibrary nslib) {
2180-
2181+
private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases, PDict namespace, Object metaclass, HashingStorageLibrary nslib,
2182+
GetBestBaseClassNode getBestBaseNode) {
21812183
Object[] array = ensureGetObjectArrayNode().execute(bases);
21822184

21832185
PythonAbstractClass[] basesArray;
@@ -2195,6 +2197,9 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
21952197
}
21962198
}
21972199
}
2200+
// check for possible layout conflicts
2201+
getBestBaseNode.execute(basesArray);
2202+
21982203
assert metaclass != null;
21992204

22002205
if (name.indexOf('\0') != -1) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/NativeCAPISymbols.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public abstract class NativeCAPISymbols {
5959
public static final String FUN_GET_OB_TYPE = "get_ob_type";
6060
public static final String FUN_GET_OB_REFCNT = "get_ob_refcnt";
6161
public static final String FUN_GET_TP_DICT = "get_tp_dict";
62+
public static final String FUN_GET_TP_BASE = "get_tp_base";
6263
public static final String FUN_GET_TP_BASES = "get_tp_bases";
6364
public static final String FUN_GET_TP_NAME = "get_tp_name";
6465
public static final String FUN_GET_TP_MRO = "get_tp_mro";

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@
117117
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
118118
import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
119119
import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
120-
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
121120
import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodNode;
122121
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
123122
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
@@ -691,7 +690,7 @@ static PythonAbstractClass doNative(PythonNativeClass obj,
691690

692691
@ImportStatic(SpecialMethodNames.class)
693692
@GenerateUncached
694-
abstract static class GetBestBaseClassNode extends PNodeWithContext {
693+
public abstract static class GetBestBaseClassNode extends PNodeWithContext {
695694

696695
static GetBestBaseClassNode create() {
697696
return TypeNodesFactory.GetBestBaseClassNodeGen.create();
@@ -750,7 +749,7 @@ private static Object bestBase(PythonAbstractClass[] bases, GetSolidBaseNode get
750749
winner = candidate;
751750
base = basei;
752751
} else {
753-
throw raiseNode.raise(SystemError, ErrorMessages.MULTIPLE_BASES_LAYOUT_CONFLICT);
752+
throw raiseNode.raise(TypeError, ErrorMessages.MULTIPLE_BASES_LAYOUT_CONFLICT);
754753
}
755754
}
756755
return base;
@@ -763,7 +762,6 @@ public abstract static class CheckCompatibleForAssigmentNode extends PNodeWithCo
763762
@Child private LookupAttributeInMRONode lookupSlotsNode;
764763
@Child private LookupAttributeInMRONode lookupNewNode;
765764
@Child private GetDictStorageNode getDictStorageNode;
766-
@Child private LookupAndCallBinaryNode getDictNode;
767765
@Child private HashingStorageLibrary hashingStorageLib;
768766
@Child private PythonObjectLibrary objectLibrary;
769767
@Child private GetObjectArrayNode getObjectArrayNode;
@@ -1012,35 +1010,35 @@ protected Object exec(Object type,
10121010
@Cached CallBinaryMethodNode callGetAttr,
10131011
@Cached GetDictStorageNode getDictStorageNode,
10141012
@CachedLibrary(limit = "4") HashingStorageLibrary storageLibrary,
1015-
@Cached GetObjectArrayNode getObjectArrayNode,
10161013
@CachedLibrary(limit = "4") PythonObjectLibrary objectLibrary) {
1017-
return solidBase(type, getBaseClassNode, context, lookupGetAttribute, callGetAttr, getDictStorageNode, storageLibrary, getObjectArrayNode, objectLibrary);
1014+
return solidBase(type, getBaseClassNode, context, lookupGetAttribute, callGetAttr, getDictStorageNode, storageLibrary, objectLibrary);
10181015
}
10191016

10201017
private Object solidBase(Object type, GetBaseClassNode getBaseClassNode, PythonContext context, LookupSpecialMethodNode.Dynamic lookupGetAttribute,
1021-
CallBinaryMethodNode callGetAttr, GetDictStorageNode getDictStorageNode, HashingStorageLibrary storageLibrary, GetObjectArrayNode getObjectArrayNode,
1018+
CallBinaryMethodNode callGetAttr, GetDictStorageNode getDictStorageNode, HashingStorageLibrary storageLibrary,
10221019
PythonObjectLibrary objectLibrary) {
10231020
Object base = getBaseClassNode.execute(type);
10241021

10251022
if (base != null) {
1026-
base = solidBase(base, getBaseClassNode, context, lookupGetAttribute, callGetAttr, getDictStorageNode, storageLibrary, getObjectArrayNode, objectLibrary);
1023+
base = solidBase(base, getBaseClassNode, context, lookupGetAttribute, callGetAttr, getDictStorageNode, storageLibrary, objectLibrary);
10271024
} else {
10281025
base = context.getCore().lookupType(PythonBuiltinClassType.PythonObject);
10291026
}
10301027

1031-
if (extraivars(type, base, lookupGetAttribute, callGetAttr, getDictStorageNode, storageLibrary, getObjectArrayNode, objectLibrary)) {
1028+
if (type != base && extraivars(type, base, lookupGetAttribute, callGetAttr, getDictStorageNode, storageLibrary, objectLibrary)) {
10321029
return type;
10331030
} else {
10341031
return base;
10351032
}
10361033
}
10371034

10381035
private boolean extraivars(Object type, Object base, LookupSpecialMethodNode.Dynamic lookupGetAttribute, CallBinaryMethodNode callGetAttr,
1039-
GetDictStorageNode getDictStorageNode, HashingStorageLibrary storageLibrary, GetObjectArrayNode getObjectArrayNode, PythonObjectLibrary objectLibrary) {
1036+
GetDictStorageNode getDictStorageNode, HashingStorageLibrary storageLibrary, PythonObjectLibrary objectLibrary) {
10401037
Object typeSlots = getSlotsFromDict(type, lookupGetAttribute, callGetAttr, getDictStorageNode, storageLibrary);
10411038
Object baseSlots = getSlotsFromDict(base, lookupGetAttribute, callGetAttr, getDictStorageNode, storageLibrary);
10421039

1043-
if (typeSlots == null ^ baseSlots == null) {
1040+
if (typeSlots == null && baseSlots != null && objectLibrary.length(baseSlots) != 0 ||
1041+
baseSlots == null && typeSlots != null && objectLibrary.length(typeSlots) != 0) {
10441042
return true;
10451043
}
10461044

@@ -1049,10 +1047,6 @@ private boolean extraivars(Object type, Object base, LookupSpecialMethodNode.Dyn
10491047
if (typeNewMethod != baseNewMethod) {
10501048
return true;
10511049
}
1052-
1053-
if (typeSlots != null && baseSlots != null) {
1054-
return compareSortedSlots(typeSlots, baseSlots, getObjectArrayNode);
1055-
}
10561050
return hasDict(base, objectLibrary) != hasDict(type, objectLibrary);
10571051
}
10581052

0 commit comments

Comments
 (0)