From 26dfe58346e02aeac19b81b3da35ed1146fa4323 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Mon, 15 Jun 2026 10:11:35 +0200
Subject: [PATCH 01/23] Remove GetNativeTupleStorage node
---
.../modules/cext/PythonCextTupleBuiltins.java | 10 ++++----
.../objects/common/SequenceNodes.java | 11 ++++-----
.../exception/BaseExceptionGroupBuiltins.java | 3 ++-
.../builtins/objects/tuple/TupleBuiltins.java | 6 ++---
.../python/nodes/builtins/TupleNodes.java | 23 +++----------------
5 files changed, 16 insertions(+), 37 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTupleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTupleBuiltins.java
index e4409a8319..b210f92929 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTupleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTupleBuiltins.java
@@ -73,7 +73,7 @@
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PRaiseNode;
-import com.oracle.graal.python.nodes.builtins.TupleNodes.GetNativeTupleStorage;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.runtime.PythonContext;
import com.oracle.graal.python.runtime.object.PFactory;
import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage;
@@ -125,12 +125,11 @@ static Object doPTuple(PTuple tuple, long key,
static Object doNative(PythonAbstractNativeObject tuple, long key,
@Bind Node inliningTarget,
@Bind PythonContext context,
- @Exclusive @Cached GetNativeTupleStorage asNativeStorage,
@Exclusive @Cached EnsurePythonObjectNode ensureNode,
@Exclusive @Cached SetItemScalarNode setItemNode,
@Exclusive @Cached GetItemScalarNode getItemNode,
@Exclusive @Cached PRaiseNode raiseNode) {
- SequenceStorage sequenceStorage = asNativeStorage.execute(tuple);
+ SequenceStorage sequenceStorage = GetTupleStorage.doNative(tuple);
int index = checkIndex(inliningTarget, key, sequenceStorage, raiseNode);
Object result = getItemNode.execute(inliningTarget, sequenceStorage, index);
if (result == null) {
@@ -185,9 +184,8 @@ static Object getSlice(PTuple tuple, Object iLow, Object iHigh,
static Object doNative(PythonAbstractNativeObject tuple, Object iLow, Object iHigh,
@Bind Node inliningTarget,
@Shared("getItem") @Cached("createForTuple()") SequenceStorageNodes.GetItemNode getItemNode,
- @Shared("newSlice") @Cached PySliceNew sliceNode,
- @Cached GetNativeTupleStorage asNativeStorage) {
- return doGetSlice(asNativeStorage.execute(tuple), inliningTarget, iLow, iHigh, getItemNode, sliceNode);
+ @Shared("newSlice") @Cached PySliceNew sliceNode) {
+ return doGetSlice(GetTupleStorage.doNative(tuple), inliningTarget, iLow, iHigh, getItemNode, sliceNode);
}
@SuppressWarnings("unused")
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java
index 31610f632e..424e265303 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java
@@ -56,7 +56,7 @@
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PNodeWithContext;
import com.oracle.graal.python.nodes.PRaiseNode;
-import com.oracle.graal.python.nodes.builtins.TupleNodes;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.object.IsForeignObjectNode;
import com.oracle.graal.python.runtime.sequence.PSequence;
import com.oracle.graal.python.runtime.sequence.storage.ForeignSequenceStorage;
@@ -141,17 +141,16 @@ static SequenceStorage doSequence(Node inliningTarget, PSequence seq,
}
@Specialization(guards = "tupleCheck.execute(inliningTarget, seq)", limit = "1")
- static SequenceStorage doNativeTuple(Node inliningTarget, PythonAbstractNativeObject seq,
- @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheck,
- @Cached TupleNodes.GetNativeTupleStorage getNativeTupleStorage) {
- return getNativeTupleStorage.execute(seq);
+ static SequenceStorage doNativeTuple(@SuppressWarnings("unused") Node inliningTarget, PythonAbstractNativeObject seq,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheck) {
+ return GetTupleStorage.doNative(seq);
}
// Note: this does not seem currently used but is good to accept foreign lists in more
// places
@Specialization(guards = {"isForeignObjectNode.execute(inliningTarget, seq)", "interop.hasArrayElements(seq)"}, limit = "1")
static SequenceStorage doForeign(Node inliningTarget, Object seq,
- @Cached IsForeignObjectNode isForeignObjectNode,
+ @SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
@CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") InteropLibrary interop,
@Cached InlinedBranchProfile errorProfile) {
try {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionGroupBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionGroupBuiltins.java
index ca874691b0..ac16acd8a4 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionGroupBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionGroupBuiltins.java
@@ -89,6 +89,7 @@
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.ListNodes;
import com.oracle.graal.python.nodes.builtins.TupleNodes;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.call.CallNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -374,7 +375,7 @@ private static SequenceStorage getExactTupleStorage(Object value) {
return tuple.getSequenceStorage();
}
if (value instanceof PythonAbstractNativeObject nativeTuple && PyTupleCheckExactNode.executeUncached(nativeTuple)) {
- return TupleNodes.GetNativeTupleStorage.getUncached().execute(nativeTuple);
+ return GetTupleStorage.doNative(nativeTuple);
}
return null;
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleBuiltins.java
index f37cabf139..b91de2043f 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/TupleBuiltins.java
@@ -81,7 +81,6 @@
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes;
-import com.oracle.graal.python.nodes.builtins.TupleNodes.GetNativeTupleStorage;
import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -468,9 +467,8 @@ long computeHash(VirtualFrame frame, PTuple self,
long computeHash(VirtualFrame frame, PythonAbstractNativeObject self,
@Bind Node inliningTarget,
@Shared("getItem") @Cached("createNotNormalized()") SequenceStorageNodes.GetItemNode getItemNode,
- @Shared("hash") @Cached PyObjectHashNode hashNode,
- @Cached GetNativeTupleStorage getStorage) {
- return doComputeHash(frame, inliningTarget, getItemNode, hashNode, getStorage.execute(self));
+ @Shared("hash") @Cached PyObjectHashNode hashNode) {
+ return doComputeHash(frame, inliningTarget, getItemNode, hashNode, GetTupleStorage.doNative(self));
}
private static long doComputeHash(VirtualFrame frame, Node inliningTarget, SequenceStorageNodes.GetItemNode getItemNode, PyObjectHashNode hashNode, SequenceStorage tupleStore) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java
index 16ac0db8d9..0cc0c7bbb9 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java
@@ -103,9 +103,8 @@ static PTuple nativeTuple(PythonAbstractNativeObject iterable,
@Bind Node inliningTarget,
@Bind PythonLanguage language,
@SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheck,
- @Cached GetNativeTupleStorage getNativeTupleStorage,
@Cached SequenceStorageNodes.ToArrayNode toArrayNode) {
- return PFactory.createTuple(language, toArrayNode.execute(inliningTarget, getNativeTupleStorage.execute(iterable)));
+ return PFactory.createTuple(language, toArrayNode.execute(inliningTarget, GetTupleStorage.doNative(iterable)));
}
@Fallback
@@ -138,28 +137,12 @@ public abstract static class GetTupleStorage extends Node {
public abstract SequenceStorage execute(Node inliningTarget, Object tuple);
@Specialization
- SequenceStorage getManaged(PTuple tuple) {
+ static SequenceStorage doManaged(PTuple tuple) {
return tuple.getSequenceStorage();
}
@Specialization
- SequenceStorage getNative(PythonAbstractNativeObject tuple,
- @Cached(inline = false) GetNativeTupleStorage getNativeTupleStorage) {
- return getNativeTupleStorage.execute(tuple);
- }
- }
-
- @GenerateInline(false)
- @GenerateUncached
- public abstract static class GetNativeTupleStorage extends Node {
- public abstract NativeObjectSequenceStorage execute(PythonAbstractNativeObject tuple);
-
- public static GetNativeTupleStorage getUncached() {
- return TupleNodesFactory.GetNativeTupleStorageNodeGen.getUncached();
- }
-
- @Specialization
- NativeObjectSequenceStorage getNative(PythonAbstractNativeObject tuple) {
+ public static SequenceStorage doNative(PythonAbstractNativeObject tuple) {
assert PyTupleCheckNode.executeUncached(tuple);
long tupleRawPtr = tuple.getPtr();
long array = CStructAccess.getFieldPtr(tupleRawPtr, CFields.PyTupleObject__ob_item);
From 65d91f1e60a264459749ea218e77f13592f741f3 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Thu, 18 Jun 2026 20:00:32 +0200
Subject: [PATCH 02/23] Some "surrogateescape" fixups
---
.../builtins/modules/cext/PythonCextUnicodeBuiltins.java | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextUnicodeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextUnicodeBuiltins.java
index d3ff63eabb..c539855181 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextUnicodeBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextUnicodeBuiltins.java
@@ -919,12 +919,7 @@ static long GraalPyPrivate_Unicode_DecodeFSDefaultAndSize(long s, long lsize) {
try {
int size = PInt.intValueExact(lsize);
TruffleString candidate = TruffleString.fromNativePointerUncached(s, 0, size, UTF_8, true);
- TruffleString str;
- if (candidate.isValidUncached(UTF_8)) {
- str = candidate.switchEncodingUncached(TS_ENCODING);
- } else {
- str = candidate.switchEncodingUncached(TS_ENCODING, SURROGATE_ESCAPE_FROM_UTF8_TRANSCODING_ERROR_HANDLER);
- }
+ TruffleString str = candidate.switchEncodingUncached(TS_ENCODING, SURROGATE_ESCAPE_FROM_UTF8_TRANSCODING_ERROR_HANDLER);
// implicitly promotes TruffleString to PString
return PythonToNativeInternalNode.executeNewRefUncached(str);
} catch (OverflowException e) {
From e4bdd7f08d6542c618329ef6e58878d3e9dd7964 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Mon, 15 Jun 2026 11:00:33 +0200
Subject: [PATCH 03/23] Don't use node to read item of
NativeByteSequenceStorage
---
.../objects/common/SequenceStorageNodes.java | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java
index a9c404d528..0851c13bdf 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java
@@ -26,6 +26,11 @@
package com.oracle.graal.python.builtins.objects.common;
import static com.oracle.graal.python.builtins.objects.common.IndexNodes.checkBounds;
+import static com.oracle.graal.python.runtime.exception.PythonErrorType.IndexError;
+import static com.oracle.graal.python.runtime.exception.PythonErrorType.MemoryError;
+import static com.oracle.graal.python.runtime.exception.PythonErrorType.OverflowError;
+import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
+import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
import static com.oracle.graal.python.runtime.nativeaccess.NativeMemory.NULLPTR;
import static com.oracle.graal.python.runtime.nativeaccess.NativeMemory.callocByteArray;
import static com.oracle.graal.python.runtime.nativeaccess.NativeMemory.callocPtrArray;
@@ -37,11 +42,6 @@
import static com.oracle.graal.python.runtime.nativeaccess.NativeMemory.writeByteArrayElement;
import static com.oracle.graal.python.runtime.nativeaccess.NativeMemory.writeByteArrayElements;
import static com.oracle.graal.python.runtime.nativeaccess.NativeMemory.writePtrArrayElement;
-import static com.oracle.graal.python.runtime.exception.PythonErrorType.IndexError;
-import static com.oracle.graal.python.runtime.exception.PythonErrorType.MemoryError;
-import static com.oracle.graal.python.runtime.exception.PythonErrorType.OverflowError;
-import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
-import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
import static com.oracle.graal.python.runtime.sequence.storage.SequenceStorage.StorageType.Boolean;
import static com.oracle.graal.python.runtime.sequence.storage.SequenceStorage.StorageType.Byte;
import static com.oracle.graal.python.runtime.sequence.storage.SequenceStorage.StorageType.Double;
@@ -663,7 +663,7 @@ protected static Object doNativeObject(NativeObjectSequenceStorage storage, int
}
@Specialization
- protected static int doNativeByte(NativeByteSequenceStorage storage, int idx) {
+ public static int doNativeByte(NativeByteSequenceStorage storage, int idx) {
return readByteArrayElement(storage.getPtr(), idx) & 0xff;
}
}
@@ -3319,18 +3319,17 @@ static SequenceStorage doNativeInt(Node inliningTarget, NativeIntSequenceStorage
}
@Specialization
- static SequenceStorage doNativeBytes(NativeByteSequenceStorage s,
- @Shared @Cached(inline = false) GetNativeItemScalarNode getItem) {
+ static SequenceStorage doNativeBytes(NativeByteSequenceStorage s) {
byte[] bytes = new byte[s.length()];
for (int i = 0; i < bytes.length; i++) {
- bytes[i] = (byte) (int) getItem.execute(s, i);
+ bytes[i] = (byte) GetNativeItemScalarNode.doNativeByte(s, i);
}
return new ByteSequenceStorage(bytes);
}
@Specialization
static SequenceStorage doNativeObjects(NativeObjectSequenceStorage s,
- @Shared @Cached(inline = false) GetNativeItemScalarNode getItem) {
+ @Cached(inline = false) GetNativeItemScalarNode getItem) {
Object[] objects = new Object[s.length()];
for (int i = 0; i < objects.length; i++) {
objects[i] = getItem.execute(s, i);
From 7d82d4bbdb0bff743d3bc11fba21ef77252a0a5c Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Mon, 15 Jun 2026 11:46:32 +0200
Subject: [PATCH 04/23] Propagate type TruffleString for "errors"
---
.../modules/cjkcodecs/MultibyteCodecUtil.java | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java
index 93a2aa4b1e..37f9b1b565 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java
@@ -141,17 +141,15 @@ static TruffleString internalErrorCallback(TruffleString errors,
@GenerateCached(alwaysInlineCached = true)
abstract static class CallErrorCallbackNode extends Node {
- abstract Object execute(VirtualFrame frame, Node inliningTarget, Object errors, Object exc);
+ abstract Object execute(VirtualFrame frame, Node inliningTarget, TruffleString errors, Object exc);
// call_error_callback
@Specialization
- static Object callErrorCallback(VirtualFrame frame, Node inliningTarget, Object errors, Object exc,
- @Cached CastToTruffleStringNode castToStringNode,
+ static Object callErrorCallback(VirtualFrame frame, Node inliningTarget, TruffleString errors, Object exc,
@Cached PyCodecLookupErrorNode lookupErrorNode,
@Cached(inline = false) CallNode callNode) {
assert (PyUnicodeCheckNode.executeUncached(errors));
- TruffleString str = castToStringNode.execute(inliningTarget, errors);
- Object cb = lookupErrorNode.execute(frame, inliningTarget, str);
+ Object cb = lookupErrorNode.execute(frame, inliningTarget, errors);
return callNode.execute(frame, cb, exc);
}
}
@@ -164,13 +162,13 @@ abstract static class EncodeErrorNode extends Node {
abstract int execute(VirtualFrame frame, MultibyteCodec codec,
MultibyteCodecState state,
MultibyteEncodeBuffer buf,
- Object errors, int e);
+ TruffleString errors, int e);
// multibytecodec_encerror
@Specialization
static int encerror(VirtualFrame frame, MultibyteCodec codec,
MultibyteCodecState state,
- MultibyteEncodeBuffer buf, Object errors, int e,
+ MultibyteEncodeBuffer buf, TruffleString errors, int e,
@Bind Node inliningTarget,
@Bind PythonLanguage language,
@Cached BaseExceptionAttrNode attrNode,
@@ -438,11 +436,11 @@ protected static PBytes encodeEmptyInput(Node inliningTarget, int len, int flags
@GenerateCached(false)
abstract static class EncodeNode extends Node {
- abstract PBytes execute(VirtualFrame frame, Node inliningTarget, MultibyteCodec codec, MultibyteCodecState state, MultibyteEncodeBuffer buf, Object errors, int flags);
+ abstract PBytes execute(VirtualFrame frame, Node inliningTarget, MultibyteCodec codec, MultibyteCodecState state, MultibyteEncodeBuffer buf, TruffleString errors, int flags);
// multibytecodec_encode
@Specialization
- static PBytes encode(VirtualFrame frame, Node inliningTarget, MultibyteCodec codec, MultibyteCodecState state, MultibyteEncodeBuffer buf, Object errors, int flags,
+ static PBytes encode(VirtualFrame frame, Node inliningTarget, MultibyteCodec codec, MultibyteCodecState state, MultibyteEncodeBuffer buf, TruffleString errors, int flags,
@Cached(inline = false) EncodeErrorNode encodeErrorNode,
@Cached PRaiseNode raiseNode) {
From 216605f886e0182f360ac1de86de72d94db4c72f Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Mon, 15 Jun 2026 11:50:20 +0200
Subject: [PATCH 05/23] Make CallErrorCallbackNode an inline node
---
.../builtins/modules/cjkcodecs/MultibyteCodecUtil.java | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java
index 37f9b1b565..448dfe01c8 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java
@@ -138,7 +138,7 @@ static TruffleString internalErrorCallback(TruffleString errors,
}
@GenerateInline
- @GenerateCached(alwaysInlineCached = true)
+ @GenerateCached(false)
abstract static class CallErrorCallbackNode extends Node {
abstract Object execute(VirtualFrame frame, Node inliningTarget, TruffleString errors, Object exc);
@@ -148,7 +148,6 @@ abstract static class CallErrorCallbackNode extends Node {
static Object callErrorCallback(VirtualFrame frame, Node inliningTarget, TruffleString errors, Object exc,
@Cached PyCodecLookupErrorNode lookupErrorNode,
@Cached(inline = false) CallNode callNode) {
- assert (PyUnicodeCheckNode.executeUncached(errors));
Object cb = lookupErrorNode.execute(frame, inliningTarget, errors);
return callNode.execute(frame, cb, exc);
}
@@ -181,7 +180,7 @@ static int encerror(VirtualFrame frame, MultibyteCodec codec,
@Cached PyLongCheckNode longCheckNode,
@Cached PyBytesCheckNode bytesCheckNode,
@Cached PyLongAsIntNode asSizeNode,
- @Cached(inline = true) CallErrorCallbackNode callErrorCallbackNode,
+ @Cached CallErrorCallbackNode callErrorCallbackNode,
@Cached BytesNodes.ToBytesNode toBytesNode,
@Cached EncodeNode encodeNode,
@Cached PRaiseNode raiseNode) {
@@ -334,7 +333,7 @@ static void decerror(VirtualFrame frame, MultibyteCodec codec,
@Cached PyLongCheckNode longCheckNode,
@Cached PyLongAsIntNode asSizeNode,
@Cached CastToJavaStringNode toString,
- @Cached(inline = true) CallErrorCallbackNode callErrorCallbackNode,
+ @Cached CallErrorCallbackNode callErrorCallbackNode,
@Cached PRaiseNode raiseNode) {
TruffleString reason = ILLEGAL_MULTIBYTE_SEQUENCE;
From 94435235262d82d56e05c0cdc0cf9ff43b33d6c8 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Mon, 15 Jun 2026 13:51:21 +0200
Subject: [PATCH 06/23] Honor native tuple in SplitLongToSAndNsNode
---
.../src/tests/cpyext/test_tuple.py | 19 +++++++++++++++++++
.../builtins/modules/PosixModuleBuiltins.java | 6 ++++--
2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py
index bc38569147..62cfa10797 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py
+++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py
@@ -36,6 +36,8 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
+import os
+import tempfile
import unittest
from . import CPyExtTestCase, CPyExtFunction, CPyExtFunctionOutVars, unhandled_error_compare, CPyExtType, \
@@ -379,3 +381,20 @@ def test_memoryview_cast_shape_native_tuple(self):
assert is_native_object(shape)
view = memoryview(b"abcd").cast("B", shape)
assert view.shape == (2, 2)
+
+ def test_utime_ns_divmod_native_tuple(self):
+ class NativeDivmod:
+ def __divmod__(self, other):
+ assert other == 1000000000
+ result = TupleSubclass(1, 234567890)
+ assert is_native_object(result)
+ return result
+
+ with tempfile.NamedTemporaryFile() as f:
+ os.utime(f.name, ns=(NativeDivmod(), NativeDivmod()))
+ stat = os.stat(f.name)
+ expected = 1234567890
+ # We don't care about the exact value. It's about if native tuples are accepted.
+ tolerance = 1_000_000_000
+ assert abs(stat.st_atime_ns - expected) <= tolerance
+ assert abs(stat.st_mtime_ns - expected) <= tolerance
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java
index 67a5506dde..940a92d7a0 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java
@@ -3265,12 +3265,14 @@ static void doLong(long value, long[] timespec, int offset) {
@Specialization(guards = {"!isInteger(value)"})
static void doGeneric(VirtualFrame frame, Node inliningTarget, Object value, long[] timespec, int offset,
@Cached PyNumberDivmodNode divmodNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
+ @Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached(value = "createNotNormalized()", inline = false) GetItemNode getItemNode,
@Cached PyLongAsLongNode asLongNode,
@Cached PRaiseNode raiseNode) {
Object divmod = divmodNode.execute(frame, inliningTarget, value, BILLION);
- if (divmod instanceof PTuple tuple) {
- SequenceStorage storage = tuple.getSequenceStorage();
+ if (tupleCheckNode.execute(inliningTarget, divmod)) {
+ SequenceStorage storage = getTupleStorage.execute(inliningTarget, divmod);
if (storage.length() == 2) {
timespec[offset] = asLongNode.execute(frame, inliningTarget, getItemNode.execute(storage, 0));
timespec[offset + 1] = asLongNode.execute(frame, inliningTarget, getItemNode.execute(storage, 1));
From dedcc26fb703844ba698a05287ecf0cfbc4d44c9 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Mon, 15 Jun 2026 14:10:36 +0200
Subject: [PATCH 07/23] Accept native tuple fds in fork_exec
---
.../modules/PosixSubprocessModuleBuiltins.java | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java
index 3092560d74..f291ed387d 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java
@@ -63,14 +63,15 @@
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode;
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
import com.oracle.graal.python.builtins.objects.list.PList;
-import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.lib.PyObjectGetItem;
import com.oracle.graal.python.lib.PyObjectSizeNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.ListNodes.FastConstructListNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode;
@@ -252,6 +253,8 @@ static int forkExec(VirtualFrame frame, Object[] args, Object executableList, bo
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Bind Node inliningTarget,
@Cached("createNotNormalized()") GetItemNode tupleGetItem,
+ @Cached PyTupleCheckNode tupleCheckNode,
+ @Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached PyObjectGetItem getItem,
@Cached CastToJavaIntExactNode castToIntNode,
@Cached ObjectToOpaquePathNode objectToOpaquePathNode,
@@ -266,11 +269,11 @@ static int forkExec(VirtualFrame frame, Object[] args, Object executableList, bo
if (closeFds && errPipeWrite < 3) {
throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.S_MUST_BE_S, "errpipe_write", ">= 3");
}
- if (!(fdsToKeepObj instanceof PTuple)) {
+ if (!tupleCheckNode.execute(inliningTarget, fdsToKeepObj)) {
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "fork_exec()", 4, "tuple", fdsToKeepObj);
}
Object[] processArgs = args;
- int[] fdsToKeep = convertFdSequence(inliningTarget, (PTuple) fdsToKeepObj, tupleGetItem, castToIntNode, raiseNode);
+ int[] fdsToKeep = convertFdSequence(inliningTarget, getTupleStorage.execute(inliningTarget, fdsToKeepObj), tupleGetItem, castToIntNode, raiseNode);
Object cwd = PGuards.isPNone(cwdObj) ? null : objectToOpaquePathNode.execute(frame, inliningTarget, cwdObj, false);
PythonContext context = PythonContext.get(inliningTarget);
@@ -319,8 +322,7 @@ static int forkExec(VirtualFrame frame, Object[] args, Object executableList, bo
* Checks that the tuple contains only valid fds (positive integers fitting into an int) in
* ascending order.
*/
- private static int[] convertFdSequence(Node inliningTarget, PTuple fdSequence, GetItemNode getItemNode, CastToJavaIntExactNode castToIntNode, PRaiseNode raiseNode) {
- SequenceStorage storage = fdSequence.getSequenceStorage();
+ private static int[] convertFdSequence(Node inliningTarget, SequenceStorage storage, GetItemNode getItemNode, CastToJavaIntExactNode castToIntNode, PRaiseNode raiseNode) {
int len = storage.length();
int[] fds = new int[len];
int prevFd = -1;
From 9d818143ed12569030b4ad035ffd1c86db5d579f Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Mon, 15 Jun 2026 15:35:23 +0200
Subject: [PATCH 08/23] Accept native tuples in warning filters
---
.../modules/WarningsModuleBuiltins.java | 22 +++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java
index a303144e2f..8635d1fe53 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java
@@ -79,6 +79,7 @@
import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltinsClinicProviders.WarnBuiltinNodeClinicProviderGen;
import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltinsFactory.WarnBuiltinNodeFactory;
import com.oracle.graal.python.builtins.objects.PNone;
+import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetSequenceStorageNode;
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.dict.PDict;
import com.oracle.graal.python.builtins.objects.frame.PFrame;
@@ -100,10 +101,12 @@
import com.oracle.graal.python.lib.PyObjectRichCompareBool.CachedPyObjectRichCompareBool;
import com.oracle.graal.python.lib.PyObjectSetItem;
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.SpecialAttributeNames;
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes;
import com.oracle.graal.python.nodes.call.CallNode;
import com.oracle.graal.python.nodes.frame.ReadFrameNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -225,6 +228,7 @@ static final class WarningsModuleNode extends Node {
@Child TruffleString.RegionEqualNode regionEqualNode;
@Child TruffleString.EqualNode equalNode;
@Child TruffleString.SubstringNode substringNode;
+ @Child GetSequenceStorageNode tupleStorageNode;
@NeverDefault
static WarningsModuleNode create() {
@@ -311,6 +315,14 @@ private SequenceStorageNodes.GetItemScalarNode getSequenceGetItemNode() {
return sequenceGetItemNode;
}
+ private GetSequenceStorageNode getTupleStorageNode() {
+ if (tupleStorageNode == null) {
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ tupleStorageNode = insert(GetSequenceStorageNode.create());
+ }
+ return tupleStorageNode;
+ }
+
private Object getPythonClass(Object object) {
if (getClassNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -571,10 +583,10 @@ private TruffleString getFilter(VirtualFrame frame, BoundaryCallData boundaryCal
SequenceStorageNodes.GetItemScalarNode sequenceGetItem = getSequenceGetItemNode();
for (int i = 0; i < filtersStorage.length(); i++) {
Object tmpItem = sequenceGetItem.executeCached(filtersStorage, i);
- if (!(tmpItem instanceof PTuple)) {
+ if (!PyTupleCheckNode.executeUncached(tmpItem)) {
throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.ValueError, ErrorMessages.WARN_FILTERS_IETM_ISNT_5TUPLE, i);
}
- SequenceStorage tmpStorage = ((PTuple) tmpItem).getSequenceStorage();
+ SequenceStorage tmpStorage = getTupleStorageNode().execute(this, tmpItem);
if (tmpStorage.length() != 5) {
throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.ValueError, ErrorMessages.WARN_FILTERS_IETM_ISNT_5TUPLE, i);
}
@@ -989,12 +1001,14 @@ Object doWarn(VirtualFrame frame, PythonModule mod, Object message, Object categ
@Cached("createFor($node)") BoundaryCallData boundaryCallData,
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
@Cached StringNodes.CastToTruffleStringChecked1Node castToStringChecked,
+ @Cached PyTupleCheckNode tupleCheckNode,
+ @Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached PRaiseNode raiseNode,
@Cached WarningsModuleNode moduleFunctionsNode) {
// warnings_warn_impl
TruffleString[] skipFilePrefixes = null;
- if (skipFilePrefixesObj instanceof PTuple tuple) {
- SequenceStorage storage = tuple.getSequenceStorage();
+ if (tupleCheckNode.execute(inliningTarget, skipFilePrefixesObj)) {
+ SequenceStorage storage = getTupleStorage.execute(inliningTarget, skipFilePrefixesObj);
if (storage.length() > 0) {
skipFilePrefixes = new TruffleString[storage.length()];
for (int i = 0; i < storage.length(); i++) {
From 212a550432c7dc88bccb4822a8c7d23525723966 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Mon, 15 Jun 2026 16:13:58 +0200
Subject: [PATCH 09/23] Accept native tuple integer ratios
---
.../python/builtins/modules/datetime/TimeDeltaBuiltins.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaBuiltins.java
index 7cf1b79071..6a2a2bc432 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/datetime/TimeDeltaBuiltins.java
@@ -86,6 +86,7 @@
import com.oracle.graal.python.lib.PyNumberTrueDivideNode;
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
import com.oracle.graal.python.lib.PyObjectHashNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.lib.RichCmpOp;
@@ -721,7 +722,7 @@ private static Object toMicrosecondsUncached(TimeDeltaValue timeDelta) {
* get_float_as_integer_ratio())
*/
private static void validateAsIntegerRatioResult(Object object, Node inliningTarget, PRaiseNode raiseNode) {
- if (!(object instanceof PTuple)) {
+ if (!PyTupleCheckNode.executeUncached(object)) {
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.UNEXPECTED_RETURN_TYPE_FROM_AS_INTEGER_RATIO_EXPECTED_TUPLE_GOT_P, object);
}
if (PyTupleSizeNode.executeUncached(object) != 2) {
From 9de55b1d6bd18b26452e0706d1746fc90e403d02 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Mon, 15 Jun 2026 16:17:47 +0200
Subject: [PATCH 10/23] Accept native decoder state tuples
---
.../builtins/modules/io/TextIOWrapperBuiltins.java | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java
index f4cdabfe1d..c71b8703d8 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java
@@ -143,7 +143,6 @@
import com.oracle.graal.python.builtins.objects.ints.PInt;
import com.oracle.graal.python.builtins.objects.str.StringNodes.StringReplaceNode;
import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
-import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
@@ -158,6 +157,7 @@
import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
import com.oracle.graal.python.lib.PyObjectSizeNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.RichCmpOp;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -923,6 +923,7 @@ static Object tell(VirtualFrame frame, PTextIO self,
@Exclusive @Cached PyObjectCallMethodObjArgs callMethodDecode,
@Exclusive @Cached PyObjectCallMethodObjArgs callMethodGetState,
@Exclusive @Cached PyObjectCallMethodObjArgs callMethodSetState,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached PyNumberAsSizeNode asSizeNode,
@Exclusive @Cached PyLongAsLongNode asLongNode,
@Cached PyObjectSizeNode sizeNode,
@@ -945,7 +946,7 @@ static Object tell(VirtualFrame frame, PTextIO self,
PBytes in = PFactory.createBytes(language, snapshotNextInput, skipBytes);
int charsDecoded = decoderDecode(frame, inliningTarget, self, in, callMethodDecode, toString, codePointLengthNode);
if (charsDecoded <= decodedCharsUsed) {
- Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, raiseNode);
+ Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, tupleCheckNode, raiseNode);
int decFlags = asSizeNode.executeExact(frame, inliningTarget, state[1]);
int decBufferLen = sizeNode.execute(frame, inliningTarget, state[0]);
if (decBufferLen == 0) {
@@ -987,7 +988,7 @@ static Object tell(VirtualFrame frame, PTextIO self,
/* We got n chars for 1 byte */
charsDecoded += n;
cookie.bytesToFeed += 1;
- Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, raiseNode);
+ Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, tupleCheckNode, raiseNode);
int decFlags = asSizeNode.executeExact(frame, inliningTarget, state[1]);
int decBufferLen = sizeNode.execute(frame, inliningTarget, state[0]);
@@ -1038,9 +1039,10 @@ static Object[] decoderGetstate(VirtualFrame frame, Node inliningTarget, PTextIO
SequenceNodes.GetObjectArrayNode getArray,
PyObjectCallMethodObjArgs callMethodGetState,
PyObjectCallMethodObjArgs callMethodSetState,
+ PyTupleCheckNode tupleCheckNode,
PRaiseNode raiseNode) {
Object state = callMethodGetState.execute(frame, inliningTarget, self.getDecoder(), T_GETSTATE);
- if (!(state instanceof PTuple)) {
+ if (!tupleCheckNode.execute(inliningTarget, state)) {
fail(frame, inliningTarget, self, saved_state, callMethodSetState);
throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_DECODER_STATE);
}
From 186ceccedcc9b4ee92f725f17fe139338ad84c17 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Tue, 16 Jun 2026 17:53:13 +0200
Subject: [PATCH 11/23] Accept native tuples
---
.../src/tests/cpyext/test_tuple.py | 74 ++++++++++
.../builtins/modules/BuiltinFunctions.java | 15 +-
.../modules/SocketModuleBuiltins.java | 10 +-
.../builtins/modules/TimeModuleBuiltins.java | 43 +++---
.../cext/PythonCextGenericAliasBuiltins.java | 29 +++-
.../modules/codecs/ErrorHandlers.java | 19 ++-
.../modules/functools/PartialBuiltins.java | 17 ++-
.../builtins/modules/io/BytesIOBuiltins.java | 13 +-
.../io/IncrementalNewlineDecoderBuiltins.java | 43 ++++--
.../builtins/modules/io/StringIOBuiltins.java | 13 +-
.../modules/io/TextIOWrapperBuiltins.java | 2 +-
.../modules/io/TextIOWrapperNodes.java | 4 +-
.../modules/json/JSONEncoderBuiltins.java | 21 ++-
.../builtins/modules/pickle/PUnpickler.java | 12 +-
.../modules/pickle/PicklerBuiltins.java | 23 ++-
.../objects/PythonAbstractObject.java | 53 +++----
.../objects/common/SequenceNodes.java | 6 +-
.../exception/PrepareExceptionNode.java | 7 +-
.../function/AbstractFunctionBuiltins.java | 15 +-
.../objects/function/FunctionBuiltins.java | 76 +++++++++-
.../objects/itertools/ChainBuiltins.java | 5 +-
.../itertools/CombinationsBuiltins.java | 12 +-
.../objects/itertools/CycleBuiltins.java | 5 +-
.../objects/itertools/GroupByBuiltins.java | 5 +-
.../objects/itertools/TeeBuiltins.java | 5 +-
.../mappingproxy/MappingproxyBuiltins.java | 7 +-
.../objects/memoryview/MemoryViewNodes.java | 11 +-
.../objects/random/RandomBuiltins.java | 19 ++-
.../objects/thread/RLockBuiltins.java | 11 +-
.../builtins/objects/type/TypeBuiltins.java | 35 +++--
.../builtins/objects/type/TypeNodes.java | 7 +-
.../objects/types/GenericAliasBuiltins.java | 21 ++-
.../objects/types/GenericTypeNodes.java | 69 ++++-----
.../objects/typing/TypeAliasTypeBuiltins.java | 11 +-
.../python/lib/PyErrExceptionMatchesNode.java | 8 +-
.../python/lib/PyObjectIsInstanceNode.java | 3 +-
.../python/lib/PyObjectIsSubclassNode.java | 3 +-
.../lib/PyObjectRecursiveBinaryCheckNode.java | 9 +-
.../graal/python/lib/PyTupleCheckNode.java | 19 +++
.../python/nodes/builtins/ListNodes.java | 4 +-
.../python/nodes/builtins/TupleNodes.java | 12 +-
.../nodes/exception/ExceptMatchNode.java | 13 +-
.../builtins/clinic/TupleConversionNode.java | 15 +-
.../formatting/BytesFormatProcessor.java | 5 +-
.../runtime/formatting/FormatProcessor.java | 8 +-
.../formatting/StringFormatProcessor.java | 4 +-
.../graal/python/runtime/object/PFactory.java | 20 ++-
.../storage/NativeObjectSequenceStorage.java | 8 +-
.../storage/NativeSequenceStorage.java | 135 ++++++++++++++++--
49 files changed, 720 insertions(+), 264 deletions(-)
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py
index 62cfa10797..5ab44035a4 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py
+++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py
@@ -36,7 +36,13 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
+import _io
+import functools
+import io
+import itertools
+import json
import os
+import pickle
import tempfile
import unittest
@@ -398,3 +404,71 @@ def __divmod__(self, other):
tolerance = 1_000_000_000
assert abs(stat.st_atime_ns - expected) <= tolerance
assert abs(stat.st_mtime_ns - expected) <= tolerance
+
+ def test_percent_format_native_tuple(self):
+ args = TupleSubclass("native", 7)
+ assert is_native_object(args)
+ assert "%s:%d" % args == "native:7"
+
+ bytes_args = TupleSubclass(b"native", 7)
+ assert is_native_object(bytes_args)
+ assert b"%s:%d" % bytes_args == b"native:7"
+
+ def test_incremental_newline_decoder_getstate_native_tuple(self):
+ class Decoder:
+ def getstate(self):
+ state = TupleSubclass(b"", 0)
+ assert is_native_object(state)
+ return state
+
+ decoder = _io.IncrementalNewlineDecoder(Decoder(), translate=False)
+ assert decoder.getstate() == (b"", 0)
+
+ def test_incremental_newline_decoder_setstate_native_tuple(self):
+ state = TupleSubclass(b"buffer", 1)
+ assert is_native_object(state)
+
+ decoder = _io.IncrementalNewlineDecoder(None, translate=False)
+ decoder.setstate(state)
+ assert decoder.getstate() == (b"", 1)
+
+ class Decoder:
+ def setstate(self, state):
+ self.state = state
+
+ def getstate(self):
+ return self.state
+
+ state = TupleSubclass(b"buffer", 3)
+ assert is_native_object(state)
+
+ wrapped_decoder = Decoder()
+ decoder = _io.IncrementalNewlineDecoder(wrapped_decoder, translate=False)
+ decoder.setstate(state)
+ assert wrapped_decoder.state == (b"buffer", 1)
+ assert decoder.getstate() == (b"buffer", 3)
+
+ def test_functools_partial_setstate_native_tuple_args(self):
+ args = TupleSubclass(2, 5)
+ assert is_native_object(args)
+ partial = functools.partial(int)
+ partial.__setstate__((pow, args, None, None))
+ assert partial() == 32
+
+ def test_pickle_memo_accepts_native_tuple_value(self):
+ value = TupleSubclass(11, "memo")
+ assert is_native_object(value)
+ pickler = pickle.Pickler(io.BytesIO())
+ pickler.memo = {0: value}
+
+ def test_json_encodes_native_tuple(self):
+ array = TupleSubclass("native", 7)
+ assert is_native_object(array)
+ assert json.dumps(array, separators=(",", ":")) == '["native",7]'
+
+ def test_itertools_cycle_setstate_native_tuple(self):
+ state = TupleSubclass([], 0)
+ assert is_native_object(state)
+ cycle = itertools.cycle([1])
+ cycle.__setstate__(state)
+ assert next(cycle) == 1
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java
index 5e9249feb9..caf1e85437 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java
@@ -205,6 +205,9 @@
import com.oracle.graal.python.lib.PyObjectSizeNode;
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
+import com.oracle.graal.python.lib.PyTupleGetItem;
+import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
import com.oracle.graal.python.lib.PyUnicodeFSDecoderNode;
import com.oracle.graal.python.lib.RichCmpOp;
@@ -2137,6 +2140,9 @@ static Object[] update(Object[] bases,
@Bind PythonLanguage language,
@Cached PyObjectLookupAttr getMroEntries,
@Cached CallUnaryMethodNode callMroEntries,
+ @Cached PyTupleCheckNode tupleCheck,
+ @Cached PyTupleSizeNode tupleSize,
+ @Cached PyTupleGetItem tupleGetItem,
@Cached PRaiseNode raiseNode) {
CompilerAsserts.neverPartOfCompilation();
PTuple originalBases = null;
@@ -2163,10 +2169,9 @@ static Object[] update(Object[] bases,
originalBases = PFactory.createTuple(language, bases);
}
Object newBase = callMroEntries.executeObject(null, meth, originalBases);
- if (!PGuards.isPTuple(newBase)) {
+ if (!tupleCheck.execute(inliningTarget, newBase)) {
throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.MRO_ENTRIES_MUST_RETURN_TUPLE);
}
- PTuple newBaseTuple = (PTuple) newBase;
if (newBases == null) {
// If this is a first successful replacement, create new_bases list and copy
// previously encountered bases.
@@ -2175,9 +2180,9 @@ static Object[] update(Object[] bases,
newBases.add(bases[j]);
}
}
- SequenceStorage storage = newBaseTuple.getSequenceStorage();
- for (int j = 0; j < storage.length(); j++) {
- newBases.add(SequenceStorageNodes.GetItemScalarNode.executeUncached(storage, j));
+ int newBaseLen = tupleSize.execute(inliningTarget, newBase);
+ for (int j = 0; j < newBaseLen; j++) {
+ newBases.add(tupleGetItem.execute(inliningTarget, newBase, j));
}
}
if (newBases == null) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java
index c2a3bdf724..68b41767e4 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java
@@ -92,6 +92,7 @@
import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -125,6 +126,7 @@
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
+import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NeverDefault;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
@@ -544,11 +546,13 @@ protected ArgumentClinicProvider getArgumentClinic() {
@Builtin(name = "getnameinfo", minNumOfPositionalArgs = 2, numOfPositionalOnlyArgs = 2, parameterNames = {"sockaddr", "flags"})
@ArgumentClinic(name = "flags", conversion = ArgumentClinic.ClinicConversion.Int)
@GenerateNodeFactory
+ @ImportStatic(PGuards.class)
public abstract static class GetNameInfoNode extends PythonBinaryClinicBuiltinNode {
- @Specialization
- static Object getNameInfo(VirtualFrame frame, PTuple sockaddr, int flags,
+ @Specialization(guards = "isTuple(sockaddr)")
+ static Object getNameInfo(VirtualFrame frame, Object sockaddr, int flags,
@Bind Node inliningTarget,
@Bind PythonContext context,
+ @Cached GetTupleStorage getTupleStorage,
@CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@CachedLibrary(limit = "1") AddrInfoCursorLibrary addrInfoCursorLib,
@CachedLibrary(limit = "1") UniversalSockAddrLibrary sockAddrLibrary,
@@ -560,7 +564,7 @@ static Object getNameInfo(VirtualFrame frame, PTuple sockaddr, int flags,
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
@Cached TruffleString.FromLongNode fromLongNode,
@Cached PRaiseNode raiseNode) {
- SequenceStorage addr = sockaddr.getSequenceStorage();
+ SequenceStorage addr = getTupleStorage.execute(inliningTarget, sockaddr);
int addrLen = addr.length();
if (addrLen < 2 || addrLen > 4) {
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ILLEGAL_SOCKET_ADDR_ARG, "getnameinfo()");
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java
index a09bafc73a..ac7dd84845 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java
@@ -62,7 +62,6 @@
import com.oracle.graal.python.builtins.modules.TimeModuleBuiltinsClinicProviders.StrfTimeNodeClinicProviderGen;
import com.oracle.graal.python.builtins.modules.TimeModuleBuiltinsClinicProviders.StrptimeNodeClinicProviderGen;
import com.oracle.graal.python.builtins.objects.PNone;
-import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode;
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.ints.PInt;
import com.oracle.graal.python.builtins.objects.module.PythonModule;
@@ -76,9 +75,11 @@
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
import com.oracle.graal.python.nodes.ErrorMessages;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PNodeWithContext;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -94,6 +95,7 @@
import com.oracle.graal.python.runtime.GilNode;
import com.oracle.graal.python.runtime.PythonContext;
import com.oracle.graal.python.runtime.object.PFactory;
+import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
import com.oracle.graal.python.util.PythonUtils;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.TruffleOptions;
@@ -106,6 +108,7 @@
import com.oracle.truffle.api.dsl.GenerateCached;
import com.oracle.truffle.api.dsl.GenerateInline;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
+import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NeverDefault;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
@@ -617,6 +620,7 @@ public static SleepNode create() {
@Builtin(name = "strftime", minNumOfPositionalArgs = 2, declaresExplicitSelf = true, parameterNames = {"$self", "format", "time"})
@ArgumentClinic(name = "format", conversion = ArgumentClinic.ClinicConversion.TString)
@GenerateNodeFactory
+ @ImportStatic(PGuards.class)
public abstract static class StrfTimeNode extends PythonTernaryClinicBuiltinNode {
@Override
protected ArgumentClinicProvider getArgumentClinic() {
@@ -635,12 +639,12 @@ private static String timeFormat(int[] date) {
return PythonUtils.formatJString("%02d:%02d:%02d", date[TM_HOUR], date[TM_MIN], date[TM_SEC]);
}
- protected static int[] checkStructtime(VirtualFrame frame, Node inliningTarget, PTuple time,
+ protected static int[] checkStructtime(VirtualFrame frame, Node inliningTarget, SequenceStorage timeStorage,
SequenceStorageNodes.GetInternalObjectArrayNode getInternalObjectArrayNode,
PyNumberAsSizeNode asSizeNode,
PRaiseNode raiseNode) {
- Object[] otime = getInternalObjectArrayNode.execute(inliningTarget, time.getSequenceStorage());
- if (time.getSequenceStorage().length() != 9) {
+ Object[] otime = getInternalObjectArrayNode.execute(inliningTarget, timeStorage);
+ if (timeStorage.length() != 9) {
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_ILLEGAL_TIME_TUPLE_ARG, "asctime()");
}
int[] date = new int[9];
@@ -987,16 +991,17 @@ static TruffleString formatTime(PythonModule module, TruffleString format, @Supp
return format(toJavaStringNode.execute(format), getIntLocalTimeStruct(moduleState.currentZoneId, (long) timeSeconds()), getTimeZone(moduleState.currentZoneId), fromJavaStringNode);
}
- @Specialization
- static TruffleString formatTime(VirtualFrame frame, PythonModule module, TruffleString format, PTuple time,
+ @Specialization(guards = "isTuple(time)")
+ static TruffleString formatTime(VirtualFrame frame, PythonModule module, TruffleString format, Object time,
@Bind Node inliningTarget,
+ @Cached GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@Cached PyNumberAsSizeNode asSizeNode,
@Shared("byteIndexOfCp") @Cached TruffleString.ByteIndexOfCodePointNode byteIndexOfCodePointNode,
@Shared("ts2js") @Cached ToJavaStringNode toJavaStringNode,
@Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode,
@Exclusive @Cached PRaiseNode raiseNode) {
- int[] date = checkStructtime(frame, inliningTarget, time, getArray, asSizeNode, raiseNode);
+ int[] date = checkStructtime(frame, inliningTarget, getTupleStorage.execute(inliningTarget, time), getArray, asSizeNode, raiseNode);
return format(toJavaStringNode.execute(format), date, getTimeZone(module.getModuleState(ModuleState.class).currentZoneId), fromJavaStringNode);
}
@@ -1014,20 +1019,24 @@ static TruffleString formatTime(PythonModule module, TruffleString format, Objec
"time zones; instead the returned value will either be equal to that\n" +
"of the timezone or altzone attributes on the time module.")
@GenerateNodeFactory
+ @ImportStatic(PGuards.class)
abstract static class MkTimeNode extends PythonBinaryBuiltinNode {
private static final int ELEMENT_COUNT = 9;
- @Specialization
@ExplodeLoop
- static double mktime(VirtualFrame frame, PythonModule module, PTuple tuple,
+ @Specialization(guards = "isTuple(tuple)")
+ static double mktime(VirtualFrame frame, PythonModule module, Object tuple,
@Bind Node inliningTarget,
+ @Cached GetTupleStorage getTupleStorage,
@Cached PyNumberAsSizeNode asSizeNode,
- @Cached GetObjectArrayNode getObjectArrayNode,
+ @Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@Cached PRaiseNode raiseNode) {
- Object[] items = getObjectArrayNode.execute(inliningTarget, tuple);
- if (items.length != ELEMENT_COUNT) {
- throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.FUNC_TAKES_EXACTLY_D_ARGS, ELEMENT_COUNT, items.length);
+ SequenceStorage storage = getTupleStorage.execute(inliningTarget, tuple);
+ int storageLength = storage.length();
+ if (storageLength != ELEMENT_COUNT) {
+ throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.FUNC_TAKES_EXACTLY_D_ARGS, ELEMENT_COUNT, storageLength);
}
+ Object[] items = getArray.execute(inliningTarget, storage);
int[] integers = new int[ELEMENT_COUNT];
for (int i = 0; i < ELEMENT_COUNT; i++) {
integers[i] = asSizeNode.executeExact(frame, inliningTarget, items[i]);
@@ -1066,6 +1075,7 @@ protected static TruffleString format(int[] tm, TruffleString.FromJavaStringNode
// time.asctime([t])
@Builtin(name = "asctime", maxNumOfPositionalArgs = 2, declaresExplicitSelf = true)
@GenerateNodeFactory
+ @ImportStatic(PGuards.class)
public abstract static class ASCTimeNode extends PythonBinaryBuiltinNode {
static final String[] WDAY_NAME = new String[]{
@@ -1083,14 +1093,15 @@ static TruffleString localtime(PythonModule module, @SuppressWarnings("unused")
return format(getIntLocalTimeStruct(moduleState.currentZoneId, (long) timeSeconds()), fromJavaStringNode);
}
- @Specialization
- static TruffleString localtime(VirtualFrame frame, @SuppressWarnings("unused") PythonModule module, PTuple time,
+ @Specialization(guards = "isTuple(time)")
+ static TruffleString localtime(VirtualFrame frame, @SuppressWarnings("unused") PythonModule module, Object time,
@Bind Node inliningTarget,
+ @Cached GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@Cached PyNumberAsSizeNode asSizeNode,
@Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode,
@Cached PRaiseNode raiseNode) {
- return format(StrfTimeNode.checkStructtime(frame, inliningTarget, time, getArray, asSizeNode, raiseNode), fromJavaStringNode);
+ return format(StrfTimeNode.checkStructtime(frame, inliningTarget, getTupleStorage.execute(inliningTarget, time), getArray, asSizeNode, raiseNode), fromJavaStringNode);
}
@Fallback
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java
index bb8895a010..7ea777288f 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -47,9 +47,17 @@
import com.oracle.graal.python.PythonLanguage;
import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode;
import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin;
+import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
+import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
+import com.oracle.graal.python.builtins.objects.tuple.PTuple;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.runtime.object.PFactory;
+import com.oracle.graal.python.runtime.sequence.storage.NativeObjectSequenceStorage;
import com.oracle.truffle.api.dsl.Bind;
+import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.nodes.Node;
public final class PythonCextGenericAliasBuiltins {
@@ -57,8 +65,23 @@ public final class PythonCextGenericAliasBuiltins {
abstract static class Py_GenericAlias extends CApiBinaryBuiltinNode {
@Specialization
static Object genericAlias(Object origin, Object args,
- @Bind PythonLanguage language) {
- return PFactory.createGenericAlias(language, origin, args);
+ @Bind Node inliningTarget,
+ @Bind PythonLanguage language,
+ @Cached PyTupleCheckNode tupleCheck,
+ @Cached SequenceStorageNodes.CopyNode copyNode) {
+ PTuple argsTuple;
+ if (args instanceof PTuple) {
+ argsTuple = (PTuple) args;
+ } else if (tupleCheck.execute(inliningTarget, args)) {
+ /* 'GetTupleStorageNode.doNative' will just "wrap" the 'ob_item' pointer. The memory is then still owned by the native tuple object. Therefore, we need to copy the storage to a managed
+ * storage.
+ */
+ NativeObjectSequenceStorage nativeObjectSequenceStorage = GetTupleStorage.doNative((PythonAbstractNativeObject) args);
+ argsTuple = PFactory.createTuple(language, copyNode.execute(inliningTarget, nativeObjectSequenceStorage));
+ } else {
+ argsTuple = PFactory.createTuple(language, new Object[]{args});
+ }
+ return PFactory.createGenericAlias(language, origin, argsTuple);
}
}
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java
index c7103d9d74..b50b592401 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java
@@ -87,7 +87,9 @@
import com.oracle.graal.python.lib.PyObjectTypeCheck;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.call.CallNode;
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData;
@@ -104,6 +106,7 @@
import com.oracle.truffle.api.dsl.GenerateInline;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.GenerateUncached;
+import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.frame.VirtualFrame;
@@ -845,16 +848,18 @@ public static final class DecodingErrorHandlerResult {
@GenerateInline
@GenerateCached(false)
@GenerateUncached
+ @ImportStatic(PGuards.class)
abstract static class ParseDecodingErrorHandlerResultNode extends Node {
abstract DecodingErrorHandlerResult execute(VirtualFrame frame, Node inliningTarget, Object result);
- @Specialization
- static DecodingErrorHandlerResult doTuple(VirtualFrame frame, Node inliningTarget, PTuple result,
+ @Specialization(guards = "isTuple(result)")
+ static DecodingErrorHandlerResult doTuple(VirtualFrame frame, Node inliningTarget, Object result,
+ @Cached GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
@Cached CastToTruffleStringChecked0Node castToTruffleStringCheckedNode,
@Cached PyNumberAsSizeNode asSizeNode,
@Cached PRaiseNode raiseNode) {
- SequenceStorage storage = result.getSequenceStorage();
+ SequenceStorage storage = getTupleStorage.execute(inliningTarget, result);
if (storage.length() != 2) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.DECODING_ERROR_HANDLER_MUST_RETURN_STR_INT_TUPLE);
}
@@ -918,17 +923,19 @@ public static final class EncodingErrorHandlerResult {
@GenerateInline
@GenerateCached(false)
@GenerateUncached
+ @ImportStatic(PGuards.class)
abstract static class ParseEncodingErrorHandlerResultNode extends Node {
abstract EncodingErrorHandlerResult execute(Frame frame, Node inliningTarget, Object result);
- @Specialization
- static EncodingErrorHandlerResult doTuple(VirtualFrame frame, Node inliningTarget, PTuple result,
+ @Specialization(guards = "isTuple(result)")
+ static EncodingErrorHandlerResult doTuple(VirtualFrame frame, Node inliningTarget, Object result,
+ @Cached GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
@Cached PyNumberAsSizeNode asSizeNode,
@Cached PyUnicodeCheckNode pyUnicodeCheckNode,
@Cached PyBytesCheckNode pyBytesCheckNode,
@Cached PRaiseNode raiseNode) {
- SequenceStorage storage = result.getSequenceStorage();
+ SequenceStorage storage = getTupleStorage.execute(inliningTarget, result);
if (storage.length() != 2) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ENCODING_ERROR_HANDLER_MUST_RETURN_STR_BYTES_INT_TUPLE);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java
index 4d223f6cc3..c5972269ae 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -87,6 +87,7 @@
import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode;
import com.oracle.graal.python.lib.PyTupleCheckExactNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
@@ -346,21 +347,23 @@ static Object reduce(PPartial self,
public abstract static class PartialSetStateNode extends PythonBinaryBuiltinNode {
@Specialization
- static Object setState(VirtualFrame frame, PPartial self, PTuple state,
+ static Object setState(VirtualFrame frame, PPartial self, Object state,
@Bind Node inliningTarget,
@Cached SetDictNode setDictNode,
@Cached DeleteDictNode deleteDictNode,
@Cached SequenceNodes.GetSequenceStorageNode storageNode,
@Cached SequenceStorageNodes.ToArrayNode arrayNode,
@Cached PyCallableCheckNode callableCheckNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached PyTupleCheckExactNode tupleCheckExactNode,
@Cached PyDictCheckExactNode dictCheckExactNode,
@Cached PyTupleGetItem getItemNode,
@Cached TupleNodes.ConstructTupleNode constructTupleNode,
+ @Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached HashingStorageCopy copyStorageNode,
@Bind PythonLanguage language,
@Cached PRaiseNode raiseNode) {
- if (state.getSequenceStorage().length() != 4) {
+ if (!tupleCheckNode.execute(inliningTarget, state) || getTupleStorage.execute(inliningTarget, state).length() != 4) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, INVALID_PARTIAL_STATE);
}
@@ -370,7 +373,7 @@ static Object setState(VirtualFrame frame, PPartial self, PTuple state,
final Object dict = getItemNode.execute(inliningTarget, state, 3);
if (!callableCheckNode.execute(inliningTarget, function) ||
- !PGuards.isPTuple(fnArgs) ||
+ !tupleCheckNode.execute(inliningTarget, fnArgs) ||
(fnKwargs != PNone.NONE && !PGuards.isDict(fnKwargs))) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, INVALID_PARTIAL_STATE);
}
@@ -378,10 +381,10 @@ static Object setState(VirtualFrame frame, PPartial self, PTuple state,
self.setFn(function);
final PTuple fnArgsTuple;
- if (!tupleCheckExactNode.execute(inliningTarget, fnArgs)) {
- fnArgsTuple = constructTupleNode.execute(frame, fnArgs);
- } else {
+ if (fnArgs instanceof PTuple && tupleCheckExactNode.execute(inliningTarget, fnArgs)) {
fnArgsTuple = (PTuple) fnArgs;
+ } else {
+ fnArgsTuple = constructTupleNode.execute(frame, fnArgs);
}
self.setArgs(inliningTarget, fnArgsTuple, storageNode, arrayNode);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java
index 41f6370b94..c928e0830a 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java
@@ -97,7 +97,6 @@
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetInternalObjectArrayNode;
import com.oracle.graal.python.builtins.objects.dict.PDict;
-import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
@@ -107,8 +106,10 @@
import com.oracle.graal.python.lib.PyMemoryViewFromObject;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectGetIter;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -662,8 +663,10 @@ static Object doit(VirtualFrame frame, PBytesIO self,
@GenerateNodeFactory
abstract static class SetStateNode extends PythonBinaryBuiltinNode {
@Specialization
- static Object doit(VirtualFrame frame, PBytesIO self, PTuple state,
+ static Object doit(VirtualFrame frame, PBytesIO self, Object state,
@Bind Node inliningTarget,
+ @Cached PyTupleCheckNode tupleCheck,
+ @Cached GetTupleStorage getTupleStorage,
@Cached GetInternalObjectArrayNode getArray,
@Cached WriteNode writeNode,
@Cached PyIndexCheckNode indexCheckNode,
@@ -671,8 +674,11 @@ static Object doit(VirtualFrame frame, PBytesIO self, PTuple state,
@Cached GetOrCreateDictNode getDict,
@Cached HashingStorageAddAllToOther addAllToOtherNode,
@Cached PRaiseNode raiseNode) {
+ if (!tupleCheck.execute(inliningTarget, state)) {
+ return notTuple(self, state, inliningTarget);
+ }
self.checkExports(inliningTarget, raiseNode);
- SequenceStorage storage = state.getSequenceStorage();
+ SequenceStorage storage = getTupleStorage.execute(inliningTarget, state);
Object[] array = getArray.execute(inliningTarget, storage);
if (storage.length() < 3) {
return notTuple(self, state, inliningTarget);
@@ -717,7 +723,6 @@ static Object doit(VirtualFrame frame, PBytesIO self, PTuple state,
return PNone.NONE;
}
- @Specialization(guards = "!isPTuple(state)")
static Object notTuple(PBytesIO self, Object state,
@Bind Node inliningTarget) {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 3, state);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java
index 7231427974..cb0e3db778 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -72,13 +72,16 @@
import com.oracle.graal.python.builtins.objects.PNone;
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
import com.oracle.graal.python.builtins.objects.common.SequenceNodes;
+import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
import com.oracle.graal.python.lib.PyIndexCheckNode;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PRaiseNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -88,6 +91,7 @@
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
import com.oracle.graal.python.runtime.object.PFactory;
+import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Exclusive;
@@ -320,9 +324,10 @@ static Object withDecoder(VirtualFrame frame, PNLDecoder self,
@Cached PyIndexCheckNode indexCheckNode,
@Cached PyNumberAsSizeNode asSizeNode,
@Cached PyObjectCallMethodObjArgs callMethod,
+ @Cached PyTupleCheckNode tupleCheck,
@Cached PRaiseNode raiseNode) {
Object state = callMethod.execute(frame, inliningTarget, self.getDecoder(), T_GETSTATE);
- if (!(state instanceof PTuple)) {
+ if (!tupleCheck.execute(inliningTarget, state)) {
throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_STATE_ARGUMENT);
}
Object[] objects = getObjectArrayNode.execute(inliningTarget, state);
@@ -343,14 +348,23 @@ static Object withDecoder(VirtualFrame frame, PNLDecoder self,
abstract static class SetStateNode extends PythonBinaryBuiltinNode {
@Specialization(guards = "!self.hasDecoder()")
- static Object noDecoder(VirtualFrame frame, PNLDecoder self, PTuple state,
+ static Object noDecoder(VirtualFrame frame, PNLDecoder self, Object state,
@Bind Node inliningTarget,
- @Exclusive @Cached SequenceNodes.GetObjectArrayNode getObjectArrayNode,
+ @Exclusive @Cached PyTupleCheckNode tupleCheck,
+ @Exclusive @Cached GetTupleStorage getTupleStorage,
+ @Exclusive @Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@Exclusive @Cached PyIndexCheckNode indexCheckNode,
@Exclusive @Cached PyNumberAsSizeNode asSizeNode,
@Exclusive @Cached PRaiseNode raiseNode) {
- Object[] objects = getObjectArrayNode.execute(inliningTarget, state);
- if (objects.length != 2 || !indexCheckNode.execute(inliningTarget, objects[1])) {
+ if (!tupleCheck.execute(inliningTarget, state)) {
+ return err(self, state, inliningTarget);
+ }
+ SequenceStorage storage = getTupleStorage.execute(inliningTarget, state);
+ if (storage.length() != 2) {
+ throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_STATE_ARGUMENT);
+ }
+ Object[] objects = getArray.execute(inliningTarget, storage);
+ if (!indexCheckNode.execute(inliningTarget, objects[1])) {
throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_STATE_ARGUMENT);
}
int flag = asSizeNode.executeExact(frame, inliningTarget, objects[1]);
@@ -359,16 +373,25 @@ static Object noDecoder(VirtualFrame frame, PNLDecoder self, PTuple state,
}
@Specialization(guards = "self.hasDecoder()")
- static Object withDecoder(VirtualFrame frame, PNLDecoder self, PTuple state,
+ static Object withDecoder(VirtualFrame frame, PNLDecoder self, Object state,
@Bind Node inliningTarget,
@Bind PythonLanguage language,
- @Exclusive @Cached SequenceNodes.GetObjectArrayNode getObjectArrayNode,
+ @Exclusive @Cached PyTupleCheckNode tupleCheck,
+ @Exclusive @Cached GetTupleStorage getTupleStorage,
+ @Exclusive @Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@Exclusive @Cached PyIndexCheckNode indexCheckNode,
@Exclusive @Cached PyNumberAsSizeNode asSizeNode,
@Cached PyObjectCallMethodObjArgs callMethod,
@Exclusive @Cached PRaiseNode raiseNode) {
- Object[] objects = getObjectArrayNode.execute(inliningTarget, state);
- if (objects.length != 2 || !indexCheckNode.execute(inliningTarget, objects[1])) {
+ if (!tupleCheck.execute(inliningTarget, state)) {
+ return err(self, state, inliningTarget);
+ }
+ SequenceStorage storage = getTupleStorage.execute(inliningTarget, state);
+ if (storage.length() != 2) {
+ throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_STATE_ARGUMENT);
+ }
+ Object[] objects = getArray.execute(inliningTarget, storage);
+ if (!indexCheckNode.execute(inliningTarget, objects[1])) {
throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_STATE_ARGUMENT);
}
int flag = asSizeNode.executeExact(frame, inliningTarget, objects[1]);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java
index b1c2a16f1b..d1abc668d3 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java
@@ -100,7 +100,6 @@
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.dict.PDict;
import com.oracle.graal.python.builtins.objects.str.StringNodes.StringReplaceNode;
-import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
@@ -109,8 +108,10 @@
import com.oracle.graal.python.lib.PyNumberIndexNode;
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
import com.oracle.graal.python.lib.PyObjectGetAttr;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -662,8 +663,10 @@ static Object doit(VirtualFrame frame, PStringIO self,
abstract static class SetStateNode extends PythonBinaryBuiltinNode {
@Specialization(guards = {"!self.isClosed()"})
- static Object doit(VirtualFrame frame, PStringIO self, PTuple state,
+ static Object doit(VirtualFrame frame, PStringIO self, Object state,
@Bind Node inliningTarget,
+ @Cached PyTupleCheckNode tupleCheck,
+ @Cached GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@Cached InitNode initNode,
@Cached CastToTruffleStringNode toString,
@@ -674,7 +677,10 @@ static Object doit(VirtualFrame frame, PStringIO self, PTuple state,
@Cached TruffleStringBuilder.AppendStringNode appendStringNode,
@Cached HashingStorageAddAllToOther addAllToOtherNode,
@Cached PRaiseNode raiseNode) {
- SequenceStorage storage = state.getSequenceStorage();
+ if (!tupleCheck.execute(inliningTarget, state)) {
+ return notTuple(self, state, inliningTarget);
+ }
+ SequenceStorage storage = getTupleStorage.execute(inliningTarget, state);
Object[] array = getArray.execute(inliningTarget, storage);
if (storage.length() < 4) {
return notTuple(self, state, inliningTarget);
@@ -726,7 +732,6 @@ static Object doit(VirtualFrame frame, PStringIO self, PTuple state,
return PNone.NONE;
}
- @Specialization(guards = {"!self.isClosed()", "!isPTuple(state)"})
static Object notTuple(PStringIO self, Object state,
@Bind Node inliningTarget) {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 4, state);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java
index c71b8703d8..dfcfa63e07 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java
index 71d9832ae4..8f69c57072 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java
@@ -95,6 +95,7 @@
import com.oracle.graal.python.lib.PyObjectIsTrueNode;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PNodeWithContext;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -508,6 +509,7 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self,
@Cached PyObjectCallMethodObjArgs callMethodRead,
@Cached PyNumberAsSizeNode asSizeNode,
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
+ @Cached PyTupleCheckNode tupleCheck,
@CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib,
@CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib,
@Cached PRaiseNode raiseNode) {
@@ -529,7 +531,7 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self,
* Given this, we know there was a valid snapshot point len(decBuffer) bytes ago
* with decoder state (b'', decFlags).
*/
- if (!(state instanceof PTuple)) {
+ if (!tupleCheck.execute(inliningTarget, state)) {
throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_DECODER_STATE);
}
Object[] array = getArray.execute(inliningTarget, state);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java
index 07da9493a0..1135c1bf68 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java
@@ -77,7 +77,6 @@
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
import com.oracle.graal.python.runtime.formatting.FloatFormatter;
import com.oracle.graal.python.runtime.object.PFactory;
-import com.oracle.graal.python.runtime.sequence.PSequence;
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
import com.oracle.graal.python.util.ArrayBuilder;
import com.oracle.graal.python.util.PythonUtils;
@@ -267,11 +266,10 @@ PTuple call(VirtualFrame frame, PJSONEncoder self, Object obj, @SuppressWarnings
parent = value;
final Object stackIterator;
final Object stackStorage;
- if (value instanceof PList || value instanceof PTuple) {
- PSequence list = (PSequence) value;
+ if (value instanceof PList list) {
appendCodePointNode.execute(builder, '[');
first = true;
- if (pyTupleCheckExactNode.execute(inliningTarget, list) || pyListCheckExactNode.execute(inliningTarget, list)) {
+ if (pyListCheckExactNode.execute(inliningTarget, list)) {
state = STATE_BUILTIN_LIST;
builtinListStorage = list.getSequenceStorage();
stackStorage = builtinListStorage;
@@ -283,6 +281,21 @@ PTuple call(VirtualFrame frame, PJSONEncoder self, Object obj, @SuppressWarnings
stackStorage = null;
stackIterator = genericIterator;
}
+ } else if (tupleCheckNode.execute(inliningTarget, value)) {
+ appendCodePointNode.execute(builder, '[');
+ first = true;
+ if (pyTupleCheckExactNode.execute(inliningTarget, value)) {
+ state = STATE_BUILTIN_LIST;
+ builtinListStorage = getTupleStorage.execute(inliningTarget, value);
+ stackStorage = builtinListStorage;
+ stackIterator = null;
+ } else {
+ genericListProfile.enter(inliningTarget);
+ state = STATE_GENERIC_LIST;
+ genericIterator = callGetListIter.executeCached(frame, value);
+ stackStorage = null;
+ stackIterator = genericIterator;
+ }
} else if (value instanceof PDict dict) {
appendCodePointNode.execute(builder, '{');
first = true;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PUnpickler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PUnpickler.java
index 4c00d8ac08..305f47cede 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PUnpickler.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PUnpickler.java
@@ -168,6 +168,7 @@
import com.oracle.graal.python.lib.PyObjectLookupAttr;
import com.oracle.graal.python.lib.PyObjectSetAttrO;
import com.oracle.graal.python.lib.PyObjectSetItem;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -691,6 +692,7 @@ public abstract static class LoadNode extends BasePickleReadNode {
@Child private PyObjectSetItem setItemNode;
@Child HashingStorageCopy hashCopy;
@Child HashingStorageAddAllToOther addAllToOther;
+ @Child private PyTupleCheckNode.CachedNode tupleCheck;
public abstract Object execute(VirtualFrame frame, PUnpickler self);
@@ -710,6 +712,14 @@ protected HashingStorageAddAllToOther ensureHashingStorageAddAllToOther() {
return addAllToOther;
}
+ protected boolean isTuple(Object object) {
+ if (tupleCheck == null) {
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ tupleCheck = insert(PyTupleCheckNode.CachedNode.create());
+ }
+ return tupleCheck.execute(object);
+ }
+
protected Object longFromBytes(byte[] data, boolean littleEndian) {
if (pyLongFromByteArray == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -1761,7 +1771,7 @@ private void loadExtension(VirtualFrame frame, BoundaryCallData boundaryCallData
// Since the extension registry is manipulable via Python code, confirm that pair is
// really a 2-tuple of strings.
- if (!(pair instanceof PTuple) || length(frame, pair) != 2) {
+ if (!isTuple(pair) || length(frame, pair) != 2) {
throw raise(PythonBuiltinClassType.ValueError, ErrorMessages.INV_REG_NOT_2TUPLE, code);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java
index 1d91c0a770..59310a5f1a 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -69,18 +69,17 @@
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIterator;
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorNext;
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageIteratorValue;
-import com.oracle.graal.python.builtins.objects.common.SequenceNodes;
-import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.dict.PDict;
import com.oracle.graal.python.builtins.objects.function.PKeyword;
-import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
import com.oracle.graal.python.lib.PyCallableCheckNode;
import com.oracle.graal.python.lib.PyLongAsLongNode;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
-import com.oracle.graal.python.lib.PyObjectSizeNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
+import com.oracle.graal.python.lib.PyTupleGetItem;
+import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -92,7 +91,6 @@
import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
import com.oracle.graal.python.runtime.object.PFactory;
-import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Exclusive;
@@ -273,10 +271,10 @@ static Object get(PPickler self, @SuppressWarnings("unused") PNone none,
@Specialization(guards = {"!isNoValue(obj)", "!isDeleteMarker(obj)"})
static Object set(VirtualFrame frame, PPickler self, Object obj,
@Bind Node inliningTarget,
- @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode,
- @Cached SequenceStorageNodes.GetItemNode getItemNode,
@Cached PyNumberAsSizeNode asSizeNode,
- @Cached PyObjectSizeNode sizeNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
+ @Cached PyTupleSizeNode sizeNode,
+ @Cached PyTupleGetItem getItemNode,
@Cached HashingStorageGetIterator getIter,
@Cached HashingStorageIteratorNext iterNext,
@Cached HashingStorageIteratorValue iterValue,
@@ -291,12 +289,11 @@ static Object set(VirtualFrame frame, PPickler self, Object obj,
HashingStorageIterator it = getIter.execute(inliningTarget, dictStorage);
while (iterNext.execute(inliningTarget, dictStorage, it)) {
Object value = iterValue.execute(inliningTarget, dictStorage, it);
- if (!(value instanceof PTuple) || sizeNode.execute(frame, inliningTarget, value) != 2) {
+ if (!tupleCheckNode.execute(inliningTarget, value) || sizeNode.execute(inliningTarget, value) != 2) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.VALUES_MUST_BE_2TUPLES, "memo");
}
- SequenceStorage tupleStorage = getSequenceStorageNode.execute(inliningTarget, value);
- int memoId = asSizeNode.executeExact(frame, inliningTarget, getItemNode.execute(frame, tupleStorage, 0));
- Object memoObj = getItemNode.execute(frame, tupleStorage, 1);
+ int memoId = asSizeNode.executeExact(frame, inliningTarget, getItemNode.execute(inliningTarget, value, 0));
+ Object memoObj = getItemNode.execute(inliningTarget, value, 1);
newMemo.set(memoObj, memoId);
}
} else {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java
index ee391fe12e..f42a2adca2 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java
@@ -110,6 +110,8 @@
import com.oracle.graal.python.lib.PySequenceGetItemNode;
import com.oracle.graal.python.lib.PySequenceSetItemNode;
import com.oracle.graal.python.lib.PySequenceSizeNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
+import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.nodes.BuiltinNames;
import com.oracle.graal.python.nodes.HiddenAttr;
@@ -850,10 +852,12 @@ public LocalDate asDate(
// GR-44020: make shared:
@Exclusive @Cached PRaiseNode raiseNode,
// GR-44020: make shared:
- @Exclusive @Cached SequenceStorageNodes.GetItemDynamicNode getItemNode,
- // GR-44020: make shared:
@Exclusive @Cached PyTupleSizeNode pyTupleSizeNode,
// GR-44020: make shared:
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
+ // GR-44020: make shared:
+ @Exclusive @Cached PyTupleGetItem tupleGetItem,
+ // GR-44020: make shared:
@Exclusive @Cached GilNode gil) throws UnsupportedMessageException {
boolean mustRelease = gil.acquire();
try {
@@ -861,14 +865,13 @@ public LocalDate asDate(
InteropBehavior behavior = getBehavior.execute(inliningTarget, this, method);
if (behavior != null) {
Object value = getValue.execute(inliningTarget, behavior, method, this);
- if (value instanceof PTuple tuple) {
- if (pyTupleSizeNode.execute(inliningTarget, tuple) != 3) {
+ if (tupleCheckNode.execute(inliningTarget, value)) {
+ if (pyTupleSizeNode.execute(inliningTarget, value) != 3) {
throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_A_S_TUPLE, "return value", "3");
}
- SequenceStorage storage = tuple.getSequenceStorage();
- int year = castToIntNode.executeWithThrowSystemError(inliningTarget, getItemNode.execute(inliningTarget, storage, 0), raiseNode);
- int month = castToIntNode.executeWithThrowSystemError(inliningTarget, getItemNode.execute(inliningTarget, storage, 1), raiseNode);
- int day = castToIntNode.executeWithThrowSystemError(inliningTarget, getItemNode.execute(inliningTarget, storage, 2), raiseNode);
+ int year = castToIntNode.executeWithThrowSystemError(inliningTarget, tupleGetItem.execute(inliningTarget, value, 0), raiseNode);
+ int month = castToIntNode.executeWithThrowSystemError(inliningTarget, tupleGetItem.execute(inliningTarget, value, 1), raiseNode);
+ int day = castToIntNode.executeWithThrowSystemError(inliningTarget, tupleGetItem.execute(inliningTarget, value, 2), raiseNode);
try {
return createLocalDate(year, month, day);
} catch (Exception e) {
@@ -923,10 +926,12 @@ public LocalTime asTime(
// GR-44020: make shared:
@Exclusive @Cached PRaiseNode raiseNode,
// GR-44020: make shared:
- @Exclusive @Cached SequenceStorageNodes.GetItemDynamicNode getItemNode,
- // GR-44020: make shared:
@Exclusive @Cached PyTupleSizeNode pyTupleSizeNode,
// GR-44020: make shared:
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
+ // GR-44020: make shared:
+ @Exclusive @Cached PyTupleGetItem tupleGetItem,
+ // GR-44020: make shared:
@Exclusive @Cached GilNode gil) throws UnsupportedMessageException {
boolean mustRelease = gil.acquire();
try {
@@ -934,15 +939,14 @@ public LocalTime asTime(
InteropBehavior behavior = getBehavior.execute(inliningTarget, this, method);
if (behavior != null) {
Object value = getValue.execute(inliningTarget, behavior, method, this);
- if (value instanceof PTuple tuple) {
- if (pyTupleSizeNode.execute(inliningTarget, tuple) != 4) {
+ if (tupleCheckNode.execute(inliningTarget, value)) {
+ if (pyTupleSizeNode.execute(inliningTarget, value) != 4) {
throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_A_S_TUPLE, "return value", "4");
}
- SequenceStorage storage = tuple.getSequenceStorage();
- int hour = castToIntNode.executeWithThrowSystemError(inliningTarget, getItemNode.execute(inliningTarget, storage, 0), raiseNode);
- int min = castToIntNode.executeWithThrowSystemError(inliningTarget, getItemNode.execute(inliningTarget, storage, 1), raiseNode);
- int sec = castToIntNode.executeWithThrowSystemError(inliningTarget, getItemNode.execute(inliningTarget, storage, 2), raiseNode);
- int micro = castToIntNode.executeWithThrowSystemError(inliningTarget, getItemNode.execute(inliningTarget, storage, 3), raiseNode);
+ int hour = castToIntNode.executeWithThrowSystemError(inliningTarget, tupleGetItem.execute(inliningTarget, value, 0), raiseNode);
+ int min = castToIntNode.executeWithThrowSystemError(inliningTarget, tupleGetItem.execute(inliningTarget, value, 1), raiseNode);
+ int sec = castToIntNode.executeWithThrowSystemError(inliningTarget, tupleGetItem.execute(inliningTarget, value, 2), raiseNode);
+ int micro = castToIntNode.executeWithThrowSystemError(inliningTarget, tupleGetItem.execute(inliningTarget, value, 3), raiseNode);
try {
return createLocalTime(hour, min, sec, micro);
} catch (Exception e) {
@@ -1085,10 +1089,12 @@ public Duration asDuration(
// GR-44020: make shared:
@Exclusive @Cached PRaiseNode raiseNode,
// GR-44020: make shared:
- @Exclusive @Cached SequenceStorageNodes.GetItemDynamicNode getItemNode,
- // GR-44020: make shared:
@Exclusive @Cached PyTupleSizeNode pyTupleSizeNode,
// GR-44020: make shared:
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
+ // GR-44020: make shared:
+ @Exclusive @Cached PyTupleGetItem tupleGetItem,
+ // GR-44020: make shared:
@Exclusive @Cached GilNode gil) throws UnsupportedMessageException {
boolean mustRelease = gil.acquire();
try {
@@ -1096,13 +1102,12 @@ public Duration asDuration(
InteropBehavior behavior = getBehavior.execute(inliningTarget, this, method);
if (behavior != null) {
Object value = getValue.execute(inliningTarget, behavior, method, this);
- if (value instanceof PTuple tuple) {
- if (pyTupleSizeNode.execute(inliningTarget, tuple) != 2) {
+ if (tupleCheckNode.execute(inliningTarget, value)) {
+ if (pyTupleSizeNode.execute(inliningTarget, value) != 2) {
throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_A_S_TUPLE, "return value", "2");
}
- SequenceStorage storage = tuple.getSequenceStorage();
- long sec = castToLongNode.executeWithThrowSystemError(inliningTarget, getItemNode.execute(inliningTarget, storage, 0), raiseNode);
- long nano = castToLongNode.executeWithThrowSystemError(inliningTarget, getItemNode.execute(inliningTarget, storage, 1), raiseNode);
+ long sec = castToLongNode.executeWithThrowSystemError(inliningTarget, tupleGetItem.execute(inliningTarget, value, 0), raiseNode);
+ long nano = castToLongNode.executeWithThrowSystemError(inliningTarget, tupleGetItem.execute(inliningTarget, value, 1), raiseNode);
try {
return createDuration(sec, nano);
} catch (Exception e) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java
index 424e265303..7a26e57308 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java
@@ -52,7 +52,6 @@
import com.oracle.graal.python.builtins.objects.list.PList;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.lib.PySequenceCheckNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PNodeWithContext;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -140,9 +139,8 @@ static SequenceStorage doSequence(Node inliningTarget, PSequence seq,
return getPSequenceStorageNode.execute(inliningTarget, seq);
}
- @Specialization(guards = "tupleCheck.execute(inliningTarget, seq)", limit = "1")
- static SequenceStorage doNativeTuple(@SuppressWarnings("unused") Node inliningTarget, PythonAbstractNativeObject seq,
- @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheck) {
+ @Specialization(guards = "isTuple(seq)")
+ static SequenceStorage doNativeTuple(@SuppressWarnings("unused") Node inliningTarget, PythonAbstractNativeObject seq) {
return GetTupleStorage.doNative(seq);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PrepareExceptionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PrepareExceptionNode.java
index dd31b7aca9..753d63a461 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PrepareExceptionNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PrepareExceptionNode.java
@@ -50,7 +50,6 @@
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
import com.oracle.graal.python.lib.PyExceptionInstanceCheckNode;
import com.oracle.graal.python.lib.PyObjectIsInstanceNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -97,12 +96,11 @@ static Object doException(@SuppressWarnings("unused") PBaseException exc, @Suppr
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.INSTANCE_EX_MAY_NOT_HAVE_SEP_VALUE);
}
- @Specialization(guards = {"isTypeNode.execute(inliningTarget, type)", "!isPNone(value)", "!tupleCheck.execute(inliningTarget, value)"}, limit = "1")
+ @Specialization(guards = {"isTypeNode.execute(inliningTarget, type)", "!isPNone(value)", "!isTuple(value)"}, limit = "1")
static Object doExceptionOrCreate(VirtualFrame frame, Object type, Object value,
@Bind Node inliningTarget,
@SuppressWarnings("unused") @Exclusive @Cached IsTypeNode isTypeNode,
@Exclusive @Cached PyExceptionInstanceCheckNode check,
- @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheck,
@Cached PyObjectIsInstanceNode isInstanceNode,
@Cached InlinedConditionProfile isInstanceProfile,
@Shared @Cached IsSubtypeNode isSubtypeNode,
@@ -138,12 +136,11 @@ static Object doCreate(VirtualFrame frame, Object type, @SuppressWarnings("unuse
}
}
- @Specialization(guards = {"isTypeNode.execute(inliningTarget, type)", "tupleCheck.execute(inliningTarget, value)"}, limit = "1")
+ @Specialization(guards = {"isTypeNode.execute(inliningTarget, type)", "isTuple(value)"}, limit = "1")
static Object doCreateTuple(VirtualFrame frame, Object type, Object value,
@Bind Node inliningTarget,
@SuppressWarnings("unused") @Exclusive @Cached IsTypeNode isTypeNode,
@Exclusive @Cached PyExceptionInstanceCheckNode check,
- @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheck,
@Exclusive @Cached GetTupleStorage getTupleStorage,
@Exclusive @Cached SequenceStorageNodes.ToArrayNode toArrayNode,
@Shared @Cached IsSubtypeNode isSubtypeNode,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java
index 44e6836809..04d146137e 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java
@@ -66,10 +66,12 @@
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.lib.PyObjectGetItem;
import com.oracle.graal.python.nodes.ErrorMessages;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.StringLiterals;
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.EnsureManagedTupleNode;
import com.oracle.graal.python.nodes.call.CallDispatchers;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
@@ -82,9 +84,11 @@
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.Cached.Exclusive;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
+import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
@@ -257,6 +261,7 @@ static Object getModule(PBuiltinFunction self, Object value,
@Builtin(name = J___TYPE_PARAMS__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
@GenerateNodeFactory
+ @ImportStatic(PGuards.class)
abstract static class GetTypeParamsNode extends PythonBuiltinNode {
@Specialization(guards = {"!isBuiltinFunction(self)", "isNoValue(none)"})
static Object getTypeParams(PFunction self, @SuppressWarnings("unused") PNone none,
@@ -269,14 +274,16 @@ static Object getTypeParams(PFunction self, @SuppressWarnings("unused") PNone no
return typeParams;
}
- @Specialization(guards = {"!isBuiltinFunction(self)"})
- static Object setTypeParams(PFunction self, PTuple value,
+ @Specialization(guards = {"!isBuiltinFunction(self)", "isTuple(value)"})
+ static Object setTypeParams(PFunction self, Object value,
+ @Bind Node inliningTarget,
+ @Cached EnsureManagedTupleNode ensureManagedTupleNode,
@Cached WriteAttributeToObjectNode writeObject) {
- writeObject.execute(self, T___TYPE_PARAMS__, value);
+ writeObject.execute(self, T___TYPE_PARAMS__, ensureManagedTupleNode.execute(inliningTarget, value));
return PNone.NONE;
}
- @Specialization(guards = {"!isBuiltinFunction(self)", "!isNoValue(value)", "!isPTuple(value)"})
+ @Specialization(guards = {"!isBuiltinFunction(self)", "!isNoValue(value)", "!isTuple(value)"})
@SuppressWarnings("unused")
static Object setNotTuple(PFunction self, Object value,
@Bind Node inliningTarget) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java
index 6b5af3e289..4645239a0e 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java
@@ -67,6 +67,7 @@
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageLen;
import com.oracle.graal.python.builtins.objects.common.KeywordsStorage;
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode;
+import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ToArrayNode;
import com.oracle.graal.python.builtins.objects.dict.PDict;
import com.oracle.graal.python.builtins.objects.getsetdescriptor.DescriptorDeleteMarker;
import com.oracle.graal.python.builtins.objects.method.PMethod;
@@ -77,10 +78,13 @@
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode;
import com.oracle.graal.python.nodes.ErrorMessages;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetFunctionCodeNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.EnsureManagedTupleNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -94,6 +98,7 @@
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.GenerateUncached;
+import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
@@ -111,6 +116,7 @@ protected List extends NodeFactory extends PythonBuiltinBaseNode>> getNodeFa
@Slot(value = SlotKind.tp_new, isComplex = true)
@SlotSignature(name = "function", minNumOfPositionalArgs = 3, parameterNames = {"$cls", "code", "globals", "name", "argdefs", "closure"})
@GenerateNodeFactory
+ @ImportStatic(PGuards.class)
public abstract static class FunctionNode extends PythonBuiltinNode {
@Specialization
@@ -174,6 +180,57 @@ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PD
PCell.toCellArray(getObjectArrayNode.execute(inliningTarget, closure)));
}
+ @Specialization(guards = "isTuple(closure)")
+ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, @SuppressWarnings("unused") PNone defaultArgs,
+ Object closure,
+ @Bind Node inliningTarget,
+ @Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
+ @Shared("toArray") @Cached ToArrayNode toArray,
+ @Bind PythonLanguage language) {
+ return PFactory.createFunction(language, T_LAMBDA_NAME, code, globals, PCell.toCellArray(toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, closure))));
+ }
+
+ @Specialization(guards = "isTuple(closure)")
+ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, @SuppressWarnings("unused") PNone defaultArgs, Object closure,
+ @Bind Node inliningTarget,
+ @Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
+ @Shared("toArray") @Cached ToArrayNode toArray,
+ @Bind PythonLanguage language) {
+ return PFactory.createFunction(language, name, code, globals, PCell.toCellArray(toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, closure))));
+ }
+
+ @Specialization(guards = "isTuple(defaultArgs)")
+ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, Object defaultArgs,
+ @SuppressWarnings("unused") PNone closure,
+ @Bind Node inliningTarget,
+ @Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
+ @Shared("toArray") @Cached ToArrayNode toArray,
+ @Bind PythonLanguage language) {
+ // TODO split defaults of positional args from kwDefaults
+ return PFactory.createFunction(language, code.getName(), code, globals, toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, defaultArgs)), null, null);
+ }
+
+ @Specialization(guards = "isTuple(defaultArgs)")
+ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, Object defaultArgs, @SuppressWarnings("unused") PNone closure,
+ @Bind Node inliningTarget,
+ @Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
+ @Shared("toArray") @Cached ToArrayNode toArray,
+ @Bind PythonLanguage language) {
+ // TODO split defaults of positional args from kwDefaults
+ return PFactory.createFunction(language, name, code, globals, toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, defaultArgs)), null, null);
+ }
+
+ @Specialization(guards = {"isTuple(defaultArgs)", "isTuple(closure)"})
+ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, Object defaultArgs, Object closure,
+ @Bind Node inliningTarget,
+ @Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
+ @Shared("toArray") @Cached ToArrayNode toArray,
+ @Bind PythonLanguage language) {
+ // TODO split defaults of positional args from kwDefaults
+ return PFactory.createFunction(language, name, code, globals, toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, defaultArgs)), null,
+ PCell.toCellArray(toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, closure))));
+ }
+
@Fallback
@SuppressWarnings("unused")
static PFunction function(@SuppressWarnings("unused") Object cls, Object code, Object globals, Object name, Object defaultArgs, Object closure,
@@ -254,6 +311,7 @@ static Object setQualname(PFunction self, Object value,
@Builtin(name = J___DEFAULTS__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true, allowsDelete = true)
@GenerateNodeFactory
+ @ImportStatic(PGuards.class)
public abstract static class GetDefaultsNode extends PythonBinaryBuiltinNode {
@Specialization(guards = "isNoValue(defaults)")
static Object defaults(PFunction self, @SuppressWarnings("unused") PNone defaults,
@@ -263,11 +321,12 @@ static Object defaults(PFunction self, @SuppressWarnings("unused") PNone default
return (argDefaults.length == 0) ? PNone.NONE : PFactory.createTuple(language, argDefaults);
}
- @Specialization
- static Object setDefaults(PFunction self, PTuple defaults,
+ @Specialization(guards = "isTuple(defaults)")
+ static Object setDefaults(PFunction self, Object defaults,
@Bind Node inliningTarget,
- @Cached GetObjectArrayNode getObjectArrayNode) {
- self.setDefaults(getObjectArrayNode.execute(inliningTarget, defaults));
+ @Cached GetTupleStorage getTupleStorage,
+ @Cached ToArrayNode toArray) {
+ self.setDefaults(toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, defaults)));
return PNone.NONE;
}
@@ -412,6 +471,7 @@ Object delete(PFunction self, @SuppressWarnings("unused") DescriptorDeleteMarker
@Builtin(name = J___TYPE_PARAMS__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
@GenerateNodeFactory
+ @ImportStatic(PGuards.class)
public abstract static class GetTypeParamsNode extends PythonBinaryBuiltinNode {
@Specialization(guards = "isNoValue(value)")
static Object get(PFunction self, @SuppressWarnings("unused") PNone value,
@@ -424,10 +484,12 @@ static Object get(PFunction self, @SuppressWarnings("unused") PNone value,
return typeParams;
}
- @Specialization
- static Object set(PFunction self, PTuple typeParams,
+ @Specialization(guards = "isTuple(typeParams)")
+ static Object set(PFunction self, Object typeParams,
+ @Bind Node inliningTarget,
+ @Cached EnsureManagedTupleNode ensureManagedTupleNode,
@Cached WriteAttributeToObjectNode writeObject) {
- writeObject.execute(self, T___TYPE_PARAMS__, typeParams);
+ writeObject.execute(self, T___TYPE_PARAMS__, ensureManagedTupleNode.execute(inliningTarget, typeParams));
return PNone.NONE;
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ChainBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ChainBuiltins.java
index c8beab0279..cec3c67921 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ChainBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/ChainBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -69,6 +69,7 @@
import com.oracle.graal.python.lib.PyIterCheckNode;
import com.oracle.graal.python.lib.PyIterNextNode;
import com.oracle.graal.python.lib.PyObjectGetIter;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -221,7 +222,7 @@ public abstract static class SetStateNode extends DeprecatedSetStateBuiltin {
@Specialization
static Object setState(PChain self, Object state,
@Bind Node node) {
- if (!(state instanceof PTuple)) {
+ if (!PyTupleCheckNode.executeUncached(state)) {
throw PRaiseNode.raiseStatic(node, TypeError, IS_NOT_A, "state", "a length 1 or 2 tuple");
}
int len = PyTupleSizeNode.executeUncached(state);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsBuiltins.java
index 236a291b5d..eb3f88248f 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -61,13 +61,15 @@
import com.oracle.graal.python.builtins.modules.ItertoolsModuleBuiltins.DeprecatedReduceBuiltin;
import com.oracle.graal.python.builtins.modules.ItertoolsModuleBuiltins.DeprecatedSetStateBuiltin;
import com.oracle.graal.python.builtins.objects.PNone;
-import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.iterator.IteratorNodes;
import com.oracle.graal.python.builtins.objects.itertools.CombinationsBuiltinsClinicProviders.CombinationsNodeClinicProviderGen;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
+import com.oracle.graal.python.lib.PyTupleGetItem;
+import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -78,7 +80,6 @@
import com.oracle.graal.python.nodes.util.CannotCastException;
import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
import com.oracle.graal.python.runtime.object.PFactory;
-import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
import com.oracle.graal.python.util.PythonUtils;
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.dsl.Bind;
@@ -275,11 +276,10 @@ public abstract static class SetStateNode extends DeprecatedSetStateBuiltin {
static Object setState(PAbstractCombinations self, Object stateObj,
@Bind Node inliningTarget) {
int n = self.getPool().length;
- if (stateObj instanceof PTuple state && state.getSequenceStorage().length() == self.getR()) {
- SequenceStorage storage = state.getSequenceStorage();
+ if (PyTupleCheckNode.executeUncached(stateObj) && PyTupleSizeNode.executeUncached(stateObj) == self.getR()) {
try {
for (int i = 0; i < self.getR(); i++) {
- int index = CastToJavaIntExactNode.executeUncached(SequenceStorageNodes.GetItemScalarNode.executeUncached(storage, i));
+ int index = CastToJavaIntExactNode.executeUncached(PyTupleGetItem.executeUncached(stateObj, i));
int max = i + n - self.getR();
if (index > max) {
index = max;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CycleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CycleBuiltins.java
index 3abd88468f..43514594da 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CycleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CycleBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -74,6 +74,7 @@
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectGetIter;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -243,7 +244,7 @@ public abstract static class SetStateNode extends DeprecatedSetStateBuiltin {
@Specialization
static Object setState(PCycle self, Object state,
@Bind Node inliningTarget) {
- if (!((state instanceof PTuple) && (PyTupleSizeNode.executeUncached(state) == 2))) {
+ if (!(PyTupleCheckNode.executeUncached(state) && PyTupleSizeNode.executeUncached(state) == 2)) {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, IS_NOT_A, "state", "2-tuple");
}
Object obj = PyTupleGetItem.executeUncached(state, 0);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GroupByBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GroupByBuiltins.java
index 17c121e634..1c84cd9fb4 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GroupByBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GroupByBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -67,6 +67,7 @@
import com.oracle.graal.python.lib.PyIterNextNode;
import com.oracle.graal.python.lib.PyObjectGetIter;
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -205,7 +206,7 @@ public abstract static class SetStateNode extends DeprecatedSetStateBuiltin {
@Specialization
static Object setState(PGroupBy self, Object state,
@Bind Node inliningTarget) {
- if (!(state instanceof PTuple) || PyTupleSizeNode.executeUncached(state) != 3) {
+ if (!PyTupleCheckNode.executeUncached(state) || PyTupleSizeNode.executeUncached(state) != 3) {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, IS_NOT_A, "state", "3-tuple");
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeBuiltins.java
index 639669155b..9be5b37b26 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -69,6 +69,7 @@
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin;
import com.oracle.graal.python.lib.PyIterNextNode;
import com.oracle.graal.python.lib.PyObjectGetIter;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -189,7 +190,7 @@ public abstract static class SetStateNode extends DeprecatedSetStateBuiltin {
static Object setState(PTee self, Object state,
@Bind Node inliningTarget) {
- if (!(state instanceof PTuple) || PyTupleSizeNode.executeUncached(state) != 2) {
+ if (!PyTupleCheckNode.executeUncached(state) || PyTupleSizeNode.executeUncached(state) != 2) {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, IS_NOT_A, "state", "2-tuple");
}
Object dataObject = PyTupleGetItem.executeUncached(state, 0);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
index 803851cab2..c5ef1c99fa 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
+ * Copyright (c) 2017, 2026, Oracle and/or its affiliates.
* Copyright (c) 2013, Regents of the University of California
*
* All rights reserved.
@@ -53,7 +53,6 @@
import com.oracle.graal.python.builtins.objects.PNone;
import com.oracle.graal.python.builtins.objects.list.PList;
import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
-import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode;
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryOp.BinaryOpBuiltinNode;
@@ -61,6 +60,7 @@
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare;
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode;
import com.oracle.graal.python.lib.PyMappingCheckNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyNumberOrNode;
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
import com.oracle.graal.python.lib.PyObjectGetItem;
@@ -106,10 +106,11 @@ public abstract static class MappingproxyNode extends PythonBinaryBuiltinNode {
static Object doMapping(@SuppressWarnings("unused") Object cls, Object obj,
@Bind Node inliningTarget,
@Cached PyMappingCheckNode mappingCheckNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Bind PythonLanguage language,
@Cached PRaiseNode raiseNode) {
// descrobject.c mappingproxy_check_mapping()
- if (!(obj instanceof PList || obj instanceof PTuple) && mappingCheckNode.execute(inliningTarget, obj)) {
+ if (!(obj instanceof PList || tupleCheckNode.execute(inliningTarget, obj)) && mappingCheckNode.execute(inliningTarget, obj)) {
return PFactory.createMappingproxy(language, obj);
}
throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.S_ARG_MUST_BE_S_NOT_P, "mappingproxy()", "mapping", obj);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java
index 1bf17b91fb..27759d7e59 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java
@@ -61,6 +61,7 @@
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.call.CallNode;
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
import com.oracle.graal.python.nodes.util.CastToByteNode;
@@ -391,15 +392,15 @@ MemoryPointer resolveTupleCached(VirtualFrame frame, PMemoryView self, PTuple in
return ptr;
}
- @Specialization(replaces = "resolveTupleCached")
- MemoryPointer resolveTupleGeneric(VirtualFrame frame, PMemoryView self, PTuple indices,
+ @Specialization(guards = "isTuple(indices)", replaces = "resolveTupleCached")
+ MemoryPointer resolveTupleGeneric(VirtualFrame frame, PMemoryView self, Object indices,
@Bind Node inliningTarget,
@Shared @Cached InlinedConditionProfile hasSuboffsetsProfile,
@Shared @Cached PyIndexCheckNode indexCheckNode,
- @Shared @Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode,
+ @Shared @Cached GetTupleStorage getTupleStorage,
@Shared @Cached SequenceStorageNodes.GetItemScalarNode getItemNode,
@Shared @Cached PRaiseNode raiseNode) {
- SequenceStorage indicesStorage = getSequenceStorageNode.execute(inliningTarget, indices);
+ SequenceStorage indicesStorage = getTupleStorage.execute(inliningTarget, indices);
int ndim = self.getDimensions();
checkTupleLength(inliningTarget, indicesStorage, ndim, raiseNode);
MemoryPointer ptr = new MemoryPointer(self.getBufferPointer(), self.getOffset());
@@ -411,7 +412,7 @@ MemoryPointer resolveTupleGeneric(VirtualFrame frame, PMemoryView self, PTuple i
return ptr;
}
- @Specialization(guards = "!isPTuple(indexObj)")
+ @Specialization(guards = "!isTuple(indexObj)")
MemoryPointer resolveIntObj(VirtualFrame frame, PMemoryView self, Object indexObj,
@Bind Node inliningTarget,
@Shared @Cached InlinedConditionProfile hasOneDimensionProfile,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java
index 33b12a6040..c083105be4 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java
@@ -60,14 +60,16 @@
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
import com.oracle.graal.python.builtins.PythonBuiltins;
import com.oracle.graal.python.builtins.objects.PNone;
-import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode;
+import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetInternalObjectArrayNode;
import com.oracle.graal.python.builtins.objects.ints.PInt;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
import com.oracle.graal.python.lib.PyObjectHashNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PRaiseNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
import com.oracle.graal.python.nodes.call.special.SpecialMethodNotFound;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -78,6 +80,7 @@
import com.oracle.graal.python.nodes.util.CastToJavaUnsignedLongNode;
import com.oracle.graal.python.runtime.exception.PythonErrorType;
import com.oracle.graal.python.runtime.object.PFactory;
+import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
@@ -190,15 +193,21 @@ static PNone seedGeneric(VirtualFrame frame, PRandom random, Object inputSeed,
public abstract static class SetStateNode extends PythonBuiltinNode {
@Specialization
- static PNone setstate(PRandom random, PTuple tuple,
+ static PNone setstate(PRandom random, Object tuple,
@Bind Node inliningTarget,
- @Cached GetObjectArrayNode getObjectArrayNode,
+ @Cached PyTupleCheckNode tupleCheck,
+ @Cached GetTupleStorage getTupleStorage,
+ @Cached GetInternalObjectArrayNode getArray,
@Cached CastToJavaUnsignedLongNode castNode,
@Cached PRaiseNode raiseNode) {
- Object[] arr = getObjectArrayNode.execute(inliningTarget, tuple);
- if (arr.length != PRandom.N + 1) {
+ if (!tupleCheck.execute(inliningTarget, tuple)) {
+ throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.STATE_VECTOR_MUST_BE_A_TUPLE);
+ }
+ SequenceStorage storage = getTupleStorage.execute(inliningTarget, tuple);
+ if (storage.length() != PRandom.N + 1) {
throw raiseNode.raise(inliningTarget, PythonErrorType.ValueError, ErrorMessages.STATE_VECTOR_INVALID);
}
+ Object[] arr = getArray.execute(inliningTarget, storage);
int[] state = new int[PRandom.N];
for (int i = 0; i < PRandom.N; ++i) {
long l = castNode.execute(inliningTarget, arr[i]);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java
index 19a35cad51..1142cb0817 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java
@@ -55,8 +55,10 @@
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PRaiseNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
@@ -106,11 +108,16 @@ boolean isOwned(PRLock self) {
@GenerateNodeFactory
abstract static class AcquireRestoreRLockNode extends PythonBinaryBuiltinNode {
@Specialization
- Object acquireRestore(PRLock self, PTuple state,
+ Object acquireRestore(PRLock self, Object state,
@Bind Node inliningTarget,
+ @Cached PyTupleCheckNode tupleCheck,
+ @Cached GetTupleStorage getTupleStorage,
@Cached GilNode gil,
@Cached CastToJavaUnsignedLongNode castLong,
@Cached SequenceStorageNodes.GetItemDynamicNode getItemNode) {
+ if (!tupleCheck.execute(inliningTarget, state)) {
+ throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.STATE_ARGUMENT_MUST_BE_A_TUPLE);
+ }
if (!self.acquireNonBlocking()) {
gil.release(true);
try {
@@ -120,7 +127,7 @@ Object acquireRestore(PRLock self, PTuple state,
}
}
// ignore owner, we use the Java lock and cannot set it
- long count = castLong.execute(inliningTarget, getItemNode.execute(inliningTarget, state.getSequenceStorage(), 0));
+ long count = castLong.execute(inliningTarget, getItemNode.execute(inliningTarget, getTupleStorage.execute(inliningTarget, state), 0));
long actualCount = self.getCount();
while (count > actualCount) {
self.acquireBlocking(this); // we already own it at this point
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java
index a7ffa2ac9f..270fc5e50f 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java
@@ -344,7 +344,7 @@ public final Object execute(VirtualFrame frame, Object self, Object[] arguments,
@Specialization(guards = "isString(wName)")
@SuppressWarnings("truffle-static-method")
- Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict namespaceOrig, PKeyword[] kwds,
+ Object typeNew(VirtualFrame frame, Object cls, Object wName, Object bases, PDict namespaceOrig, PKeyword[] kwds,
@Bind Node inliningTarget,
@Cached GetClassNode getClassNode,
@Cached GetCachedTpSlotsNode getSlots,
@@ -353,26 +353,37 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, PTuple bases, PDict
@Cached PyObjectLookupAttr lookupMroEntriesNode,
@Cached CastToTruffleStringNode castStr,
@Cached TypeNodes.CreateTypeNode createType,
- @Cached GetObjectArrayNode getObjectArrayNode) {
+ @Cached GetObjectArrayNode getObjectArrayNode,
+ @Exclusive @Cached PyTupleCheckNode tupleCheck,
+ @Exclusive @Cached ConstructTupleNode constructTupleNode) {
+ PTuple basesTuple;
+ if (bases instanceof PTuple) {
+ basesTuple = (PTuple) bases;
+ } else if (tupleCheck.execute(inliningTarget, bases)) {
+ basesTuple = constructTupleNode.execute(frame, bases);
+ } else {
+ throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "type.__new__()", 2, "tuple", bases);
+ }
+
// Determine the proper metatype to deal with this
TruffleString name = castStr.execute(inliningTarget, wName);
Object metaclass = cls;
- Object winner = calculateMetaclass(frame, inliningTarget, metaclass, bases, getClassNode, isTypeNode, lookupMroEntriesNode, getObjectArrayNode);
+ Object winner = calculateMetaclass(frame, inliningTarget, metaclass, basesTuple, getClassNode, isTypeNode, lookupMroEntriesNode, getObjectArrayNode);
if (winner != metaclass) {
TpSlot winnerNew = getSlots.execute(inliningTarget, winner).tp_new();
if (winnerNew != SLOTS.tp_new()) {
// Pass it to the winner
- return callNew.execute(frame, inliningTarget, winnerNew, winner, new Object[]{name, bases, namespaceOrig}, kwds);
+ return callNew.execute(frame, inliningTarget, winnerNew, winner, new Object[]{name, basesTuple, namespaceOrig}, kwds);
}
metaclass = winner;
}
- return createType.execute(frame, namespaceOrig, name, bases, metaclass, kwds);
+ return createType.execute(frame, namespaceOrig, name, basesTuple, metaclass, kwds);
}
@Fallback
Object generic(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") Object name, Object bases, Object namespace, @SuppressWarnings("unused") PKeyword[] kwds) {
- if (!(bases instanceof PTuple)) {
+ if (!PyTupleCheckNode.executeUncached(bases)) {
throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "type.__new__()", 2, "tuple", bases);
} else if (!(namespace instanceof PDict)) {
throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "type.__new__()", 3, "dict", bases);
@@ -421,8 +432,8 @@ static Object typeGeneric(VirtualFrame frame, Object cls, Object name, Object ba
@Bind Node inliningTarget,
@Cached TypeNode nextTypeNode,
@Cached PRaiseNode raiseNode,
- @Cached PyTupleCheckNode tupleCheck,
- @Cached ConstructTupleNode constructTupleNode,
+ @Exclusive @Cached PyTupleCheckNode tupleCheck,
+ @Exclusive @Cached ConstructTupleNode constructTupleNode,
@Exclusive @Cached IsTypeNode isTypeNode) {
Object basesTuple;
if (!(name instanceof TruffleString || name instanceof PString)) {
@@ -686,10 +697,9 @@ static Object getBases(Object self, @SuppressWarnings("unused") PNone value,
return PFactory.createTuple(language, getBaseClassesNode.execute(inliningTarget, self));
}
- @Specialization(guards = "tupleCheck.execute(inliningTarget, value)", limit = "1")
+ @Specialization(guards = "isTuple(value)")
static Object setBases(VirtualFrame frame, PythonClass cls, Object value,
@Bind Node inliningTarget,
- @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheck,
@Cached ConstructTupleNode constructTupleNode,
@Cached GetObjectArrayNode getArray,
@Cached GetBaseClassNode getBase,
@@ -759,10 +769,9 @@ private static boolean typeIsSubtypeBaseChain(Node inliningTarget, Object a, Obj
return (isSameTypeNode.execute(inliningTarget, b, PythonBuiltinClassType.PythonObject));
}
- @Specialization(guards = "!tupleCheck.execute(inliningTarget, value)", limit = "1")
+ @Specialization(guards = "!isTuple(value)")
static Object setObject(@SuppressWarnings("unused") PythonClass cls, @SuppressWarnings("unused") Object value,
- @Bind Node inliningTarget,
- @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheck) {
+ @Bind Node inliningTarget) {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CAN_ONLY_ASSIGN_S_TO_S_S_NOT_P, "tuple", GetNameNode.executeUncached(cls), "__bases__", value);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java
index 960f28b93f..7aaae79156 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java
@@ -183,6 +183,7 @@
import com.oracle.graal.python.lib.PyEvalGetGlobals;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
import com.oracle.graal.python.lib.PyObjectSizeNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.HiddenAttr;
@@ -2156,6 +2157,8 @@ static PythonClass typeMetaclass(VirtualFrame frame, TruffleString name, PTuple
@Cached GetInstanceShape getInstanceShape,
@Cached CastToListNode castToListNode,
@Cached PyUnicodeCheckNode stringCheck,
+ @Cached PyTupleCheckNode tupleCheck,
+ @Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached TruffleString.IsValidNode isValidNode,
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
@Cached TruffleString.IndexOfCodePointNode indexOfCodePointNode,
@@ -2234,8 +2237,8 @@ static PythonClass typeMetaclass(VirtualFrame frame, TruffleString name, PTuple
Object slotsObject = ctx.slotsObject;
if (stringCheck.execute(inliningTarget, ctx.slotsObject)) {
slotsStorage = new ObjectSequenceStorage(new Object[]{castToStringNode.execute(inliningTarget, ctx.slotsObject)});
- } else if (ctx.slotsObject instanceof PTuple slotsTuple) {
- slotsStorage = slotsTuple.getSequenceStorage();
+ } else if (tupleCheck.execute(inliningTarget, ctx.slotsObject)) {
+ slotsStorage = getTupleStorage.execute(inliningTarget, ctx.slotsObject);
} else if (ctx.slotsObject instanceof PList slotsList) {
slotsStorage = slotsList.getSequenceStorage();
} else {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasBuiltins.java
index 792357d470..2256034c6a 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -100,11 +100,13 @@
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
import com.oracle.graal.python.lib.PyObjectSetAttr;
import com.oracle.graal.python.lib.PySequenceContainsNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.RichCmpOp;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.StringLiterals;
import com.oracle.graal.python.nodes.builtins.ListNodes;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.ConstructTupleNode;
import com.oracle.graal.python.nodes.call.CallNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -164,10 +166,21 @@ protected List extends NodeFactory extends PythonBuiltinBaseNode>> getNodeFa
@GenerateNodeFactory
public abstract static class GenericAliasNode extends PythonTernaryBuiltinNode {
@Specialization
- static PGenericAlias doit(Object cls, Object origin, Object arguments,
+ static PGenericAlias doit(VirtualFrame frame, Object cls, Object origin, Object arguments,
+ @Bind Node inliningTarget,
@Bind PythonLanguage language,
- @Cached TypeNodes.GetInstanceShape getInstanceShape) {
- return PFactory.createGenericAlias(language, cls, getInstanceShape.execute(cls), origin, arguments, false);
+ @Cached TypeNodes.GetInstanceShape getInstanceShape,
+ @Cached PyTupleCheckNode tupleCheck,
+ @Cached ConstructTupleNode constructTupleNode) {
+ PTuple argumentsTuple;
+ if (arguments instanceof PTuple) {
+ argumentsTuple = (PTuple) arguments;
+ } else if (tupleCheck.execute(inliningTarget, arguments)) {
+ argumentsTuple = constructTupleNode.execute(frame, arguments);
+ } else {
+ argumentsTuple = PFactory.createTuple(language, new Object[]{arguments});
+ }
+ return PFactory.createGenericAlias(language, cls, getInstanceShape.execute(cls), origin, argumentsTuple, false);
}
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericTypeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericTypeNodes.java
index b1fb359a91..89d7061d7a 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericTypeNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericTypeNodes.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -59,7 +59,6 @@
import com.oracle.graal.python.builtins.objects.PNone;
import com.oracle.graal.python.builtins.objects.PNotImplemented;
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
-import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetInternalObjectArrayNode;
import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
@@ -71,6 +70,9 @@
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode;
import com.oracle.graal.python.lib.PyObjectTypeCheck;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
+import com.oracle.graal.python.lib.PyTupleGetItem;
+import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
import com.oracle.graal.python.nodes.BuiltinNames;
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -166,10 +168,10 @@ static Object[] makeParametersUncached(PTuple args) {
listAdd(parameters, t);
} else {
Object subparams = lookup.execute(null, null, t, T___PARAMETERS__);
- if (subparams instanceof PTuple subparamsTuple) {
- SequenceStorage subparamsStorage = subparamsTuple.getSequenceStorage();
- for (int j = 0; j < subparamsStorage.length(); j++) {
- listAdd(parameters, getItemUncached(subparamsStorage, j));
+ if (PyTupleCheckNode.executeUncached(subparams)) {
+ int subparamsLen = PyTupleSizeNode.executeUncached(subparams);
+ for (int j = 0; j < subparamsLen; j++) {
+ listAdd(parameters, PyTupleGetItem.executeUncached(subparams, j));
}
}
}
@@ -209,10 +211,10 @@ private static int tupleIndex(PTuple tuple, Object obj) {
// Equivalent of tuple_extend, but we use list
@TruffleBoundary
- private static void listExtend(List
*/
- private Object[] replicatedNativeReferences;
+ private Object nativeReferenceState;
NativeSequenceStorage(long ptr, int length, int capacity) {
super(length, capacity);
@@ -95,6 +133,7 @@ public void setCapacity(int capacity) {
public final void setReference(NativeStorageReference reference) {
assert this.reference == null : "attempting to set another NativeStorageReference";
+ clearBorrowedMemoryOwner();
this.reference = reference;
}
@@ -121,14 +160,94 @@ public String toString() {
}
/**
- * For a description, see {@link #replicatedNativeReferences}.
+ * For a description, see {@link #nativeReferenceState}.
*/
public void setReplicatedNativeReferences(Object[] replicatedNativeReferences) {
- this.replicatedNativeReferences = replicatedNativeReferences;
+ if (hasBorrowedMemoryOwner()) {
+ Object owner = getBorrowedMemoryOwner();
+ if (replicatedNativeReferences == null) {
+ nativeReferenceState = owner;
+ } else {
+ nativeReferenceState = createBorrowedOwnerState(owner, replicatedNativeReferences);
+ }
+ } else {
+ nativeReferenceState = replicatedNativeReferences;
+ }
}
public Object[] getReplicatedNativeReferences() {
- return replicatedNativeReferences;
+ if (nativeReferenceState instanceof Object[] refs) {
+ if (isBorrowedOwnerState(refs)) {
+ assert validateBorrowedOwnerState(refs);
+ return Arrays.copyOfRange(refs, 2, refs.length);
+ }
+ return refs;
+ }
+ return null;
+ }
+
+ public void setBorrowedMemoryOwner(Object owner) {
+ assert isValidBorrowedMemoryOwner(owner);
+ assert !hasReference();
+ assert !hasBorrowedMemoryOwner();
+ Object[] replicatedNativeReferences = getReplicatedNativeReferences();
+ if (replicatedNativeReferences == null) {
+ nativeReferenceState = owner;
+ } else {
+ nativeReferenceState = createBorrowedOwnerState(owner, replicatedNativeReferences);
+ }
+ }
+
+ private void clearBorrowedMemoryOwner() {
+ if (nativeReferenceState instanceof Object[] refs) {
+ if (isBorrowedOwnerState(refs)) {
+ assert validateBorrowedOwnerState(refs);
+ nativeReferenceState = Arrays.copyOfRange(refs, 2, refs.length);
+ }
+ } else {
+ nativeReferenceState = null;
+ }
+ }
+
+ private boolean hasBorrowedMemoryOwner() {
+ if (nativeReferenceState instanceof Object[] refs) {
+ return isBorrowedOwnerState(refs);
+ }
+ return nativeReferenceState != null;
+ }
+
+ private Object getBorrowedMemoryOwner() {
+ if (nativeReferenceState instanceof Object[] refs) {
+ assert isBorrowedOwnerState(refs);
+ assert validateBorrowedOwnerState(refs);
+ return refs[1];
+ }
+ assert isValidBorrowedMemoryOwner(nativeReferenceState);
+ return nativeReferenceState;
+ }
+
+ private static Object[] createBorrowedOwnerState(Object owner, Object[] replicatedNativeReferences) {
+ Object[] ownerState = new Object[replicatedNativeReferences.length + 2];
+ ownerState[0] = BORROWED_OWNER_MARKER;
+ ownerState[1] = owner;
+ System.arraycopy(replicatedNativeReferences, 0, ownerState, 2, replicatedNativeReferences.length);
+ assert validateBorrowedOwnerState(ownerState);
+ return ownerState;
+ }
+
+ private static boolean isBorrowedOwnerState(Object[] state) {
+ return state.length > 0 && state[0] == BORROWED_OWNER_MARKER;
+ }
+
+ private static boolean validateBorrowedOwnerState(Object[] state) {
+ assert isBorrowedOwnerState(state);
+ assert state.length >= 2;
+ assert isValidBorrowedMemoryOwner(state[1]);
+ return true;
+ }
+
+ private static boolean isValidBorrowedMemoryOwner(Object owner) {
+ return owner != null && !(owner instanceof Object[]);
}
}
From 6b5ab8ce1bb894d139b552dc7fbbccac01799ac3 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Wed, 17 Jun 2026 08:44:35 +0200
Subject: [PATCH 12/23] Add TruffleBoundary to setState methods
---
.../python/builtins/objects/itertools/CombinationsBuiltins.java | 2 ++
.../graal/python/builtins/objects/itertools/CycleBuiltins.java | 1 +
.../python/builtins/objects/itertools/GroupByBuiltins.java | 2 ++
.../graal/python/builtins/objects/itertools/TeeBuiltins.java | 2 ++
4 files changed, 7 insertions(+)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsBuiltins.java
index eb3f88248f..d42d9186d9 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CombinationsBuiltins.java
@@ -82,6 +82,7 @@
import com.oracle.graal.python.runtime.object.PFactory;
import com.oracle.graal.python.util.PythonUtils;
import com.oracle.truffle.api.CompilerAsserts;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Exclusive;
@@ -273,6 +274,7 @@ static Object reduce(PAbstractCombinations self) {
public abstract static class SetStateNode extends DeprecatedSetStateBuiltin {
@Specialization
+ @TruffleBoundary
static Object setState(PAbstractCombinations self, Object stateObj,
@Bind Node inliningTarget) {
int n = self.getPool().length;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CycleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CycleBuiltins.java
index 43514594da..37927f7db6 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CycleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/CycleBuiltins.java
@@ -242,6 +242,7 @@ protected boolean hasIterable(PCycle self) {
@GenerateNodeFactory
public abstract static class SetStateNode extends DeprecatedSetStateBuiltin {
@Specialization
+ @TruffleBoundary
static Object setState(PCycle self, Object state,
@Bind Node inliningTarget) {
if (!(PyTupleCheckNode.executeUncached(state) && PyTupleSizeNode.executeUncached(state) == 2)) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GroupByBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GroupByBuiltins.java
index 1c84cd9fb4..e7acde6d75 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GroupByBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/GroupByBuiltins.java
@@ -80,6 +80,7 @@
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
import com.oracle.graal.python.nodes.object.GetClassNode;
import com.oracle.graal.python.runtime.object.PFactory;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
@@ -204,6 +205,7 @@ private static boolean valuesSet(PGroupBy self) {
@GenerateNodeFactory
public abstract static class SetStateNode extends DeprecatedSetStateBuiltin {
@Specialization
+ @TruffleBoundary
static Object setState(PGroupBy self, Object state,
@Bind Node inliningTarget) {
if (!PyTupleCheckNode.executeUncached(state) || PyTupleSizeNode.executeUncached(state) != 3) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeBuiltins.java
index 9be5b37b26..1bbad4bb4f 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/itertools/TeeBuiltins.java
@@ -81,6 +81,7 @@
import com.oracle.graal.python.nodes.util.CannotCastException;
import com.oracle.graal.python.nodes.util.CastToJavaIntLossyNode;
import com.oracle.graal.python.runtime.object.PFactory;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
@@ -187,6 +188,7 @@ static Object reduce(PTee self) {
public abstract static class SetStateNode extends DeprecatedSetStateBuiltin {
@Specialization
+ @TruffleBoundary
static Object setState(PTee self, Object state,
@Bind Node inliningTarget) {
From 531287534771cc568fb650765e694295469e706d Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Wed, 17 Jun 2026 13:59:18 +0200
Subject: [PATCH 13/23] Introduce and use EnsureManagedTupleNode
---
.../cext/PythonCextGenericAliasBuiltins.java | 20 ++++++--------
.../objects/types/GenericAliasBuiltins.java | 17 +++++-------
.../python/nodes/builtins/TupleNodes.java | 27 +++++++++++++++++++
3 files changed, 41 insertions(+), 23 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java
index 7ea777288f..a3714a17b5 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java
@@ -51,6 +51,7 @@
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.lib.PyTupleCheckNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes;
import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.runtime.object.PFactory;
import com.oracle.graal.python.runtime.sequence.storage.NativeObjectSequenceStorage;
@@ -61,24 +62,19 @@
public final class PythonCextGenericAliasBuiltins {
+ private PythonCextGenericAliasBuiltins() {
+ }
+
@CApiBuiltin(ret = PyObjectTransfer, args = {PyObject, PyObject}, call = Direct)
abstract static class Py_GenericAlias extends CApiBinaryBuiltinNode {
@Specialization
static Object genericAlias(Object origin, Object args,
@Bind Node inliningTarget,
@Bind PythonLanguage language,
- @Cached PyTupleCheckNode tupleCheck,
- @Cached SequenceStorageNodes.CopyNode copyNode) {
- PTuple argsTuple;
- if (args instanceof PTuple) {
- argsTuple = (PTuple) args;
- } else if (tupleCheck.execute(inliningTarget, args)) {
- /* 'GetTupleStorageNode.doNative' will just "wrap" the 'ob_item' pointer. The memory is then still owned by the native tuple object. Therefore, we need to copy the storage to a managed
- * storage.
- */
- NativeObjectSequenceStorage nativeObjectSequenceStorage = GetTupleStorage.doNative((PythonAbstractNativeObject) args);
- argsTuple = PFactory.createTuple(language, copyNode.execute(inliningTarget, nativeObjectSequenceStorage));
- } else {
+ @Cached TupleNodes.EnsureManagedTupleNode ensureManagedTupleNode) {
+ PTuple argsTuple = ensureManagedTupleNode.execute(inliningTarget, args);
+ if (argsTuple == null) {
+ // in this case, 'args' is not a tuple object
argsTuple = PFactory.createTuple(language, new Object[]{args});
}
return PFactory.createGenericAlias(language, origin, argsTuple);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasBuiltins.java
index 2256034c6a..00eec6a44c 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/GenericAliasBuiltins.java
@@ -100,13 +100,12 @@
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
import com.oracle.graal.python.lib.PyObjectSetAttr;
import com.oracle.graal.python.lib.PySequenceContainsNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.RichCmpOp;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.StringLiterals;
import com.oracle.graal.python.nodes.builtins.ListNodes;
-import com.oracle.graal.python.nodes.builtins.TupleNodes.ConstructTupleNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes;
import com.oracle.graal.python.nodes.call.CallNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -166,18 +165,14 @@ protected List extends NodeFactory extends PythonBuiltinBaseNode>> getNodeFa
@GenerateNodeFactory
public abstract static class GenericAliasNode extends PythonTernaryBuiltinNode {
@Specialization
- static PGenericAlias doit(VirtualFrame frame, Object cls, Object origin, Object arguments,
+ static PGenericAlias doit(Object cls, Object origin, Object arguments,
@Bind Node inliningTarget,
@Bind PythonLanguage language,
@Cached TypeNodes.GetInstanceShape getInstanceShape,
- @Cached PyTupleCheckNode tupleCheck,
- @Cached ConstructTupleNode constructTupleNode) {
- PTuple argumentsTuple;
- if (arguments instanceof PTuple) {
- argumentsTuple = (PTuple) arguments;
- } else if (tupleCheck.execute(inliningTarget, arguments)) {
- argumentsTuple = constructTupleNode.execute(frame, arguments);
- } else {
+ @Cached TupleNodes.EnsureManagedTupleNode ensureManagedTupleNode) {
+ PTuple argumentsTuple = ensureManagedTupleNode.execute(inliningTarget, arguments);
+ if (argumentsTuple == null) {
+ // in this case, 'args' is not a tuple object
argumentsTuple = PFactory.createTuple(language, new Object[]{arguments});
}
return PFactory.createGenericAlias(language, cls, getInstanceShape.execute(cls), origin, argumentsTuple, false);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java
index 295b1be373..a1a3d8f6d1 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java
@@ -154,4 +154,31 @@ public static NativeObjectSequenceStorage doNative(PythonAbstractNativeObject tu
return NativeObjectSequenceStorage.create(array, size, size, tuple);
}
}
+
+ @GenerateUncached
+ @GenerateInline
+ @GenerateCached(false)
+ public abstract static class EnsureManagedTupleNode extends Node {
+
+ /**
+ * Ensures that the given tuple object is a managed tuple (i.e. {@link PTuple}). If the
+ * object is not a tuple at all, this node returns {@code null}.
+ */
+ public abstract PTuple execute(Node inliningTarget, Object object);
+
+ @Specialization
+ static PTuple doGeneric(Node inliningTarget, Object object,
+ @Cached SequenceStorageNodes.CopyNode copyNode) {
+ if (object instanceof PTuple managedTuple) {
+ return managedTuple;
+ }
+ if (object instanceof PythonAbstractNativeObject nativeTuple && PyTupleCheckNode.checkNative(nativeTuple)) {
+ // 'GetTupleStorageNode.doNative' will just "wrap" the 'ob_item' pointer. The memory is then still
+ // owned by the native tuple object. Therefore, we need to copy the storage to a managed storage.
+ NativeObjectSequenceStorage nativeObjectSequenceStorage = GetTupleStorage.doNative(nativeTuple);
+ return PFactory.createTuple(PythonLanguage.get(inliningTarget), copyNode.execute(inliningTarget, nativeObjectSequenceStorage));
+ }
+ return null;
+ }
+ }
}
From f74c2c95d68e0105c51782ef472e511331641787 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Thu, 18 Jun 2026 14:38:33 +0200
Subject: [PATCH 14/23] Replace redundant tuple check profiling
---
.../builtins/modules/BuiltinFunctions.java | 4 +---
.../builtins/modules/PosixModuleBuiltins.java | 7 ++-----
.../modules/PosixSubprocessModuleBuiltins.java | 4 +---
.../builtins/modules/SysModuleBuiltins.java | 4 +---
.../builtins/modules/WarningsModuleBuiltins.java | 4 ++--
.../modules/cext/PythonCextObjectBuiltins.java | 5 ++---
.../modules/cjkcodecs/MultibyteCodecUtil.java | 8 +++-----
.../modules/functools/PartialBuiltins.java | 4 ++--
.../builtins/modules/io/BytesIOBuiltins.java | 6 ++----
.../io/IncrementalNewlineDecoderBuiltins.java | 11 ++++-------
.../builtins/modules/io/StringIOBuiltins.java | 6 ++----
.../modules/io/TextIOWrapperBuiltins.java | 10 ++++------
.../builtins/modules/io/TextIOWrapperNodes.java | 5 ++---
.../modules/json/JSONEncoderBuiltins.java | 6 ++----
.../builtins/modules/pickle/PicklerBuiltins.java | 4 +---
.../builtins/objects/PythonAbstractObject.java | 13 +++----------
.../builtins/objects/code/CodeBuiltins.java | 16 +++++++---------
.../mappingproxy/MappingproxyBuiltins.java | 5 ++---
.../objects/memoryview/MemoryViewBuiltins.java | 5 ++---
.../builtins/objects/object/ObjectNodes.java | 9 +++------
.../builtins/objects/random/RandomBuiltins.java | 5 ++---
.../builtins/objects/socket/SocketNodes.java | 7 ++-----
.../builtins/objects/thread/RLockBuiltins.java | 7 +++----
.../builtins/objects/type/TypeBuiltins.java | 6 ++----
.../python/builtins/objects/type/TypeNodes.java | 4 +---
.../classes/AbstractObjectGetBasesNode.java | 5 ++---
26 files changed, 60 insertions(+), 110 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java
index caf1e85437..d1aae5a9b1 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java
@@ -205,7 +205,6 @@
import com.oracle.graal.python.lib.PyObjectSizeNode;
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
@@ -2140,7 +2139,6 @@ static Object[] update(Object[] bases,
@Bind PythonLanguage language,
@Cached PyObjectLookupAttr getMroEntries,
@Cached CallUnaryMethodNode callMroEntries,
- @Cached PyTupleCheckNode tupleCheck,
@Cached PyTupleSizeNode tupleSize,
@Cached PyTupleGetItem tupleGetItem,
@Cached PRaiseNode raiseNode) {
@@ -2169,7 +2167,7 @@ static Object[] update(Object[] bases,
originalBases = PFactory.createTuple(language, bases);
}
Object newBase = callMroEntries.executeObject(null, meth, originalBases);
- if (!tupleCheck.execute(inliningTarget, newBase)) {
+ if (!PGuards.isTuple(newBase)) {
throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.MRO_ENTRIES_MUST_RETURN_TUPLE);
}
if (newBases == null) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java
index 940a92d7a0..bdf6854591 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java
@@ -94,7 +94,6 @@
import com.oracle.graal.python.lib.PyObjectGetAttr;
import com.oracle.graal.python.lib.PyObjectGetItem;
import com.oracle.graal.python.lib.PyObjectSizeNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
@@ -510,7 +509,6 @@ static Object execvArgs(VirtualFrame frame, PosixPath path, Object argv,
@Bind PythonContext context,
@CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached InlinedConditionProfile isPListProfile,
- @Cached PyTupleCheckNode tupleCheck,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached ToArrayNode toArrayNode,
@Cached ObjectToOpaquePathNode toOpaquePathNode,
@@ -522,7 +520,7 @@ static Object execvArgs(VirtualFrame frame, PosixPath path, Object argv,
SequenceStorage argvStorage;
if (isPListProfile.profile(inliningTarget, argv instanceof PList)) {
argvStorage = ((PList) argv).getSequenceStorage();
- } else if (tupleCheck.execute(inliningTarget, argv)) {
+ } else if (PGuards.isTuple(argv)) {
argvStorage = getTupleStorage.execute(inliningTarget, argv);
} else {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S, "execv()", 2, "tuple or list");
@@ -3265,13 +3263,12 @@ static void doLong(long value, long[] timespec, int offset) {
@Specialization(guards = {"!isInteger(value)"})
static void doGeneric(VirtualFrame frame, Node inliningTarget, Object value, long[] timespec, int offset,
@Cached PyNumberDivmodNode divmodNode,
- @Cached PyTupleCheckNode tupleCheckNode,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached(value = "createNotNormalized()", inline = false) GetItemNode getItemNode,
@Cached PyLongAsLongNode asLongNode,
@Cached PRaiseNode raiseNode) {
Object divmod = divmodNode.execute(frame, inliningTarget, value, BILLION);
- if (tupleCheckNode.execute(inliningTarget, divmod)) {
+ if (PGuards.isTuple(divmod)) {
SequenceStorage storage = getTupleStorage.execute(inliningTarget, divmod);
if (storage.length() == 2) {
timespec[offset] = asLongNode.execute(frame, inliningTarget, getItemNode.execute(storage, 0));
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java
index f291ed387d..85b9ddf4c7 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java
@@ -65,7 +65,6 @@
import com.oracle.graal.python.builtins.objects.list.PList;
import com.oracle.graal.python.lib.PyObjectGetItem;
import com.oracle.graal.python.lib.PyObjectSizeNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
import com.oracle.graal.python.nodes.PGuards;
@@ -253,7 +252,6 @@ static int forkExec(VirtualFrame frame, Object[] args, Object executableList, bo
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Bind Node inliningTarget,
@Cached("createNotNormalized()") GetItemNode tupleGetItem,
- @Cached PyTupleCheckNode tupleCheckNode,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached PyObjectGetItem getItem,
@Cached CastToJavaIntExactNode castToIntNode,
@@ -269,7 +267,7 @@ static int forkExec(VirtualFrame frame, Object[] args, Object executableList, bo
if (closeFds && errPipeWrite < 3) {
throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.S_MUST_BE_S, "errpipe_write", ">= 3");
}
- if (!tupleCheckNode.execute(inliningTarget, fdsToKeepObj)) {
+ if (!PGuards.isTuple(fdsToKeepObj)) {
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "fork_exec()", 4, "tuple", fdsToKeepObj);
}
Object[] processArgs = args;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java
index 7eddea3b60..d2adb637f9 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java
@@ -220,7 +220,6 @@
import com.oracle.graal.python.lib.PyObjectSetAttr;
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
import com.oracle.graal.python.lib.PyTraceBackPrint;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyUnicodeAsEncodedString;
import com.oracle.graal.python.lib.PyUnicodeFromEncodedObject;
@@ -2252,11 +2251,10 @@ static Object exitNoCode(PythonModule sys, PNone status,
@Specialization(guards = "!isPNone(status)")
static Object exit(VirtualFrame frame, @SuppressWarnings("unused") PythonModule sys, Object status,
@Bind Node inliningTarget,
- @Cached PyTupleCheckNode tupleCheckNode,
@Cached TupleBuiltins.LenNode tupleLenNode,
@Cached PyTupleGetItem getItemNode) {
Object code = status;
- if (tupleCheckNode.execute(inliningTarget, status)) {
+ if (PGuards.isTuple(status)) {
if (tupleLenNode.executeInt(frame, status) == 1) {
code = getItemNode.execute(inliningTarget, status, 0);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java
index 8635d1fe53..e6e7f1eec6 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java
@@ -103,6 +103,7 @@
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.SpecialAttributeNames;
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode;
@@ -1001,13 +1002,12 @@ Object doWarn(VirtualFrame frame, PythonModule mod, Object message, Object categ
@Cached("createFor($node)") BoundaryCallData boundaryCallData,
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
@Cached StringNodes.CastToTruffleStringChecked1Node castToStringChecked,
- @Cached PyTupleCheckNode tupleCheckNode,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached PRaiseNode raiseNode,
@Cached WarningsModuleNode moduleFunctionsNode) {
// warnings_warn_impl
TruffleString[] skipFilePrefixes = null;
- if (tupleCheckNode.execute(inliningTarget, skipFilePrefixesObj)) {
+ if (PGuards.isTuple(skipFilePrefixesObj)) {
SequenceStorage storage = getTupleStorage.execute(inliningTarget, skipFilePrefixesObj);
if (storage.length() > 0) {
skipFilePrefixes = new TruffleString[storage.length()];
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextObjectBuiltins.java
index 736485da88..1b14c47d69 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextObjectBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextObjectBuiltins.java
@@ -119,9 +119,9 @@
import com.oracle.graal.python.lib.PyObjectReprAsObjectNode;
import com.oracle.graal.python.lib.PyObjectSetItem;
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.BuiltinNames;
import com.oracle.graal.python.nodes.ErrorMessages;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.StringLiterals;
import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode;
@@ -304,7 +304,6 @@ static Object doGeneric(@SuppressWarnings("unused") long threadState, Object cal
@Cached ExpandKeywordStarargsNode castKwargsNode,
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
@Cached CallNode callNode,
- @Cached PyTupleCheckNode tupleCheck,
@Cached GetTupleStorage getTupleStorage,
@Cached CastToTruffleStringNode castToTruffleStringNode) {
try {
@@ -315,7 +314,7 @@ static Object doGeneric(@SuppressWarnings("unused") long threadState, Object cal
keywords = PKeyword.EMPTY_KEYWORDS;
} else if (kwargs instanceof PDict) {
keywords = castKwargsNode.execute(inliningTarget, kwargs);
- } else if (tupleCheck.execute(inliningTarget, kwargs)) {
+ } else if (PGuards.isTuple(kwargs)) {
// We have a tuple with kw names and an array with kw values
SequenceStorage storage = getTupleStorage.execute(inliningTarget, kwargs);
int kwcount = storage.length();
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java
index 448dfe01c8..992f0d3226 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java
@@ -80,8 +80,8 @@
import com.oracle.graal.python.lib.PyBytesCheckNode;
import com.oracle.graal.python.lib.PyLongAsIntNode;
import com.oracle.graal.python.lib.PyLongCheckNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes;
import com.oracle.graal.python.nodes.call.CallNode;
@@ -171,7 +171,6 @@ static int encerror(VirtualFrame frame, MultibyteCodec codec,
@Bind Node inliningTarget,
@Bind PythonLanguage language,
@Cached BaseExceptionAttrNode attrNode,
- @Cached PyTupleCheckNode tupleCheckNode,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetItemScalarNode getItemNode,
@Cached PyUnicodeCheckNode unicodeCheckNode,
@@ -252,7 +251,7 @@ static int encerror(VirtualFrame frame, MultibyteCodec codec,
Object retobj = callErrorCallbackNode.execute(frame, inliningTarget, errors, buf.excobj);
- boolean isError = !tupleCheckNode.execute(inliningTarget, retobj);
+ boolean isError = !PGuards.isTuple(retobj);
Object tobj = null;
Object newposobj = null;
boolean isUnicode = false;
@@ -326,7 +325,6 @@ static void decerror(VirtualFrame frame, MultibyteCodec codec,
@Bind Node inliningTarget,
@Bind PythonLanguage language,
@Cached BaseExceptionAttrNode attrNode,
- @Cached PyTupleCheckNode tupleCheckNode,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetItemScalarNode getItemNode,
@Cached PyUnicodeCheckNode unicodeCheckNode,
@@ -387,7 +385,7 @@ static void decerror(VirtualFrame frame, MultibyteCodec codec,
Object retobj = callErrorCallbackNode.execute(frame, inliningTarget, errors, buf.excobj);
- boolean isError = !tupleCheckNode.execute(inliningTarget, retobj);
+ boolean isError = !PGuards.isTuple(retobj);
Object retuni = null;
Object newposobj = null;
if (!isError) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java
index c5972269ae..17f9619253 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java
@@ -363,7 +363,7 @@ static Object setState(VirtualFrame frame, PPartial self, Object state,
@Cached HashingStorageCopy copyStorageNode,
@Bind PythonLanguage language,
@Cached PRaiseNode raiseNode) {
- if (!tupleCheckNode.execute(inliningTarget, state) || getTupleStorage.execute(inliningTarget, state).length() != 4) {
+ if (!PGuards.isTuple(state) || getTupleStorage.execute(inliningTarget, state).length() != 4) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, INVALID_PARTIAL_STATE);
}
@@ -373,7 +373,7 @@ static Object setState(VirtualFrame frame, PPartial self, Object state,
final Object dict = getItemNode.execute(inliningTarget, state, 3);
if (!callableCheckNode.execute(inliningTarget, function) ||
- !tupleCheckNode.execute(inliningTarget, fnArgs) ||
+ !PGuards.isTuple(fnArgs) ||
(fnKwargs != PNone.NONE && !PGuards.isDict(fnKwargs))) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, INVALID_PARTIAL_STATE);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java
index c928e0830a..0c77dd746a 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -106,7 +106,6 @@
import com.oracle.graal.python.lib.PyMemoryViewFromObject;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectGetIter;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
@@ -665,7 +664,6 @@ abstract static class SetStateNode extends PythonBinaryBuiltinNode {
@Specialization
static Object doit(VirtualFrame frame, PBytesIO self, Object state,
@Bind Node inliningTarget,
- @Cached PyTupleCheckNode tupleCheck,
@Cached GetTupleStorage getTupleStorage,
@Cached GetInternalObjectArrayNode getArray,
@Cached WriteNode writeNode,
@@ -674,7 +672,7 @@ static Object doit(VirtualFrame frame, PBytesIO self, Object state,
@Cached GetOrCreateDictNode getDict,
@Cached HashingStorageAddAllToOther addAllToOtherNode,
@Cached PRaiseNode raiseNode) {
- if (!tupleCheck.execute(inliningTarget, state)) {
+ if (!PGuards.isTuple(state)) {
return notTuple(self, state, inliningTarget);
}
self.checkExports(inliningTarget, raiseNode);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java
index cb0e3db778..8036aea8bf 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java
@@ -53,6 +53,7 @@
import static com.oracle.graal.python.builtins.modules.io.IONodes.T_SETSTATE;
import static com.oracle.graal.python.nodes.ErrorMessages.ILLEGAL_STATE_ARGUMENT;
import static com.oracle.graal.python.nodes.ErrorMessages.STATE_ARGUMENT_MUST_BE_A_TUPLE;
+import static com.oracle.graal.python.nodes.PGuards.isTuple;
import static com.oracle.graal.python.nodes.StringLiterals.T_CR;
import static com.oracle.graal.python.nodes.StringLiterals.T_CRLF;
import static com.oracle.graal.python.nodes.StringLiterals.T_NEWLINE;
@@ -79,7 +80,6 @@
import com.oracle.graal.python.lib.PyIndexCheckNode;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -324,10 +324,9 @@ static Object withDecoder(VirtualFrame frame, PNLDecoder self,
@Cached PyIndexCheckNode indexCheckNode,
@Cached PyNumberAsSizeNode asSizeNode,
@Cached PyObjectCallMethodObjArgs callMethod,
- @Cached PyTupleCheckNode tupleCheck,
@Cached PRaiseNode raiseNode) {
Object state = callMethod.execute(frame, inliningTarget, self.getDecoder(), T_GETSTATE);
- if (!tupleCheck.execute(inliningTarget, state)) {
+ if (!isTuple(state)) {
throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_STATE_ARGUMENT);
}
Object[] objects = getObjectArrayNode.execute(inliningTarget, state);
@@ -350,13 +349,12 @@ abstract static class SetStateNode extends PythonBinaryBuiltinNode {
@Specialization(guards = "!self.hasDecoder()")
static Object noDecoder(VirtualFrame frame, PNLDecoder self, Object state,
@Bind Node inliningTarget,
- @Exclusive @Cached PyTupleCheckNode tupleCheck,
@Exclusive @Cached GetTupleStorage getTupleStorage,
@Exclusive @Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@Exclusive @Cached PyIndexCheckNode indexCheckNode,
@Exclusive @Cached PyNumberAsSizeNode asSizeNode,
@Exclusive @Cached PRaiseNode raiseNode) {
- if (!tupleCheck.execute(inliningTarget, state)) {
+ if (!isTuple(state)) {
return err(self, state, inliningTarget);
}
SequenceStorage storage = getTupleStorage.execute(inliningTarget, state);
@@ -376,14 +374,13 @@ static Object noDecoder(VirtualFrame frame, PNLDecoder self, Object state,
static Object withDecoder(VirtualFrame frame, PNLDecoder self, Object state,
@Bind Node inliningTarget,
@Bind PythonLanguage language,
- @Exclusive @Cached PyTupleCheckNode tupleCheck,
@Exclusive @Cached GetTupleStorage getTupleStorage,
@Exclusive @Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@Exclusive @Cached PyIndexCheckNode indexCheckNode,
@Exclusive @Cached PyNumberAsSizeNode asSizeNode,
@Cached PyObjectCallMethodObjArgs callMethod,
@Exclusive @Cached PRaiseNode raiseNode) {
- if (!tupleCheck.execute(inliningTarget, state)) {
+ if (!isTuple(state)) {
return err(self, state, inliningTarget);
}
SequenceStorage storage = getTupleStorage.execute(inliningTarget, state);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java
index d1abc668d3..31f10d3718 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -108,7 +108,6 @@
import com.oracle.graal.python.lib.PyNumberIndexNode;
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
import com.oracle.graal.python.lib.PyObjectGetAttr;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
@@ -665,7 +664,6 @@ abstract static class SetStateNode extends PythonBinaryBuiltinNode {
@Specialization(guards = {"!self.isClosed()"})
static Object doit(VirtualFrame frame, PStringIO self, Object state,
@Bind Node inliningTarget,
- @Cached PyTupleCheckNode tupleCheck,
@Cached GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@Cached InitNode initNode,
@@ -677,7 +675,7 @@ static Object doit(VirtualFrame frame, PStringIO self, Object state,
@Cached TruffleStringBuilder.AppendStringNode appendStringNode,
@Cached HashingStorageAddAllToOther addAllToOtherNode,
@Cached PRaiseNode raiseNode) {
- if (!tupleCheck.execute(inliningTarget, state)) {
+ if (!PGuards.isTuple(state)) {
return notTuple(self, state, inliningTarget);
}
SequenceStorage storage = getTupleStorage.execute(inliningTarget, state);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java
index dfcfa63e07..40a05b9ecb 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java
@@ -117,6 +117,7 @@
import static com.oracle.graal.python.nodes.ErrorMessages.UNDERLYING_STREAM_IS_NOT_SEEKABLE;
import static com.oracle.graal.python.nodes.PGuards.isNoValue;
import static com.oracle.graal.python.nodes.PGuards.isPNone;
+import static com.oracle.graal.python.nodes.PGuards.isTuple;
import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING;
import static com.oracle.graal.python.nodes.StringLiterals.T_NEWLINE;
import static com.oracle.graal.python.runtime.exception.PythonErrorType.OSError;
@@ -157,7 +158,6 @@
import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
import com.oracle.graal.python.lib.PyObjectSizeNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.RichCmpOp;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -923,7 +923,6 @@ static Object tell(VirtualFrame frame, PTextIO self,
@Exclusive @Cached PyObjectCallMethodObjArgs callMethodDecode,
@Exclusive @Cached PyObjectCallMethodObjArgs callMethodGetState,
@Exclusive @Cached PyObjectCallMethodObjArgs callMethodSetState,
- @Cached PyTupleCheckNode tupleCheckNode,
@Cached PyNumberAsSizeNode asSizeNode,
@Exclusive @Cached PyLongAsLongNode asLongNode,
@Cached PyObjectSizeNode sizeNode,
@@ -946,7 +945,7 @@ static Object tell(VirtualFrame frame, PTextIO self,
PBytes in = PFactory.createBytes(language, snapshotNextInput, skipBytes);
int charsDecoded = decoderDecode(frame, inliningTarget, self, in, callMethodDecode, toString, codePointLengthNode);
if (charsDecoded <= decodedCharsUsed) {
- Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, tupleCheckNode, raiseNode);
+ Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, raiseNode);
int decFlags = asSizeNode.executeExact(frame, inliningTarget, state[1]);
int decBufferLen = sizeNode.execute(frame, inliningTarget, state[0]);
if (decBufferLen == 0) {
@@ -988,7 +987,7 @@ static Object tell(VirtualFrame frame, PTextIO self,
/* We got n chars for 1 byte */
charsDecoded += n;
cookie.bytesToFeed += 1;
- Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, tupleCheckNode, raiseNode);
+ Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, raiseNode);
int decFlags = asSizeNode.executeExact(frame, inliningTarget, state[1]);
int decBufferLen = sizeNode.execute(frame, inliningTarget, state[0]);
@@ -1039,10 +1038,9 @@ static Object[] decoderGetstate(VirtualFrame frame, Node inliningTarget, PTextIO
SequenceNodes.GetObjectArrayNode getArray,
PyObjectCallMethodObjArgs callMethodGetState,
PyObjectCallMethodObjArgs callMethodSetState,
- PyTupleCheckNode tupleCheckNode,
PRaiseNode raiseNode) {
Object state = callMethodGetState.execute(frame, inliningTarget, self.getDecoder(), T_GETSTATE);
- if (!tupleCheckNode.execute(inliningTarget, state)) {
+ if (!isTuple(state)) {
fail(frame, inliningTarget, self, saved_state, callMethodSetState);
throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_DECODER_STATE);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java
index 8f69c57072..a5bfe7db94 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java
@@ -66,6 +66,7 @@
import static com.oracle.graal.python.nodes.ErrorMessages.NOT_READABLE;
import static com.oracle.graal.python.nodes.ErrorMessages.S_SHOULD_HAVE_RETURNED_A_BYTES_LIKE_OBJECT_NOT_P;
import static com.oracle.graal.python.nodes.PGuards.isPNone;
+import static com.oracle.graal.python.nodes.PGuards.isTuple;
import static com.oracle.graal.python.nodes.SpecialMethodNames.T_DECODE;
import static com.oracle.graal.python.nodes.StringLiterals.T_CRLF;
import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING;
@@ -95,7 +96,6 @@
import com.oracle.graal.python.lib.PyObjectIsTrueNode;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PNodeWithContext;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -509,7 +509,6 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self,
@Cached PyObjectCallMethodObjArgs callMethodRead,
@Cached PyNumberAsSizeNode asSizeNode,
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
- @Cached PyTupleCheckNode tupleCheck,
@CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib,
@CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib,
@Cached PRaiseNode raiseNode) {
@@ -531,7 +530,7 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self,
* Given this, we know there was a valid snapshot point len(decBuffer) bytes ago
* with decoder state (b'', decFlags).
*/
- if (!tupleCheck.execute(inliningTarget, state)) {
+ if (!isTuple(state)) {
throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_DECODER_STATE);
}
Object[] array = getArray.execute(inliningTarget, state);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java
index 1135c1bf68..fae35ffe7f 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java
@@ -58,7 +58,6 @@
import com.oracle.graal.python.lib.PyListCheckExactNode;
import com.oracle.graal.python.lib.PyObjectGetIter;
import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleCheckExactNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
@@ -196,7 +195,6 @@ PTuple call(VirtualFrame frame, PJSONEncoder self, Object obj, @SuppressWarnings
@Cached CallUnaryMethodNode callDefaultFn,
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarCustomNode,
- @Cached PyTupleCheckNode tupleCheckNode,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached HashingStorageGetIterator hashingStorageGetIterator,
@Cached HashingStorageIteratorNext hashingStorageIteratorNext,
@@ -281,7 +279,7 @@ PTuple call(VirtualFrame frame, PJSONEncoder self, Object obj, @SuppressWarnings
stackStorage = null;
stackIterator = genericIterator;
}
- } else if (tupleCheckNode.execute(inliningTarget, value)) {
+ } else if (PGuards.isTuple(value)) {
appendCodePointNode.execute(builder, '[');
first = true;
if (pyTupleCheckExactNode.execute(inliningTarget, value)) {
@@ -355,7 +353,7 @@ PTuple call(VirtualFrame frame, PJSONEncoder self, Object obj, @SuppressWarnings
Object item = pyIterNextNode.execute(frame, inliningTarget, genericIterator);
if (state == STATE_GENERIC_DICT) {
genericDictProfile.enter(inliningTarget);
- if (!tupleCheckNode.execute(inliningTarget, item)) {
+ if (!PGuards.isTuple(item)) {
errorProfile.enter(inliningTarget);
throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.ITEMS_MUST_RETURN_2_TUPLES);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java
index 59310a5f1a..ef52dc4b77 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java
@@ -77,7 +77,6 @@
import com.oracle.graal.python.lib.PyLongAsLongNode;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -272,7 +271,6 @@ static Object get(PPickler self, @SuppressWarnings("unused") PNone none,
static Object set(VirtualFrame frame, PPickler self, Object obj,
@Bind Node inliningTarget,
@Cached PyNumberAsSizeNode asSizeNode,
- @Cached PyTupleCheckNode tupleCheckNode,
@Cached PyTupleSizeNode sizeNode,
@Cached PyTupleGetItem getItemNode,
@Cached HashingStorageGetIterator getIter,
@@ -289,7 +287,7 @@ static Object set(VirtualFrame frame, PPickler self, Object obj,
HashingStorageIterator it = getIter.execute(inliningTarget, dictStorage);
while (iterNext.execute(inliningTarget, dictStorage, it)) {
Object value = iterValue.execute(inliningTarget, dictStorage, it);
- if (!tupleCheckNode.execute(inliningTarget, value) || sizeNode.execute(inliningTarget, value) != 2) {
+ if (!PGuards.isTuple(value) || sizeNode.execute(inliningTarget, value) != 2) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.VALUES_MUST_BE_2TUPLES, "memo");
}
int memoId = asSizeNode.executeExact(frame, inliningTarget, getItemNode.execute(inliningTarget, value, 0));
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java
index f42a2adca2..85bf7f2f10 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java
@@ -110,7 +110,6 @@
import com.oracle.graal.python.lib.PySequenceGetItemNode;
import com.oracle.graal.python.lib.PySequenceSetItemNode;
import com.oracle.graal.python.lib.PySequenceSizeNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.nodes.BuiltinNames;
@@ -854,8 +853,6 @@ public LocalDate asDate(
// GR-44020: make shared:
@Exclusive @Cached PyTupleSizeNode pyTupleSizeNode,
// GR-44020: make shared:
- @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
- // GR-44020: make shared:
@Exclusive @Cached PyTupleGetItem tupleGetItem,
// GR-44020: make shared:
@Exclusive @Cached GilNode gil) throws UnsupportedMessageException {
@@ -865,7 +862,7 @@ public LocalDate asDate(
InteropBehavior behavior = getBehavior.execute(inliningTarget, this, method);
if (behavior != null) {
Object value = getValue.execute(inliningTarget, behavior, method, this);
- if (tupleCheckNode.execute(inliningTarget, value)) {
+ if (PGuards.isTuple(value)) {
if (pyTupleSizeNode.execute(inliningTarget, value) != 3) {
throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_A_S_TUPLE, "return value", "3");
}
@@ -928,8 +925,6 @@ public LocalTime asTime(
// GR-44020: make shared:
@Exclusive @Cached PyTupleSizeNode pyTupleSizeNode,
// GR-44020: make shared:
- @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
- // GR-44020: make shared:
@Exclusive @Cached PyTupleGetItem tupleGetItem,
// GR-44020: make shared:
@Exclusive @Cached GilNode gil) throws UnsupportedMessageException {
@@ -939,7 +934,7 @@ public LocalTime asTime(
InteropBehavior behavior = getBehavior.execute(inliningTarget, this, method);
if (behavior != null) {
Object value = getValue.execute(inliningTarget, behavior, method, this);
- if (tupleCheckNode.execute(inliningTarget, value)) {
+ if (PGuards.isTuple(value)) {
if (pyTupleSizeNode.execute(inliningTarget, value) != 4) {
throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_A_S_TUPLE, "return value", "4");
}
@@ -1091,8 +1086,6 @@ public Duration asDuration(
// GR-44020: make shared:
@Exclusive @Cached PyTupleSizeNode pyTupleSizeNode,
// GR-44020: make shared:
- @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
- // GR-44020: make shared:
@Exclusive @Cached PyTupleGetItem tupleGetItem,
// GR-44020: make shared:
@Exclusive @Cached GilNode gil) throws UnsupportedMessageException {
@@ -1102,7 +1095,7 @@ public Duration asDuration(
InteropBehavior behavior = getBehavior.execute(inliningTarget, this, method);
if (behavior != null) {
Object value = getValue.execute(inliningTarget, behavior, method, this);
- if (tupleCheckNode.execute(inliningTarget, value)) {
+ if (PGuards.isTuple(value)) {
if (pyTupleSizeNode.execute(inliningTarget, value) != 2) {
throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_A_S_TUPLE, "return value", "2");
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java
index 45236dca11..51833d6870 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java
@@ -61,7 +61,6 @@
import com.oracle.graal.python.lib.PyBytesCheckNode;
import com.oracle.graal.python.lib.PyObjectGetIter;
import com.oracle.graal.python.lib.PyObjectHashNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.RichCmpOp;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
@@ -134,21 +133,20 @@ static PCode call(VirtualFrame frame, @SuppressWarnings("unused") Object cls, in
@Cached GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.ToArrayNode toArrayNode,
@Cached PyBytesCheckNode bytesCheckNode,
- @Cached PyTupleCheckNode tupleCheckNode,
@Cached CastToTruffleStringNode castToTruffleStringNode) {
byte[] codeBytes = getBytes(inliningTarget, codestring, bytesCheckNode, getBytesStorage, bufferLib);
byte[] linetableBytes = getBytes(inliningTarget, linetable, bytesCheckNode, getBytesStorage, bufferLib);
checkBytes(inliningTarget, exceptiontable, bytesCheckNode);
- Object[] constantsArr = getTupleArray(inliningTarget, constants, tupleCheckNode, getTupleStorage, toArrayNode);
+ Object[] constantsArr = getTupleArray(inliningTarget, constants, getTupleStorage, toArrayNode);
TruffleString[] namesArr = objectArrayToTruffleStringArray(inliningTarget,
- getTupleArray(inliningTarget, names, tupleCheckNode, getTupleStorage, toArrayNode), castToTruffleStringNode);
+ getTupleArray(inliningTarget, names, getTupleStorage, toArrayNode), castToTruffleStringNode);
TruffleString[] varnamesArr = objectArrayToTruffleStringArray(inliningTarget,
- getTupleArray(inliningTarget, varnames, tupleCheckNode, getTupleStorage, toArrayNode), castToTruffleStringNode);
+ getTupleArray(inliningTarget, varnames, getTupleStorage, toArrayNode), castToTruffleStringNode);
TruffleString[] freevarsArr = objectArrayToTruffleStringArray(inliningTarget,
- getTupleArray(inliningTarget, freevars, tupleCheckNode, getTupleStorage, toArrayNode), castToTruffleStringNode);
+ getTupleArray(inliningTarget, freevars, getTupleStorage, toArrayNode), castToTruffleStringNode);
TruffleString[] cellcarsArr = objectArrayToTruffleStringArray(inliningTarget,
- getTupleArray(inliningTarget, cellvars, tupleCheckNode, getTupleStorage, toArrayNode), castToTruffleStringNode);
+ getTupleArray(inliningTarget, cellvars, getTupleStorage, toArrayNode), castToTruffleStringNode);
return createCodeNode.execute(frame, argcount, posonlyargcount, kwonlyargcount,
nlocals, stacksize, flags,
@@ -170,9 +168,9 @@ private static void checkBytes(Node inliningTarget, Object object, PyBytesCheckN
}
}
- private static Object[] getTupleArray(Node inliningTarget, Object object, PyTupleCheckNode tupleCheckNode,
+ private static Object[] getTupleArray(Node inliningTarget, Object object,
GetTupleStorage getTupleStorage, SequenceStorageNodes.ToArrayNode toArrayNode) {
- if (!tupleCheckNode.execute(inliningTarget, object)) {
+ if (!PGuards.isTuple(object)) {
throw invalidArgs(inliningTarget);
}
return toArrayNode.execute(inliningTarget, getTupleStorage.execute(inliningTarget, object));
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
index c5ef1c99fa..0da511ba97 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
@@ -60,7 +60,6 @@
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare;
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode;
import com.oracle.graal.python.lib.PyMappingCheckNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyNumberOrNode;
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
import com.oracle.graal.python.lib.PyObjectGetItem;
@@ -72,6 +71,7 @@
import com.oracle.graal.python.lib.PySequenceContainsNode;
import com.oracle.graal.python.lib.RichCmpOp;
import com.oracle.graal.python.nodes.ErrorMessages;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
@@ -106,11 +106,10 @@ public abstract static class MappingproxyNode extends PythonBinaryBuiltinNode {
static Object doMapping(@SuppressWarnings("unused") Object cls, Object obj,
@Bind Node inliningTarget,
@Cached PyMappingCheckNode mappingCheckNode,
- @Cached PyTupleCheckNode tupleCheckNode,
@Bind PythonLanguage language,
@Cached PRaiseNode raiseNode) {
// descrobject.c mappingproxy_check_mapping()
- if (!(obj instanceof PList || tupleCheckNode.execute(inliningTarget, obj)) && mappingCheckNode.execute(inliningTarget, obj)) {
+ if (!(obj instanceof PList || PGuards.isTuple(obj)) && mappingCheckNode.execute(inliningTarget, obj)) {
return PFactory.createMappingproxy(language, obj);
}
throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.S_ARG_MUST_BE_S_NOT_P, "mappingproxy()", "mapping", obj);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewBuiltins.java
index 7970c7d41d..c2ecf66c5e 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewBuiltins.java
@@ -91,9 +91,9 @@
import com.oracle.graal.python.lib.PyMemoryViewFromObject;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.RichCmpOp;
import com.oracle.graal.python.nodes.ErrorMessages;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PNodeWithContext;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes;
@@ -656,7 +656,6 @@ static PMemoryView doGeneric(VirtualFrame frame, PMemoryView self, TruffleString
@Cached PyNumberAsSizeNode asSizeNode,
@Cached TruffleString.CodePointLengthNode lengthNode,
@Cached TruffleString.CodePointAtIndexUTF32Node atIndexNode,
- @Cached PyTupleCheckNode tupleCheck,
@Exclusive @Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached PRaiseNode raiseNode) {
self.checkReleased(inliningTarget, raiseNode);
@@ -667,7 +666,7 @@ static PMemoryView doGeneric(VirtualFrame frame, PMemoryView self, TruffleString
} else if (shapeObj instanceof PList) {
isPListProfile.enter(inliningTarget);
shape = shapeFromStorage(frame, inliningTarget, ((PList) shapeObj).getSequenceStorage(), getItemScalarNode, asSizeNode, raiseNode);
- } else if (tupleCheck.execute(inliningTarget, shapeObj)) {
+ } else if (PGuards.isTuple(shapeObj)) {
SequenceStorage storage = getTupleStorage.execute(inliningTarget, shapeObj);
shape = shapeFromStorage(frame, inliningTarget, storage, getItemScalarNode, asSizeNode, raiseNode);
} else {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java
index 93207ee1d0..51aa666446 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java
@@ -122,7 +122,6 @@
import com.oracle.graal.python.lib.PyObjectLookupAttr;
import com.oracle.graal.python.lib.PyObjectLookupAttrO;
import com.oracle.graal.python.lib.PyObjectSizeNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.BuiltinNames;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.HiddenAttr;
@@ -452,13 +451,12 @@ abstract static class GetNewArgsInternalNode extends Node {
static Pair doNewArgsEx(VirtualFrame frame, Object getNewArgsExAttr, @SuppressWarnings("unused") Object getNewArgsAttr,
@Bind Node inliningTarget,
@Exclusive @Cached CallNode callNode,
- @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Cached PyDictCheckNode isDictSubClassNode,
@Cached PyObjectGetItem getItemNode,
@Cached PyObjectSizeNode sizeNode,
@Exclusive @Cached PRaiseNode raiseNode) {
Object newargs = callNode.execute(frame, getNewArgsExAttr);
- if (!tupleCheckNode.execute(inliningTarget, newargs)) {
+ if (!PGuards.isTuple(newargs)) {
throw raiseNode.raise(inliningTarget, TypeError, SHOULD_RETURN_TYPE_A_NOT_TYPE_B, T___GETNEWARGS_EX__, "tuple", newargs);
}
int length = sizeNode.execute(frame, inliningTarget, newargs);
@@ -469,7 +467,7 @@ static Pair doNewArgsEx(VirtualFrame frame, Object getNewArgsExA
Object args = getItemNode.execute(frame, inliningTarget, newargs, 0);
Object kwargs = getItemNode.execute(frame, inliningTarget, newargs, 1);
- if (!tupleCheckNode.execute(inliningTarget, args)) {
+ if (!PGuards.isTuple(args)) {
throw raiseNode.raise(inliningTarget, TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "first item of the tuple returned by __getnewargs_ex__", "tuple", args);
}
if (!isDictSubClassNode.execute(inliningTarget, kwargs)) {
@@ -483,10 +481,9 @@ static Pair doNewArgsEx(VirtualFrame frame, Object getNewArgsExA
static Pair doNewArgs(VirtualFrame frame, @SuppressWarnings("unused") PNone getNewArgsExAttr, Object getNewArgsAttr,
@Bind Node inliningTarget,
@Exclusive @Cached CallNode callNode,
- @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached PRaiseNode raiseNode) {
Object args = callNode.execute(frame, getNewArgsAttr);
- if (!tupleCheckNode.execute(inliningTarget, args)) {
+ if (!PGuards.isTuple(args)) {
throw raiseNode.raise(inliningTarget, TypeError, SHOULD_RETURN_TYPE_A_NOT_TYPE_B, T___GETNEWARGS__, "tuple", args);
}
return Pair.create(args, PNone.NONE);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java
index c083105be4..4879c74c82 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java
@@ -66,8 +66,8 @@
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
import com.oracle.graal.python.lib.PyObjectHashNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
@@ -195,12 +195,11 @@ public abstract static class SetStateNode extends PythonBuiltinNode {
@Specialization
static PNone setstate(PRandom random, Object tuple,
@Bind Node inliningTarget,
- @Cached PyTupleCheckNode tupleCheck,
@Cached GetTupleStorage getTupleStorage,
@Cached GetInternalObjectArrayNode getArray,
@Cached CastToJavaUnsignedLongNode castNode,
@Cached PRaiseNode raiseNode) {
- if (!tupleCheck.execute(inliningTarget, tuple)) {
+ if (!PGuards.isTuple(tuple)) {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.STATE_VECTOR_MUST_BE_A_TUPLE);
}
SequenceStorage storage = getTupleStorage.execute(inliningTarget, tuple);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java
index 72b3c64866..2d23f5cc2b 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java
@@ -71,7 +71,6 @@
import com.oracle.graal.python.lib.PyLongAsIntNode;
import com.oracle.graal.python.lib.PyTimeFromObjectNode;
import com.oracle.graal.python.lib.PyTimeFromObjectNode.RoundType;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
@@ -128,7 +127,6 @@ static UniversalSockAddr doInet(VirtualFrame frame, @SuppressWarnings("unused")
@Bind Node inliningTarget,
@CachedLibrary(limit = "1") @Shared("posixLib") PosixSupportLibrary posixLib,
@CachedLibrary(limit = "1") @Shared("sockAddrLib") UniversalSockAddrLibrary sockAddrLib,
- @Cached @Shared("tupleCheck") PyTupleCheckNode tupleCheck,
@Cached @Shared("tupleSize") PyTupleSizeNode tupleSize,
@Cached @Shared("tupleGetItem") PyTupleGetItem tupleGetItem,
@Cached @Shared("asInt") PyLongAsIntNode asIntNode,
@@ -137,7 +135,7 @@ static UniversalSockAddr doInet(VirtualFrame frame, @SuppressWarnings("unused")
@Cached @Shared("setIpAddr") SetIpAddrNode setIpAddrNode,
@Cached @Shared PRaiseNode raiseNode) {
PythonContext context = PythonContext.get(inliningTarget);
- if (!tupleCheck.execute(inliningTarget, address)) {
+ if (!PGuards.isTuple(address)) {
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_AF_INET_VALUES_MUST_BE_TUPLE_NOT_P, caller, address);
}
int length = tupleSize.execute(inliningTarget, address);
@@ -156,7 +154,6 @@ static UniversalSockAddr doInet6(VirtualFrame frame, @SuppressWarnings("unused")
@Bind Node inliningTarget,
@CachedLibrary(limit = "1") @Shared("posixLib") PosixSupportLibrary posixLib,
@CachedLibrary(limit = "1") @Shared("sockAddrLib") UniversalSockAddrLibrary sockAddrLib,
- @Cached @Shared("tupleCheck") PyTupleCheckNode tupleCheck,
@Cached @Shared("tupleSize") PyTupleSizeNode tupleSize,
@Cached @Shared("tupleGetItem") PyTupleGetItem tupleGetItem,
@Cached @Shared("asInt") PyLongAsIntNode asIntNode,
@@ -165,7 +162,7 @@ static UniversalSockAddr doInet6(VirtualFrame frame, @SuppressWarnings("unused")
@Cached @Shared("setIpAddr") SetIpAddrNode setIpAddrNode,
@Cached @Shared PRaiseNode raiseNode) {
PythonContext context = PythonContext.get(inliningTarget);
- if (!tupleCheck.execute(inliningTarget, address)) {
+ if (!PGuards.isTuple(address)) {
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_AF_INET_VALUES_MUST_BE_TUPLE_NOT_S, caller, address);
}
int length = tupleSize.execute(inliningTarget, address);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java
index 1142cb0817..e9b1b1ea4b 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -55,8 +55,8 @@
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -110,12 +110,11 @@ abstract static class AcquireRestoreRLockNode extends PythonBinaryBuiltinNode {
@Specialization
Object acquireRestore(PRLock self, Object state,
@Bind Node inliningTarget,
- @Cached PyTupleCheckNode tupleCheck,
@Cached GetTupleStorage getTupleStorage,
@Cached GilNode gil,
@Cached CastToJavaUnsignedLongNode castLong,
@Cached SequenceStorageNodes.GetItemDynamicNode getItemNode) {
- if (!tupleCheck.execute(inliningTarget, state)) {
+ if (!PGuards.isTuple(state)) {
throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.STATE_ARGUMENT_MUST_BE_A_TUPLE);
}
if (!self.acquireNonBlocking()) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java
index 270fc5e50f..70c7adf4b9 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java
@@ -354,12 +354,11 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, Object bases, PDict
@Cached CastToTruffleStringNode castStr,
@Cached TypeNodes.CreateTypeNode createType,
@Cached GetObjectArrayNode getObjectArrayNode,
- @Exclusive @Cached PyTupleCheckNode tupleCheck,
@Exclusive @Cached ConstructTupleNode constructTupleNode) {
PTuple basesTuple;
if (bases instanceof PTuple) {
basesTuple = (PTuple) bases;
- } else if (tupleCheck.execute(inliningTarget, bases)) {
+ } else if (PGuards.isTuple(bases)) {
basesTuple = constructTupleNode.execute(frame, bases);
} else {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "type.__new__()", 2, "tuple", bases);
@@ -432,7 +431,6 @@ static Object typeGeneric(VirtualFrame frame, Object cls, Object name, Object ba
@Bind Node inliningTarget,
@Cached TypeNode nextTypeNode,
@Cached PRaiseNode raiseNode,
- @Exclusive @Cached PyTupleCheckNode tupleCheck,
@Exclusive @Cached ConstructTupleNode constructTupleNode,
@Exclusive @Cached IsTypeNode isTypeNode) {
Object basesTuple;
@@ -440,7 +438,7 @@ static Object typeGeneric(VirtualFrame frame, Object cls, Object name, Object ba
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "type() argument 1", name);
} else if (bases instanceof PTuple) {
basesTuple = bases;
- } else if (tupleCheck.execute(inliningTarget, bases)) {
+ } else if (PGuards.isTuple(bases)) {
basesTuple = constructTupleNode.execute(frame, bases);
} else {
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "type() argument 2", bases);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java
index 7aaae79156..abdcbcebe3 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java
@@ -183,7 +183,6 @@
import com.oracle.graal.python.lib.PyEvalGetGlobals;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
import com.oracle.graal.python.lib.PyObjectSizeNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.HiddenAttr;
@@ -2157,7 +2156,6 @@ static PythonClass typeMetaclass(VirtualFrame frame, TruffleString name, PTuple
@Cached GetInstanceShape getInstanceShape,
@Cached CastToListNode castToListNode,
@Cached PyUnicodeCheckNode stringCheck,
- @Cached PyTupleCheckNode tupleCheck,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached TruffleString.IsValidNode isValidNode,
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
@@ -2237,7 +2235,7 @@ static PythonClass typeMetaclass(VirtualFrame frame, TruffleString name, PTuple
Object slotsObject = ctx.slotsObject;
if (stringCheck.execute(inliningTarget, ctx.slotsObject)) {
slotsStorage = new ObjectSequenceStorage(new Object[]{castToStringNode.execute(inliningTarget, ctx.slotsObject)});
- } else if (tupleCheck.execute(inliningTarget, ctx.slotsObject)) {
+ } else if (PGuards.isTuple(ctx.slotsObject)) {
slotsStorage = getTupleStorage.execute(inliningTarget, ctx.slotsObject);
} else if (ctx.slotsObject instanceof PList slotsList) {
slotsStorage = slotsList.getSequenceStorage();
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectGetBasesNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectGetBasesNode.java
index 2a80ba9b32..adefd20e98 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectGetBasesNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectGetBasesNode.java
@@ -44,7 +44,7 @@
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PNodeWithContext;
import com.oracle.graal.python.nodes.builtins.TupleNodes.ConstructTupleNode;
import com.oracle.truffle.api.dsl.Cached;
@@ -70,12 +70,11 @@ public static AbstractObjectGetBasesNode getUncached() {
@Specialization
static PTuple getBasesCached(VirtualFrame frame, Node inliningTarget, Object cls,
@Cached PyObjectLookupAttr lookupAttr,
- @Cached PyTupleCheckNode tupleCheck,
@Cached ConstructTupleNode constructTupleNode) {
Object bases = lookupAttr.execute(frame, inliningTarget, cls, T___BASES__);
if (bases instanceof PTuple) {
return (PTuple) bases;
- } else if (tupleCheck.execute(inliningTarget, bases)) {
+ } else if (PGuards.isTuple(bases)) {
return constructTupleNode.execute(frame, bases);
}
return null;
From a42429070b691545d5ff33f37e9c296933686910 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Thu, 18 Jun 2026 16:01:28 +0200
Subject: [PATCH 15/23] Allow native tuples as sequences
---
.../src/tests/cpyext/test_tuple.py | 34 +++++++++++++++++++
.../mappingproxy/MappingproxyBuiltins.java | 3 +-
.../graal/python/lib/PyMappingCheckNode.java | 8 ++++-
.../graal/python/lib/PySequenceCheckNode.java | 17 +++++++++-
.../oracle/graal/python/nodes/PGuards.java | 4 +++
5 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py
index 5ab44035a4..45f894ffda 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py
+++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_tuple.py
@@ -37,6 +37,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import _io
+import codecs
import functools
import io
import itertools
@@ -472,3 +473,36 @@ def test_itertools_cycle_setstate_native_tuple(self):
cycle = itertools.cycle([1])
cycle.__setstate__(state)
assert next(cycle) == 1
+
+ def test_reversed_native_tuple(self):
+ values = TupleSubclass(1, 2, 3)
+ assert is_native_object(values)
+ assert list(reversed(values)) == [3, 2, 1]
+
+ def test_base_exception_group_native_tuple(self):
+ exceptions = TupleSubclass(ValueError("native"), TypeError("tuple"))
+ assert is_native_object(exceptions)
+ group = BaseExceptionGroup("msg", exceptions)
+ assert group.message == "msg"
+ assert tuple(type(e) for e in group.exceptions) == (ValueError, TypeError)
+
+ def test_base_exception_group_copies_native_tuple_notes(self):
+ group = BaseExceptionGroup("msg", (ValueError("native"), TypeError("tuple")))
+ notes = TupleSubclass("note 1", "note 2")
+ assert is_native_object(notes)
+ group.__notes__ = notes
+
+ match, rest = group.split(ValueError)
+ assert match.__notes__ == ["note 1", "note 2"]
+ assert rest.__notes__ == ["note 1", "note 2"]
+ assert match.__notes__ is not notes
+ assert rest.__notes__ is not notes
+ assert match.__notes__ is not rest.__notes__
+
+ def test_multibyte_stream_writer_writelines_native_tuple(self):
+ lines = TupleSubclass("native", " tuple")
+ assert is_native_object(lines)
+ stream = io.BytesIO()
+ writer = codecs.getwriter("euc_jp")(stream)
+ writer.writelines(lines)
+ assert stream.getvalue() == b"native tuple"
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
index 0da511ba97..cb7b0a193c 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
@@ -51,7 +51,6 @@
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
import com.oracle.graal.python.builtins.PythonBuiltins;
import com.oracle.graal.python.builtins.objects.PNone;
-import com.oracle.graal.python.builtins.objects.list.PList;
import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode;
@@ -109,7 +108,7 @@ static Object doMapping(@SuppressWarnings("unused") Object cls, Object obj,
@Bind PythonLanguage language,
@Cached PRaiseNode raiseNode) {
// descrobject.c mappingproxy_check_mapping()
- if (!(obj instanceof PList || PGuards.isTuple(obj)) && mappingCheckNode.execute(inliningTarget, obj)) {
+ if (!PGuards.isTupleOrList(obj) && mappingCheckNode.execute(inliningTarget, obj)) {
return PFactory.createMappingproxy(language, obj);
}
throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.S_ARG_MUST_BE_S_NOT_P, "mappingproxy()", "mapping", obj);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMappingCheckNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMappingCheckNode.java
index f1b1a9c8a5..9710f088ae 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMappingCheckNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMappingCheckNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -40,6 +40,7 @@
*/
package com.oracle.graal.python.lib;
+import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
import com.oracle.graal.python.builtins.objects.dict.PDict;
import com.oracle.graal.python.builtins.objects.str.PString;
import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode;
@@ -82,6 +83,11 @@ static boolean doSequence(@SuppressWarnings("unused") PSequence object) {
return true;
}
+ @Specialization(guards = "isTuple(object)")
+ static boolean doSequence(@SuppressWarnings("unused") PythonAbstractNativeObject object) {
+ return true;
+ }
+
@Specialization
static boolean doString(@SuppressWarnings("unused") PString object) {
return true;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceCheckNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceCheckNode.java
index 2624cc5bc1..0527a67649 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceCheckNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceCheckNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -40,6 +40,7 @@
*/
package com.oracle.graal.python.lib;
+import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
import com.oracle.graal.python.builtins.objects.dict.PDict;
import com.oracle.graal.python.builtins.objects.str.PString;
import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode;
@@ -73,6 +74,11 @@ static boolean doSequence(@SuppressWarnings("unused") PSequence object) {
return true;
}
+ @Specialization(guards = "isTuple(object)")
+ static boolean doSequence(@SuppressWarnings("unused") PythonAbstractNativeObject object) {
+ return true;
+ }
+
@Specialization
static boolean doString(@SuppressWarnings("unused") TruffleString object) {
return true;
@@ -88,6 +94,15 @@ static boolean doDict(@SuppressWarnings("unused") PDict object) {
return false;
}
+ @Specialization(guards = "isNativeTuple(object)")
+ static boolean doNativeTuple(@SuppressWarnings("unused") PythonAbstractNativeObject object) {
+ return true;
+ }
+
+ static boolean isNativeTuple(PythonAbstractNativeObject object) {
+ return PyTupleCheckNode.checkNative(object);
+ }
+
@Fallback
static boolean doGeneric(Node inliningTarget, Object object,
@Cached PyDictCheckNode dictCheckNode,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java
index 74bd1f80a9..d40b687eec 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java
@@ -331,6 +331,10 @@ public static boolean isTuple(Object obj) {
return PyTupleCheckNode.doGeneric(null, obj, InlinedBranchProfile.getUncached(), InlinedBranchProfile.getUncached());
}
+ public static boolean isTupleOrList(Object obj) {
+ return obj instanceof PList || isTuple(obj);
+ }
+
public static boolean isPSequence(Object obj) {
return obj instanceof PSequence;
}
From de624bbfb0ca5f0d9caa5d5fbb85147020e9b3e3 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Thu, 18 Jun 2026 15:14:48 +0200
Subject: [PATCH 16/23] Accept native tuples storage builtins
---
.../modules/GraalPythonModuleBuiltins.java | 75 +++++++++----------
1 file changed, 36 insertions(+), 39 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java
index 6f99ff5b69..cced245e17 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java
@@ -119,6 +119,7 @@
import com.oracle.graal.python.builtins.objects.common.EmptyStorage;
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageLen;
+import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetSequenceStorageNode;
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.dict.PDict;
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
@@ -143,6 +144,7 @@
import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
+import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.arrow.ArrowArray;
import com.oracle.graal.python.nodes.arrow.ArrowSchema;
@@ -178,8 +180,6 @@
import com.oracle.graal.python.runtime.exception.PythonExitException;
import com.oracle.graal.python.runtime.object.PFactory;
import com.oracle.graal.python.runtime.sequence.PSequence;
-import com.oracle.graal.python.runtime.sequence.storage.NativePrimitiveSequenceStorage;
-import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage;
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
import com.oracle.graal.python.util.PythonUtils;
import com.oracle.truffle.api.CompilerAsserts;
@@ -193,7 +193,6 @@
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Exclusive;
-import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.NeverDefault;
@@ -1021,8 +1020,13 @@ private void validate(HashingStorage dictStorage) {
public abstract static class GetStorageStrategyNode extends PythonUnaryBuiltinNode {
@Specialization
@TruffleBoundary
- TruffleString doSet(PSequence seq) {
- return PythonUtils.toTruffleStringUncached(seq.getSequenceStorage().getClass().getSimpleName());
+ static TruffleString doSet(Object object,
+ @Bind Node inliningTarget) {
+ if (PGuards.isTupleOrList(object)) {
+ SequenceStorage sequenceStorage = GetSequenceStorageNode.executeUncached(object);
+ return PythonUtils.toTruffleStringUncached(sequenceStorage.getClass().getSimpleName());
+ }
+ throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC);
}
}
@@ -1030,22 +1034,38 @@ TruffleString doSet(PSequence seq) {
@GenerateNodeFactory
abstract static class StorageToNative extends PythonUnaryBuiltinNode {
- @Specialization
@TruffleBoundary
- Object toNative(PArray array) {
- CApiContext.ensureCapiWasLoaded("internal API");
- NativeSequenceStorage newStorage = ToNativeStorageNode.executeUncached(array.getSequenceStorage(), true);
- array.setSequenceStorage(newStorage);
- return array;
+ @Specialization
+ static Object doGeneric(Object object,
+ @Bind Node inliningTarget) {
+ if (object instanceof PArray array) {
+ array.setSequenceStorage(ToNativeStorageNode.executeUncached(array.getSequenceStorage(), true));
+ } else if (object instanceof PSequence sequence) {
+ sequence.setSequenceStorage(ToNativeStorageNode.executeUncached(sequence.getSequenceStorage(), sequence instanceof PBytesLike));
+ } else if (!PGuards.isTupleOrList(object)) {
+ throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC);
+ }
+ return object;
}
+ }
+
+ @Builtin(name = "storage_to_native_primitive", minNumOfPositionalArgs = 1)
+ @GenerateNodeFactory
+ abstract static class StorageToNativePrimitive extends PythonUnaryBuiltinNode {
- @Specialization
@TruffleBoundary
- Object toNative(PSequence sequence) {
+ @Specialization
+ static Object doGeneric(Object object,
+ @Bind Node inliningTarget) {
CApiContext.ensureCapiWasLoaded("internal API");
- NativeSequenceStorage newStorage = ToNativeStorageNode.executeUncached(sequence.getSequenceStorage(), sequence instanceof PBytesLike);
- sequence.setSequenceStorage(newStorage);
- return sequence;
+ if (object instanceof PArray array) {
+ array.setSequenceStorage(ToNativePrimitiveStorageNode.executeUncached(array.getSequenceStorage()));
+ } else if (object instanceof PSequence sequence) {
+ sequence.setSequenceStorage(ToNativePrimitiveStorageNode.executeUncached(sequence.getSequenceStorage()));
+ } else if (!PGuards.isTupleOrList(object)) {
+ throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC);
+ }
+ return object;
}
}
@@ -1340,29 +1360,6 @@ TruffleString get() {
}
}
- @Builtin(name = "storage_to_native_primitive", minNumOfPositionalArgs = 1)
- @GenerateNodeFactory
- abstract static class StorageToNativePrimitive extends PythonUnaryBuiltinNode {
-
- @Specialization
- static Object doArray(PArray array,
- @Shared @Cached ToNativePrimitiveStorageNode toNativePrimitiveNode,
- @Bind Node inliningTarget) {
- NativePrimitiveSequenceStorage newStorage = toNativePrimitiveNode.execute(inliningTarget, array.getSequenceStorage());
- array.setSequenceStorage(newStorage);
- return array;
- }
-
- @Specialization
- static Object doSequence(PSequence sequence,
- @Shared @Cached ToNativePrimitiveStorageNode toNativePrimitiveNode,
- @Bind Node inliningTarget) {
- NativePrimitiveSequenceStorage newStorage = toNativePrimitiveNode.execute(inliningTarget, sequence.getSequenceStorage());
- sequence.setSequenceStorage(newStorage);
- return sequence;
- }
- }
-
@Builtin(name = "clear_interop_type_registry", maxNumOfPositionalArgs = 0)
@GenerateNodeFactory
public abstract static class ClearInteropTypeRegistry extends PythonBuiltinNode {
From 3f07b7bfce2d5033d20ca68f938b648170bca0a4 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Thu, 18 Jun 2026 16:16:39 +0200
Subject: [PATCH 17/23] Allow native tuples in IteratorNodes.ToArrayNode
---
.../objects/iterator/IteratorNodes.java | 22 +++++++------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java
index ea20fa3462..b443efb51a 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java
@@ -47,7 +47,6 @@
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
import java.util.ArrayList;
-import java.util.List;
import com.oracle.graal.python.builtins.objects.PNone;
import com.oracle.graal.python.builtins.objects.PNotImplemented;
@@ -83,8 +82,8 @@
import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode;
import com.oracle.graal.python.nodes.util.CastBuiltinStringToTruffleStringNode;
import com.oracle.graal.python.runtime.exception.PException;
-import com.oracle.graal.python.runtime.sequence.PSequence;
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
+import com.oracle.graal.python.util.PythonUtils;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
@@ -341,7 +340,7 @@ public abstract static class ToArrayNode extends Node {
public abstract Object[] execute(VirtualFrame frame, Object iterable);
@Specialization(guards = "isString(iterableObj)")
- public static Object[] doIt(Object iterableObj,
+ static Object[] doString(Object iterableObj,
@Bind Node inliningTarget,
@Cached CastBuiltinStringToTruffleStringNode castToStringNode,
@Cached InlinedLoopConditionProfile loopProfile,
@@ -361,22 +360,22 @@ public static Object[] doIt(Object iterableObj,
return result;
}
- @Specialization
- public static Object[] doIt(PSequence iterable,
+ @Specialization(guards = "isPSequence(seq) || isTuple(seq)")
+ static Object[] doSequenceWithStorage(Object seq,
@Bind Node inliningTarget,
@Cached GetSequenceStorageNode getStorageNode,
@Cached SequenceStorageNodes.ToArrayNode toArrayNode) {
- SequenceStorage storage = getStorageNode.execute(inliningTarget, iterable);
+ SequenceStorage storage = getStorageNode.execute(inliningTarget, seq);
return toArrayNode.execute(inliningTarget, storage);
}
@Fallback
- public static Object[] doIt(VirtualFrame frame, Object iterable,
+ static Object[] doGeneric(VirtualFrame frame, Object iterable,
@Bind Node inliningTarget,
@Cached PyObjectGetIter getIter,
@Cached PyIterNextNode nextNode) {
Object it = getIter.execute(frame, inliningTarget, iterable);
- List result = createlist();
+ ArrayList result = new ArrayList<>();
while (true) {
try {
Object next = nextNode.execute(frame, inliningTarget, it);
@@ -385,12 +384,7 @@ public static Object[] doIt(VirtualFrame frame, Object iterable,
break;
}
}
- return result.toArray(new Object[result.size()]);
- }
-
- @TruffleBoundary
- private static List createlist() {
- return new ArrayList<>();
+ return PythonUtils.toArray(result);
}
}
}
From 15bdeca2dcf4ed598639337c60e8ea7d94a1ea58 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Thu, 18 Jun 2026 16:51:42 +0200
Subject: [PATCH 18/23] Improve PyTupleCheckExactNode
---
.../python/lib/PyTupleCheckExactNode.java | 36 ++++++++++++-------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTupleCheckExactNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTupleCheckExactNode.java
index 464979834a..8b7e80633f 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTupleCheckExactNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTupleCheckExactNode.java
@@ -40,20 +40,25 @@
*/
package com.oracle.graal.python.lib;
+import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyObject__ob_type;
+import static com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess.readPtrField;
+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PNodeWithContext;
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectExactProfile;
+import com.oracle.graal.python.runtime.PythonContext;
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
-import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateCached;
import com.oracle.truffle.api.dsl.GenerateInline;
import com.oracle.truffle.api.dsl.GenerateUncached;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.profiles.InlinedBranchProfile;
/**
* Equivalent of CPython's {@code PyTuple_CheckExact}.
@@ -63,25 +68,32 @@
@GenerateInline
@ImportStatic(PGuards.class)
public abstract class PyTupleCheckExactNode extends PNodeWithContext {
+ @TruffleBoundary
public static boolean executeUncached(Object object) {
return PyTupleCheckExactNodeGen.getUncached().execute(null, object);
}
public abstract boolean execute(Node inliningTarget, Object object);
- @Specialization(guards = "isBuiltinTuple(tuple)")
- static boolean doBuiltinTuple(@SuppressWarnings("unused") PTuple tuple) {
- return true;
- }
-
@Specialization
- static boolean doNativeTuple(PythonAbstractNativeObject tuple,
- @Cached(inline = false) IsBuiltinObjectExactProfile check) {
- return check.profileObject(check, tuple, PythonBuiltinClassType.PTuple);
+ public static boolean doGeneric(Node inliningTarget, Object object,
+ @Cached InlinedBranchProfile isPTupleProfile,
+ @Cached InlinedBranchProfile isNativeProfile) {
+ if (object instanceof PTuple tuple) {
+ isPTupleProfile.enter(inliningTarget);
+ return PGuards.isBuiltinTuple(tuple);
+ }
+ if (object instanceof PythonAbstractNativeObject nativeObject) {
+ isNativeProfile.enter(inliningTarget);
+ return checkNative(PythonContext.get(inliningTarget), nativeObject);
+ }
+ return false;
}
- @Fallback
- static boolean doOther(@SuppressWarnings("unused") Object object) {
- return false;
+ public static boolean checkNative(PythonContext context, PythonAbstractNativeObject nativeObject) {
+ long obType = readPtrField(nativeObject.pointer, PyObject__ob_type);
+ boolean isTupleExact = obType == context.lookupType(PythonBuiltinClassType.PTuple).getNativePointer();
+ assert IsBuiltinObjectExactProfile.profileObjectUncached(nativeObject, PythonBuiltinClassType.PTuple) == isTupleExact;
+ return isTupleExact;
}
}
From 27fec8486a0787ae0d0b0c590bed419eaacee3c0 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Thu, 18 Jun 2026 18:43:06 +0200
Subject: [PATCH 19/23] Fix MultibyteStreamWriterBuiltins.WritelinesNode
---
.../MultibyteStreamWriterBuiltins.java | 34 ++++++++-----------
1 file changed, 15 insertions(+), 19 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamWriterBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamWriterBuiltins.java
index b5c3851b38..a811e8f7a4 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamWriterBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamWriterBuiltins.java
@@ -53,20 +53,21 @@
import java.util.List;
+import com.oracle.graal.python.annotations.Builtin;
import com.oracle.graal.python.annotations.Slot;
import com.oracle.graal.python.annotations.Slot.SlotKind;
import com.oracle.graal.python.annotations.Slot.SlotSignature;
-import com.oracle.graal.python.annotations.Builtin;
import com.oracle.graal.python.builtins.CoreFunctions;
import com.oracle.graal.python.builtins.PythonBuiltins;
import com.oracle.graal.python.builtins.objects.PNone;
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
-import com.oracle.graal.python.builtins.objects.common.SequenceNodes;
-import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
import com.oracle.graal.python.lib.PyObjectGetAttr;
+import com.oracle.graal.python.lib.PySequenceCheckNode;
+import com.oracle.graal.python.lib.PySequenceGetItemNode;
+import com.oracle.graal.python.lib.PySequenceSizeNode;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.StringLiterals;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -75,11 +76,8 @@
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
import com.oracle.graal.python.runtime.object.PFactory;
-import com.oracle.graal.python.runtime.sequence.PSequence;
-import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
-import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
@@ -168,30 +166,28 @@ abstract static class WritelinesNode extends PythonBinaryBuiltinNode {
// _multibytecodec_MultibyteStreamWriter_writelines
@Specialization
- static Object writelines(VirtualFrame frame, MultibyteStreamWriterObject self, PSequence lines,
+ static Object doGeneric(VirtualFrame frame, MultibyteStreamWriterObject self, Object lines,
@Bind Node inliningTarget,
+ @Cached PySequenceCheckNode sequenceCheckNode,
+ @Cached PySequenceSizeNode sizeNode,
+ @Cached PySequenceGetItemNode getItemNode,
@Cached MultibyteIncrementalEncoderBuiltins.EncodeStatefulNode encodeStatefulNode,
- @Cached SequenceNodes.GetSequenceStorageNode getStorage,
- @Cached SequenceStorageNodes.GetItemNode getItem,
@Cached PyObjectCallMethodObjArgs callMethod) {
- SequenceStorage sq = getStorage.execute(inliningTarget, lines);
- for (int i = 0; i < sq.length(); i++) {
+ if (!sequenceCheckNode.execute(inliningTarget, lines)) {
+ throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ARG_MUST_BE_A_SEQUENCE_OBJECT);
+ }
+
+ int n = sizeNode.execute(frame, inliningTarget, lines);
+ for (int i = 0; i < n; i++) {
/* length can be changed even within this loop */
- Object strobj = getItem.execute(sq, i);
+ Object strobj = getItemNode.execute(lines, i);
// mbstreamwriter_iwrite
Object str = encodeStatefulNode.execute(frame, self, strobj, 0);
callMethod.execute(frame, inliningTarget, self.stream, WRITE, str);
}
return PNone.NONE;
}
-
- // assuming !pySequenceCheck.execute(lines)
- @Fallback
- static Object writelines(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object lines,
- @Bind Node inliningTarget) {
- throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ARG_MUST_BE_A_SEQUENCE_OBJECT);
- }
}
@Builtin(name = "reset", minNumOfPositionalArgs = 1, doc = "reset($self, /)\n--\n\n")
From 708112245a726406818ec8eee7bd5740b8af191d Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Thu, 18 Jun 2026 19:09:40 +0200
Subject: [PATCH 20/23] Fix style
---
.../python/builtins/modules/GraalPythonModuleBuiltins.java | 4 ++--
.../modules/cext/PythonCextGenericAliasBuiltins.java | 5 -----
.../modules/cjkcodecs/MultibyteStreamWriterBuiltins.java | 2 +-
.../graal/python/builtins/modules/codecs/ErrorHandlers.java | 1 -
.../graal/python/builtins/objects/PythonAbstractObject.java | 1 -
.../builtins/objects/function/AbstractFunctionBuiltins.java | 2 --
6 files changed, 3 insertions(+), 12 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java
index cced245e17..3da2e8595f 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java
@@ -1037,7 +1037,7 @@ abstract static class StorageToNative extends PythonUnaryBuiltinNode {
@TruffleBoundary
@Specialization
static Object doGeneric(Object object,
- @Bind Node inliningTarget) {
+ @Bind Node inliningTarget) {
if (object instanceof PArray array) {
array.setSequenceStorage(ToNativeStorageNode.executeUncached(array.getSequenceStorage(), true));
} else if (object instanceof PSequence sequence) {
@@ -1056,7 +1056,7 @@ abstract static class StorageToNativePrimitive extends PythonUnaryBuiltinNode {
@TruffleBoundary
@Specialization
static Object doGeneric(Object object,
- @Bind Node inliningTarget) {
+ @Bind Node inliningTarget) {
CApiContext.ensureCapiWasLoaded("internal API");
if (object instanceof PArray array) {
array.setSequenceStorage(ToNativePrimitiveStorageNode.executeUncached(array.getSequenceStorage()));
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java
index a3714a17b5..9baf679d5d 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextGenericAliasBuiltins.java
@@ -47,14 +47,9 @@
import com.oracle.graal.python.PythonLanguage;
import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode;
import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin;
-import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
-import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes;
-import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.runtime.object.PFactory;
-import com.oracle.graal.python.runtime.sequence.storage.NativeObjectSequenceStorage;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamWriterBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamWriterBuiltins.java
index a811e8f7a4..40317f7de0 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamWriterBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteStreamWriterBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java
index b50b592401..3e55f00ad2 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java
@@ -80,7 +80,6 @@
import com.oracle.graal.python.builtins.objects.exception.UnicodeEncodeErrorBuiltins.PyUnicodeEncodeOrTranslateErrorGetObjectNode;
import com.oracle.graal.python.builtins.objects.exception.UnicodeEncodeErrorBuiltins.PyUnicodeEncodeOrTranslateErrorGetStartNode;
import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked0Node;
-import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.lib.PyBytesCheckNode;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectSizeNode;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java
index 85bf7f2f10..2927b6e257 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java
@@ -87,7 +87,6 @@
import com.oracle.graal.python.builtins.objects.object.PythonObject;
import com.oracle.graal.python.builtins.objects.str.PString;
import com.oracle.graal.python.builtins.objects.str.StringNodes.StringMaterializeNode;
-import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
import com.oracle.graal.python.builtins.objects.type.PythonClass;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java
index 04d146137e..8947d6c061 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java
@@ -62,7 +62,6 @@
import com.oracle.graal.python.builtins.objects.dict.PDict;
import com.oracle.graal.python.builtins.objects.module.PythonModule;
import com.oracle.graal.python.builtins.objects.object.PythonObject;
-import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.lib.PyObjectGetItem;
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -84,7 +83,6 @@
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
-import com.oracle.truffle.api.dsl.Cached.Exclusive;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
From 5329f80d4a9a3eb8763ecabfb369cc5322a4a430 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Thu, 25 Jun 2026 10:21:06 +0200
Subject: [PATCH 21/23] Accept native tuple in PyException_SetArgs
---
.../builtins/modules/cext/PythonCextErrBuiltins.java | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java
index c032befcfd..c38b70518d 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java
@@ -99,10 +99,12 @@
import com.oracle.graal.python.lib.PyObjectSetAttr;
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
import com.oracle.graal.python.lib.PyTupleCheckNode;
+import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.WriteUnraisableNode;
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes.ConstructTupleNode;
+import com.oracle.graal.python.nodes.builtins.TupleNodes.EnsureManagedTupleNode;
import com.oracle.graal.python.nodes.call.CallNode;
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
import com.oracle.graal.python.nodes.object.GetClassNode;
@@ -522,10 +524,16 @@ static Object get(Object exc,
abstract static class PyException_SetArgs extends CApiBinaryBuiltinNode {
@Specialization
- static Object set(PBaseException exc, PTuple args,
+ static Object set(PBaseException exc, Object args,
@Bind Node inliningTarget,
+ @Cached EnsureManagedTupleNode ensureManagedTupleNode,
@Cached ExceptionNodes.SetArgsNode setArgsNode) {
- setArgsNode.execute(inliningTarget, exc, args);
+ PTuple execute = ensureManagedTupleNode.execute(inliningTarget, args);
+ if (execute == null) {
+ // CPython doesn't do that check but they just expect that to be a tuple. We need to convert to PTuple, so we need to check eagerly.
+ throw PRaiseNode.raiseStatic(inliningTarget, SystemError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC_WAS_S_P, args, args);
+ }
+ setArgsNode.execute(inliningTarget, exc, execute);
return PNone.NO_VALUE;
}
}
From c4dd79db5201d05a97599f0eebae35768d4939a3 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Thu, 25 Jun 2026 11:54:56 +0200
Subject: [PATCH 22/23] Address review comments
---
.../builtins/modules/io/BytesIOBuiltins.java | 9 +--
.../builtins/modules/io/StringIOBuiltins.java | 9 +--
.../objects/function/FunctionBuiltins.java | 71 ++++---------------
3 files changed, 19 insertions(+), 70 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java
index 0c77dd746a..47aefd399c 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java
@@ -673,13 +673,13 @@ static Object doit(VirtualFrame frame, PBytesIO self, Object state,
@Cached HashingStorageAddAllToOther addAllToOtherNode,
@Cached PRaiseNode raiseNode) {
if (!PGuards.isTuple(state)) {
- return notTuple(self, state, inliningTarget);
+ throw raiseNode.raise(inliningTarget, TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 3, state);
}
self.checkExports(inliningTarget, raiseNode);
SequenceStorage storage = getTupleStorage.execute(inliningTarget, state);
Object[] array = getArray.execute(inliningTarget, storage);
if (storage.length() < 3) {
- return notTuple(self, state, inliningTarget);
+ throw raiseNode.raise(inliningTarget, TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 3, state);
}
/*
* Reset the object to its default state. This is only needed to handle the case of
@@ -720,11 +720,6 @@ static Object doit(VirtualFrame frame, PBytesIO self, Object state,
}
return PNone.NONE;
}
-
- static Object notTuple(PBytesIO self, Object state,
- @Bind Node inliningTarget) {
- throw PRaiseNode.raiseStatic(inliningTarget, TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 3, state);
- }
}
@Builtin(name = J_FLUSH, minNumOfPositionalArgs = 1)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java
index 31f10d3718..567712aef4 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java
@@ -676,12 +676,12 @@ static Object doit(VirtualFrame frame, PStringIO self, Object state,
@Cached HashingStorageAddAllToOther addAllToOtherNode,
@Cached PRaiseNode raiseNode) {
if (!PGuards.isTuple(state)) {
- return notTuple(self, state, inliningTarget);
+ throw raiseNode.raise(inliningTarget, TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 4, state);
}
SequenceStorage storage = getTupleStorage.execute(inliningTarget, state);
Object[] array = getArray.execute(inliningTarget, storage);
if (storage.length() < 4) {
- return notTuple(self, state, inliningTarget);
+ throw raiseNode.raise(inliningTarget, TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 4, state);
}
initNode.execute(frame, self, array[0], array[1]);
/*
@@ -730,11 +730,6 @@ static Object doit(VirtualFrame frame, PStringIO self, Object state,
return PNone.NONE;
}
- static Object notTuple(PStringIO self, Object state,
- @Bind Node inliningTarget) {
- throw PRaiseNode.raiseStatic(inliningTarget, TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 4, state);
- }
-
@Specialization(guards = "self.isClosed()")
static Object closedError(@SuppressWarnings("unused") PStringIO self, @SuppressWarnings("unused") Object arg,
@Bind Node inliningTarget) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java
index 4645239a0e..782de28b26 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java
@@ -126,13 +126,15 @@ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PD
return PFactory.createFunction(language, name, code, globals, null);
}
- @Specialization
+ @Specialization(guards = "isTuple(closure)")
static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, @SuppressWarnings("unused") PNone defaultArgs,
- PTuple closure,
+ Object closure,
@Bind Node inliningTarget,
- @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode,
+ @Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
+ @Shared("toArray") @Cached ToArrayNode toArray,
@Bind PythonLanguage language) {
- return PFactory.createFunction(language, T_LAMBDA_NAME, code, globals, PCell.toCellArray(getObjectArrayNode.execute(inliningTarget, closure)));
+ Object[] closureArray = toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, closure));
+ return PFactory.createFunction(language, T_LAMBDA_NAME, code, globals, PCell.toCellArray(closureArray));
}
@Specialization
@@ -143,60 +145,14 @@ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PD
return PFactory.createFunction(language, T_LAMBDA_NAME, code, globals, null);
}
- @Specialization
- static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, @SuppressWarnings("unused") PNone defaultArgs, PTuple closure,
- @Bind Node inliningTarget,
- @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode,
- @Bind PythonLanguage language) {
- return PFactory.createFunction(language, name, code, globals, PCell.toCellArray(getObjectArrayNode.execute(inliningTarget, closure)));
- }
-
- @Specialization
- static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, PTuple defaultArgs,
- @SuppressWarnings("unused") PNone closure,
- @Bind Node inliningTarget,
- @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode,
- @Bind PythonLanguage language) {
- // TODO split defaults of positional args from kwDefaults
- return PFactory.createFunction(language, code.getName(), code, globals, getObjectArrayNode.execute(inliningTarget, defaultArgs), null, null);
- }
-
- @Specialization
- static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, PTuple defaultArgs, @SuppressWarnings("unused") PNone closure,
- @Bind Node inliningTarget,
- @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode,
- @Bind PythonLanguage language) {
- // TODO split defaults of positional args from kwDefaults
- return PFactory.createFunction(language, name, code, globals, getObjectArrayNode.execute(inliningTarget, defaultArgs), null, null);
- }
-
- @Specialization
- static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, PTuple defaultArgs, PTuple closure,
- @Bind Node inliningTarget,
- @Shared("getObjectArrayNode") @Cached GetObjectArrayNode getObjectArrayNode,
- @Bind PythonLanguage language) {
- // TODO split defaults of positional args from kwDefaults
- return PFactory.createFunction(language, name, code, globals, getObjectArrayNode.execute(inliningTarget, defaultArgs), null,
- PCell.toCellArray(getObjectArrayNode.execute(inliningTarget, closure)));
- }
-
- @Specialization(guards = "isTuple(closure)")
- static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, @SuppressWarnings("unused") PNone defaultArgs,
- Object closure,
- @Bind Node inliningTarget,
- @Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
- @Shared("toArray") @Cached ToArrayNode toArray,
- @Bind PythonLanguage language) {
- return PFactory.createFunction(language, T_LAMBDA_NAME, code, globals, PCell.toCellArray(toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, closure))));
- }
-
@Specialization(guards = "isTuple(closure)")
static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, @SuppressWarnings("unused") PNone defaultArgs, Object closure,
@Bind Node inliningTarget,
@Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
@Shared("toArray") @Cached ToArrayNode toArray,
@Bind PythonLanguage language) {
- return PFactory.createFunction(language, name, code, globals, PCell.toCellArray(toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, closure))));
+ Object[] closureArray = toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, closure));
+ return PFactory.createFunction(language, name, code, globals, PCell.toCellArray(closureArray));
}
@Specialization(guards = "isTuple(defaultArgs)")
@@ -207,7 +163,8 @@ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PD
@Shared("toArray") @Cached ToArrayNode toArray,
@Bind PythonLanguage language) {
// TODO split defaults of positional args from kwDefaults
- return PFactory.createFunction(language, code.getName(), code, globals, toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, defaultArgs)), null, null);
+ Object[] defaultArgsArray = toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, defaultArgs));
+ return PFactory.createFunction(language, code.getName(), code, globals, defaultArgsArray, null, null);
}
@Specialization(guards = "isTuple(defaultArgs)")
@@ -217,7 +174,8 @@ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PD
@Shared("toArray") @Cached ToArrayNode toArray,
@Bind PythonLanguage language) {
// TODO split defaults of positional args from kwDefaults
- return PFactory.createFunction(language, name, code, globals, toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, defaultArgs)), null, null);
+ Object[] defaultArgsArray = toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, defaultArgs));
+ return PFactory.createFunction(language, name, code, globals, defaultArgsArray, null, null);
}
@Specialization(guards = {"isTuple(defaultArgs)", "isTuple(closure)"})
@@ -227,8 +185,9 @@ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PD
@Shared("toArray") @Cached ToArrayNode toArray,
@Bind PythonLanguage language) {
// TODO split defaults of positional args from kwDefaults
- return PFactory.createFunction(language, name, code, globals, toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, defaultArgs)), null,
- PCell.toCellArray(toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, closure))));
+ Object[] closureArray = toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, closure));
+ Object[] defaultArgsArray = toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, defaultArgs));
+ return PFactory.createFunction(language, name, code, globals, defaultArgsArray, null, PCell.toCellArray(closureArray));
}
@Fallback
From fc00ce49f6889131160fe50ed67ea4c4b0bdc0a2 Mon Sep 17 00:00:00 2001
From: Florian Angerer
Date: Thu, 25 Jun 2026 15:27:02 +0200
Subject: [PATCH 23/23] Use cached tuple check nodes
---
.../builtins/modules/BuiltinFunctions.java | 4 +++-
.../modules/GraalPythonModuleBuiltins.java | 17 ++++++++------
.../builtins/modules/PosixModuleBuiltins.java | 21 +++++++++++------
.../PosixSubprocessModuleBuiltins.java | 4 +++-
.../modules/SocketModuleBuiltins.java | 4 +++-
.../builtins/modules/SysModuleBuiltins.java | 4 +++-
.../builtins/modules/TimeModuleBuiltins.java | 10 +++++---
.../modules/WarningsModuleBuiltins.java | 4 ++--
.../cext/PythonCextObjectBuiltins.java | 5 ++--
.../modules/cjkcodecs/MultibyteCodecUtil.java | 8 ++++---
.../modules/codecs/ErrorHandlers.java | 7 ++++--
.../modules/functools/PartialBuiltins.java | 4 ++--
.../builtins/modules/io/BytesIOBuiltins.java | 4 +++-
.../io/IncrementalNewlineDecoderBuiltins.java | 11 +++++----
.../builtins/modules/io/StringIOBuiltins.java | 4 +++-
.../modules/io/TextIOWrapperBuiltins.java | 10 ++++----
.../modules/io/TextIOWrapperNodes.java | 5 ++--
.../modules/json/JSONEncoderBuiltins.java | 6 +++--
.../modules/pickle/PicklerBuiltins.java | 4 +++-
.../objects/PythonAbstractObject.java | 13 ++++++++---
.../objects/bytes/BytesCommonBuiltins.java | 4 +++-
.../builtins/objects/code/CodeBuiltins.java | 16 +++++++------
.../objects/common/SequenceNodes.java | 9 ++++++--
.../objects/dict/DictViewBuiltins.java | 13 +++++++----
.../exception/PrepareExceptionNode.java | 7 ++++--
.../function/AbstractFunctionBuiltins.java | 10 +++++---
.../objects/function/FunctionBuiltins.java | 23 ++++++++++++-------
.../objects/iterator/IteratorNodes.java | 4 +++-
.../mappingproxy/MappingproxyBuiltins.java | 5 ++--
.../memoryview/MemoryViewBuiltins.java | 5 ++--
.../objects/memoryview/MemoryViewNodes.java | 7 ++++--
.../builtins/objects/object/ObjectNodes.java | 9 +++++---
.../objects/random/RandomBuiltins.java | 5 ++--
.../builtins/objects/socket/SocketNodes.java | 7 ++++--
.../builtins/objects/str/StringBuiltins.java | 6 +++--
.../objects/thread/RLockBuiltins.java | 5 ++--
.../builtins/objects/type/TypeBuiltins.java | 14 +++++++----
.../builtins/objects/type/TypeNodes.java | 4 +++-
.../objects/typing/TypeAliasTypeBuiltins.java | 4 +++-
.../python/lib/PyErrExceptionMatchesNode.java | 3 ++-
.../graal/python/lib/PyMappingCheckNode.java | 6 ++++-
.../python/lib/PyObjectIsInstanceNode.java | 3 ++-
.../python/lib/PyObjectIsSubclassNode.java | 3 ++-
.../lib/PyObjectRecursiveBinaryCheckNode.java | 9 +++++---
.../graal/python/lib/PySequenceCheckNode.java | 5 ----
.../graal/python/lib/PyTupleCheckNode.java | 14 +++++++++--
.../oracle/graal/python/nodes/PGuards.java | 10 --------
.../python/nodes/builtins/TupleNodes.java | 4 ++--
.../classes/AbstractObjectGetBasesNode.java | 5 ++--
.../nodes/exception/ExceptMatchNode.java | 13 +++++++----
.../builtins/clinic/TupleConversionNode.java | 5 ++--
51 files changed, 249 insertions(+), 137 deletions(-)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java
index d1aae5a9b1..56772accb8 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java
@@ -205,6 +205,7 @@
import com.oracle.graal.python.lib.PyObjectSizeNode;
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
@@ -2139,6 +2140,7 @@ static Object[] update(Object[] bases,
@Bind PythonLanguage language,
@Cached PyObjectLookupAttr getMroEntries,
@Cached CallUnaryMethodNode callMroEntries,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached PyTupleSizeNode tupleSize,
@Cached PyTupleGetItem tupleGetItem,
@Cached PRaiseNode raiseNode) {
@@ -2167,7 +2169,7 @@ static Object[] update(Object[] bases,
originalBases = PFactory.createTuple(language, bases);
}
Object newBase = callMroEntries.executeObject(null, meth, originalBases);
- if (!PGuards.isTuple(newBase)) {
+ if (!tupleCheckNode.execute(inliningTarget, newBase)) {
throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.MRO_ENTRIES_MUST_RETURN_TUPLE);
}
if (newBases == null) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java
index 3da2e8595f..93730906d9 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java
@@ -142,9 +142,9 @@
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
import com.oracle.graal.python.lib.PyObjectGetItem;
import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
-import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.arrow.ArrowArray;
import com.oracle.graal.python.nodes.arrow.ArrowSchema;
@@ -1021,8 +1021,9 @@ public abstract static class GetStorageStrategyNode extends PythonUnaryBuiltinNo
@Specialization
@TruffleBoundary
static TruffleString doSet(Object object,
- @Bind Node inliningTarget) {
- if (PGuards.isTupleOrList(object)) {
+ @Bind Node inliningTarget,
+ @Cached PyTupleCheckNode tupleCheckNode) {
+ if (tupleCheckNode.isTupleOrList(inliningTarget, object)) {
SequenceStorage sequenceStorage = GetSequenceStorageNode.executeUncached(object);
return PythonUtils.toTruffleStringUncached(sequenceStorage.getClass().getSimpleName());
}
@@ -1037,12 +1038,13 @@ abstract static class StorageToNative extends PythonUnaryBuiltinNode {
@TruffleBoundary
@Specialization
static Object doGeneric(Object object,
- @Bind Node inliningTarget) {
+ @Bind Node inliningTarget,
+ @Cached PyTupleCheckNode tupleCheckNode) {
if (object instanceof PArray array) {
array.setSequenceStorage(ToNativeStorageNode.executeUncached(array.getSequenceStorage(), true));
} else if (object instanceof PSequence sequence) {
sequence.setSequenceStorage(ToNativeStorageNode.executeUncached(sequence.getSequenceStorage(), sequence instanceof PBytesLike));
- } else if (!PGuards.isTupleOrList(object)) {
+ } else if (!tupleCheckNode.isTupleOrList(inliningTarget, object)) {
throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC);
}
return object;
@@ -1056,13 +1058,14 @@ abstract static class StorageToNativePrimitive extends PythonUnaryBuiltinNode {
@TruffleBoundary
@Specialization
static Object doGeneric(Object object,
- @Bind Node inliningTarget) {
+ @Bind Node inliningTarget,
+ @Cached PyTupleCheckNode tupleCheckNode) {
CApiContext.ensureCapiWasLoaded("internal API");
if (object instanceof PArray array) {
array.setSequenceStorage(ToNativePrimitiveStorageNode.executeUncached(array.getSequenceStorage()));
} else if (object instanceof PSequence sequence) {
sequence.setSequenceStorage(ToNativePrimitiveStorageNode.executeUncached(sequence.getSequenceStorage()));
- } else if (!PGuards.isTupleOrList(object)) {
+ } else if (!tupleCheckNode.isTupleOrList(inliningTarget, object)) {
throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BAD_ARG_TO_INTERNAL_FUNC);
}
return object;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java
index bdf6854591..b54fc9dc13 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java
@@ -94,6 +94,7 @@
import com.oracle.graal.python.lib.PyObjectGetAttr;
import com.oracle.graal.python.lib.PyObjectGetItem;
import com.oracle.graal.python.lib.PyObjectSizeNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
@@ -510,6 +511,7 @@ static Object execvArgs(VirtualFrame frame, PosixPath path, Object argv,
@CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@Cached InlinedConditionProfile isPListProfile,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached ToArrayNode toArrayNode,
@Cached ObjectToOpaquePathNode toOpaquePathNode,
@Cached SysModuleBuiltins.AuditNode auditNode,
@@ -520,7 +522,7 @@ static Object execvArgs(VirtualFrame frame, PosixPath path, Object argv,
SequenceStorage argvStorage;
if (isPListProfile.profile(inliningTarget, argv instanceof PList)) {
argvStorage = ((PList) argv).getSequenceStorage();
- } else if (PGuards.isTuple(argv)) {
+ } else if (tupleCheckNode.execute(inliningTarget, argv)) {
argvStorage = getTupleStorage.execute(inliningTarget, argv);
} else {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S, "execv()", 2, "tuple or list");
@@ -2035,9 +2037,10 @@ static long[] now(VirtualFrame frame, PNone times, PNone ns) {
return null;
}
- @Specialization(guards = {"isTuple(times)", "isNoValue(ns)"})
+ @Specialization(guards = {"tupleCheckNode.execute(inliningTarget, times)", "isNoValue(ns)"}, limit = "1")
static long[] times(VirtualFrame frame, Object times, @SuppressWarnings("unused") PNone ns,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached TupleNodes.GetTupleStorage getTupleStorage,
@Exclusive @Cached SequenceStorageNodes.GetItemScalarNode getItemNode,
@Cached ObjectToTimespecNode objectToTimespecNode,
@@ -2045,9 +2048,10 @@ static long[] times(VirtualFrame frame, Object times, @SuppressWarnings("unused"
return convertToTimespec(frame, inliningTarget, getTupleStorage.execute(inliningTarget, times), getItemNode, objectToTimespecNode, raiseNode);
}
- @Specialization(guards = "isTuple(ns)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, ns)", limit = "1")
static long[] ns(VirtualFrame frame, @SuppressWarnings("unused") PNone times, Object ns,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached TupleNodes.GetTupleStorage getTupleStorage,
@Exclusive @Cached SequenceStorageNodes.GetItemScalarNode getItemNode,
@Cached SplitLongToSAndNsNode splitLongToSAndNsNode,
@@ -2062,18 +2066,20 @@ static long[] bothSpecified(VirtualFrame frame, Object times, Object ns,
throw PRaiseNode.raiseStatic(inliningTarget, ValueError, ErrorMessages.YOU_MAY_SPECIFY_EITHER_OR_BUT_NOT_BOTH, "utime", "times", "ns");
}
- @Specialization(guards = {"!isPNone(times)", "!isTuple(times)", "isNoValue(ns)"})
+ @Specialization(guards = {"!isPNone(times)", "!tupleCheckNode.execute(inliningTarget, times)", "isNoValue(ns)"}, limit = "1")
@SuppressWarnings("unused")
static long[] timesNotATuple(VirtualFrame frame, Object times, PNone ns,
@Bind Node inliningTarget,
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached PRaiseNode raiseNode) {
throw timesTupleError(inliningTarget, raiseNode);
}
- @Specialization(guards = {"!isNoValue(ns)", "!isTuple(ns)"})
+ @Specialization(guards = {"!isNoValue(ns)", "!tupleCheckNode.execute(inliningTarget, ns)"}, limit = "1")
@SuppressWarnings("unused")
static long[] nsNotATuple(VirtualFrame frame, PNone times, Object ns,
- @Bind Node inliningTarget) {
+ @Bind Node inliningTarget,
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode) {
// ns can actually also contain objects implementing __divmod__, but CPython produces
// this error message
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.MUST_BE, "utime", "ns", "a tuple of two ints");
@@ -3264,11 +3270,12 @@ static void doLong(long value, long[] timespec, int offset) {
static void doGeneric(VirtualFrame frame, Node inliningTarget, Object value, long[] timespec, int offset,
@Cached PyNumberDivmodNode divmodNode,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached(value = "createNotNormalized()", inline = false) GetItemNode getItemNode,
@Cached PyLongAsLongNode asLongNode,
@Cached PRaiseNode raiseNode) {
Object divmod = divmodNode.execute(frame, inliningTarget, value, BILLION);
- if (PGuards.isTuple(divmod)) {
+ if (tupleCheckNode.execute(inliningTarget, divmod)) {
SequenceStorage storage = getTupleStorage.execute(inliningTarget, divmod);
if (storage.length() == 2) {
timespec[offset] = asLongNode.execute(frame, inliningTarget, getItemNode.execute(storage, 0));
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java
index 85b9ddf4c7..519654fa9d 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java
@@ -65,6 +65,7 @@
import com.oracle.graal.python.builtins.objects.list.PList;
import com.oracle.graal.python.lib.PyObjectGetItem;
import com.oracle.graal.python.lib.PyObjectSizeNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
import com.oracle.graal.python.nodes.PGuards;
@@ -253,6 +254,7 @@ static int forkExec(VirtualFrame frame, Object[] args, Object executableList, bo
@Bind Node inliningTarget,
@Cached("createNotNormalized()") GetItemNode tupleGetItem,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached PyObjectGetItem getItem,
@Cached CastToJavaIntExactNode castToIntNode,
@Cached ObjectToOpaquePathNode objectToOpaquePathNode,
@@ -267,7 +269,7 @@ static int forkExec(VirtualFrame frame, Object[] args, Object executableList, bo
if (closeFds && errPipeWrite < 3) {
throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.S_MUST_BE_S, "errpipe_write", ">= 3");
}
- if (!PGuards.isTuple(fdsToKeepObj)) {
+ if (!tupleCheckNode.execute(inliningTarget, fdsToKeepObj)) {
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "fork_exec()", 4, "tuple", fdsToKeepObj);
}
Object[] processArgs = args;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java
index 68b41767e4..765a7ab0e2 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java
@@ -88,6 +88,7 @@
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.lib.PyLongAsIntNode;
import com.oracle.graal.python.lib.PyLongAsLongNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
import com.oracle.graal.python.nodes.PGuards;
@@ -548,10 +549,11 @@ protected ArgumentClinicProvider getArgumentClinic() {
@GenerateNodeFactory
@ImportStatic(PGuards.class)
public abstract static class GetNameInfoNode extends PythonBinaryClinicBuiltinNode {
- @Specialization(guards = "isTuple(sockaddr)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, sockaddr)", limit = "1")
static Object getNameInfo(VirtualFrame frame, Object sockaddr, int flags,
@Bind Node inliningTarget,
@Bind PythonContext context,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached GetTupleStorage getTupleStorage,
@CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib,
@CachedLibrary(limit = "1") AddrInfoCursorLibrary addrInfoCursorLib,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java
index d2adb637f9..bbd4d5ee00 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java
@@ -220,6 +220,7 @@
import com.oracle.graal.python.lib.PyObjectSetAttr;
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
import com.oracle.graal.python.lib.PyTraceBackPrint;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyUnicodeAsEncodedString;
import com.oracle.graal.python.lib.PyUnicodeFromEncodedObject;
@@ -2252,9 +2253,10 @@ static Object exitNoCode(PythonModule sys, PNone status,
static Object exit(VirtualFrame frame, @SuppressWarnings("unused") PythonModule sys, Object status,
@Bind Node inliningTarget,
@Cached TupleBuiltins.LenNode tupleLenNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached PyTupleGetItem getItemNode) {
Object code = status;
- if (PGuards.isTuple(status)) {
+ if (tupleCheckNode.execute(inliningTarget, status)) {
if (tupleLenNode.executeInt(frame, status) == 1) {
code = getItemNode.execute(inliningTarget, status, 0);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java
index ac7dd84845..0b6665fb07 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java
@@ -74,6 +74,7 @@
import com.oracle.graal.python.lib.PyLongAsLongNode;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PNodeWithContext;
@@ -991,9 +992,10 @@ static TruffleString formatTime(PythonModule module, TruffleString format, @Supp
return format(toJavaStringNode.execute(format), getIntLocalTimeStruct(moduleState.currentZoneId, (long) timeSeconds()), getTimeZone(moduleState.currentZoneId), fromJavaStringNode);
}
- @Specialization(guards = "isTuple(time)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, time)", limit = "1")
static TruffleString formatTime(VirtualFrame frame, PythonModule module, TruffleString format, Object time,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@Cached PyNumberAsSizeNode asSizeNode,
@@ -1024,9 +1026,10 @@ abstract static class MkTimeNode extends PythonBinaryBuiltinNode {
private static final int ELEMENT_COUNT = 9;
@ExplodeLoop
- @Specialization(guards = "isTuple(tuple)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, tuple)", limit = "1")
static double mktime(VirtualFrame frame, PythonModule module, Object tuple,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached GetTupleStorage getTupleStorage,
@Cached PyNumberAsSizeNode asSizeNode,
@Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@@ -1093,9 +1096,10 @@ static TruffleString localtime(PythonModule module, @SuppressWarnings("unused")
return format(getIntLocalTimeStruct(moduleState.currentZoneId, (long) timeSeconds()), fromJavaStringNode);
}
- @Specialization(guards = "isTuple(time)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, time)", limit = "1")
static TruffleString localtime(VirtualFrame frame, @SuppressWarnings("unused") PythonModule module, Object time,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@Cached PyNumberAsSizeNode asSizeNode,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java
index e6e7f1eec6..d8ca582b2c 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java
@@ -103,7 +103,6 @@
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
-import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.SpecialAttributeNames;
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode;
@@ -1003,11 +1002,12 @@ Object doWarn(VirtualFrame frame, PythonModule mod, Object message, Object categ
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
@Cached StringNodes.CastToTruffleStringChecked1Node castToStringChecked,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached PRaiseNode raiseNode,
@Cached WarningsModuleNode moduleFunctionsNode) {
// warnings_warn_impl
TruffleString[] skipFilePrefixes = null;
- if (PGuards.isTuple(skipFilePrefixesObj)) {
+ if (tupleCheckNode.execute(inliningTarget, skipFilePrefixesObj)) {
SequenceStorage storage = getTupleStorage.execute(inliningTarget, skipFilePrefixesObj);
if (storage.length() > 0) {
skipFilePrefixes = new TruffleString[storage.length()];
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextObjectBuiltins.java
index 1b14c47d69..b7541a0397 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextObjectBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextObjectBuiltins.java
@@ -119,9 +119,9 @@
import com.oracle.graal.python.lib.PyObjectReprAsObjectNode;
import com.oracle.graal.python.lib.PyObjectSetItem;
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.BuiltinNames;
import com.oracle.graal.python.nodes.ErrorMessages;
-import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.StringLiterals;
import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode;
@@ -305,6 +305,7 @@ static Object doGeneric(@SuppressWarnings("unused") long threadState, Object cal
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
@Cached CallNode callNode,
@Cached GetTupleStorage getTupleStorage,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached CastToTruffleStringNode castToTruffleStringNode) {
try {
@@ -314,7 +315,7 @@ static Object doGeneric(@SuppressWarnings("unused") long threadState, Object cal
keywords = PKeyword.EMPTY_KEYWORDS;
} else if (kwargs instanceof PDict) {
keywords = castKwargsNode.execute(inliningTarget, kwargs);
- } else if (PGuards.isTuple(kwargs)) {
+ } else if (tupleCheckNode.execute(inliningTarget, kwargs)) {
// We have a tuple with kw names and an array with kw values
SequenceStorage storage = getTupleStorage.execute(inliningTarget, kwargs);
int kwcount = storage.length();
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java
index 992f0d3226..e3971e0d70 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cjkcodecs/MultibyteCodecUtil.java
@@ -80,8 +80,8 @@
import com.oracle.graal.python.lib.PyBytesCheckNode;
import com.oracle.graal.python.lib.PyLongAsIntNode;
import com.oracle.graal.python.lib.PyLongCheckNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
-import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes;
import com.oracle.graal.python.nodes.call.CallNode;
@@ -179,6 +179,7 @@ static int encerror(VirtualFrame frame, MultibyteCodec codec,
@Cached PyLongCheckNode longCheckNode,
@Cached PyBytesCheckNode bytesCheckNode,
@Cached PyLongAsIntNode asSizeNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached CallErrorCallbackNode callErrorCallbackNode,
@Cached BytesNodes.ToBytesNode toBytesNode,
@Cached EncodeNode encodeNode,
@@ -251,7 +252,7 @@ static int encerror(VirtualFrame frame, MultibyteCodec codec,
Object retobj = callErrorCallbackNode.execute(frame, inliningTarget, errors, buf.excobj);
- boolean isError = !PGuards.isTuple(retobj);
+ boolean isError = !tupleCheckNode.execute(inliningTarget, retobj);
Object tobj = null;
Object newposobj = null;
boolean isUnicode = false;
@@ -330,6 +331,7 @@ static void decerror(VirtualFrame frame, MultibyteCodec codec,
@Cached PyUnicodeCheckNode unicodeCheckNode,
@Cached PyLongCheckNode longCheckNode,
@Cached PyLongAsIntNode asSizeNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached CastToJavaStringNode toString,
@Cached CallErrorCallbackNode callErrorCallbackNode,
@Cached PRaiseNode raiseNode) {
@@ -385,7 +387,7 @@ static void decerror(VirtualFrame frame, MultibyteCodec codec,
Object retobj = callErrorCallbackNode.execute(frame, inliningTarget, errors, buf.excobj);
- boolean isError = !PGuards.isTuple(retobj);
+ boolean isError = !tupleCheckNode.execute(inliningTarget, retobj);
Object retuni = null;
Object newposobj = null;
if (!isError) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java
index 3e55f00ad2..445cc11c6d 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java
@@ -84,6 +84,7 @@
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectSizeNode;
import com.oracle.graal.python.lib.PyObjectTypeCheck;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
@@ -851,8 +852,9 @@ public static final class DecodingErrorHandlerResult {
abstract static class ParseDecodingErrorHandlerResultNode extends Node {
abstract DecodingErrorHandlerResult execute(VirtualFrame frame, Node inliningTarget, Object result);
- @Specialization(guards = "isTuple(result)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, result)", limit = "1")
static DecodingErrorHandlerResult doTuple(VirtualFrame frame, Node inliningTarget, Object result,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
@Cached CastToTruffleStringChecked0Node castToTruffleStringCheckedNode,
@@ -926,8 +928,9 @@ public static final class EncodingErrorHandlerResult {
abstract static class ParseEncodingErrorHandlerResultNode extends Node {
abstract EncodingErrorHandlerResult execute(Frame frame, Node inliningTarget, Object result);
- @Specialization(guards = "isTuple(result)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, result)", limit = "1")
static EncodingErrorHandlerResult doTuple(VirtualFrame frame, Node inliningTarget, Object result,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
@Cached PyNumberAsSizeNode asSizeNode,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java
index 17f9619253..c5972269ae 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/functools/PartialBuiltins.java
@@ -363,7 +363,7 @@ static Object setState(VirtualFrame frame, PPartial self, Object state,
@Cached HashingStorageCopy copyStorageNode,
@Bind PythonLanguage language,
@Cached PRaiseNode raiseNode) {
- if (!PGuards.isTuple(state) || getTupleStorage.execute(inliningTarget, state).length() != 4) {
+ if (!tupleCheckNode.execute(inliningTarget, state) || getTupleStorage.execute(inliningTarget, state).length() != 4) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, INVALID_PARTIAL_STATE);
}
@@ -373,7 +373,7 @@ static Object setState(VirtualFrame frame, PPartial self, Object state,
final Object dict = getItemNode.execute(inliningTarget, state, 3);
if (!callableCheckNode.execute(inliningTarget, function) ||
- !PGuards.isTuple(fnArgs) ||
+ !tupleCheckNode.execute(inliningTarget, fnArgs) ||
(fnKwargs != PNone.NONE && !PGuards.isDict(fnKwargs))) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, INVALID_PARTIAL_STATE);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java
index 47aefd399c..5bc9da8838 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java
@@ -106,6 +106,7 @@
import com.oracle.graal.python.lib.PyMemoryViewFromObject;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectGetIter;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
@@ -671,8 +672,9 @@ static Object doit(VirtualFrame frame, PBytesIO self, Object state,
@Cached PyNumberAsSizeNode asSizeNode,
@Cached GetOrCreateDictNode getDict,
@Cached HashingStorageAddAllToOther addAllToOtherNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached PRaiseNode raiseNode) {
- if (!PGuards.isTuple(state)) {
+ if (!tupleCheckNode.execute(inliningTarget, state)) {
throw raiseNode.raise(inliningTarget, TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 3, state);
}
self.checkExports(inliningTarget, raiseNode);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java
index 8036aea8bf..3c8cb85c1c 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IncrementalNewlineDecoderBuiltins.java
@@ -53,7 +53,6 @@
import static com.oracle.graal.python.builtins.modules.io.IONodes.T_SETSTATE;
import static com.oracle.graal.python.nodes.ErrorMessages.ILLEGAL_STATE_ARGUMENT;
import static com.oracle.graal.python.nodes.ErrorMessages.STATE_ARGUMENT_MUST_BE_A_TUPLE;
-import static com.oracle.graal.python.nodes.PGuards.isTuple;
import static com.oracle.graal.python.nodes.StringLiterals.T_CR;
import static com.oracle.graal.python.nodes.StringLiterals.T_CRLF;
import static com.oracle.graal.python.nodes.StringLiterals.T_NEWLINE;
@@ -80,6 +79,7 @@
import com.oracle.graal.python.lib.PyIndexCheckNode;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -324,9 +324,10 @@ static Object withDecoder(VirtualFrame frame, PNLDecoder self,
@Cached PyIndexCheckNode indexCheckNode,
@Cached PyNumberAsSizeNode asSizeNode,
@Cached PyObjectCallMethodObjArgs callMethod,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached PRaiseNode raiseNode) {
Object state = callMethod.execute(frame, inliningTarget, self.getDecoder(), T_GETSTATE);
- if (!isTuple(state)) {
+ if (!tupleCheckNode.execute(inliningTarget, state)) {
throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_STATE_ARGUMENT);
}
Object[] objects = getObjectArrayNode.execute(inliningTarget, state);
@@ -353,8 +354,9 @@ static Object noDecoder(VirtualFrame frame, PNLDecoder self, Object state,
@Exclusive @Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray,
@Exclusive @Cached PyIndexCheckNode indexCheckNode,
@Exclusive @Cached PyNumberAsSizeNode asSizeNode,
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached PRaiseNode raiseNode) {
- if (!isTuple(state)) {
+ if (!tupleCheckNode.execute(inliningTarget, state)) {
return err(self, state, inliningTarget);
}
SequenceStorage storage = getTupleStorage.execute(inliningTarget, state);
@@ -379,8 +381,9 @@ static Object withDecoder(VirtualFrame frame, PNLDecoder self, Object state,
@Exclusive @Cached PyIndexCheckNode indexCheckNode,
@Exclusive @Cached PyNumberAsSizeNode asSizeNode,
@Cached PyObjectCallMethodObjArgs callMethod,
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached PRaiseNode raiseNode) {
- if (!isTuple(state)) {
+ if (!tupleCheckNode.execute(inliningTarget, state)) {
return err(self, state, inliningTarget);
}
SequenceStorage storage = getTupleStorage.execute(inliningTarget, state);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java
index 567712aef4..84b2bc626f 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/StringIOBuiltins.java
@@ -108,6 +108,7 @@
import com.oracle.graal.python.lib.PyNumberIndexNode;
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
import com.oracle.graal.python.lib.PyObjectGetAttr;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
@@ -674,8 +675,9 @@ static Object doit(VirtualFrame frame, PStringIO self, Object state,
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
@Cached TruffleStringBuilder.AppendStringNode appendStringNode,
@Cached HashingStorageAddAllToOther addAllToOtherNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached PRaiseNode raiseNode) {
- if (!PGuards.isTuple(state)) {
+ if (!tupleCheckNode.execute(inliningTarget, state)) {
throw raiseNode.raise(inliningTarget, TypeError, P_SETSTATE_ARGUMENT_SHOULD_BE_D_TUPLE_GOT_P, self, 4, state);
}
SequenceStorage storage = getTupleStorage.execute(inliningTarget, state);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java
index 40a05b9ecb..48cdb1c5ef 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperBuiltins.java
@@ -117,7 +117,6 @@
import static com.oracle.graal.python.nodes.ErrorMessages.UNDERLYING_STREAM_IS_NOT_SEEKABLE;
import static com.oracle.graal.python.nodes.PGuards.isNoValue;
import static com.oracle.graal.python.nodes.PGuards.isPNone;
-import static com.oracle.graal.python.nodes.PGuards.isTuple;
import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING;
import static com.oracle.graal.python.nodes.StringLiterals.T_NEWLINE;
import static com.oracle.graal.python.runtime.exception.PythonErrorType.OSError;
@@ -158,6 +157,7 @@
import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
import com.oracle.graal.python.lib.PyObjectSizeNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.RichCmpOp;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -926,6 +926,7 @@ static Object tell(VirtualFrame frame, PTextIO self,
@Cached PyNumberAsSizeNode asSizeNode,
@Exclusive @Cached PyLongAsLongNode asLongNode,
@Cached PyObjectSizeNode sizeNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@CachedLibrary(limit = "2") InteropLibrary isString,
@Cached PRaiseNode raiseNode) {
PTextIO.CookieType cookie = getCookie(frame, inliningTarget, self, writeFlushNode, callMethodFlush, callMethodTell, asLongNode);
@@ -945,7 +946,7 @@ static Object tell(VirtualFrame frame, PTextIO self,
PBytes in = PFactory.createBytes(language, snapshotNextInput, skipBytes);
int charsDecoded = decoderDecode(frame, inliningTarget, self, in, callMethodDecode, toString, codePointLengthNode);
if (charsDecoded <= decodedCharsUsed) {
- Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, raiseNode);
+ Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, tupleCheckNode, raiseNode);
int decFlags = asSizeNode.executeExact(frame, inliningTarget, state[1]);
int decBufferLen = sizeNode.execute(frame, inliningTarget, state[0]);
if (decBufferLen == 0) {
@@ -987,7 +988,7 @@ static Object tell(VirtualFrame frame, PTextIO self,
/* We got n chars for 1 byte */
charsDecoded += n;
cookie.bytesToFeed += 1;
- Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, raiseNode);
+ Object[] state = decoderGetstate(frame, inliningTarget, self, savedState, getObjectArrayNode, callMethodGetState, callMethodSetState, tupleCheckNode, raiseNode);
int decFlags = asSizeNode.executeExact(frame, inliningTarget, state[1]);
int decBufferLen = sizeNode.execute(frame, inliningTarget, state[0]);
@@ -1038,9 +1039,10 @@ static Object[] decoderGetstate(VirtualFrame frame, Node inliningTarget, PTextIO
SequenceNodes.GetObjectArrayNode getArray,
PyObjectCallMethodObjArgs callMethodGetState,
PyObjectCallMethodObjArgs callMethodSetState,
+ PyTupleCheckNode tupleCheckNode,
PRaiseNode raiseNode) {
Object state = callMethodGetState.execute(frame, inliningTarget, self.getDecoder(), T_GETSTATE);
- if (!isTuple(state)) {
+ if (!tupleCheckNode.execute(inliningTarget, state)) {
fail(frame, inliningTarget, self, saved_state, callMethodSetState);
throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_DECODER_STATE);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java
index a5bfe7db94..30fa8ea2c5 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java
@@ -66,7 +66,6 @@
import static com.oracle.graal.python.nodes.ErrorMessages.NOT_READABLE;
import static com.oracle.graal.python.nodes.ErrorMessages.S_SHOULD_HAVE_RETURNED_A_BYTES_LIKE_OBJECT_NOT_P;
import static com.oracle.graal.python.nodes.PGuards.isPNone;
-import static com.oracle.graal.python.nodes.PGuards.isTuple;
import static com.oracle.graal.python.nodes.SpecialMethodNames.T_DECODE;
import static com.oracle.graal.python.nodes.StringLiterals.T_CRLF;
import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING;
@@ -96,6 +95,7 @@
import com.oracle.graal.python.lib.PyObjectIsTrueNode;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PNodeWithContext;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -508,6 +508,7 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self,
@Cached PyObjectCallMethodObjArgs callMethodGetState,
@Cached PyObjectCallMethodObjArgs callMethodRead,
@Cached PyNumberAsSizeNode asSizeNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
@CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib,
@CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib,
@@ -530,7 +531,7 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self,
* Given this, we know there was a valid snapshot point len(decBuffer) bytes ago
* with decoder state (b'', decFlags).
*/
- if (!isTuple(state)) {
+ if (!tupleCheckNode.execute(inliningTarget, state)) {
throw raiseNode.raise(inliningTarget, TypeError, ILLEGAL_DECODER_STATE);
}
Object[] array = getArray.execute(inliningTarget, state);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java
index fae35ffe7f..f8edd3fe1e 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONEncoderBuiltins.java
@@ -58,6 +58,7 @@
import com.oracle.graal.python.lib.PyListCheckExactNode;
import com.oracle.graal.python.lib.PyObjectGetIter;
import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleCheckExactNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
@@ -188,6 +189,7 @@ PTuple call(VirtualFrame frame, PJSONEncoder self, Object obj, @SuppressWarnings
@Cached InlinedBranchProfile errorProfile,
@Cached GetClassNode getClassNode,
@Cached IsSubtypeNode isSubtypeNode,
+ @Cached PyTupleCheckNode pyTupleCheckNode,
@Cached PyTupleCheckExactNode pyTupleCheckExactNode,
@Cached PyListCheckExactNode pyListCheckExactNode,
@Cached ConstructListNode constructListNode,
@@ -279,7 +281,7 @@ PTuple call(VirtualFrame frame, PJSONEncoder self, Object obj, @SuppressWarnings
stackStorage = null;
stackIterator = genericIterator;
}
- } else if (PGuards.isTuple(value)) {
+ } else if (pyTupleCheckNode.execute(inliningTarget, value)) {
appendCodePointNode.execute(builder, '[');
first = true;
if (pyTupleCheckExactNode.execute(inliningTarget, value)) {
@@ -353,7 +355,7 @@ PTuple call(VirtualFrame frame, PJSONEncoder self, Object obj, @SuppressWarnings
Object item = pyIterNextNode.execute(frame, inliningTarget, genericIterator);
if (state == STATE_GENERIC_DICT) {
genericDictProfile.enter(inliningTarget);
- if (!PGuards.isTuple(item)) {
+ if (!pyTupleCheckNode.execute(inliningTarget, item)) {
errorProfile.enter(inliningTarget);
throw PRaiseNode.raiseStatic(this, ValueError, ErrorMessages.ITEMS_MUST_RETURN_2_TUPLES);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java
index ef52dc4b77..59310a5f1a 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PicklerBuiltins.java
@@ -77,6 +77,7 @@
import com.oracle.graal.python.lib.PyLongAsLongNode;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -271,6 +272,7 @@ static Object get(PPickler self, @SuppressWarnings("unused") PNone none,
static Object set(VirtualFrame frame, PPickler self, Object obj,
@Bind Node inliningTarget,
@Cached PyNumberAsSizeNode asSizeNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached PyTupleSizeNode sizeNode,
@Cached PyTupleGetItem getItemNode,
@Cached HashingStorageGetIterator getIter,
@@ -287,7 +289,7 @@ static Object set(VirtualFrame frame, PPickler self, Object obj,
HashingStorageIterator it = getIter.execute(inliningTarget, dictStorage);
while (iterNext.execute(inliningTarget, dictStorage, it)) {
Object value = iterValue.execute(inliningTarget, dictStorage, it);
- if (!PGuards.isTuple(value) || sizeNode.execute(inliningTarget, value) != 2) {
+ if (!tupleCheckNode.execute(inliningTarget, value) || sizeNode.execute(inliningTarget, value) != 2) {
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.VALUES_MUST_BE_2TUPLES, "memo");
}
int memoId = asSizeNode.executeExact(frame, inliningTarget, getItemNode.execute(inliningTarget, value, 0));
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java
index 2927b6e257..c225d3c1f0 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java
@@ -109,6 +109,7 @@
import com.oracle.graal.python.lib.PySequenceGetItemNode;
import com.oracle.graal.python.lib.PySequenceSetItemNode;
import com.oracle.graal.python.lib.PySequenceSizeNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.nodes.BuiltinNames;
@@ -850,6 +851,8 @@ public LocalDate asDate(
// GR-44020: make shared:
@Exclusive @Cached PRaiseNode raiseNode,
// GR-44020: make shared:
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
+ // GR-44020: make shared:
@Exclusive @Cached PyTupleSizeNode pyTupleSizeNode,
// GR-44020: make shared:
@Exclusive @Cached PyTupleGetItem tupleGetItem,
@@ -861,7 +864,7 @@ public LocalDate asDate(
InteropBehavior behavior = getBehavior.execute(inliningTarget, this, method);
if (behavior != null) {
Object value = getValue.execute(inliningTarget, behavior, method, this);
- if (PGuards.isTuple(value)) {
+ if (tupleCheckNode.execute(inliningTarget, value)) {
if (pyTupleSizeNode.execute(inliningTarget, value) != 3) {
throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_A_S_TUPLE, "return value", "3");
}
@@ -922,6 +925,8 @@ public LocalTime asTime(
// GR-44020: make shared:
@Exclusive @Cached PRaiseNode raiseNode,
// GR-44020: make shared:
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
+ // GR-44020: make shared:
@Exclusive @Cached PyTupleSizeNode pyTupleSizeNode,
// GR-44020: make shared:
@Exclusive @Cached PyTupleGetItem tupleGetItem,
@@ -933,7 +938,7 @@ public LocalTime asTime(
InteropBehavior behavior = getBehavior.execute(inliningTarget, this, method);
if (behavior != null) {
Object value = getValue.execute(inliningTarget, behavior, method, this);
- if (PGuards.isTuple(value)) {
+ if (tupleCheckNode.execute(inliningTarget, value)) {
if (pyTupleSizeNode.execute(inliningTarget, value) != 4) {
throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_A_S_TUPLE, "return value", "4");
}
@@ -1083,6 +1088,8 @@ public Duration asDuration(
// GR-44020: make shared:
@Exclusive @Cached PRaiseNode raiseNode,
// GR-44020: make shared:
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
+ // GR-44020: make shared:
@Exclusive @Cached PyTupleSizeNode pyTupleSizeNode,
// GR-44020: make shared:
@Exclusive @Cached PyTupleGetItem tupleGetItem,
@@ -1094,7 +1101,7 @@ public Duration asDuration(
InteropBehavior behavior = getBehavior.execute(inliningTarget, this, method);
if (behavior != null) {
Object value = getValue.execute(inliningTarget, behavior, method, this);
- if (PGuards.isTuple(value)) {
+ if (tupleCheckNode.execute(inliningTarget, value)) {
if (pyTupleSizeNode.execute(inliningTarget, value) != 2) {
throw raiseNode.raise(inliningTarget, ValueError, S_MUST_BE_A_S_TUPLE, "return value", "2");
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesCommonBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesCommonBuiltins.java
index c1b9d1983f..f401e4aacb 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesCommonBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesCommonBuiltins.java
@@ -94,6 +94,7 @@
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyNumberIndexNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
@@ -437,8 +438,9 @@ private boolean doIt(VirtualFrame frame, byte[] self, int len, SequenceStorage s
abstract static class PrefixSuffixDispatchNode extends Node {
abstract boolean execute(VirtualFrame frame, Node inliningTarget, PrefixSuffixBaseNode parent, byte[] bytes, int len, Object substrs, int begin, int last);
- @Specialization(guards = "isTuple(substrs)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, substrs)", limit = "1")
static boolean doTuple(VirtualFrame frame, Node inliningTarget, PrefixSuffixBaseNode parent, byte[] bytes, int len, Object substrs, int begin, int last,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached(value = "createToBytesFromTuple()", inline = false) BytesNodes.ToBytesNode tobytes,
@Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode,
@Cached SequenceStorageNodes.GetItemScalarNode getItemNode) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java
index 51833d6870..26ac624882 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java
@@ -61,6 +61,7 @@
import com.oracle.graal.python.lib.PyBytesCheckNode;
import com.oracle.graal.python.lib.PyObjectGetIter;
import com.oracle.graal.python.lib.PyObjectHashNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.RichCmpOp;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
@@ -133,20 +134,21 @@ static PCode call(VirtualFrame frame, @SuppressWarnings("unused") Object cls, in
@Cached GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.ToArrayNode toArrayNode,
@Cached PyBytesCheckNode bytesCheckNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached CastToTruffleStringNode castToTruffleStringNode) {
byte[] codeBytes = getBytes(inliningTarget, codestring, bytesCheckNode, getBytesStorage, bufferLib);
byte[] linetableBytes = getBytes(inliningTarget, linetable, bytesCheckNode, getBytesStorage, bufferLib);
checkBytes(inliningTarget, exceptiontable, bytesCheckNode);
- Object[] constantsArr = getTupleArray(inliningTarget, constants, getTupleStorage, toArrayNode);
+ Object[] constantsArr = getTupleArray(inliningTarget, constants, getTupleStorage, toArrayNode, tupleCheckNode);
TruffleString[] namesArr = objectArrayToTruffleStringArray(inliningTarget,
- getTupleArray(inliningTarget, names, getTupleStorage, toArrayNode), castToTruffleStringNode);
+ getTupleArray(inliningTarget, names, getTupleStorage, toArrayNode, tupleCheckNode), castToTruffleStringNode);
TruffleString[] varnamesArr = objectArrayToTruffleStringArray(inliningTarget,
- getTupleArray(inliningTarget, varnames, getTupleStorage, toArrayNode), castToTruffleStringNode);
+ getTupleArray(inliningTarget, varnames, getTupleStorage, toArrayNode, tupleCheckNode), castToTruffleStringNode);
TruffleString[] freevarsArr = objectArrayToTruffleStringArray(inliningTarget,
- getTupleArray(inliningTarget, freevars, getTupleStorage, toArrayNode), castToTruffleStringNode);
+ getTupleArray(inliningTarget, freevars, getTupleStorage, toArrayNode, tupleCheckNode), castToTruffleStringNode);
TruffleString[] cellcarsArr = objectArrayToTruffleStringArray(inliningTarget,
- getTupleArray(inliningTarget, cellvars, getTupleStorage, toArrayNode), castToTruffleStringNode);
+ getTupleArray(inliningTarget, cellvars, getTupleStorage, toArrayNode, tupleCheckNode), castToTruffleStringNode);
return createCodeNode.execute(frame, argcount, posonlyargcount, kwonlyargcount,
nlocals, stacksize, flags,
@@ -169,8 +171,8 @@ private static void checkBytes(Node inliningTarget, Object object, PyBytesCheckN
}
private static Object[] getTupleArray(Node inliningTarget, Object object,
- GetTupleStorage getTupleStorage, SequenceStorageNodes.ToArrayNode toArrayNode) {
- if (!PGuards.isTuple(object)) {
+ GetTupleStorage getTupleStorage, SequenceStorageNodes.ToArrayNode toArrayNode, PyTupleCheckNode tupleCheckNode) {
+ if (!tupleCheckNode.execute(inliningTarget, object)) {
throw invalidArgs(inliningTarget);
}
return toArrayNode.execute(inliningTarget, getTupleStorage.execute(inliningTarget, object));
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java
index 7a26e57308..7255a16a7b 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceNodes.java
@@ -52,6 +52,7 @@
import com.oracle.graal.python.builtins.objects.list.PList;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.lib.PySequenceCheckNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PNodeWithContext;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -139,11 +140,15 @@ static SequenceStorage doSequence(Node inliningTarget, PSequence seq,
return getPSequenceStorageNode.execute(inliningTarget, seq);
}
- @Specialization(guards = "isTuple(seq)")
- static SequenceStorage doNativeTuple(@SuppressWarnings("unused") Node inliningTarget, PythonAbstractNativeObject seq) {
+ @Specialization(guards = "isNativeTuple(seq)")
+ static SequenceStorage doNativeTuple(PythonAbstractNativeObject seq) {
return GetTupleStorage.doNative(seq);
}
+ static boolean isNativeTuple(PythonAbstractNativeObject seq) {
+ return PyTupleCheckNode.checkNative(seq);
+ }
+
// Note: this does not seem currently used but is good to accept foreign lists in more
// places
@Specialization(guards = {"isForeignObjectNode.execute(inliningTarget, seq)", "interop.hasArrayElements(seq)"}, limit = "1")
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictViewBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictViewBuiltins.java
index c97b4631f2..a203480f5d 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictViewBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictViewBuiltins.java
@@ -97,6 +97,7 @@
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
import com.oracle.graal.python.lib.PyObjectSizeNode;
import com.oracle.graal.python.lib.PySequenceContainsNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.RichCmpOp;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PNodeWithContext;
@@ -225,9 +226,10 @@ static boolean contains(VirtualFrame frame, PDictKeysView self, Object key,
return getItem.hasKey(frame, inliningTarget, self.getWrappedStorage(), key);
}
- @Specialization(guards = "isTuple(key)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, key)", limit = "1")
static boolean contains(VirtualFrame frame, PDictItemsView self, Object key,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached HashingStorageGetItem getItem,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached PyObjectRichCompareBool eqNode,
@@ -246,14 +248,15 @@ static boolean contains(VirtualFrame frame, PDictItemsView self, Object key,
}
}
- protected static boolean isFallback(Node inliningTarget, Object self, Object key) {
- return !(self instanceof PDictView) || self instanceof PDictItemsView && !PGuards.isTuple(key);
+ protected static boolean isFallback(Node inliningTarget, Object self, Object key, PyTupleCheckNode tupleCheckNode) {
+ return !(self instanceof PDictView) || self instanceof PDictItemsView && !tupleCheckNode.execute(inliningTarget, key);
}
@SuppressWarnings("unused")
- @Specialization(guards = "isFallback(inliningTarget, self, key)")
+ @Specialization(guards = "isFallback(inliningTarget, self, key, tupleCheckNode)", limit = "1")
static boolean contains(Object self, Object key,
- @Bind Node inliningTarget) {
+ @Bind Node inliningTarget,
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode) {
return false;
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PrepareExceptionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PrepareExceptionNode.java
index 753d63a461..66b209c7ff 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PrepareExceptionNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PrepareExceptionNode.java
@@ -50,6 +50,7 @@
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
import com.oracle.graal.python.lib.PyExceptionInstanceCheckNode;
import com.oracle.graal.python.lib.PyObjectIsInstanceNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -96,10 +97,11 @@ static Object doException(@SuppressWarnings("unused") PBaseException exc, @Suppr
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.INSTANCE_EX_MAY_NOT_HAVE_SEP_VALUE);
}
- @Specialization(guards = {"isTypeNode.execute(inliningTarget, type)", "!isPNone(value)", "!isTuple(value)"}, limit = "1")
+ @Specialization(guards = {"isTypeNode.execute(inliningTarget, type)", "!isPNone(value)", "!tupleCheckNode.execute(inliningTarget, value)"}, limit = "1")
static Object doExceptionOrCreate(VirtualFrame frame, Object type, Object value,
@Bind Node inliningTarget,
@SuppressWarnings("unused") @Exclusive @Cached IsTypeNode isTypeNode,
+ @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached PyExceptionInstanceCheckNode check,
@Cached PyObjectIsInstanceNode isInstanceNode,
@Cached InlinedConditionProfile isInstanceProfile,
@@ -136,10 +138,11 @@ static Object doCreate(VirtualFrame frame, Object type, @SuppressWarnings("unuse
}
}
- @Specialization(guards = {"isTypeNode.execute(inliningTarget, type)", "isTuple(value)"}, limit = "1")
+ @Specialization(guards = {"isTypeNode.execute(inliningTarget, type)", "tupleCheckNode.execute(inliningTarget, value)"}, limit = "1")
static Object doCreateTuple(VirtualFrame frame, Object type, Object value,
@Bind Node inliningTarget,
@SuppressWarnings("unused") @Exclusive @Cached IsTypeNode isTypeNode,
+ @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached PyExceptionInstanceCheckNode check,
@Exclusive @Cached GetTupleStorage getTupleStorage,
@Exclusive @Cached SequenceStorageNodes.ToArrayNode toArrayNode,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java
index 8947d6c061..cf21985bf3 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java
@@ -64,6 +64,7 @@
import com.oracle.graal.python.builtins.objects.object.PythonObject;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.lib.PyObjectGetItem;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -83,6 +84,7 @@
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.Cached.Exclusive;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
@@ -272,19 +274,21 @@ static Object getTypeParams(PFunction self, @SuppressWarnings("unused") PNone no
return typeParams;
}
- @Specialization(guards = {"!isBuiltinFunction(self)", "isTuple(value)"})
+ @Specialization(guards = {"!isBuiltinFunction(self)", "tupleCheckNode.execute(inliningTarget, value)"}, limit = "1")
static Object setTypeParams(PFunction self, Object value,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Cached EnsureManagedTupleNode ensureManagedTupleNode,
@Cached WriteAttributeToObjectNode writeObject) {
writeObject.execute(self, T___TYPE_PARAMS__, ensureManagedTupleNode.execute(inliningTarget, value));
return PNone.NONE;
}
- @Specialization(guards = {"!isBuiltinFunction(self)", "!isNoValue(value)", "!isTuple(value)"})
+ @Specialization(guards = {"!isBuiltinFunction(self)", "!isNoValue(value)", "!tupleCheckNode.execute(inliningTarget, value)"}, limit = "1")
@SuppressWarnings("unused")
static Object setNotTuple(PFunction self, Object value,
- @Bind Node inliningTarget) {
+ @Bind Node inliningTarget,
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode) {
throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.MUST_BE_SET_TO_S, J___TYPE_PARAMS__, "tuple");
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java
index 782de28b26..eb0bc2bac3 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java
@@ -74,9 +74,9 @@
import com.oracle.graal.python.builtins.objects.str.PString;
import com.oracle.graal.python.builtins.objects.str.StringNodes;
import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
-import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -126,10 +126,11 @@ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PD
return PFactory.createFunction(language, name, code, globals, null);
}
- @Specialization(guards = "isTuple(closure)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, closure)")
static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, @SuppressWarnings("unused") PNone defaultArgs,
Object closure,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Shared("tupleCheck") @Cached PyTupleCheckNode tupleCheckNode,
@Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
@Shared("toArray") @Cached ToArrayNode toArray,
@Bind PythonLanguage language) {
@@ -145,9 +146,10 @@ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PD
return PFactory.createFunction(language, T_LAMBDA_NAME, code, globals, null);
}
- @Specialization(guards = "isTuple(closure)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, closure)")
static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, @SuppressWarnings("unused") PNone defaultArgs, Object closure,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Shared("tupleCheck") @Cached PyTupleCheckNode tupleCheckNode,
@Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
@Shared("toArray") @Cached ToArrayNode toArray,
@Bind PythonLanguage language) {
@@ -155,10 +157,11 @@ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PD
return PFactory.createFunction(language, name, code, globals, PCell.toCellArray(closureArray));
}
- @Specialization(guards = "isTuple(defaultArgs)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, defaultArgs)")
static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, @SuppressWarnings("unused") PNone name, Object defaultArgs,
@SuppressWarnings("unused") PNone closure,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Shared("tupleCheck") @Cached PyTupleCheckNode tupleCheckNode,
@Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
@Shared("toArray") @Cached ToArrayNode toArray,
@Bind PythonLanguage language) {
@@ -167,9 +170,10 @@ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PD
return PFactory.createFunction(language, code.getName(), code, globals, defaultArgsArray, null, null);
}
- @Specialization(guards = "isTuple(defaultArgs)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, defaultArgs)")
static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, Object defaultArgs, @SuppressWarnings("unused") PNone closure,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Shared("tupleCheck") @Cached PyTupleCheckNode tupleCheckNode,
@Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
@Shared("toArray") @Cached ToArrayNode toArray,
@Bind PythonLanguage language) {
@@ -178,9 +182,10 @@ static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PD
return PFactory.createFunction(language, name, code, globals, defaultArgsArray, null, null);
}
- @Specialization(guards = {"isTuple(defaultArgs)", "isTuple(closure)"})
+ @Specialization(guards = {"tupleCheckNode.execute(inliningTarget, defaultArgs)", "tupleCheckNode.execute(inliningTarget, closure)"})
static PFunction function(@SuppressWarnings("unused") Object cls, PCode code, PDict globals, TruffleString name, Object defaultArgs, Object closure,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Shared("tupleCheck") @Cached PyTupleCheckNode tupleCheckNode,
@Shared("getTupleStorage") @Cached GetTupleStorage getTupleStorage,
@Shared("toArray") @Cached ToArrayNode toArray,
@Bind PythonLanguage language) {
@@ -280,9 +285,10 @@ static Object defaults(PFunction self, @SuppressWarnings("unused") PNone default
return (argDefaults.length == 0) ? PNone.NONE : PFactory.createTuple(language, argDefaults);
}
- @Specialization(guards = "isTuple(defaults)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, defaults)", limit = "1")
static Object setDefaults(PFunction self, Object defaults,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached GetTupleStorage getTupleStorage,
@Cached ToArrayNode toArray) {
self.setDefaults(toArray.execute(inliningTarget, getTupleStorage.execute(inliningTarget, defaults)));
@@ -443,9 +449,10 @@ static Object get(PFunction self, @SuppressWarnings("unused") PNone value,
return typeParams;
}
- @Specialization(guards = "isTuple(typeParams)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, typeParams)", limit = "1")
static Object set(PFunction self, Object typeParams,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached EnsureManagedTupleNode ensureManagedTupleNode,
@Cached WriteAttributeToObjectNode writeObject) {
writeObject.execute(self, T___TYPE_PARAMS__, ensureManagedTupleNode.execute(inliningTarget, typeParams));
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java
index b443efb51a..921d1ec4ab 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java
@@ -70,6 +70,7 @@
import com.oracle.graal.python.lib.PyIterNextNode;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectGetIter;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PNodeWithContext;
@@ -360,9 +361,10 @@ static Object[] doString(Object iterableObj,
return result;
}
- @Specialization(guards = "isPSequence(seq) || isTuple(seq)")
+ @Specialization(guards = "isPSequence(seq) || tupleCheckNode.execute(inliningTarget, seq)", limit = "1")
static Object[] doSequenceWithStorage(Object seq,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached GetSequenceStorageNode getStorageNode,
@Cached SequenceStorageNodes.ToArrayNode toArrayNode) {
SequenceStorage storage = getStorageNode.execute(inliningTarget, seq);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
index cb7b0a193c..ea68575aa2 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mappingproxy/MappingproxyBuiltins.java
@@ -68,9 +68,9 @@
import com.oracle.graal.python.lib.PyObjectSizeNode;
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
import com.oracle.graal.python.lib.PySequenceContainsNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.RichCmpOp;
import com.oracle.graal.python.nodes.ErrorMessages;
-import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
@@ -105,10 +105,11 @@ public abstract static class MappingproxyNode extends PythonBinaryBuiltinNode {
static Object doMapping(@SuppressWarnings("unused") Object cls, Object obj,
@Bind Node inliningTarget,
@Cached PyMappingCheckNode mappingCheckNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Bind PythonLanguage language,
@Cached PRaiseNode raiseNode) {
// descrobject.c mappingproxy_check_mapping()
- if (!PGuards.isTupleOrList(obj) && mappingCheckNode.execute(inliningTarget, obj)) {
+ if (!tupleCheckNode.isTupleOrList(inliningTarget, obj) && mappingCheckNode.execute(inliningTarget, obj)) {
return PFactory.createMappingproxy(language, obj);
}
throw raiseNode.raise(inliningTarget, PythonErrorType.TypeError, ErrorMessages.S_ARG_MUST_BE_S_NOT_P, "mappingproxy()", "mapping", obj);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewBuiltins.java
index c2ecf66c5e..b68a8c7486 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewBuiltins.java
@@ -91,9 +91,9 @@
import com.oracle.graal.python.lib.PyMemoryViewFromObject;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
import com.oracle.graal.python.lib.PyObjectRichCompareBool;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.RichCmpOp;
import com.oracle.graal.python.nodes.ErrorMessages;
-import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PNodeWithContext;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes;
@@ -654,6 +654,7 @@ static PMemoryView doGeneric(VirtualFrame frame, PMemoryView self, TruffleString
@Cached InlinedBranchProfile isPListProfile,
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
@Cached PyNumberAsSizeNode asSizeNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached TruffleString.CodePointLengthNode lengthNode,
@Cached TruffleString.CodePointAtIndexUTF32Node atIndexNode,
@Exclusive @Cached TupleNodes.GetTupleStorage getTupleStorage,
@@ -666,7 +667,7 @@ static PMemoryView doGeneric(VirtualFrame frame, PMemoryView self, TruffleString
} else if (shapeObj instanceof PList) {
isPListProfile.enter(inliningTarget);
shape = shapeFromStorage(frame, inliningTarget, ((PList) shapeObj).getSequenceStorage(), getItemScalarNode, asSizeNode, raiseNode);
- } else if (PGuards.isTuple(shapeObj)) {
+ } else if (tupleCheckNode.execute(inliningTarget, shapeObj)) {
SequenceStorage storage = getTupleStorage.execute(inliningTarget, shapeObj);
shape = shapeFromStorage(frame, inliningTarget, storage, getItemScalarNode, asSizeNode, raiseNode);
} else {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java
index 27759d7e59..2fcbda6741 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java
@@ -57,6 +57,7 @@
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.lib.PyIndexCheckNode;
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.runtime.nativeaccess.NativeMemory;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
@@ -392,9 +393,10 @@ MemoryPointer resolveTupleCached(VirtualFrame frame, PMemoryView self, PTuple in
return ptr;
}
- @Specialization(guards = "isTuple(indices)", replaces = "resolveTupleCached")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, indices)", replaces = "resolveTupleCached")
MemoryPointer resolveTupleGeneric(VirtualFrame frame, PMemoryView self, Object indices,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Shared @Cached PyTupleCheckNode tupleCheckNode,
@Shared @Cached InlinedConditionProfile hasSuboffsetsProfile,
@Shared @Cached PyIndexCheckNode indexCheckNode,
@Shared @Cached GetTupleStorage getTupleStorage,
@@ -412,9 +414,10 @@ MemoryPointer resolveTupleGeneric(VirtualFrame frame, PMemoryView self, Object i
return ptr;
}
- @Specialization(guards = "!isTuple(indexObj)")
+ @Specialization(guards = "!tupleCheckNode.execute(inliningTarget, indexObj)")
MemoryPointer resolveIntObj(VirtualFrame frame, PMemoryView self, Object indexObj,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Shared @Cached PyTupleCheckNode tupleCheckNode,
@Shared @Cached InlinedConditionProfile hasOneDimensionProfile,
@Shared @Cached InlinedConditionProfile hasSuboffsetsProfile,
@Shared @Cached PyIndexCheckNode indexCheckNode,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java
index 51aa666446..a5237a9456 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java
@@ -122,6 +122,7 @@
import com.oracle.graal.python.lib.PyObjectLookupAttr;
import com.oracle.graal.python.lib.PyObjectLookupAttrO;
import com.oracle.graal.python.lib.PyObjectSizeNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.BuiltinNames;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.HiddenAttr;
@@ -454,9 +455,10 @@ static Pair doNewArgsEx(VirtualFrame frame, Object getNewArgsExA
@Cached PyDictCheckNode isDictSubClassNode,
@Cached PyObjectGetItem getItemNode,
@Cached PyObjectSizeNode sizeNode,
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached PRaiseNode raiseNode) {
Object newargs = callNode.execute(frame, getNewArgsExAttr);
- if (!PGuards.isTuple(newargs)) {
+ if (!tupleCheckNode.execute(inliningTarget, newargs)) {
throw raiseNode.raise(inliningTarget, TypeError, SHOULD_RETURN_TYPE_A_NOT_TYPE_B, T___GETNEWARGS_EX__, "tuple", newargs);
}
int length = sizeNode.execute(frame, inliningTarget, newargs);
@@ -467,7 +469,7 @@ static Pair doNewArgsEx(VirtualFrame frame, Object getNewArgsExA
Object args = getItemNode.execute(frame, inliningTarget, newargs, 0);
Object kwargs = getItemNode.execute(frame, inliningTarget, newargs, 1);
- if (!PGuards.isTuple(args)) {
+ if (!tupleCheckNode.execute(inliningTarget, args)) {
throw raiseNode.raise(inliningTarget, TypeError, MUST_BE_TYPE_A_NOT_TYPE_B, "first item of the tuple returned by __getnewargs_ex__", "tuple", args);
}
if (!isDictSubClassNode.execute(inliningTarget, kwargs)) {
@@ -481,9 +483,10 @@ static Pair doNewArgsEx(VirtualFrame frame, Object getNewArgsExA
static Pair doNewArgs(VirtualFrame frame, @SuppressWarnings("unused") PNone getNewArgsExAttr, Object getNewArgsAttr,
@Bind Node inliningTarget,
@Exclusive @Cached CallNode callNode,
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached PRaiseNode raiseNode) {
Object args = callNode.execute(frame, getNewArgsAttr);
- if (!PGuards.isTuple(args)) {
+ if (!tupleCheckNode.execute(inliningTarget, args)) {
throw raiseNode.raise(inliningTarget, TypeError, SHOULD_RETURN_TYPE_A_NOT_TYPE_B, T___GETNEWARGS__, "tuple", args);
}
return Pair.create(args, PNone.NONE);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java
index 4879c74c82..1b4cac834f 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/random/RandomBuiltins.java
@@ -66,8 +66,8 @@
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
import com.oracle.graal.python.lib.PyObjectHashNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
-import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
@@ -198,8 +198,9 @@ static PNone setstate(PRandom random, Object tuple,
@Cached GetTupleStorage getTupleStorage,
@Cached GetInternalObjectArrayNode getArray,
@Cached CastToJavaUnsignedLongNode castNode,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached PRaiseNode raiseNode) {
- if (!PGuards.isTuple(tuple)) {
+ if (!tupleCheckNode.execute(inliningTarget, tuple)) {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.STATE_VECTOR_MUST_BE_A_TUPLE);
}
SequenceStorage storage = getTupleStorage.execute(inliningTarget, tuple);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java
index 2d23f5cc2b..3db5196ae5 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java
@@ -71,6 +71,7 @@
import com.oracle.graal.python.lib.PyLongAsIntNode;
import com.oracle.graal.python.lib.PyTimeFromObjectNode;
import com.oracle.graal.python.lib.PyTimeFromObjectNode.RoundType;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyTupleGetItem;
import com.oracle.graal.python.lib.PyTupleSizeNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
@@ -127,6 +128,7 @@ static UniversalSockAddr doInet(VirtualFrame frame, @SuppressWarnings("unused")
@Bind Node inliningTarget,
@CachedLibrary(limit = "1") @Shared("posixLib") PosixSupportLibrary posixLib,
@CachedLibrary(limit = "1") @Shared("sockAddrLib") UniversalSockAddrLibrary sockAddrLib,
+ @Shared("tupleCheck") @Cached PyTupleCheckNode tupleCheckNode,
@Cached @Shared("tupleSize") PyTupleSizeNode tupleSize,
@Cached @Shared("tupleGetItem") PyTupleGetItem tupleGetItem,
@Cached @Shared("asInt") PyLongAsIntNode asIntNode,
@@ -135,7 +137,7 @@ static UniversalSockAddr doInet(VirtualFrame frame, @SuppressWarnings("unused")
@Cached @Shared("setIpAddr") SetIpAddrNode setIpAddrNode,
@Cached @Shared PRaiseNode raiseNode) {
PythonContext context = PythonContext.get(inliningTarget);
- if (!PGuards.isTuple(address)) {
+ if (!tupleCheckNode.execute(inliningTarget, address)) {
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_AF_INET_VALUES_MUST_BE_TUPLE_NOT_P, caller, address);
}
int length = tupleSize.execute(inliningTarget, address);
@@ -154,6 +156,7 @@ static UniversalSockAddr doInet6(VirtualFrame frame, @SuppressWarnings("unused")
@Bind Node inliningTarget,
@CachedLibrary(limit = "1") @Shared("posixLib") PosixSupportLibrary posixLib,
@CachedLibrary(limit = "1") @Shared("sockAddrLib") UniversalSockAddrLibrary sockAddrLib,
+ @Shared("tupleCheck") @Cached PyTupleCheckNode tupleCheckNode,
@Cached @Shared("tupleSize") PyTupleSizeNode tupleSize,
@Cached @Shared("tupleGetItem") PyTupleGetItem tupleGetItem,
@Cached @Shared("asInt") PyLongAsIntNode asIntNode,
@@ -162,7 +165,7 @@ static UniversalSockAddr doInet6(VirtualFrame frame, @SuppressWarnings("unused")
@Cached @Shared("setIpAddr") SetIpAddrNode setIpAddrNode,
@Cached @Shared PRaiseNode raiseNode) {
PythonContext context = PythonContext.get(inliningTarget);
- if (!PGuards.isTuple(address)) {
+ if (!tupleCheckNode.execute(inliningTarget, address)) {
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_AF_INET_VALUES_MUST_BE_TUPLE_NOT_S, caller, address);
}
int length = tupleSize.execute(inliningTarget, address);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java
index 978671eb31..5c5ffad650 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java
@@ -651,9 +651,10 @@ public final boolean endsWith(Object self, Object subStr, int start, int end) {
return execute(self, subStr, start, end, Op.SUFFIX);
}
- @Specialization(guards = "!isTuple(subStrObj)")
+ @Specialization(guards = "!tupleCheckNode.execute(inliningTarget, subStrObj)", limit = "1")
static boolean doString(Object selfObj, Object subStrObj, int start, int end, Op op,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached CastToTruffleStringChecked2Node castSelfNode,
@Exclusive @Cached CastToTruffleStringChecked3Node castPrefixNode,
@Shared @Cached TruffleString.CodePointLengthNode codePointLengthNode,
@@ -665,9 +666,10 @@ static boolean doString(Object selfObj, Object subStrObj, int start, int end, Op
return doIt(self, subStr, adjustStartIndex(start, selfLen), adjustEndIndex(end, selfLen), selfLen, subStrLen, regionEqualNode, op);
}
- @Specialization(guards = "isTuple(subStrs)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, subStrs)", limit = "1")
static boolean doTuple(Object selfObj, Object subStrs, int start, int end, Op op,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached TupleNodes.GetTupleStorage getTupleStorage,
@Exclusive @Cached SequenceStorageNodes.GetItemScalarNode getItemNode,
@Exclusive @Cached CastToTruffleStringChecked2Node castSelfNode,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java
index e9b1b1ea4b..7e39fd9078 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/RLockBuiltins.java
@@ -55,8 +55,8 @@
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
-import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -113,8 +113,9 @@ Object acquireRestore(PRLock self, Object state,
@Cached GetTupleStorage getTupleStorage,
@Cached GilNode gil,
@Cached CastToJavaUnsignedLongNode castLong,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached SequenceStorageNodes.GetItemDynamicNode getItemNode) {
- if (!PGuards.isTuple(state)) {
+ if (!tupleCheckNode.execute(inliningTarget, state)) {
throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.STATE_ARGUMENT_MUST_BE_A_TUPLE);
}
if (!self.acquireNonBlocking()) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java
index 70c7adf4b9..d5e9ef293e 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java
@@ -351,6 +351,7 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, Object bases, PDict
@Cached CallSlotTpNewNode callNew,
@Cached @Exclusive IsTypeNode isTypeNode,
@Cached PyObjectLookupAttr lookupMroEntriesNode,
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Cached CastToTruffleStringNode castStr,
@Cached TypeNodes.CreateTypeNode createType,
@Cached GetObjectArrayNode getObjectArrayNode,
@@ -358,7 +359,7 @@ Object typeNew(VirtualFrame frame, Object cls, Object wName, Object bases, PDict
PTuple basesTuple;
if (bases instanceof PTuple) {
basesTuple = (PTuple) bases;
- } else if (PGuards.isTuple(bases)) {
+ } else if (tupleCheckNode.execute(inliningTarget, bases)) {
basesTuple = constructTupleNode.execute(frame, bases);
} else {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S_NOT_P, "type.__new__()", 2, "tuple", bases);
@@ -431,6 +432,7 @@ static Object typeGeneric(VirtualFrame frame, Object cls, Object name, Object ba
@Bind Node inliningTarget,
@Cached TypeNode nextTypeNode,
@Cached PRaiseNode raiseNode,
+ @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached ConstructTupleNode constructTupleNode,
@Exclusive @Cached IsTypeNode isTypeNode) {
Object basesTuple;
@@ -438,7 +440,7 @@ static Object typeGeneric(VirtualFrame frame, Object cls, Object name, Object ba
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "type() argument 1", name);
} else if (bases instanceof PTuple) {
basesTuple = bases;
- } else if (PGuards.isTuple(bases)) {
+ } else if (tupleCheckNode.execute(inliningTarget, bases)) {
basesTuple = constructTupleNode.execute(frame, bases);
} else {
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MUST_BE_STRINGS_NOT_P, "type() argument 2", bases);
@@ -695,9 +697,10 @@ static Object getBases(Object self, @SuppressWarnings("unused") PNone value,
return PFactory.createTuple(language, getBaseClassesNode.execute(inliningTarget, self));
}
- @Specialization(guards = "isTuple(value)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, value)", limit = "1")
static Object setBases(VirtualFrame frame, PythonClass cls, Object value,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Cached ConstructTupleNode constructTupleNode,
@Cached GetObjectArrayNode getArray,
@Cached GetBaseClassNode getBase,
@@ -767,9 +770,10 @@ private static boolean typeIsSubtypeBaseChain(Node inliningTarget, Object a, Obj
return (isSameTypeNode.execute(inliningTarget, b, PythonBuiltinClassType.PythonObject));
}
- @Specialization(guards = "!isTuple(value)")
+ @Specialization(guards = "!tupleCheckNode.execute(inliningTarget, value)", limit = "1")
static Object setObject(@SuppressWarnings("unused") PythonClass cls, @SuppressWarnings("unused") Object value,
- @Bind Node inliningTarget) {
+ @Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheckNode) {
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CAN_ONLY_ASSIGN_S_TO_S_S_NOT_P, "tuple", GetNameNode.executeUncached(cls), "__bases__", value);
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java
index abdcbcebe3..df7e624ce4 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java
@@ -183,6 +183,7 @@
import com.oracle.graal.python.lib.PyEvalGetGlobals;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
import com.oracle.graal.python.lib.PyObjectSizeNode;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.HiddenAttr;
@@ -2156,6 +2157,7 @@ static PythonClass typeMetaclass(VirtualFrame frame, TruffleString name, PTuple
@Cached GetInstanceShape getInstanceShape,
@Cached CastToListNode castToListNode,
@Cached PyUnicodeCheckNode stringCheck,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached TruffleString.IsValidNode isValidNode,
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
@@ -2235,7 +2237,7 @@ static PythonClass typeMetaclass(VirtualFrame frame, TruffleString name, PTuple
Object slotsObject = ctx.slotsObject;
if (stringCheck.execute(inliningTarget, ctx.slotsObject)) {
slotsStorage = new ObjectSequenceStorage(new Object[]{castToStringNode.execute(inliningTarget, ctx.slotsObject)});
- } else if (PGuards.isTuple(ctx.slotsObject)) {
+ } else if (tupleCheckNode.execute(inliningTarget, ctx.slotsObject)) {
slotsStorage = getTupleStorage.execute(inliningTarget, ctx.slotsObject);
} else if (ctx.slotsObject instanceof PList slotsList) {
slotsStorage = slotsList.getSequenceStorage();
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/typing/TypeAliasTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/typing/TypeAliasTypeBuiltins.java
index 4722c1b55c..214a07368f 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/typing/TypeAliasTypeBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/typing/TypeAliasTypeBuiltins.java
@@ -74,6 +74,7 @@
import com.oracle.graal.python.builtins.objects.types.GenericTypeNodes.UnionTypeOrNode;
import com.oracle.graal.python.builtins.objects.typing.TypeAliasTypeBuiltinsClinicProviders.TypeAliasTypeNodeClinicProviderGen;
import com.oracle.graal.python.lib.PyObjectGetItem;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes.EnsureManagedTupleNode;
@@ -141,8 +142,9 @@ static PTuple doDefault(@SuppressWarnings("unused") Object o) {
return null;
}
- @Specialization(guards = "isTuple(o)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, o)", limit = "1")
static PTuple doTuple(Node inliningTarget, Object o,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached EnsureManagedTupleNode ensureManagedTupleNode) {
PTuple tuple = ensureManagedTupleNode.execute(inliningTarget, o);
return tuple.getSequenceStorage().length() == 0 ? null : tuple;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyErrExceptionMatchesNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyErrExceptionMatchesNode.java
index d98218bedf..1c4951a910 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyErrExceptionMatchesNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyErrExceptionMatchesNode.java
@@ -92,8 +92,9 @@ static boolean doException(@SuppressWarnings("unused") Node inliningTarget, Obje
}
}
- @Specialization(guards = "isTuple(tuple)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, tuple)", limit = "1")
static boolean doTuple(Node inliningTarget, Object exception, Object tuple,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
@Cached InlinedLoopConditionProfile loopConditionProfile,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMappingCheckNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMappingCheckNode.java
index 9710f088ae..4a954a6536 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMappingCheckNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMappingCheckNode.java
@@ -83,11 +83,15 @@ static boolean doSequence(@SuppressWarnings("unused") PSequence object) {
return true;
}
- @Specialization(guards = "isTuple(object)")
+ @Specialization(guards = "isNativeTuple(object)")
static boolean doSequence(@SuppressWarnings("unused") PythonAbstractNativeObject object) {
return true;
}
+ static boolean isNativeTuple(PythonAbstractNativeObject object) {
+ return PyTupleCheckNode.checkNative(object);
+ }
+
@Specialization
static boolean doString(@SuppressWarnings("unused") PString object) {
return true;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsInstanceNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsInstanceNode.java
index 1255fd6b67..b6156c4407 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsInstanceNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsInstanceNode.java
@@ -87,9 +87,10 @@ public static PyObjectIsInstanceNode getUncached() {
return PyObjectIsInstanceNodeGen.getUncached();
}
- @Specialization(guards = "!isTuple(cls)", insertBefore = "doRecursiveWithNode")
+ @Specialization(guards = "!tupleCheckNode.execute(inliningTarget, cls)", insertBefore = "doRecursiveWithNode", limit = "1")
static boolean isInstance(VirtualFrame frame, Object instance, Object cls, @SuppressWarnings("unused") int depth,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached GetClassNode getClsClassNode,
@Cached IsBuiltinClassExactProfile classProfile,
@Cached GetClassNode getInstanceClassNode,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsSubclassNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsSubclassNode.java
index f4745587ad..c43b30fcc6 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsSubclassNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectIsSubclassNode.java
@@ -87,9 +87,10 @@ public static PyObjectIsSubclassNode getUncached() {
return PyObjectIsSubclassNodeGen.getUncached();
}
- @Specialization(guards = "!isTuple(cls)", insertBefore = "doRecursiveWithNode")
+ @Specialization(guards = "!tupleCheckNode.execute(inliningTarget, cls)", insertBefore = "doRecursiveWithNode", limit = "1")
static boolean isSubclass(VirtualFrame frame, Object derived, Object cls, @SuppressWarnings("unused") int depth,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached GetClassNode getClsClassNode,
@Cached IsBuiltinClassExactProfile classProfile,
@Cached LookupSpecialMethodNode.Dynamic subclassCheckLookup,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectRecursiveBinaryCheckNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectRecursiveBinaryCheckNode.java
index e845f24ed7..58c19a75d5 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectRecursiveBinaryCheckNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectRecursiveBinaryCheckNode.java
@@ -82,10 +82,11 @@ public final boolean execute(Frame frame, Object arg, Object classinfo) {
abstract PyObjectRecursiveBinaryCheckNode getUncachedRecursive();
- @Specialization(guards = {"depth < getNodeRecursionLimit(language)", "isTuple(clsTuple)"}, excludeForUncached = true)
+ @Specialization(guards = {"depth < getNodeRecursionLimit(language)", "tupleCheckNode.execute(inliningTarget, clsTuple)"}, excludeForUncached = true, limit = "1")
static boolean doRecursiveWithNode(VirtualFrame frame, Object arg, Object clsTuple, int depth,
@Bind Node inliningTarget,
@SuppressWarnings("unused") @Bind PythonLanguage language,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.ToArrayNode toArrayNode,
@Cached("createRecursive()") PyObjectRecursiveBinaryCheckNode recursiveNode) {
@@ -93,10 +94,11 @@ static boolean doRecursiveWithNode(VirtualFrame frame, Object arg, Object clsTup
}
@SuppressWarnings("truffle-static-method")
- @Specialization(guards = {"depth >= getNodeRecursionLimit(language)", "isTuple(clsTuple)"}, excludeForUncached = true)
+ @Specialization(guards = {"depth >= getNodeRecursionLimit(language)", "tupleCheckNode.execute(inliningTarget, clsTuple)"}, excludeForUncached = true, limit = "1")
boolean doRecursiveTransition(VirtualFrame frame, Object arg, Object clsTuple, @SuppressWarnings("unused") int depth,
@Bind Node inliningTarget,
@SuppressWarnings("unused") @Bind PythonLanguage language,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached("createFor($node)") BoundaryCallData boundaryCallData,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.ToArrayNode toArrayNode) {
@@ -110,9 +112,10 @@ boolean doRecursiveTransition(VirtualFrame frame, Object arg, Object clsTuple, @
}
@SuppressWarnings("truffle-static-method")
- @Specialization(guards = "isTuple(clsTuple)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, clsTuple)", limit = "1")
boolean doRecursiveUncached(VirtualFrame frame, Object arg, Object clsTuple, @SuppressWarnings("unused") int depth,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Cached PyTupleCheckNode tupleCheckNode,
@Cached TupleNodes.GetTupleStorage getTupleStorage,
@Cached SequenceStorageNodes.ToArrayNode toArrayNode) {
assert this instanceof UnadoptableNode;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceCheckNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceCheckNode.java
index 0527a67649..a9906bdd09 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceCheckNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PySequenceCheckNode.java
@@ -74,11 +74,6 @@ static boolean doSequence(@SuppressWarnings("unused") PSequence object) {
return true;
}
- @Specialization(guards = "isTuple(object)")
- static boolean doSequence(@SuppressWarnings("unused") PythonAbstractNativeObject object) {
- return true;
- }
-
@Specialization
static boolean doString(@SuppressWarnings("unused") TruffleString object) {
return true;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTupleCheckNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTupleCheckNode.java
index 2fd382854e..5b1f264234 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTupleCheckNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyTupleCheckNode.java
@@ -47,6 +47,7 @@
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
import com.oracle.graal.python.builtins.objects.cext.structs.CFields;
+import com.oracle.graal.python.builtins.objects.list.PList;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.TypeFlags;
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
@@ -67,6 +68,10 @@
public abstract class PyTupleCheckNode extends Node {
public abstract boolean execute(Node inliningTarget, Object object);
+ public final boolean isTupleOrList(Node inliningTarget, Object object) {
+ return object instanceof PList || execute(inliningTarget, object);
+ }
+
public static boolean executeUncached(Object object) {
return PyTupleCheckNodeGen.getUncached().execute(null, object);
}
@@ -97,11 +102,16 @@ public static boolean checkNative(PythonAbstractNativeObject nativeObject) {
public abstract static class CachedNode extends Node {
public abstract boolean execute(Object object);
+ public final boolean isTupleOrList(Object object) {
+ return object instanceof PList || execute(object);
+ }
+
@Specialization
static boolean doGeneric(Object object,
@Bind Node inliningTarget,
- @Cached PyTupleCheckNode tupleCheck) {
- return tupleCheck.execute(inliningTarget, object);
+ @Cached InlinedBranchProfile isPTupleProfile,
+ @Cached InlinedBranchProfile isNativeProfile) {
+ return PyTupleCheckNode.doGeneric(inliningTarget, object, isPTupleProfile, isNativeProfile);
}
@NeverDefault
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java
index d40b687eec..05cb1cb880 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java
@@ -90,7 +90,6 @@
import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
import com.oracle.graal.python.lib.PyIndexCheckNode;
-import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode;
import com.oracle.graal.python.nodes.object.IsForeignObjectNode;
import com.oracle.graal.python.runtime.exception.PException;
@@ -109,7 +108,6 @@
import com.oracle.truffle.api.exception.AbstractTruffleException;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
-import com.oracle.truffle.api.profiles.InlinedBranchProfile;
import com.oracle.truffle.api.strings.TruffleString;
import com.oracle.truffle.api.strings.TruffleString.CodeRange;
@@ -327,14 +325,6 @@ public static boolean isPTuple(Object obj) {
return obj instanceof PTuple;
}
- public static boolean isTuple(Object obj) {
- return PyTupleCheckNode.doGeneric(null, obj, InlinedBranchProfile.getUncached(), InlinedBranchProfile.getUncached());
- }
-
- public static boolean isTupleOrList(Object obj) {
- return obj instanceof PList || isTuple(obj);
- }
-
public static boolean isPSequence(Object obj) {
return obj instanceof PSequence;
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java
index a1a3d8f6d1..5e5ba28be1 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/TupleNodes.java
@@ -78,7 +78,7 @@ public abstract class TupleNodes {
@GenerateUncached
@GenerateInline(false) // footprint reduction 40 -> 21
- @ImportStatic(PGuards.class)
+ @ImportStatic({PGuards.class, PyTupleCheckNode.class})
public abstract static class ConstructTupleNode extends PNodeWithContext {
public abstract PTuple execute(Frame frame, Object value);
@@ -101,7 +101,7 @@ static PTuple list(PList iterable,
return PFactory.createTuple(language, copyNode.execute(inliningTarget, iterable.getSequenceStorage()));
}
- @Specialization(guards = "isTuple(iterable)")
+ @Specialization(guards = "checkNative(iterable)")
static PTuple nativeTuple(PythonAbstractNativeObject iterable,
@Bind Node inliningTarget,
@Bind PythonLanguage language,
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectGetBasesNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectGetBasesNode.java
index adefd20e98..7e171aff33 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectGetBasesNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectGetBasesNode.java
@@ -44,7 +44,7 @@
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
-import com.oracle.graal.python.nodes.PGuards;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PNodeWithContext;
import com.oracle.graal.python.nodes.builtins.TupleNodes.ConstructTupleNode;
import com.oracle.truffle.api.dsl.Cached;
@@ -70,11 +70,12 @@ public static AbstractObjectGetBasesNode getUncached() {
@Specialization
static PTuple getBasesCached(VirtualFrame frame, Node inliningTarget, Object cls,
@Cached PyObjectLookupAttr lookupAttr,
+ @Cached PyTupleCheckNode tupleCheckNode,
@Cached ConstructTupleNode constructTupleNode) {
Object bases = lookupAttr.execute(frame, inliningTarget, cls, T___BASES__);
if (bases instanceof PTuple) {
return (PTuple) bases;
- } else if (PGuards.isTuple(bases)) {
+ } else if (tupleCheckNode.execute(inliningTarget, bases)) {
return constructTupleNode.execute(frame, bases);
}
return null;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/ExceptMatchNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/ExceptMatchNode.java
index fa65ca9b38..44593245aa 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/ExceptMatchNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/ExceptMatchNode.java
@@ -42,6 +42,7 @@
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.exception.PBaseException;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -81,9 +82,10 @@ private static void raiseIfNoException(Node inliningTarget, Object clause, Valid
}
}
- @Specialization(guards = "!isTuple(clause)")
+ @Specialization(guards = "!tupleCheckNode.execute(inliningTarget, clause)")
public static boolean matchPythonSingle(PException e, Object clause,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Shared @Cached PyTupleCheckNode tupleCheckNode,
@Shared @Cached ValidExceptionNode isValidException,
@Shared @Cached GetClassNode getClassNode,
@Shared @Cached IsSubtypeNode isSubtype) {
@@ -91,9 +93,10 @@ public static boolean matchPythonSingle(PException e, Object clause,
return isSubtype.execute(getClassNode.execute(inliningTarget, e.getUnreifiedException()), clause);
}
- @Specialization(guards = "!isTuple(clause)")
+ @Specialization(guards = "!tupleCheckNode.execute(inliningTarget, clause)")
public static boolean matchPythonBaseSingle(PBaseException e, Object clause,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Shared @Cached PyTupleCheckNode tupleCheckNode,
@Shared @Cached ValidExceptionNode isValidException,
@Shared @Cached GetClassNode getClassNode,
@Shared @Cached IsSubtypeNode isSubtype) {
@@ -101,9 +104,10 @@ public static boolean matchPythonBaseSingle(PBaseException e, Object clause,
return isSubtype.execute(getClassNode.execute(inliningTarget, e), clause);
}
- @Specialization(guards = {"!isTuple(clause)", "!isPException(e)"}, limit = "1")
+ @Specialization(guards = {"!tupleCheckNode.execute(inliningTarget, clause)", "!isPException(e)"}, limit = "1")
public static boolean matchJava(AbstractTruffleException e, Object clause,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Shared @Cached PyTupleCheckNode tupleCheckNode,
@Shared @Cached ValidExceptionNode isValidException,
@CachedLibrary("clause") InteropLibrary clauseLib) {
// n.b.: we can only allow Java exceptions in clauses, because we cannot tell for other
@@ -121,9 +125,10 @@ public static boolean matchJava(AbstractTruffleException e, Object clause,
}
}
- @Specialization(guards = "isTuple(clause)")
+ @Specialization(guards = "tupleCheckNode.execute(inliningTarget, clause)", limit = "1")
public static boolean matchTuple(Object e, Object clause,
@Bind Node inliningTarget,
+ @SuppressWarnings("unused") @Exclusive @Cached PyTupleCheckNode tupleCheckNode,
@Exclusive @Cached ExceptMatchNode recursiveNode,
@Exclusive @Cached TupleNodes.GetTupleStorage getTupleStorage,
@Exclusive @Cached SequenceStorageNodes.GetItemScalarNode getItemNode) {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/TupleConversionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/TupleConversionNode.java
index 59b5977590..63fab02265 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/TupleConversionNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/TupleConversionNode.java
@@ -48,6 +48,7 @@
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
+import com.oracle.graal.python.lib.PyTupleCheckNode;
import com.oracle.graal.python.nodes.PGuards;
import com.oracle.graal.python.nodes.PRaiseNode;
import com.oracle.graal.python.nodes.builtins.TupleNodes;
@@ -60,7 +61,7 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
-@ImportStatic(PGuards.class)
+@ImportStatic({PGuards.class, PyTupleCheckNode.class})
public abstract class TupleConversionNode extends ArgumentCastNode {
@Specialization
static Object[] doNone(@SuppressWarnings("unused") PNone none) {
@@ -74,7 +75,7 @@ static Object[] doTuple(PTuple t,
return getInternalArrayNode.execute(inliningTarget, t.getSequenceStorage());
}
- @Specialization(guards = "isTuple(t)")
+ @Specialization(guards = "checkNative(t)")
static Object[] doNativeTuple(PythonAbstractNativeObject t,
@Bind Node inliningTarget,
@Cached TupleNodes.GetTupleStorage getTupleStorage,