Skip to content

Commit e8ea8fd

Browse files
committed
Merge PythonTypeLibrary and PythonObjectLibrary
1 parent f3b8f8d commit e8ea8fd

File tree

6 files changed

+141
-165
lines changed

6 files changed

+141
-165
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.HashSet;
2929

3030
import com.oracle.graal.python.PythonLanguage;
31+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
3132
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
3233
import com.oracle.graal.python.nodes.BuiltinNames;
3334
import com.oracle.graal.python.runtime.PythonContext;
@@ -45,6 +46,7 @@
4546
import com.oracle.truffle.api.object.Shape;
4647

4748
@ExportLibrary(InteropLibrary.class)
49+
@ExportLibrary(PythonObjectLibrary.class)
4850
public enum PythonBuiltinClassType implements LazyPythonClass {
4951

5052
ForeignObject(BuiltinNames.FOREIGN),
@@ -441,4 +443,23 @@ public boolean hasMemberWriteSideEffects(String key,
441443
@CachedContext(PythonLanguage.class) PythonContext context) {
442444
return lib.hasMemberWriteSideEffects(context.getCore().lookupType(this), key);
443445
}
446+
447+
@ExportMessage
448+
static boolean isSequenceType(PythonBuiltinClassType type,
449+
@CachedContext(PythonLanguage.class) PythonContext context,
450+
@CachedLibrary(limit = "1") PythonObjectLibrary lib) {
451+
return lib.isSequenceType(context.getCore().lookupType(type));
452+
}
453+
454+
@ExportMessage
455+
static boolean isMappingType(PythonBuiltinClassType type,
456+
@CachedContext(PythonLanguage.class) PythonContext context,
457+
@CachedLibrary(limit = "1") PythonObjectLibrary lib) {
458+
return lib.isMappingType(context.getCore().lookupType(type));
459+
}
460+
461+
@ExportMessage
462+
static LazyPythonClass getLazyPythonClass(@SuppressWarnings("unused") PythonBuiltinClassType type) {
463+
return PythonClass;
464+
}
444465
}

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

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@
7373
import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
7474
import com.oracle.graal.python.builtins.objects.object.PythonObject;
7575
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
76-
import com.oracle.graal.python.builtins.objects.object.PythonTypeLibrary;
7776
import com.oracle.graal.python.builtins.objects.str.PString;
7877
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
7978
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
@@ -571,14 +570,62 @@ private static void addKeysFromObject(HashSet<String> keys, PythonObject o, bool
571570
}
572571
}
573572

573+
@ExportMessage
574+
public boolean isSequence(@Shared("thisObject") @Cached GetLazyClassNode getClassNode,
575+
@CachedLibrary(limit = "1") PythonObjectLibrary pythonTypeLibrary) {
576+
return pythonTypeLibrary.isSequenceType(getClassNode.execute(this));
577+
}
578+
579+
@ExportMessage
580+
public boolean isMapping(@Shared("thisObject") @Cached GetLazyClassNode getClassNode,
581+
@CachedLibrary(limit = "1") PythonObjectLibrary pythonTypeLibrary) {
582+
return pythonTypeLibrary.isMappingType(getClassNode.execute(this));
583+
}
584+
585+
@ExportMessage
586+
public boolean isSequenceType(
587+
@Shared("hasGetItemNode") @Cached LookupAttributeInMRONode.Dynamic hasGetItemNode,
588+
@Shared("hasLenNode") @Cached LookupAttributeInMRONode.Dynamic hasLenNode,
589+
@Shared("isLazyClass") @Cached("createBinaryProfile()") ConditionProfile isLazyClass,
590+
@Shared("lenProfile") @Cached("createBinaryProfile()") ConditionProfile lenProfile,
591+
@Shared("getItemProfile") @Cached("createBinaryProfile()") ConditionProfile getItemProfile) {
592+
if (isLazyClass.profile(this instanceof LazyPythonClass)) {
593+
LazyPythonClass type = (LazyPythonClass) this; // guaranteed to succeed because of guard
594+
if (lenProfile.profile(hasLenNode.execute(type, SpecialMethodNames.__LEN__) != PNone.NO_VALUE)) {
595+
return getItemProfile.profile(hasGetItemNode.execute(type, SpecialMethodNames.__GETITEM__) != PNone.NO_VALUE);
596+
}
597+
}
598+
return false;
599+
}
600+
601+
@ExportMessage
602+
public boolean isMappingType(
603+
@Shared("hasGetItemNode") @Cached LookupAttributeInMRONode.Dynamic hasGetItemNode,
604+
@Shared("hasLenNode") @Cached LookupAttributeInMRONode.Dynamic hasLenNode,
605+
@Shared("isLazyClass") @Cached("createBinaryProfile()") ConditionProfile isLazyClass,
606+
@Shared("lenProfile") @Cached("createBinaryProfile()") ConditionProfile lenProfile,
607+
@Shared("getItemProfile") @Cached("createBinaryProfile()") ConditionProfile getItemProfile,
608+
@Exclusive @Cached LookupAttributeInMRONode.Dynamic hasKeysNode,
609+
@Exclusive @Cached LookupAttributeInMRONode.Dynamic hasItemsNode,
610+
@Exclusive @Cached LookupAttributeInMRONode.Dynamic hasValuesNode,
611+
@Exclusive @Cached("createBinaryProfile()") ConditionProfile profile) {
612+
if (isSequenceType(hasGetItemNode, hasLenNode, isLazyClass, lenProfile, getItemProfile)) {
613+
LazyPythonClass type = (LazyPythonClass) this; // guaranteed to succeed b/c it's a sequence type
614+
return profile.profile(hasKeysNode.execute(type, SpecialMethodNames.KEYS) != PNone.NO_VALUE &&
615+
hasItemsNode.execute(type, SpecialMethodNames.ITEMS) != PNone.NO_VALUE &&
616+
hasValuesNode.execute(type, SpecialMethodNames.VALUES) != PNone.NO_VALUE);
617+
}
618+
return false;
619+
}
620+
574621
@ExportMessage
575622
public final boolean isIterable(@Shared("thisObject") @Cached GetLazyClassNode getClassNode,
576-
@Cached LookupAttributeInMRONode.Dynamic getIterNode,
577-
@Cached LookupAttributeInMRONode.Dynamic getGetItemNode,
578-
@Cached LookupAttributeInMRONode.Dynamic hasNextNode,
623+
@Exclusive @Cached LookupAttributeInMRONode.Dynamic getIterNode,
624+
@Shared("hasGetItemNode") @Cached LookupAttributeInMRONode.Dynamic getGetItemNode,
625+
@Exclusive @Cached LookupAttributeInMRONode.Dynamic hasNextNode,
579626
@CachedLibrary(limit = "1") PythonObjectLibrary dataModelLibrary,
580627
@Exclusive @Cached("createBinaryProfile()") ConditionProfile profileIter,
581-
@Exclusive @Cached("createBinaryProfile()") ConditionProfile profileGetItem,
628+
@Shared("getItemProfile") @Cached("createBinaryProfile()") ConditionProfile profileGetItem,
582629
@Exclusive @Cached("createBinaryProfile()") ConditionProfile profileNext) {
583630
LazyPythonClass klass = getClassNode.execute(this);
584631
Object iterMethod = getIterNode.execute(klass, __ITER__);
@@ -621,18 +668,6 @@ public final boolean isContextManager(@Exclusive @Cached HasInheritedAttributeNo
621668
return profile.profile(hasEnterNode.execute(this, __ENTER__) && hasExitNode.execute(this, __EXIT__));
622669
}
623670

624-
@ExportMessage
625-
public boolean isSequence(@Shared("thisObject") @Cached GetLazyClassNode getClassNode,
626-
@CachedLibrary(limit = "1") PythonTypeLibrary pythonTypeLibrary) {
627-
return pythonTypeLibrary.isSequenceType(getClassNode.execute(this));
628-
}
629-
630-
@ExportMessage
631-
public boolean isMapping(@Shared("thisObject") @Cached GetLazyClassNode getClassNode,
632-
@CachedLibrary(limit = "1") PythonTypeLibrary pythonTypeLibrary) {
633-
return pythonTypeLibrary.isMappingType(getClassNode.execute(this));
634-
}
635-
636671
@GenerateUncached
637672
public abstract static class PKeyInfoNode extends Node {
638673
private static final int NONE = 0;

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@
102102
import com.oracle.graal.python.builtins.objects.mmap.PMMap;
103103
import com.oracle.graal.python.builtins.objects.object.PythonObject;
104104
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
105-
import com.oracle.graal.python.builtins.objects.object.PythonTypeLibrary;
106105
import com.oracle.graal.python.builtins.objects.set.PSet;
107106
import com.oracle.graal.python.builtins.objects.slice.PSlice;
108107
import com.oracle.graal.python.builtins.objects.str.PString;
@@ -405,7 +404,7 @@ Object doTpAsSequence(PythonManagedClass object, @SuppressWarnings("unused") Str
405404

406405
@Specialization(guards = "eq(TP_AS_MAPPING, key)")
407406
Object doTpAsMapping(PythonManagedClass object, @SuppressWarnings("unused") String key,
408-
@CachedLibrary(limit = "1") PythonTypeLibrary pythonTypeLibrary,
407+
@CachedLibrary(limit = "1") PythonObjectLibrary pythonTypeLibrary,
409408
@Shared("toSulongNode") @Cached CExtNodes.ToSulongNode toSulongNode) {
410409
if (pythonTypeLibrary.isSequenceType(object)) {
411410
return new PyMappingMethodsWrapper(object);
Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -40,48 +40,29 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.object;
4242

43-
import static com.oracle.graal.python.nodes.SpecialMethodNames.ITEMS;
44-
import static com.oracle.graal.python.nodes.SpecialMethodNames.KEYS;
45-
import static com.oracle.graal.python.nodes.SpecialMethodNames.VALUES;
46-
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GETITEM__;
47-
import static com.oracle.graal.python.nodes.SpecialMethodNames.__LEN__;
48-
49-
import com.oracle.graal.python.builtins.objects.PNone;
43+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
5044
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
51-
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
52-
import com.oracle.truffle.api.dsl.Cached;
53-
import com.oracle.truffle.api.dsl.Cached.Exclusive;
45+
import com.oracle.truffle.api.interop.InteropLibrary;
5446
import com.oracle.truffle.api.library.CachedLibrary;
5547
import com.oracle.truffle.api.library.ExportLibrary;
5648
import com.oracle.truffle.api.library.ExportMessage;
57-
import com.oracle.truffle.api.profiles.ConditionProfile;
5849

59-
@ExportLibrary(value = PythonTypeLibrary.class, receiverType = LazyPythonClass.class)
60-
final class DefaultTypeLazyPythonClassExports {
50+
@ExportLibrary(value = PythonObjectLibrary.class, receiverType = Object.class)
51+
final class DefaultPythonObjectExports {
52+
@ExportMessage
53+
static boolean isSequence(Object receiver,
54+
@CachedLibrary("receiver") InteropLibrary interopLib) {
55+
return interopLib.hasArrayElements(receiver);
56+
}
57+
6158
@ExportMessage
62-
public static boolean isSequenceType(LazyPythonClass type,
63-
@Cached LookupAttributeInMRONode.Dynamic hasGetItemNode,
64-
@Exclusive @Cached LookupAttributeInMRONode.Dynamic hasLenNode,
65-
@Exclusive @Cached("createBinaryProfile()") ConditionProfile lenProfile,
66-
@Exclusive @Cached("createBinaryProfile()") ConditionProfile getItemProfile) {
67-
if (lenProfile.profile(hasLenNode.execute(type, __LEN__) != PNone.NO_VALUE)) {
68-
return getItemProfile.profile(hasGetItemNode.execute(type, __GETITEM__) != PNone.NO_VALUE);
69-
}
70-
return false;
59+
static boolean isMapping(Object receiver,
60+
@CachedLibrary("receiver") InteropLibrary interopLib) {
61+
return interopLib.hasMembers(receiver);
7162
}
7263

7364
@ExportMessage
74-
public static boolean isMappingType(LazyPythonClass type,
75-
@Exclusive @Cached LookupAttributeInMRONode.Dynamic hasKeysNode,
76-
@Exclusive @Cached LookupAttributeInMRONode.Dynamic hasItemsNode,
77-
@Exclusive @Cached LookupAttributeInMRONode.Dynamic hasValuesNode,
78-
@CachedLibrary(limit = "1") PythonTypeLibrary pythonTypeLibrary,
79-
@Exclusive @Cached("createBinaryProfile()") ConditionProfile profile) {
80-
if (pythonTypeLibrary.isSequenceType(type)) {
81-
return profile.profile(hasKeysNode.execute(type, KEYS) != PNone.NO_VALUE &&
82-
hasItemsNode.execute(type, ITEMS) != PNone.NO_VALUE &&
83-
hasValuesNode.execute(type, VALUES) != PNone.NO_VALUE);
84-
}
85-
return false;
65+
static LazyPythonClass getLazyPythonClass(@SuppressWarnings("unused") Object value) {
66+
return PythonBuiltinClassType.ForeignObject;
8667
}
8768
}

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

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,12 @@
5858
import com.oracle.truffle.api.nodes.Node;
5959

6060
@GenerateLibrary
61-
@DefaultExport(DefaultPythonStringExports.class)
62-
@DefaultExport(DefaultPythonDoubleExports.class)
61+
@DefaultExport(DefaultPythonBooleanExports.class)
6362
@DefaultExport(DefaultPythonIntegerExports.class)
6463
@DefaultExport(DefaultPythonLongExports.class)
65-
@DefaultExport(DefaultPythonBooleanExports.class)
64+
@DefaultExport(DefaultPythonDoubleExports.class)
65+
@DefaultExport(DefaultPythonStringExports.class)
66+
@DefaultExport(DefaultPythonObjectExports.class)
6667
@SuppressWarnings("unused")
6768
public abstract class PythonObjectLibrary extends Library {
6869
public boolean hasDict(Object receiver) {
@@ -192,7 +193,7 @@ public boolean canBeIndex(Object receiver) {
192193
* Containers</a>
193194
*
194195
* <br>
195-
* See {@link PythonTypeLibrary#isSequenceType(Object)}
196+
* See {@link #isSequenceType(Object)}
196197
*
197198
* @param receiver the receiver Object
198199
* @return True if object is a Python sequence object
@@ -208,7 +209,7 @@ public boolean isSequence(Object receiver) {
208209
* Containers</a>
209210
*
210211
* <br>
211-
* See {@link PythonTypeLibrary#isMappingType(Object)}
212+
* See {@link #isMappingType(Object)}
212213
*
213214
* @param receiver the receiver Object
214215
* @return True if object is a Python mapping object
@@ -217,6 +218,52 @@ public boolean isMapping(Object receiver) {
217218
return false;
218219
}
219220

221+
/**
222+
* Checks whether the receiver is a Python sequence type. As described in the
223+
* <a href="https://docs.python.org/3/reference/datamodel.html">Python Data Model</a> and
224+
* <a href="https://docs.python.org/3/library/collections.abc.html">Abstract Base Classes for
225+
* Containers</a>
226+
*
227+
* <br>
228+
* Specifically the default implementation checks for the implementation of the following
229+
* special methods: <b>
230+
* <ul>
231+
* <li>__getitem__</li>
232+
* <li>__len__</li>
233+
* </ul>
234+
* </b>
235+
*
236+
* @param receiver the receiver Object
237+
* @return True if a sequence type
238+
*/
239+
public boolean isSequenceType(Object receiver) {
240+
return false;
241+
}
242+
243+
/**
244+
* Checks whether the receiver is a Python mapping type. As described in the
245+
* <a href="https://docs.python.org/3/reference/datamodel.html">Python Data Model</a> and
246+
* <a href="https://docs.python.org/3/library/collections.abc.html">Abstract Base Classes for
247+
* Containers</a>
248+
*
249+
* <br>
250+
* Specifically the default implementation checks whether the receiver
251+
* {@link #isSequenceType(Object)} and for the implementation of the following special methods:
252+
* <b>
253+
* <ul>
254+
* <li>keys</li>
255+
* <li>items</li>
256+
* <li>values</li>
257+
* </ul>
258+
* </b>
259+
*
260+
* @param receiver the receiver Object
261+
* @return True if a mapping type
262+
*/
263+
public boolean isMappingType(Object receiver) {
264+
return false;
265+
}
266+
220267
public static boolean checkIsIterable(PythonObjectLibrary library, ContextReference<PythonContext> contextRef, VirtualFrame frame, Object object, Node callNode) {
221268
PythonContext context = contextRef.get();
222269
PException caughtException = IndirectCallContext.enter(frame, context, callNode);

0 commit comments

Comments
 (0)