Skip to content

Commit 896cab1

Browse files
msimaceksteve-s
authored andcommitted
Inherit tp_new from dominant base
1 parent 2400dd3 commit 896cab1

File tree

6 files changed

+137
-48
lines changed

6 files changed

+137
-48
lines changed

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@
153153
import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView;
154154
import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
155155
import com.oracle.graal.python.builtins.objects.namespace.PSimpleNamespace;
156-
import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
156+
import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins.InitNode;
157157
import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsFactory;
158158
import com.oracle.graal.python.builtins.objects.object.PythonObject;
159159
import com.oracle.graal.python.builtins.objects.property.PProperty;
@@ -175,6 +175,7 @@
175175
import com.oracle.graal.python.builtins.objects.type.TypeNodes.CreateTypeNode;
176176
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsAcceptableBaseNode;
177177
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
178+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.LookupNewNode;
178179
import com.oracle.graal.python.builtins.objects.type.TypeNodes.NeedsNativeAllocationNode;
179180
import com.oracle.graal.python.builtins.objects.types.PGenericAlias;
180181
import com.oracle.graal.python.lib.CanBeDoubleNode;
@@ -1752,7 +1753,7 @@ public abstract static class ObjectNode extends PythonVarargsBuiltinNode {
17521753

17531754
@Child private SplitArgsNode splitArgsNode;
17541755
@Child private LookupCallableSlotInMRONode lookupInit;
1755-
@Child private LookupCallableSlotInMRONode lookupNew;
1756+
@Child private LookupNewNode lookupNew;
17561757
@Child private ReportAbstractClassNode reportAbstractClassNode;
17571758
@CompilationFinal private ValueProfile profileInit;
17581759
@CompilationFinal private ValueProfile profileNew;
@@ -1859,7 +1860,7 @@ private void checkExcessArgs(Object type, Object[] varargs, PKeyword[] kwargs) {
18591860
if (varargs.length != 0 || kwargs.length != 0) {
18601861
if (lookupNew == null) {
18611862
CompilerDirectives.transferToInterpreterAndInvalidate();
1862-
lookupNew = insert(LookupCallableSlotInMRONode.create(SpecialMethodSlot.New));
1863+
lookupNew = insert(LookupNewNode.create());
18631864
}
18641865
if (lookupInit == null) {
18651866
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -1881,10 +1882,10 @@ private void checkExcessArgs(Object type, Object[] varargs, PKeyword[] kwargs) {
18811882
CompilerDirectives.transferToInterpreterAndInvalidate();
18821883
profileInitFactory = ValueProfile.createClassProfile();
18831884
}
1884-
if (ObjectBuiltins.InitNode.overridesBuiltinMethod(type, profileNew, lookupNew, profileNewFactory, BuiltinConstructorsFactory.ObjectNodeFactory.class)) {
1885+
if (InitNode.overridesBuiltinMethod(profileNew.profile(lookupNew.execute(type)), BuiltinConstructorsFactory.ObjectNodeFactory.class, profileNewFactory)) {
18851886
throw raise(TypeError, ErrorMessages.NEW_TAKES_ONE_ARG);
18861887
}
1887-
if (!ObjectBuiltins.InitNode.overridesBuiltinMethod(type, profileInit, lookupInit, profileInitFactory, ObjectBuiltinsFactory.InitNodeFactory.class)) {
1888+
if (!InitNode.overridesBuiltinMethod(profileInit.profile(lookupInit.execute(type)), ObjectBuiltinsFactory.InitNodeFactory.class, profileInitFactory)) {
18881889
throw raise(TypeError, ErrorMessages.NEW_TAKES_NO_ARGS, type);
18891890
}
18901891
}
@@ -2406,7 +2407,7 @@ public Object varArgExecute(VirtualFrame frame, Object self, Object[] arguments,
24062407
Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict namespaceOrig, PKeyword[] kwds,
24072408
@Bind("this") Node inliningTarget,
24082409
@Cached GetClassNode getClassNode,
2409-
@Cached("create(New)") LookupCallableSlotInMRONode getNewFuncNode,
2410+
@Cached LookupNewNode getNewFuncNode,
24102411
@Cached TypeBuiltins.BindNew bindNew,
24112412
@Exclusive @Cached IsTypeNode isTypeNode,
24122413
@Cached PyObjectLookupAttr lookupMroEntriesNode,

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@
136136
import com.oracle.graal.python.builtins.objects.object.PythonObject;
137137
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
138138
import com.oracle.graal.python.builtins.objects.type.PythonClass;
139-
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
140139
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode;
141140
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
142141
import com.oracle.graal.python.builtins.objects.type.TypeNodes.HasSameConstructorNode;
143142
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
143+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.LookupNewNode;
144144
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
145145
import com.oracle.graal.python.lib.PyObjectIsTrueNode;
146146
import com.oracle.graal.python.lib.PyTupleSizeNode;
@@ -151,7 +151,6 @@
151151
import com.oracle.graal.python.nodes.PRaiseNode;
152152
import com.oracle.graal.python.nodes.SpecialAttributeNames;
153153
import com.oracle.graal.python.nodes.SpecialMethodNames;
154-
import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
155154
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
156155
import com.oracle.graal.python.nodes.attributes.WriteAttributeToDynamicObjectNode;
157156
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
@@ -2361,7 +2360,6 @@ record HPyTypeSpecParam(int kind, Object object) {
23612360
* } HPyType_Spec;
23622361
* </pre>
23632362
*/
2364-
@ImportStatic(SpecialMethodSlot.class)
23652363
@GenerateUncached
23662364
abstract static class HPyCreateTypeFromSpecNode extends Node {
23672365

@@ -2396,7 +2394,7 @@ Object doGeneric(GraalHPyContext context, Object typeSpec, Object typeSpecParamA
23962394
@Cached HPyCreateGetSetDescriptorNode createGetSetDescriptorNode,
23972395
@Cached GetBaseClassNode getBaseClassNode,
23982396
@Cached ReadAttributeFromObjectNode readHPyTypeFlagsNode,
2399-
@Cached(parameters = "New") LookupCallableSlotInMRONode lookupNewNode,
2397+
@Cached LookupNewNode lookupNewNode,
24002398
@Cached HPyAsPythonObjectNode hPyAsPythonObjectNode,
24012399
@Cached PRaiseNode raiseNode) {
24022400

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
9898
import com.oracle.graal.python.builtins.objects.type.TypeNodes.CheckCompatibleForAssigmentNode;
9999
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode;
100+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.LookupNewNode;
100101
import com.oracle.graal.python.lib.PyObjectLookupAttr;
101102
import com.oracle.graal.python.lib.PyObjectSizeNode;
102103
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -248,16 +249,17 @@ PNone init(Object self, Object[] arguments, PKeyword[] keywords,
248249
@Cached("create(Init)") LookupCallableSlotInMRONode lookupInit,
249250
@Cached(value = "createLookupProfile(getClassNode)", inline = false) ValueProfile profileInit,
250251
@Cached(value = "createClassProfile()", inline = false) ValueProfile profileInitFactory,
251-
@Cached("create(New)") LookupCallableSlotInMRONode lookupNew,
252+
@Cached LookupNewNode lookupNew,
252253
@Cached(value = "createLookupProfile(getClassNode)", inline = false) ValueProfile profileNew,
253254
@Cached(value = "createClassProfile()", inline = false) ValueProfile profileNewFactory) {
254255
if (arguments.length != 0 || keywords.length != 0) {
255256
Object type = getClassNode.execute(inliningTarget, self);
256-
if (overridesNew.profile(inliningTarget, overridesBuiltinMethod(type, profileInit, lookupInit, profileInitFactory, ObjectBuiltinsFactory.InitNodeFactory.class))) {
257+
if (overridesNew.profile(inliningTarget, overridesBuiltinMethod(profileInit.profile(lookupInit.execute(type)), ObjectBuiltinsFactory.InitNodeFactory.class, profileInitFactory))) {
257258
throw raise(TypeError, ErrorMessages.INIT_TAKES_ONE_ARG_OBJECT);
258259
}
259260

260-
if (overridesInit.profile(inliningTarget, !overridesBuiltinMethod(type, profileNew, lookupNew, profileNewFactory, BuiltinConstructorsFactory.ObjectNodeFactory.class))) {
261+
if (overridesInit.profile(inliningTarget,
262+
!overridesBuiltinMethod(profileNew.profile(lookupNew.execute(type)), BuiltinConstructorsFactory.ObjectNodeFactory.class, profileNewFactory))) {
261263
throw raise(TypeError, ErrorMessages.INIT_TAKES_ONE_ARG, type);
262264
}
263265
}
@@ -274,11 +276,9 @@ protected static ValueProfile createLookupProfile(Node node) {
274276

275277
/**
276278
* Simple utility method to check if a method was overridden. The {@code profile} parameter
277-
* must {@emph not} be an identity profile when AST sharing is enabled.
279+
* must not be an identity profile when AST sharing is enabled.
278280
*/
279-
public static <T extends NodeFactory<? extends PythonBuiltinBaseNode>> boolean overridesBuiltinMethod(Object type, ValueProfile profile, LookupCallableSlotInMRONode lookup,
280-
ValueProfile factoryProfile, Class<T> builtinNodeFactoryClass) {
281-
Object method = profile.profile(lookup.execute(type));
281+
public static <T extends NodeFactory<? extends PythonBuiltinBaseNode>> boolean overridesBuiltinMethod(Object method, Class<T> builtinNodeFactoryClass, ValueProfile factoryProfile) {
282282
if (method instanceof PBuiltinFunction) {
283283
NodeFactory<? extends PythonBuiltinBaseNode> factory = factoryProfile.profile(((PBuiltinFunction) method).getBuiltinNodeFactory());
284284
return !builtinNodeFactoryClass.isInstance(factory);

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

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,10 @@
155155
import com.oracle.graal.python.builtins.objects.dict.PDict;
156156
import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor;
157157
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
158+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode;
158159
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroStorageNode;
159160
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetSubclassesNode;
161+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.LookupNewNode;
160162
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
161163
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromDynamicObjectNode;
162164
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
@@ -297,6 +299,15 @@ static class Flags {
297299
}
298300

299301
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+
}
300311
private final TruffleString name;
301312
@CompilationFinal private SpecialMethodSlot reverse;
302313
/**
@@ -532,6 +543,7 @@ private static Object[] initializeSpecialMethodsSlots(PythonManagedClass klass,
532543
if (isMroSubtype(mro, managedBase)) {
533544
Object[] result = PythonUtils.arrayCopyOf(managedBase.specialMethodSlots, managedBase.specialMethodSlots.length);
534545
setSlotsFromManaged(result, klass, language);
546+
setNewSlot(result, klass);
535547
setMethodsFlags(result, klass);
536548
return result;
537549
}
@@ -573,6 +585,7 @@ private static Object[] initializeSpecialMethodsSlots(PythonManagedClass klass,
573585
setSlotsFromGeneric(slots, base, language);
574586
}
575587
}
588+
setNewSlot(slots, klass);
576589
setMethodsFlags(slots, klass);
577590
return slots;
578591
}
@@ -613,20 +626,29 @@ private static void setMethodsFlags(Object[] slots, PythonManagedClass klass) {
613626
}
614627
}
615628

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+
616638
private static void setSlotsFromManaged(Object[] slots, PythonManagedClass source, PythonLanguage language) {
617639
PDict dict = GetDictIfExistsNode.getUncached().execute(source);
618640
if (dict == null) {
619641
DynamicObject storage = source.getStorage();
620642
DynamicObjectLibrary domLib = DynamicObjectLibrary.getFactory().getUncached(storage);
621-
for (SpecialMethodSlot slot : VALUES) {
643+
for (SpecialMethodSlot slot : MRO_INHERITED_SLOTS) {
622644
final Object value = domLib.getOrDefault(source, slot.getName(), PNone.NO_VALUE);
623645
if (value != PNone.NO_VALUE) {
624646
slots[slot.ordinal()] = asSlotValue(slot, value, language);
625647
}
626648
}
627649
} else {
628650
HashingStorage storage = dict.getDictStorage();
629-
for (SpecialMethodSlot slot : VALUES) {
651+
for (SpecialMethodSlot slot : MRO_INHERITED_SLOTS) {
630652
final Object value = HashingStorageGetItem.executeUncached(storage, slot.getName());
631653
if (value != null) {
632654
slots[slot.ordinal()] = asSlotValue(slot, value, language);
@@ -637,7 +659,7 @@ private static void setSlotsFromManaged(Object[] slots, PythonManagedClass sourc
637659

638660
private static void setSlotsFromGeneric(Object[] slots, PythonAbstractClass base, PythonLanguage language) {
639661
ReadAttributeFromObjectNode readAttNode = ReadAttributeFromObjectNode.getUncachedForceType();
640-
for (SpecialMethodSlot slot : VALUES) {
662+
for (SpecialMethodSlot slot : MRO_INHERITED_SLOTS) {
641663
Object value = readAttNode.execute(base, slot.getName());
642664
if (value != PNone.NO_VALUE) {
643665
slots[slot.ordinal()] = asSlotValue(slot, value, language);
@@ -651,7 +673,11 @@ public static void fixupSpecialMethodSlot(PythonNativeClass klass, SpecialMethod
651673
if (value == PNone.NO_VALUE) {
652674
// We are removing the value: find the new value for the class that is being updated and
653675
// 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+
}
655681
}
656682
fixupSpecialMethodInSubClasses(GetSubclassesNode.executeUncached(klass), slot, newValue, PythonContext.get(null));
657683
}
@@ -675,7 +701,11 @@ public static void fixupSpecialMethodSlot(PythonManagedClass klass, SpecialMetho
675701
if (value == PNone.NO_VALUE) {
676702
// We are removing the value: find the new value for the class that is being updated and
677703
// 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+
}
679709
}
680710

681711
PythonContext context = PythonContext.get(null);
@@ -1215,7 +1245,7 @@ public static boolean validateSlots(Object klassIn) {
12151245
if (type.getSpecialMethodSlots() == null) {
12161246
return true;
12171247
}
1218-
for (SpecialMethodSlot slot : VALUES) {
1248+
for (SpecialMethodSlot slot : MRO_INHERITED_SLOTS) {
12191249
Object actual = LookupAttributeInMRONode.findAttr(core, type, slot.getName(), uncachedReadAttrNode);
12201250
Object expected = slot.getValue(type);
12211251
if (expected instanceof BuiltinMethodDescriptor) {
@@ -1230,7 +1260,7 @@ public static boolean validateSlots(Object klassIn) {
12301260
}
12311261
if (klass instanceof PythonManagedClass) {
12321262
PythonManagedClass managed = (PythonManagedClass) klass;
1233-
for (SpecialMethodSlot slot : VALUES) {
1263+
for (SpecialMethodSlot slot : MRO_INHERITED_SLOTS) {
12341264
Object actual = LookupAttributeInMRONode.lookupSlowPath(managed, slot.getName());
12351265
Object expected = slot.getValue(managed);
12361266
if (expected instanceof NodeFactory<?>) {

0 commit comments

Comments
 (0)