Skip to content

Commit 8890ec9

Browse files
committed
Implement get/set descr for '__itemsize__', '__basicsize__', and
'__dictoffset__'.
1 parent 6641fa5 commit 8890ec9

File tree

2 files changed

+147
-19
lines changed

2 files changed

+147
-19
lines changed

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

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,11 @@
4949
import static com.oracle.graal.python.nodes.BuiltinNames.TUPLE;
5050
import static com.oracle.graal.python.nodes.BuiltinNames.TYPE;
5151
import static com.oracle.graal.python.nodes.BuiltinNames.ZIP;
52+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__BASICSIZE__;
53+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICTOFFSET__;
5254
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICT__;
5355
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__FILE__;
56+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__ITEMSIZE__;
5457
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__MODULE__;
5558
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__NAME__;
5659
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__SLOTS__;
@@ -123,8 +126,8 @@
123126
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroNode;
124127
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
125128
import com.oracle.graal.python.nodes.PGuards;
126-
import com.oracle.graal.python.nodes.SpecialAttributeNames;
127129
import com.oracle.graal.python.nodes.argument.CreateArgumentsNode;
130+
import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetAnyAttributeNode;
128131
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
129132
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
130133
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
@@ -1342,6 +1345,9 @@ public final Object varArgExecute(VirtualFrame frame, Object[] arguments, PKeywo
13421345

13431346
@Specialization
13441347
Object doDirectConstruct(@SuppressWarnings("unused") PNone ignored, Object[] arguments, @SuppressWarnings("unused") PKeyword[] kwargs) {
1348+
if (PGuards.isNativeClass(arguments[0])) {
1349+
throw raise(PythonBuiltinClassType.SystemError, "cannot instantiate native class here");
1350+
}
13451351
return factory().createPythonObject((LazyPythonClass) arguments[0]);
13461352
}
13471353

@@ -1739,6 +1745,7 @@ public abstract static class TypeNode extends PythonBuiltinNode {
17391745
private static final long SIZEOF_PY_OBJECT_PTR = Long.BYTES;
17401746
@Child private ReadAttributeFromObjectNode readAttrNode;
17411747
@Child private WriteAttributeToObjectNode writeAttrNode;
1748+
@Child private GetAnyAttributeNode getAttrNode;
17421749
@Child private CastToIndexNode castToInt;
17431750
@Child private CastToListNode castToList;
17441751
@Child private CastToStringNode castToStringNode;
@@ -2043,9 +2050,10 @@ private boolean addDictIfNative(ManagedPythonClass pythonClass) {
20432050
if (pythonClass.needsNativeAllocation()) {
20442051
for (Object cls : getMro(pythonClass)) {
20452052
if (PGuards.isNativeClass(cls)) {
2046-
long dictoffset = ensureCastToIntNode().execute(ensureReadAttrNode().execute(cls, SpecialAttributeNames.__DICTOFFSET__));
2047-
long basicsize = ensureCastToIntNode().execute(ensureReadAttrNode().execute(cls, SpecialAttributeNames.__BASICSIZE__));
2048-
long itemsize = ensureCastToIntNode().execute(ensureReadAttrNode().execute(cls, SpecialAttributeNames.__ITEMSIZE__));
2053+
// Use GetAnyAttributeNode since these are get-set-descriptors
2054+
long dictoffset = ensureCastToIntNode().execute(ensureGetAttributeNode().executeObject(cls, __DICTOFFSET__));
2055+
long basicsize = ensureCastToIntNode().execute(ensureGetAttributeNode().executeObject(cls, __BASICSIZE__));
2056+
long itemsize = ensureCastToIntNode().execute(ensureGetAttributeNode().executeObject(cls, __ITEMSIZE__));
20492057
if (dictoffset == 0) {
20502058
addedNewDict = true;
20512059
// add_dict
@@ -2056,9 +2064,9 @@ private boolean addDictIfNative(ManagedPythonClass pythonClass) {
20562064
basicsize += SIZEOF_PY_OBJECT_PTR;
20572065
}
20582066
}
2059-
ensureWriteAttrNode().execute(pythonClass, SpecialAttributeNames.__DICTOFFSET__, dictoffset);
2060-
ensureWriteAttrNode().execute(pythonClass, SpecialAttributeNames.__BASICSIZE__, basicsize);
2061-
ensureWriteAttrNode().execute(pythonClass, SpecialAttributeNames.__ITEMSIZE__, itemsize);
2067+
ensureWriteAttrNode().execute(pythonClass, __DICTOFFSET__, dictoffset);
2068+
ensureWriteAttrNode().execute(pythonClass, __BASICSIZE__, basicsize);
2069+
ensureWriteAttrNode().execute(pythonClass, __ITEMSIZE__, itemsize);
20622070
break;
20632071
}
20642072
}
@@ -2138,6 +2146,14 @@ private ReadAttributeFromObjectNode ensureReadAttrNode() {
21382146
return readAttrNode;
21392147
}
21402148

2149+
private GetAnyAttributeNode ensureGetAttributeNode() {
2150+
if (getAttrNode == null) {
2151+
CompilerDirectives.transferToInterpreterAndInvalidate();
2152+
getAttrNode = insert(GetAnyAttributeNode.create());
2153+
}
2154+
return getAttrNode;
2155+
}
2156+
21412157
private WriteAttributeToObjectNode ensureWriteAttrNode() {
21422158
if (writeAttrNode == null) {
21432159
CompilerDirectives.transferToInterpreterAndInvalidate();

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

Lines changed: 124 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@
2727
package com.oracle.graal.python.builtins.objects.type;
2828

2929
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__BASES__;
30+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__BASICSIZE__;
3031
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__CLASS__;
32+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICTOFFSET__;
3133
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICT__;
34+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__ITEMSIZE__;
3235
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__MODULE__;
3336
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__MRO__;
3437
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__NAME__;
@@ -95,6 +98,7 @@
9598
import com.oracle.graal.python.nodes.object.GetClassNode;
9699
import com.oracle.graal.python.nodes.object.GetLazyClassNode;
97100
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
101+
import com.oracle.graal.python.nodes.truffle.PythonTypes;
98102
import com.oracle.graal.python.runtime.exception.PythonErrorType;
99103
import com.oracle.truffle.api.CompilerAsserts;
100104
import com.oracle.truffle.api.CompilerDirectives;
@@ -105,6 +109,7 @@
105109
import com.oracle.truffle.api.dsl.ImportStatic;
106110
import com.oracle.truffle.api.dsl.NodeFactory;
107111
import com.oracle.truffle.api.dsl.Specialization;
112+
import com.oracle.truffle.api.dsl.TypeSystemReference;
108113
import com.oracle.truffle.api.frame.VirtualFrame;
109114
import com.oracle.truffle.api.profiles.BranchProfile;
110115
import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -542,10 +547,14 @@ private static <T> Object[] toArray(Set<T> subclasses) {
542547
}
543548
}
544549

545-
@Builtin(name = __NAME__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
546550
@GenerateNodeFactory
547551
@ImportStatic(NativeMemberNames.class)
548-
static abstract class NameNode extends PythonBinaryBuiltinNode {
552+
@TypeSystemReference(PythonTypes.class)
553+
static abstract class AbstractSlotNode extends PythonBinaryBuiltinNode {
554+
}
555+
556+
@Builtin(name = __NAME__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
557+
static abstract class NameNode extends AbstractSlotNode {
549558
@Specialization(guards = "isNoValue(value)")
550559
String getName(PythonBuiltinClass cls, @SuppressWarnings("unused") PNone value) {
551560
return cls.getName();
@@ -593,9 +602,7 @@ private static String getQualName(String fqname) {
593602
}
594603

595604
@Builtin(name = __MODULE__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
596-
@GenerateNodeFactory
597-
@ImportStatic(NativeMemberNames.class)
598-
static abstract class ModuleNode extends PythonBinaryBuiltinNode {
605+
static abstract class ModuleNode extends AbstractSlotNode {
599606

600607
@Specialization(guards = "isNoValue(value)")
601608
Object getModule(PythonBuiltinClass cls, @SuppressWarnings("unused") PNone value) {
@@ -621,15 +628,15 @@ Object setModule(PythonClass cls, Object value,
621628
}
622629

623630
@Specialization(guards = "isNoValue(value)")
624-
Object getModule(PythonAbstractNativeObject cls, @SuppressWarnings("unused") PNone value,
631+
Object getModule(PythonNativeClass cls, @SuppressWarnings("unused") PNone value,
625632
@Cached("create(TP_NAME)") GetTypeMemberNode getTpNameNode) {
626633
// 'tp_name' contains the fully-qualified name, i.e., 'module.A.B...'
627634
String tpName = (String) getTpNameNode.execute(cls);
628635
return getModuleName(tpName);
629636
}
630637

631638
@Specialization(guards = "!isNoValue(value)")
632-
Object getModule(@SuppressWarnings("unused") PythonAbstractNativeObject cls, @SuppressWarnings("unused") Object value) {
639+
Object setNative(@SuppressWarnings("unused") PythonNativeClass cls, @SuppressWarnings("unused") Object value) {
633640
throw raise(PythonErrorType.RuntimeError, "can't set attributes of native type");
634641
}
635642

@@ -648,9 +655,7 @@ protected String getBuiltinsName() {
648655
}
649656

650657
@Builtin(name = __QUALNAME__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
651-
@GenerateNodeFactory
652-
@ImportStatic(NativeMemberNames.class)
653-
static abstract class QualNameNode extends PythonBinaryBuiltinNode {
658+
static abstract class QualNameNode extends AbstractSlotNode {
654659
@Specialization(guards = "isNoValue(value)")
655660
String getName(PythonBuiltinClass cls, @SuppressWarnings("unused") PNone value) {
656661
return cls.getName();
@@ -674,15 +679,15 @@ Object setName(PythonClass cls, Object value,
674679
}
675680

676681
@Specialization(guards = "isNoValue(value)")
677-
String getNative(PythonAbstractNativeObject cls, @SuppressWarnings("unused") PNone value,
682+
String getNative(PythonNativeClass cls, @SuppressWarnings("unused") PNone value,
678683
@Cached("create(TP_NAME)") GetTypeMemberNode getTpNameNode) {
679684
// 'tp_name' contains the fully-qualified name, i.e., 'module.A.B...'
680685
String tpName = (String) getTpNameNode.execute(cls);
681686
return getQualName(tpName);
682687
}
683688

684689
@Specialization(guards = "!isNoValue(value)")
685-
Object getModule(@SuppressWarnings("unused") PythonAbstractNativeObject cls, @SuppressWarnings("unused") Object value) {
690+
Object setNative(@SuppressWarnings("unused") PythonNativeClass cls, @SuppressWarnings("unused") Object value) {
686691
throw raise(PythonErrorType.RuntimeError, "can't set attributes of native type");
687692
}
688693

@@ -694,6 +699,113 @@ private static String getQualName(String fqname) {
694699
}
695700
return fqname;
696701
}
702+
}
703+
704+
@Builtin(name = __DICTOFFSET__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
705+
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+
}
710+
711+
@Specialization(guards = {"isNoValue(value)", "!isPythonBuiltinClass(cls)"})
712+
Object getName(PythonClass cls, @SuppressWarnings("unused") PNone value,
713+
@Cached("create()") ReadAttributeFromObjectNode getName) {
714+
return getName.execute(cls, __DICTOFFSET__);
715+
}
716+
717+
@Specialization(guards = "!isNoValue(value)")
718+
Object setName(@SuppressWarnings("unused") PythonBuiltinClass cls, @SuppressWarnings("unused") Object value) {
719+
throw raise(PythonErrorType.RuntimeError, "can't set attributes of built-in/extension 'type'");
720+
}
721+
722+
@Specialization(guards = {"!isNoValue(value)", "!isPythonBuiltinClass(cls)"})
723+
Object setName(PythonClass cls, Object value,
724+
@Cached("create()") WriteAttributeToObjectNode setName) {
725+
return setName.execute(cls, __DICTOFFSET__, value);
726+
}
727+
728+
@Specialization(guards = "isNoValue(value)")
729+
Object getNative(PythonNativeClass cls, @SuppressWarnings("unused") PNone value,
730+
@Cached("create(TP_DICTOFFSET)") GetTypeMemberNode getTpDictoffsetNode) {
731+
return getTpDictoffsetNode.execute(cls);
732+
}
733+
734+
@Specialization(guards = "!isNoValue(value)")
735+
Object setNative(@SuppressWarnings("unused") PythonAbstractNativeObject cls, @SuppressWarnings("unused") Object value) {
736+
throw raise(PythonErrorType.RuntimeError, "can't set attributes of native type");
737+
}
738+
}
739+
740+
@Builtin(name = __ITEMSIZE__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
741+
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+
}
746+
747+
@Specialization(guards = {"isNoValue(value)", "!isPythonBuiltinClass(cls)"})
748+
Object getName(PythonClass cls, @SuppressWarnings("unused") PNone value,
749+
@Cached("create()") ReadAttributeFromObjectNode getName) {
750+
return getName.execute(cls, __ITEMSIZE__);
751+
}
752+
753+
@Specialization(guards = "!isNoValue(value)")
754+
Object setName(@SuppressWarnings("unused") PythonBuiltinClass cls, @SuppressWarnings("unused") Object value) {
755+
throw raise(PythonErrorType.RuntimeError, "can't set attributes of built-in/extension 'type'");
756+
}
757+
758+
@Specialization(guards = {"!isNoValue(value)", "!isPythonBuiltinClass(cls)"})
759+
Object setName(PythonClass cls, Object value,
760+
@Cached("create()") WriteAttributeToObjectNode setName) {
761+
return setName.execute(cls, __ITEMSIZE__, value);
762+
}
763+
764+
@Specialization(guards = "isNoValue(value)")
765+
Object getNative(PythonNativeClass cls, @SuppressWarnings("unused") PNone value,
766+
@Cached("create(TP_ITEMSIZE)") GetTypeMemberNode getTpDictoffsetNode) {
767+
return getTpDictoffsetNode.execute(cls);
768+
}
769+
770+
@Specialization(guards = "!isNoValue(value)")
771+
Object setNative(@SuppressWarnings("unused") PythonAbstractNativeObject cls, @SuppressWarnings("unused") Object value) {
772+
throw raise(PythonErrorType.RuntimeError, "can't set attributes of native type");
773+
}
774+
}
697775

776+
@Builtin(name = __BASICSIZE__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
777+
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+
}
782+
783+
@Specialization(guards = {"isNoValue(value)", "!isPythonBuiltinClass(cls)"})
784+
Object getName(PythonClass cls, @SuppressWarnings("unused") PNone value,
785+
@Cached("create()") ReadAttributeFromObjectNode getName) {
786+
return getName.execute(cls, __BASICSIZE__);
787+
}
788+
789+
@Specialization(guards = "!isNoValue(value)")
790+
Object setName(@SuppressWarnings("unused") PythonBuiltinClass cls, @SuppressWarnings("unused") Object value) {
791+
throw raise(PythonErrorType.RuntimeError, "can't set attributes of built-in/extension 'type'");
792+
}
793+
794+
@Specialization(guards = {"!isNoValue(value)", "!isPythonBuiltinClass(cls)"})
795+
Object setName(PythonClass cls, Object value,
796+
@Cached("create()") WriteAttributeToObjectNode setName) {
797+
return setName.execute(cls, __BASICSIZE__, value);
798+
}
799+
800+
@Specialization(guards = "isNoValue(value)")
801+
Object getNative(PythonNativeClass cls, @SuppressWarnings("unused") PNone value,
802+
@Cached("create(TP_BASICSIZE)") GetTypeMemberNode getTpDictoffsetNode) {
803+
return getTpDictoffsetNode.execute(cls);
804+
}
805+
806+
@Specialization(guards = "!isNoValue(value)")
807+
Object setNative(@SuppressWarnings("unused") PythonAbstractNativeObject cls, @SuppressWarnings("unused") Object value) {
808+
throw raise(PythonErrorType.RuntimeError, "can't set attributes of native type");
809+
}
698810
}
699811
}

0 commit comments

Comments
 (0)