Skip to content

Commit 5c859a2

Browse files
committed
Do not overwrite get/set descr for '__basicsize__', '__itemsize__', and
'__dictoffset__' from native code.
1 parent 99aa8a9 commit 5c859a2

File tree

4 files changed

+51
-42
lines changed

4 files changed

+51
-42
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@
131131
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
132132
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
133133
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
134+
import com.oracle.graal.python.nodes.attributes.SetAttributeNode;
134135
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
135136
import com.oracle.graal.python.nodes.builtins.TupleNodes;
136137
import com.oracle.graal.python.nodes.call.CallDispatchNode;
@@ -1744,7 +1745,7 @@ public PFunction function(Object cls, Object method_def, Object def, Object name
17441745
public abstract static class TypeNode extends PythonBuiltinNode {
17451746
private static final long SIZEOF_PY_OBJECT_PTR = Long.BYTES;
17461747
@Child private ReadAttributeFromObjectNode readAttrNode;
1747-
@Child private WriteAttributeToObjectNode writeAttrNode;
1748+
@Child private SetAttributeNode.Dynamic writeAttrNode;
17481749
@Child private GetAnyAttributeNode getAttrNode;
17491750
@Child private CastToIndexNode castToInt;
17501751
@Child private CastToListNode castToList;
@@ -2154,10 +2155,10 @@ private GetAnyAttributeNode ensureGetAttributeNode() {
21542155
return getAttrNode;
21552156
}
21562157

2157-
private WriteAttributeToObjectNode ensureWriteAttrNode() {
2158+
private SetAttributeNode.Dynamic ensureWriteAttrNode() {
21582159
if (writeAttrNode == null) {
21592160
CompilerDirectives.transferToInterpreterAndInvalidate();
2160-
writeAttrNode = insert(WriteAttributeToObjectNode.createForceType());
2161+
writeAttrNode = insert(SetAttributeNode.Dynamic.create());
21612162
}
21622163
return writeAttrNode;
21632164
}

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

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
import com.oracle.graal.python.builtins.objects.type.ManagedPythonClass;
9999
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
100100
import com.oracle.graal.python.builtins.objects.type.PythonClass;
101+
import com.oracle.graal.python.builtins.objects.type.TypeBuiltins;
101102
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
102103
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroNode;
103104
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
@@ -108,6 +109,7 @@
108109
import com.oracle.graal.python.nodes.PNodeWithContext;
109110
import com.oracle.graal.python.nodes.SpecialAttributeNames;
110111
import com.oracle.graal.python.nodes.SpecialMethodNames;
112+
import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetFixedAttributeNode;
111113
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
112114
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
113115
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
@@ -501,14 +503,14 @@ Object doTpHash(ManagedPythonClass object, @SuppressWarnings("unused") String ke
501503

502504
@Specialization(guards = "eq(TP_BASICSIZE, key)")
503505
Object doTpBasicsize(ManagedPythonClass object, @SuppressWarnings("unused") String key,
504-
@Cached("create(__BASICSIZE__)") LookupAttributeInMRONode getAttrNode) {
505-
return getAttrNode.execute(object);
506+
@Cached("create(__BASICSIZE__)") GetFixedAttributeNode getAttrNode) {
507+
return getAttrNode.executeObject(object);
506508
}
507509

508510
@Specialization(guards = "eq(TP_ITEMSIZE, key)")
509511
Object doTpItemsize(ManagedPythonClass object, @SuppressWarnings("unused") String key,
510-
@Cached("create(__ITEMSIZE__)") LookupAttributeInMRONode getAttrNode) {
511-
Object val = getAttrNode.execute(object);
512+
@Cached("create(__ITEMSIZE__)") GetFixedAttributeNode getAttrNode) {
513+
Object val = getAttrNode.executeObject(object);
512514
// If the attribute does not exist, this means that we take 'tp_itemsize' from the base
513515
// object which is by default 0 (see typeobject.c:PyBaseObject_Type).
514516
if (val == PNone.NO_VALUE) {
@@ -520,12 +522,12 @@ Object doTpItemsize(ManagedPythonClass object, @SuppressWarnings("unused") Strin
520522
@Specialization(guards = "eq(TP_DICTOFFSET, key)")
521523
Object doTpDictoffset(ManagedPythonClass object, @SuppressWarnings("unused") String key,
522524
@Cached("create()") CastToIndexNode castToIntNode,
523-
@Cached("create(__DICTOFFSET__)") LookupAttributeInMRONode getAttrNode) {
525+
@Cached("create(__DICTOFFSET__)") GetFixedAttributeNode getAttrNode) {
524526
// TODO properly implement 'tp_dictoffset' for builtin classes
525527
if (object instanceof PythonBuiltinClass) {
526528
return 0L;
527529
}
528-
Object dictoffset = getAttrNode.execute(object);
530+
Object dictoffset = getAttrNode.executeObject(object);
529531
return castToIntNode.execute(dictoffset);
530532
}
531533

@@ -876,7 +878,7 @@ public Object access(PythonNativeWrapper object, String key, Object value) {
876878
}
877879
}
878880

879-
@ImportStatic({NativeMemberNames.class, PGuards.class, SpecialMethodNames.class})
881+
@ImportStatic({NativeMemberNames.class, PGuards.class, SpecialMethodNames.class, SpecialAttributeNames.class})
880882
abstract static class WriteNativeMemberNode extends PNodeWithContext {
881883
@Child private HashingStorageNodes.SetItemNode setItemNode;
882884

@@ -896,20 +898,14 @@ long doTpFlags(ManagedPythonClass object, @SuppressWarnings("unused") String key
896898
}
897899

898900
@Specialization(guards = "eq(TP_BASICSIZE, key)")
899-
@TruffleBoundary
900-
long doTpBasicsize(PythonBuiltinClass object, @SuppressWarnings("unused") String key, long basicsize) {
901-
// We have to use the 'setAttributeUnsafe' because this properly cannot be modified by
902-
// the user and we need to initialize it.
903-
object.setAttributeUnsafe(SpecialAttributeNames.__BASICSIZE__, basicsize);
904-
return basicsize;
905-
}
906-
907-
@Specialization(guards = "eq(TP_BASICSIZE, key)")
908-
@TruffleBoundary
909-
long doTpBasicsize(PythonClass object, @SuppressWarnings("unused") String key, long basicsize) {
910-
// Do deliberately not use "SetAttributeNode" because we want to directly set the
911-
// attribute an bypass any user code.
912-
object.setAttribute(SpecialAttributeNames.__BASICSIZE__, basicsize);
901+
long doTpBasicsize(AbstractPythonClass object, @SuppressWarnings("unused") String key, long basicsize,
902+
@Cached("create()") WriteAttributeToObjectNode writeAttrNode,
903+
@Cached("create()") IsBuiltinClassProfile profile) {
904+
if (profile.profileClass(object, PythonBuiltinClassType.PythonClass)) {
905+
writeAttrNode.execute(object, TypeBuiltins.TYPE_BASICSIZE, basicsize);
906+
} else {
907+
writeAttrNode.execute(object, SpecialAttributeNames.__BASICSIZE__, basicsize);
908+
}
913909
return basicsize;
914910
}
915911

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

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,17 @@
111111
import com.oracle.truffle.api.dsl.Specialization;
112112
import com.oracle.truffle.api.dsl.TypeSystemReference;
113113
import com.oracle.truffle.api.frame.VirtualFrame;
114+
import com.oracle.truffle.api.object.HiddenKey;
114115
import com.oracle.truffle.api.profiles.BranchProfile;
115116
import com.oracle.truffle.api.profiles.ConditionProfile;
116117

117118
@CoreFunctions(extendClasses = PythonBuiltinClassType.PythonClass)
118119
public class TypeBuiltins extends PythonBuiltins {
119120

121+
public static final HiddenKey TYPE_DICTOFFSET = new HiddenKey(__DICTOFFSET__);
122+
public static final HiddenKey TYPE_ITEMSIZE = new HiddenKey(__ITEMSIZE__);
123+
public static final HiddenKey TYPE_BASICSIZE = new HiddenKey(__BASICSIZE__);
124+
120125
@Override
121126
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
122127
return TypeBuiltinsFactory.getFactories();
@@ -703,14 +708,15 @@ private static String getQualName(String fqname) {
703708

704709
@Builtin(name = __DICTOFFSET__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
705710
static abstract class DictoffsetNode extends AbstractSlotNode {
706-
@Specialization(guards = "isNoValue(value)")
707-
String getName(PythonBuiltinClass cls, @SuppressWarnings("unused") PNone value) {
708-
return cls.getName();
709-
}
710711

711-
@Specialization(guards = {"isNoValue(value)", "!isPythonBuiltinClass(cls)"})
712-
Object getName(PythonClass cls, @SuppressWarnings("unused") PNone value,
712+
@Specialization(guards = "isNoValue(value)")
713+
Object getName(ManagedPythonClass cls, @SuppressWarnings("unused") PNone value,
714+
@Cached("create()") IsBuiltinClassProfile profile,
713715
@Cached("create()") ReadAttributeFromObjectNode getName) {
716+
// recursion anchor; since the metaclass of 'type' is 'type'
717+
if (profile.profileClass(cls, PythonBuiltinClassType.PythonClass)) {
718+
return getName.execute(cls, TYPE_DICTOFFSET);
719+
}
714720
return getName.execute(cls, __DICTOFFSET__);
715721
}
716722

@@ -739,14 +745,15 @@ Object setNative(@SuppressWarnings("unused") PythonAbstractNativeObject cls, @Su
739745

740746
@Builtin(name = __ITEMSIZE__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
741747
static abstract class ItemsizeNode extends AbstractSlotNode {
742-
@Specialization(guards = "isNoValue(value)")
743-
String getName(PythonBuiltinClass cls, @SuppressWarnings("unused") PNone value) {
744-
return cls.getName();
745-
}
746748

747-
@Specialization(guards = {"isNoValue(value)", "!isPythonBuiltinClass(cls)"})
748-
Object getName(PythonClass cls, @SuppressWarnings("unused") PNone value,
749+
@Specialization(guards = "isNoValue(value)")
750+
Object getName(ManagedPythonClass cls, @SuppressWarnings("unused") PNone value,
751+
@Cached("create()") IsBuiltinClassProfile profile,
749752
@Cached("create()") ReadAttributeFromObjectNode getName) {
753+
// recursion anchor; since the metaclass of 'type' is 'type'
754+
if (profile.profileClass(cls, PythonBuiltinClassType.PythonClass)) {
755+
return getName.execute(cls, TYPE_ITEMSIZE);
756+
}
750757
return getName.execute(cls, __ITEMSIZE__);
751758
}
752759

@@ -775,14 +782,15 @@ Object setNative(@SuppressWarnings("unused") PythonAbstractNativeObject cls, @Su
775782

776783
@Builtin(name = __BASICSIZE__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
777784
static abstract class BasicsizeNode extends AbstractSlotNode {
778-
@Specialization(guards = "isNoValue(value)")
779-
String getName(PythonBuiltinClass cls, @SuppressWarnings("unused") PNone value) {
780-
return cls.getName();
781-
}
782785

783-
@Specialization(guards = {"isNoValue(value)", "!isPythonBuiltinClass(cls)"})
784-
Object getName(PythonClass cls, @SuppressWarnings("unused") PNone value,
786+
@Specialization(guards = "isNoValue(value)")
787+
Object getName(ManagedPythonClass cls, @SuppressWarnings("unused") PNone value,
788+
@Cached("create()") IsBuiltinClassProfile profile,
785789
@Cached("create()") ReadAttributeFromObjectNode getName) {
790+
// recursion anchor; since the metaclass of 'type' is 'type'
791+
if (profile.profileClass(cls, PythonBuiltinClassType.PythonClass)) {
792+
return getName.execute(cls, TYPE_BASICSIZE);
793+
}
786794
return getName.execute(cls, __BASICSIZE__);
787795
}
788796

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/SetAttributeNode.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ public static final class Dynamic extends PNodeWithContext {
6262
public void execute(Object object, Object key, Object value) {
6363
call.execute(object, key, value);
6464
}
65+
66+
public static Dynamic create() {
67+
return new Dynamic();
68+
}
6569
}
6670

6771
private final String key;

0 commit comments

Comments
 (0)