1
- /*
2
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1
+ /* Copyright (c) 2018, 2019, Oracle and/or its affiliates.
2
+ * Copyright (C) 1996-2017 Python Software Foundation
4
3
*
5
- * The Universal Permissive License (UPL), Version 1.0
6
- *
7
- * Subject to the condition set forth below, permission is hereby granted to any
8
- * person obtaining a copy of this software, associated documentation and/or
9
- * data (collectively the "Software"), free of charge and under any and all
10
- * copyright rights in the Software, and any and all patent rights owned or
11
- * freely licensable by each licensor hereunder covering either (i) the
12
- * unmodified Software as contributed to or provided by such licensor, or (ii)
13
- * the Larger Works (as defined below), to deal in both
14
- *
15
- * (a) the Software, and
16
- *
17
- * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18
- * one is included with the Software each a "Larger Work" to which the Software
19
- * is contributed by such licensors),
20
- *
21
- * without restriction, including without limitation the rights to copy, create
22
- * derivative works of, display, perform, and distribute the Software and make,
23
- * use, sell, offer for sale, import, export, have made, and have sold the
24
- * Software and the Larger Work(s), and to sublicense the foregoing rights on
25
- * either these or other terms.
26
- *
27
- * This license is subject to the following condition:
28
- *
29
- * The above copyright notice and either this complete permission notice or at a
30
- * minimum a reference to the UPL must be included in all copies or substantial
31
- * portions of the Software.
32
- *
33
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39
- * SOFTWARE.
4
+ * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
40
5
*/
6
+
41
7
#include "capi.h"
42
8
43
9
PyTypeObject PyEllipsis_Type = PY_TRUFFLE_TYPE ("ellipsis" , & PyType_Type , Py_TPFLAGS_DEFAULT , 0 );
@@ -48,27 +14,110 @@ PyObject _Py_EllipsisObject = {
48
14
1 , & PyEllipsis_Type
49
15
};
50
16
51
- UPCALL_ID (PySlice_GetIndicesEx );
17
+ // Taken from CPython ceval.c
18
+ /* Extract a slice index from a PyLong or an object with the
19
+ nb_index slot defined, and store in *pi.
20
+ Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX,
21
+ and silently boost values less than PY_SSIZE_T_MIN to PY_SSIZE_T_MIN.
22
+ Return 0 on error, 1 on success. */
23
+ int _PyEval_SliceIndex (PyObject * v , Py_ssize_t * pi ) {
24
+ if (v != Py_None ) {
25
+ Py_ssize_t x ;
26
+ if (PyIndex_Check (v )) {
27
+ x = PyNumber_AsSsize_t (v , NULL );
28
+ if (x == -1 && PyErr_Occurred ())
29
+ return 0 ;
30
+ }
31
+ else {
32
+ PyErr_SetString (PyExc_TypeError ,
33
+ "slice indices must be integers or "
34
+ "None or have an __index__ method" );
35
+ return 0 ;
36
+ }
37
+ * pi = x ;
38
+ }
39
+ return 1 ;
40
+ }
41
+
42
+ // Taken from CPython
52
43
int PySlice_Unpack (PyObject * _r , Py_ssize_t * start , Py_ssize_t * stop , Py_ssize_t * step ) {
53
44
PySliceObject * r = (PySliceObject * )_r ;
54
- PyObject * result = UPCALL_CEXT_O (_jls_PySlice_GetIndicesEx , native_to_java (r -> start ), native_to_java (r -> stop ), native_to_java (r -> step ), PY_SSIZE_T_MAX );
55
- if (result == NULL ) {
56
- return -1 ;
45
+ /* this is harder to get right than you might think */
46
+
47
+ if (r -> step == Py_None ) {
48
+ * step = 1 ;
49
+ }
50
+ else {
51
+ if (!_PyEval_SliceIndex (r -> step , step )) return -1 ;
52
+ if (* step == 0 ) {
53
+ PyErr_SetString (PyExc_ValueError ,
54
+ "slice step cannot be zero" );
55
+ return -1 ;
56
+ }
57
+ /* Here *step might be -PY_SSIZE_T_MAX-1; in this case we replace it
58
+ * with -PY_SSIZE_T_MAX. This doesn't affect the semantics, and it
59
+ * guards against later undefined behaviour resulting from code that
60
+ * does "step = -step" as part of a slice reversal.
61
+ */
62
+ if (* step < - PY_SSIZE_T_MAX )
63
+ * step = - PY_SSIZE_T_MAX ;
64
+ }
65
+
66
+ if (r -> start == Py_None ) {
67
+ * start = * step < 0 ? PY_SSIZE_T_MAX : 0 ;
57
68
}
58
- * start = PyLong_AsSsize_t (PyTuple_GetItem (result , 0 ));
59
- * stop = PyLong_AsSsize_t (PyTuple_GetItem (result , 1 ));
60
- * step = PyLong_AsSsize_t (PyTuple_GetItem (result , 2 ));
69
+ else {
70
+ if (!_PyEval_SliceIndex (r -> start , start )) return -1 ;
71
+ }
72
+
73
+ if (r -> stop == Py_None ) {
74
+ * stop = * step < 0 ? PY_SSIZE_T_MIN : PY_SSIZE_T_MAX ;
75
+ }
76
+ else {
77
+ if (!_PyEval_SliceIndex (r -> stop , stop )) return -1 ;
78
+ }
79
+
61
80
return 0 ;
62
81
}
63
82
83
+ // taken from CPython
64
84
Py_ssize_t PySlice_AdjustIndices (Py_ssize_t length , Py_ssize_t * start , Py_ssize_t * stop , Py_ssize_t step ) {
65
- PyObject * result = UPCALL_CEXT_O (_jls_PySlice_GetIndicesEx , * start , * stop , step , length );
66
- if (result == NULL ) {
67
- return -1 ;
85
+ /* this is harder to get right than you might think */
86
+
87
+ assert (step != 0 );
88
+ assert (step >= - PY_SSIZE_T_MAX );
89
+
90
+ if (* start < 0 ) {
91
+ * start += length ;
92
+ if (* start < 0 ) {
93
+ * start = (step < 0 ) ? -1 : 0 ;
94
+ }
95
+ }
96
+ else if (* start >= length ) {
97
+ * start = (step < 0 ) ? length - 1 : length ;
68
98
}
69
- * start = PyLong_AsSsize_t (PyTuple_GetItem (result , 0 ));
70
- * stop = PyLong_AsSsize_t (PyTuple_GetItem (result , 1 ));
71
- return PyLong_AsSsize_t (PyTuple_GetItem (result , 3 )); // adjusted length
99
+
100
+ if (* stop < 0 ) {
101
+ * stop += length ;
102
+ if (* stop < 0 ) {
103
+ * stop = (step < 0 ) ? -1 : 0 ;
104
+ }
105
+ }
106
+ else if (* stop >= length ) {
107
+ * stop = (step < 0 ) ? length - 1 : length ;
108
+ }
109
+
110
+ if (step < 0 ) {
111
+ if (* stop < * start ) {
112
+ return (* start - * stop - 1 ) / (- step ) + 1 ;
113
+ }
114
+ }
115
+ else {
116
+ if (* start < * stop ) {
117
+ return (* stop - * start - 1 ) / step + 1 ;
118
+ }
119
+ }
120
+ return 0 ;
72
121
}
73
122
74
123
UPCALL_ID (PySlice_New );
0 commit comments