Skip to content

Commit 34fa858

Browse files
committed
[GR-68087] Implement PyUnstable_Long_IsCompact and PyUnstable_Long_CompactValue.
PullRequest: graalpython/3918
2 parents 73bed78 + efbc5ab commit 34fa858

File tree

6 files changed

+59
-6
lines changed

6 files changed

+59
-6
lines changed

graalpython/com.oracle.graal.python.cext/include/cpython/longintrepr.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2018, 2024, Oracle and/or its affiliates.
1+
/* Copyright (c) 2018, 2025, Oracle and/or its affiliates.
22
* Copyright (C) 1996-2017 Python Software Foundation
33
*
44
* Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -109,6 +109,7 @@ _PyLong_FromDigits(int negative, Py_ssize_t digit_count, digit *digits);
109109
#define _PyLong_SIGN_MASK 3
110110
#define _PyLong_NON_SIZE_BITS 3
111111

112+
#if 0 // GraalPy change
112113

113114
static inline int
114115
_PyLong_IsCompact(const PyLongObject* op) {
@@ -118,6 +119,12 @@ _PyLong_IsCompact(const PyLongObject* op) {
118119

119120
#define PyUnstable_Long_IsCompact _PyLong_IsCompact
120121

122+
#endif // GraalPy change
123+
124+
#define _PyLong_IsCompact PyUnstable_Long_IsCompact
125+
126+
#if 0 // GraalPy change
127+
121128
static inline Py_ssize_t
122129
_PyLong_CompactValue(const PyLongObject *op)
123130
{
@@ -130,6 +137,9 @@ _PyLong_CompactValue(const PyLongObject *op)
130137

131138
#define PyUnstable_Long_CompactValue _PyLong_CompactValue
132139

140+
#endif // GraalPy change
141+
142+
#define _PyLong_CompactValue PyUnstable_Long_CompactValue
133143

134144
#ifdef __cplusplus
135145
}

graalpython/com.oracle.graal.python.cext/src/longobject.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6100,6 +6100,12 @@ PyUnstable_Long_CompactValue(const PyLongObject* op) {
61006100

61016101
#endif // GraalPy change
61026102

6103+
#undef PyUnstable_Long_CompactValue
6104+
6105+
Py_ssize_t
6106+
PyUnstable_Long_CompactValue(const PyLongObject *op) {
6107+
return GraalPyPrivate_Long_AsPrimitive((PyObject*) op, MODE_PINT_SIGNED, sizeof(Py_ssize_t));
6108+
}
61036109

61046110
// GraalPy additions
61056111
uintptr_t GraalPyPrivate_Long_lv_tag(const PyLongObject *op) {

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_long.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0
@@ -127,6 +127,11 @@ def _reference_sign(args):
127127
else:
128128
return 1
129129

130+
def _reference_is_compact(args):
131+
n = args[0]
132+
# the range is impl. specific, but let's assume it's at least int32
133+
return 1 if -2147483648 <= n <= 2147483647 else 0
134+
130135

131136
class DummyNonInt():
132137
pass
@@ -420,7 +425,25 @@ class TestPyLong(CPyExtTestCase):
420425
argspec="OniiO",
421426
arguments=["PyObject* object", "Py_ssize_t n", "int little_endian", "int is_signed", "PyObject* unused"],
422427
)
423-
428+
429+
test_PyUnstable_Long_IsCompact = CPyExtFunction(
430+
_reference_is_compact,
431+
# for CPython the range is different, so we test only obvious values
432+
lambda: ((0,), (-1,), (1,), (9223372036854775807 * 10,)),
433+
resultspec="i",
434+
argspec='O',
435+
arguments=["PyLongObject* o"],
436+
)
437+
438+
test_PyUnstable_Long_CompactValue = CPyExtFunction(
439+
lambda x: x[0],
440+
# for CPython the range is different, so we test only obvious values
441+
lambda: ((0,), (-1,), (1,)),
442+
resultspec="l",
443+
argspec='O',
444+
arguments=["PyLongObject* o"],
445+
)
446+
424447
test__PyLong_Sign = CPyExtFunction(
425448
_reference_sign,
426449
lambda: (

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextLongBuiltins.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import static com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath.Ignored;
4646
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.CONST_UNSIGNED_CHAR_PTR;
4747
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.CharPtrAsTruffleString;
48+
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.ConstPyLongObject;
4849
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Int;
4950
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.LONG_LONG;
5051
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Pointer;
@@ -231,6 +232,20 @@ Object fromString(Object s, int base,
231232
}
232233
}
233234

235+
@CApiBuiltin(ret = Int, args = {ConstPyLongObject}, call = Direct)
236+
abstract static class PyUnstable_Long_IsCompact extends CApiUnaryBuiltinNode {
237+
@Specialization
238+
@TruffleBoundary
239+
static int doI(Object value) {
240+
if (value instanceof Integer || value instanceof Long) {
241+
return 1;
242+
} else if (value instanceof PInt pInt) {
243+
return pInt.fitsIn(PInt.MIN_LONG, PInt.MAX_LONG) ? 1 : 0;
244+
}
245+
return 0;
246+
}
247+
}
248+
234249
@CApiBuiltin(ret = LONG_LONG, args = {PyObject, Int, SIZE_T}, call = Ignored)
235250
abstract static class GraalPyPrivate_Long_AsPrimitive extends CApiTernaryBuiltinNode {
236251

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,8 +1264,7 @@ public final class CApiFunction {
12641264
@CApiBuiltin(name = "PyUnstable_InterpreterFrame_GetCode", ret = PyObjectRawPointer, args = {_PyInterpreterFrame}, call = NotImplemented)
12651265
@CApiBuiltin(name = "PyUnstable_InterpreterFrame_GetLasti", ret = PrimitiveResult32, args = {_PyInterpreterFrame}, call = NotImplemented)
12661266
@CApiBuiltin(name = "PyUnstable_InterpreterFrame_GetLine", ret = PrimitiveResult32, args = {_PyInterpreterFrame}, call = NotImplemented)
1267-
@CApiBuiltin(name = "PyUnstable_Long_CompactValue", ret = Py_ssize_t, args = {ConstPyLongObject}, call = NotImplemented)
1268-
@CApiBuiltin(name = "PyUnstable_Long_IsCompact", ret = PrimitiveResult32, args = {ConstPyLongObject}, call = NotImplemented)
1267+
@CApiBuiltin(name = "PyUnstable_Long_CompactValue", ret = Py_ssize_t, args = {ConstPyLongObject}, call = CImpl)
12691268
@CApiBuiltin(name = "PyUnstable_Object_GC_NewWithExtraData", ret = PyObjectRawPointer, args = {PyTypeObjectTransfer, SIZE_T}, call = CImpl)
12701269
@CApiBuiltin(name = "PyUnstable_PerfMapState_Fini", ret = Void, args = {}, call = NotImplemented)
12711270
@CApiBuiltin(name = "PyUnstable_PerfMapState_Init", ret = PrimitiveResult32, args = {}, call = NotImplemented)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/PInt.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ public static boolean fitsIn(BigInteger value, BigInteger left, BigInteger right
681681
return value.compareTo(left) >= 0 && value.compareTo(right) <= 0;
682682
}
683683

684-
private boolean fitsIn(BigInteger left, BigInteger right) {
684+
public boolean fitsIn(BigInteger left, BigInteger right) {
685685
return fitsIn(value, left, right);
686686
}
687687

0 commit comments

Comments
 (0)