Skip to content

Commit e4141c8

Browse files
committed
Fix infinite recursion in _Py_HashDouble
1 parent bf5f9d8 commit e4141c8

File tree

3 files changed

+26
-18
lines changed

3 files changed

+26
-18
lines changed

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -73,3 +73,21 @@ _Py_HashPointer(const void *p)
7373
}
7474
return x;
7575
}
76+
77+
/* taken from CPython */
78+
Py_hash_t
79+
_Py_HashDouble(PyObject *inst, double v)
80+
{
81+
int e, sign;
82+
double m;
83+
Py_uhash_t x, y;
84+
85+
if (!Py_IS_FINITE(v)) {
86+
if (Py_IS_INFINITY(v))
87+
return v > 0 ? _PyHASH_INF : -_PyHASH_INF;
88+
else
89+
return _Py_HashPointer(inst);
90+
}
91+
// GraalPy change: different implementation
92+
return Graal_PyTruffle_HashDouble(v);
93+
}

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

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -45,7 +45,6 @@
4545
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.CONST_VOID_PTR;
4646
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.INT8_T_PTR;
4747
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Int;
48-
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyObject;
4948
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Py_hash_t;
5049
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Py_ssize_t;
5150
import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Void;
@@ -60,13 +59,10 @@
6059
import com.oracle.graal.python.lib.PyObjectHashNode;
6160
import com.oracle.truffle.api.CompilerDirectives;
6261
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
63-
import com.oracle.truffle.api.dsl.Bind;
6462
import com.oracle.truffle.api.dsl.Cached;
65-
import com.oracle.truffle.api.dsl.ImportStatic;
6663
import com.oracle.truffle.api.dsl.Specialization;
6764
import com.oracle.truffle.api.strings.TruffleString;
6865
import com.oracle.truffle.api.strings.TruffleString.Encoding;
69-
import com.oracle.truffle.api.nodes.Node;
7066
import com.oracle.truffle.api.strings.TruffleString.HashCodeNode;
7167

7268
public final class PythonCextHashBuiltins {
@@ -102,21 +98,14 @@ static long doI(int idx) {
10298
}
10399
}
104100

105-
@CApiBuiltin(ret = Py_hash_t, args = {PyObject, ArgDescriptor.Double}, call = Direct)
106-
@ImportStatic(Double.class)
107-
abstract static class _Py_HashDouble extends CApiBinaryBuiltinNode {
101+
@CApiBuiltin(ret = Py_hash_t, args = {ArgDescriptor.Double}, call = Ignored)
102+
abstract static class _PyTruffle_HashDouble extends CApiUnaryBuiltinNode {
108103

109-
@Specialization(guards = "isFinite(value)")
110-
long doFinite(@SuppressWarnings("unused") Object inst, double value) {
104+
@Specialization
105+
long doFinite(double value) {
106+
assert !Double.isNaN(value);
111107
return PyObjectHashNode.hash(value);
112108
}
113-
114-
@Specialization(guards = "!isFinite(value)")
115-
long doNonFinite(Object inst, @SuppressWarnings("unused") double value,
116-
@Bind("this") Node inliningTarget,
117-
@Cached PyObjectHashNode hashNode) {
118-
return hashNode.execute(null, inliningTarget, inst);
119-
}
120109
}
121110

122111
@CApiBuiltin(name = "_Py_HashBytes", ret = Py_hash_t, args = {CONST_VOID_PTR, Py_ssize_t}, call = Direct)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,7 @@ public final class CApiFunction {
607607
@CApiBuiltin(name = "_Py_Dealloc", ret = Void, args = {PyObject}, call = CImpl)
608608
@CApiBuiltin(name = "_Py_DecRef", ret = Void, args = {PyObject}, call = CImpl)
609609
@CApiBuiltin(name = "_Py_FatalErrorFunc", ret = VoidNoReturn, args = {ConstCharPtr, ConstCharPtr}, call = CImpl)
610+
@CApiBuiltin(name = "_Py_HashDouble", ret = Py_hash_t, args = {PyObject, ArgDescriptor.Double}, call = CImpl)
610611
@CApiBuiltin(name = "_Py_HashPointer", ret = Py_hash_t, args = {CONST_VOID_PTR}, call = CImpl)
611612
@CApiBuiltin(name = "_Py_HashPointerRaw", ret = Py_hash_t, args = {CONST_VOID_PTR}, call = CImpl)
612613
@CApiBuiltin(name = "_Py_IncRef", ret = Void, args = {PyObject}, call = CImpl)

0 commit comments

Comments
 (0)