Skip to content

Commit e74eded

Browse files
msimacektimfel
authored andcommitted
Migrate isSequence and isMapping to nodes
1 parent 19e1794 commit e74eded

File tree

13 files changed

+285
-216
lines changed

13 files changed

+285
-216
lines changed

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

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@
189189
import com.oracle.graal.python.lib.CanBeDoubleNode;
190190
import com.oracle.graal.python.lib.PyFloatAsDoubleNode;
191191
import com.oracle.graal.python.lib.PyFloatFromString;
192+
import com.oracle.graal.python.lib.PyMappingCheckNode;
192193
import com.oracle.graal.python.lib.PyMemoryViewFromObject;
193194
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
194195
import com.oracle.graal.python.lib.PyNumberFloatNode;
@@ -3189,30 +3190,20 @@ Object initArgs(Object cls, Object[] args, @SuppressWarnings("unused") PKeyword[
31893190
@Builtin(name = "mappingproxy", constructsClass = PythonBuiltinClassType.PMappingproxy, isPublic = false, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2)
31903191
@GenerateNodeFactory
31913192
public abstract static class MappingproxyNode extends PythonBuiltinNode {
3192-
@Specialization(guards = "isMapping(obj, lib)", limit = "1")
3193+
@Specialization
31933194
Object doMapping(Object klass, PythonObject obj,
3194-
@SuppressWarnings("unused") @CachedLibrary("obj") PythonObjectLibrary lib) {
3195-
return factory().createMappingproxy(klass, obj);
3195+
@Cached PyMappingCheckNode mappingCheckNode) {
3196+
if (mappingCheckNode.execute(obj)) {
3197+
return factory().createMappingproxy(klass, obj);
3198+
}
3199+
throw raise(TypeError, ErrorMessages.ARG_MUST_BE_S_NOT_P, "mappingproxy()", "mapping", obj);
31963200
}
31973201

31983202
@Specialization(guards = "isNoValue(none)")
31993203
@SuppressWarnings("unused")
32003204
Object doMissing(Object klass, PNone none) {
32013205
throw raise(TypeError, ErrorMessages.MISSING_D_REQUIRED_S_ARGUMENT_S_POS, "mappingproxy()", "mapping", 1);
32023206
}
3203-
3204-
@Specialization(guards = {"!isMapping(obj, lib)", "!isNoValue(obj)"}, limit = "1")
3205-
Object doInvalid(@SuppressWarnings("unused") Object klass, Object obj,
3206-
@SuppressWarnings("unused") @CachedLibrary("obj") PythonObjectLibrary lib) {
3207-
throw raise(TypeError, ErrorMessages.ARG_MUST_BE_S_NOT_P, "mappingproxy()", "mapping", obj);
3208-
}
3209-
3210-
protected static boolean isMapping(Object o, PythonObjectLibrary library) {
3211-
if (o instanceof PList || o instanceof PTuple) {
3212-
return false;
3213-
}
3214-
return library.isMapping(o);
3215-
}
32163207
}
32173208

32183209
abstract static class DescriptorNode extends PythonBuiltinNode {

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

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@
222222
import com.oracle.graal.python.lib.PyMemoryViewFromObject;
223223
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
224224
import com.oracle.graal.python.lib.PyNumberFloatNode;
225+
import com.oracle.graal.python.lib.PySequenceCheckNode;
225226
import com.oracle.graal.python.nodes.BuiltinNames;
226227
import com.oracle.graal.python.nodes.ErrorMessages;
227228
import com.oracle.graal.python.nodes.PGuards;
@@ -233,7 +234,6 @@
233234
import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode;
234235
import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode;
235236
import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetAnyAttributeNode;
236-
import com.oracle.graal.python.nodes.attributes.HasInheritedAttributeNode;
237237
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
238238
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
239239
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
@@ -2187,29 +2187,10 @@ Object doPTuple(Object tuple, @SuppressWarnings("unused") Object key) {
21872187
@Builtin(name = "PySequence_Check", minNumOfPositionalArgs = 1)
21882188
@GenerateNodeFactory
21892189
abstract static class PySequence_Check extends PythonUnaryBuiltinNode {
2190-
@Child private HasInheritedAttributeNode hasInheritedAttrNode;
2191-
2192-
@Specialization(guards = "isPSequence(object)")
2193-
int doSequence(@SuppressWarnings("unused") Object object) {
2194-
return 1;
2195-
}
2196-
21972190
@Specialization
2198-
int doDict(@SuppressWarnings("unused") PDict object) {
2199-
return 0;
2200-
}
2201-
2202-
@Fallback
2203-
int doGeneric(Object object) {
2204-
if (hasInheritedAttrNode == null) {
2205-
CompilerDirectives.transferToInterpreterAndInvalidate();
2206-
hasInheritedAttrNode = insert(HasInheritedAttributeNode.create(__GETITEM__));
2207-
}
2208-
return hasInheritedAttrNode.execute(object) ? 1 : 0;
2209-
}
2210-
2211-
protected static boolean isPSequence(Object object) {
2212-
return object instanceof PList || object instanceof PTuple;
2191+
boolean check(Object object,
2192+
@Cached PySequenceCheckNode check) {
2193+
return check.execute(object);
22132194
}
22142195
}
22152196

@@ -2483,17 +2464,6 @@ private void decodeUTF8(CharBuffer resultBuffer, ByteBuffer inputBuffer, String
24832464
}
24842465
}
24852466

2486-
@Builtin(name = "PyTruffle_IsSequence", minNumOfPositionalArgs = 1)
2487-
@GenerateNodeFactory
2488-
abstract static class PyTruffleIsSequence extends PythonUnaryBuiltinNode {
2489-
2490-
@Specialization(limit = "1")
2491-
static boolean doGeneric(Object object,
2492-
@CachedLibrary("object") PythonObjectLibrary dataModelLibrary) {
2493-
return dataModelLibrary.isSequence(object);
2494-
}
2495-
}
2496-
24972467
@Builtin(name = "PyTruffle_OS_StringToDouble", minNumOfPositionalArgs = 3, declaresExplicitSelf = true)
24982468
@GenerateNodeFactory
24992469
abstract static class PyTruffle_OS_StringToDouble extends NativeBuiltin {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictBuiltins.java

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
import com.oracle.graal.python.builtins.PythonBuiltins;
6060
import com.oracle.graal.python.builtins.objects.PNone;
6161
import com.oracle.graal.python.builtins.objects.PythonAbstractObject.LookupAttributeOnTypeNode;
62-
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.CheckIsSequenceNode;
6362
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetInternalObjectArrayNode;
6463
import com.oracle.graal.python.builtins.objects.dict.PDict;
6564
import com.oracle.graal.python.builtins.objects.function.PKeyword;
@@ -70,6 +69,7 @@
7069
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
7170
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
7271
import com.oracle.graal.python.lib.PyObjectSizeNode;
72+
import com.oracle.graal.python.lib.PySequenceCheckNode;
7373
import com.oracle.graal.python.nodes.PGuards;
7474
import com.oracle.graal.python.nodes.PNodeWithRaise;
7575
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -85,7 +85,6 @@
8585
import com.oracle.graal.python.nodes.object.GetDictIfExistsNode;
8686
import com.oracle.graal.python.nodes.subscript.GetItemNode;
8787
import com.oracle.graal.python.runtime.PythonContext;
88-
import com.oracle.graal.python.runtime.exception.PException;
8988
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
9089
import com.oracle.graal.python.util.PythonUtils;
9190
import com.oracle.truffle.api.dsl.Cached;
@@ -170,19 +169,13 @@ void MakeFields(VirtualFrame frame, Object type, CFieldObject descr, int index,
170169
@Cached GetClassNode getClassNode,
171170
@Cached GetAnyAttributeNode getAttributeNode,
172171
@Cached SetAttributeNode.Dynamic setAttributeNode,
173-
@Cached CheckIsSequenceNode isSequenceNode,
172+
@Cached PySequenceCheckNode sequenceCheckNode,
174173
@Cached PyObjectSizeNode sizeNode,
175174
@Cached GetItemNode getItemNode,
176175
@Cached GetInternalObjectArrayNode getArray,
177176
@Cached("create(_fields_)") GetAttributeNode getAttrString) {
178177
Object fields = getAttrString.executeObject(frame, descr.proto);
179-
boolean isFieldsSeq = false;
180-
try {
181-
isFieldsSeq = isSequenceNode.execute(fields);
182-
} catch (PException e) {
183-
// pass through
184-
}
185-
if (!isFieldsSeq) {
178+
if (!sequenceCheckNode.execute(fields)) {
186179
throw raise(TypeError, FIELDS_MUST_BE_A_SEQUENCE);
187180
}
188181

@@ -200,7 +193,7 @@ void MakeFields(VirtualFrame frame, Object type, CFieldObject descr, int index,
200193
if (fdescr.anonymous != 0) {
201194
MakeFields(frame, type, fdescr, index + fdescr.index, offset + fdescr.offset, factory,
202195
getClassNode, getAttributeNode, setAttributeNode,
203-
isSequenceNode, sizeNode, getItemNode, getArray, getAttrString);
196+
sequenceCheckNode, sizeNode, getItemNode, getArray, getAttrString);
204197
continue;
205198
}
206199
CFieldObject new_descr = factory.createCFieldObject(CField);
@@ -279,7 +272,7 @@ protected abstract static class MakeAnonFieldsNode extends PNodeWithRaise {
279272
*/
280273
@Specialization
281274
void MakeAnonFields(VirtualFrame frame, Object type, PythonObjectFactory factory,
282-
@Cached CheckIsSequenceNode isSequenceNode,
275+
@Cached PySequenceCheckNode sequenceCheckNode,
283276
@Cached PyObjectSizeNode sizeNode,
284277
@Cached GetItemNode getItemNode,
285278
@Cached MakeFieldsNode makeFieldsNode,
@@ -290,13 +283,7 @@ void MakeAnonFields(VirtualFrame frame, Object type, PythonObjectFactory factory
290283
if (PGuards.isPNone(anon)) {
291284
return;
292285
}
293-
boolean isAnonSeq = false;
294-
try {
295-
isAnonSeq = isSequenceNode.execute(anon);
296-
} catch (PException e) {
297-
// pass through
298-
}
299-
if (!isAnonSeq) {
286+
if (!sequenceCheckNode.execute(anon)) {
300287
throw raise(TypeError, ANONYMOUS_MUST_BE_A_SEQUENCE);
301288
}
302289

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@
4343
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.AttributeError;
4444
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
4545
import static com.oracle.graal.python.nodes.SpecialMethodNames.FILENO;
46-
import static com.oracle.graal.python.nodes.SpecialMethodNames.ITEMS;
4746
import static com.oracle.graal.python.nodes.SpecialMethodNames.KEYS;
48-
import static com.oracle.graal.python.nodes.SpecialMethodNames.VALUES;
4947
import static com.oracle.graal.python.nodes.SpecialMethodNames.__DELETE__;
5048
import static com.oracle.graal.python.nodes.SpecialMethodNames.__DELITEM__;
5149
import static com.oracle.graal.python.nodes.SpecialMethodNames.__EQ__;
@@ -100,8 +98,11 @@
10098
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
10199
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroNode;
102100
import com.oracle.graal.python.lib.PyLongCheckExactNode;
101+
import com.oracle.graal.python.lib.PyMappingCheckNode;
103102
import com.oracle.graal.python.lib.PyObjectIsTrueNode;
103+
import com.oracle.graal.python.lib.PyObjectLookupAttr;
104104
import com.oracle.graal.python.lib.PyObjectSizeNode;
105+
import com.oracle.graal.python.lib.PySequenceCheckNode;
105106
import com.oracle.graal.python.nodes.BuiltinNames;
106107
import com.oracle.graal.python.nodes.ErrorMessages;
107108
import com.oracle.graal.python.nodes.PGuards;
@@ -114,8 +115,8 @@
114115
import com.oracle.graal.python.nodes.call.CallNode;
115116
import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
116117
import com.oracle.graal.python.nodes.call.special.CallTernaryMethodNode;
118+
import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
117119
import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode;
118-
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode.LookupAndCallUnaryDynamicNode;
119120
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
120121
import com.oracle.graal.python.nodes.expression.CastToListExpressionNode.CastToListInteropNode;
121122
import com.oracle.graal.python.nodes.expression.IsExpressionNode.IsNode;
@@ -215,21 +216,6 @@ public final void clearNativeWrapper(ConditionProfile hasHandleValidAssumptionPr
215216
nativeWrapper = null;
216217
}
217218

218-
/**
219-
* Checks if the object is a Mapping as described in the
220-
* <a href="https://docs.python.org/3/reference/datamodel.html">Python Data Model</a>. Mappings
221-
* are treated differently to other containers in some interop messages.
222-
*/
223-
private static boolean isAbstractMapping(Object receiver, PythonObjectLibrary lib) {
224-
return lib.isSequence(receiver) && lib.lookupAttribute(receiver, null, KEYS) != PNone.NO_VALUE && //
225-
lib.lookupAttribute(receiver, null, ITEMS) != PNone.NO_VALUE && //
226-
lib.lookupAttribute(receiver, null, VALUES) != PNone.NO_VALUE;
227-
}
228-
229-
private boolean isAbstractMapping(PythonObjectLibrary thisLib) {
230-
return isAbstractMapping(this, thisLib);
231-
}
232-
233219
@ExportMessage
234220
public void writeMember(String key, Object value,
235221
@Cached PInteropSetAttributeNode setAttributeNode,
@@ -267,11 +253,11 @@ public Object readMember(String key,
267253

268254
@ExportMessage
269255
public boolean hasArrayElements(
270-
@CachedLibrary("this") PythonObjectLibrary dataModelLibrary,
256+
@Cached PySequenceCheckNode check,
271257
@Exclusive @Cached GilNode gil) {
272258
boolean mustRelease = gil.acquire();
273259
try {
274-
return dataModelLibrary.isSequence(this) && !isAbstractMapping(dataModelLibrary);
260+
return check.execute(this);
275261
} finally {
276262
gil.release(mustRelease);
277263
}
@@ -547,10 +533,11 @@ public Object execute(Object[] arguments,
547533
@ExportMessage
548534
@TruffleBoundary
549535
public Object getMembers(boolean includeInternal,
550-
@Exclusive @Cached LookupAndCallUnaryDynamicNode keysNode,
551536
@Cached CastToListInteropNode castToList,
552537
@Shared("getClassThis") @Cached GetClassNode getClass,
553-
@CachedLibrary("this") PythonObjectLibrary dataModelLibrary,
538+
@Cached PyMappingCheckNode checkMapping,
539+
@Cached PyObjectLookupAttr lookupKeys,
540+
@Cached CallUnaryMethodNode callKeys,
554541
@Shared("getItemNode") @Cached PInteropSubscriptNode getItemNode,
555542
@Cached SequenceNodes.LenNode lenNode,
556543
@Cached TypeNodes.GetMroNode getMroNode,
@@ -570,15 +557,18 @@ public Object getMembers(boolean includeInternal,
570557
}
571558
if (includeInternal) {
572559
// we use the internal flag to also return dictionary keys for mappings
573-
if (isAbstractMapping(dataModelLibrary)) {
574-
PList mapKeys = castToList.executeWithGlobalState(keysNode.executeObject(this, KEYS));
575-
int len = lenNode.execute(mapKeys);
576-
for (int i = 0; i < len; i++) {
577-
Object key = getItemNode.execute(mapKeys, i);
578-
if (key instanceof String) {
579-
keys.add("[" + (String) key);
580-
} else if (key instanceof PString) {
581-
keys.add("[" + ((PString) key).getValue());
560+
if (checkMapping.execute(this)) {
561+
Object keysMethod = lookupKeys.execute(null, this, KEYS);
562+
if (keysMethod != PNone.NO_VALUE) {
563+
PList mapKeys = castToList.executeWithGlobalState(callKeys.executeObject(keysMethod, this));
564+
int len = lenNode.execute(mapKeys);
565+
for (int i = 0; i < len; i++) {
566+
Object key = getItemNode.execute(mapKeys, i);
567+
if (key instanceof String) {
568+
keys.add("[" + (String) key);
569+
} else if (key instanceof PString) {
570+
keys.add("[" + ((PString) key).getValue());
571+
}
582572
}
583573
}
584574
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java

Lines changed: 5 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,17 @@
4141
package com.oracle.graal.python.builtins.objects.common;
4242

4343
import static com.oracle.graal.python.nodes.ErrorMessages.IS_NOT_A_SEQUENCE;
44-
import static com.oracle.graal.python.nodes.ErrorMessages.OBJ_DOES_NOT_SUPPORT_INDEXING;
4544
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
4645

47-
import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView;
48-
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
49-
import com.oracle.graal.python.builtins.objects.range.PRange;
50-
import com.oracle.graal.python.builtins.objects.set.PFrozenSet;
51-
import com.oracle.graal.python.builtins.objects.set.PSet;
5246
import com.oracle.graal.python.builtins.objects.str.PString;
5347
import com.oracle.graal.python.builtins.objects.str.StringNodes;
48+
import com.oracle.graal.python.lib.PySequenceCheckNode;
5449
import com.oracle.graal.python.nodes.PGuards;
5550
import com.oracle.graal.python.nodes.PNodeWithRaise;
5651
import com.oracle.graal.python.runtime.sequence.PSequence;
5752
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
5853
import com.oracle.truffle.api.CompilerDirectives;
5954
import com.oracle.truffle.api.dsl.Cached;
60-
import com.oracle.truffle.api.dsl.Fallback;
6155
import com.oracle.truffle.api.dsl.GenerateUncached;
6256
import com.oracle.truffle.api.dsl.ImportStatic;
6357
import com.oracle.truffle.api.dsl.Specialization;
@@ -159,55 +153,16 @@ static void doGeneric(PSequence s, SequenceStorage storage) {
159153
}
160154
}
161155

162-
/*
163-
* The current implementation of PythonObjectLibrary.isSequences consider any object that has
164-
* __LEN__ and __GETITEM__ method a sequence which unintendedly includes dict. The CPython way
165-
* of checking sequences is by checking if the tp_as_sequence is set within the type spec.
166-
*
167-
* @see cpython/Objects/abstract.c:PySequence_GetItem
168-
*/
169156
public abstract static class CheckIsSequenceNode extends PNodeWithRaise {
170157

171-
@Child private PythonObjectLibrary lib = PythonObjectLibrary.getFactory().createDispatched(2);
172-
173-
public abstract boolean execute(Object seq);
174-
175-
@Specialization
176-
static boolean sequence(@SuppressWarnings("unused") PSequence seq) {
177-
return true;
178-
}
179-
180-
@Specialization
181-
static boolean mem(@SuppressWarnings("unused") PMemoryView mv) {
182-
return true;
183-
}
184-
185-
@Specialization
186-
static boolean range(@SuppressWarnings("unused") PRange range) {
187-
return true;
188-
}
158+
public abstract void execute(Object seq);
189159

190160
@Specialization
191-
static boolean set(@SuppressWarnings("unused") PSet set) {
192-
return true;
193-
}
194-
195-
@Specialization
196-
static boolean fset(@SuppressWarnings("unused") PFrozenSet fset) {
197-
return true;
198-
}
199-
200-
@Specialization
201-
static boolean string(@SuppressWarnings("unused") String str) {
202-
return true;
203-
}
204-
205-
@Fallback
206-
boolean notSeqence(Object obj) {
207-
if (lib.isMapping(obj)) {
161+
void check(Object obj,
162+
@Cached PySequenceCheckNode sequenceCheckNode) {
163+
if (!sequenceCheckNode.execute(obj)) {
208164
throw raise(TypeError, IS_NOT_A_SEQUENCE, obj);
209165
}
210-
throw raise(TypeError, OBJ_DOES_NOT_SUPPORT_INDEXING, obj);
211166
}
212167
}
213168
}

0 commit comments

Comments
 (0)