Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersOperationInplaceAddUtils.c
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3/* These slots are still manually coded and are used by the generated code.
4 *
5 * The plan should be to generate these as well. Currently also naming is
6 * very inconsistent.
7 */
8
9#if PYTHON_VERSION < 0x300
10#include <stddef.h>
11
12#define PyStringObject_SIZE (offsetof(PyStringObject, ob_sval) + 1)
13
14NUITKA_MAY_BE_UNUSED static bool STRING_RESIZE(PyObject **value, Py_ssize_t newsize) {
15 PyStringObject *sv;
16
17 _Py_DEC_REFTOTAL;
18 _Py_ForgetReference(*value);
19
20 *value = (PyObject *)PyObject_REALLOC((char *)*value, PyStringObject_SIZE + newsize);
21
22 if (unlikely(*value == NULL)) {
23 PyErr_NoMemory();
24
25 return false;
26 }
27 Nuitka_Py_NewReference(*value);
28
29 sv = (PyStringObject *)*value;
30 Py_SIZE(sv) = newsize;
31
32 sv->ob_sval[newsize] = '\0';
33 sv->ob_shash = -1;
34
35 return true;
36}
37
38NUITKA_MAY_BE_UNUSED static bool STRING_ADD_INPLACE(PyObject **operand1, PyObject *operand2) {
39 assert(PyString_CheckExact(*operand1));
40 assert(!PyString_CHECK_INTERNED(*operand1));
41 assert(PyString_CheckExact(operand2));
42
43 Py_ssize_t operand1_size = PyString_GET_SIZE(*operand1);
44 Py_ssize_t operand2_size = PyString_GET_SIZE(operand2);
45
46 Py_ssize_t new_size = operand1_size + operand2_size;
47
48 if (unlikely(new_size < 0)) {
49 PyErr_Format(PyExc_OverflowError, "strings are too large to concat");
50
51 return false;
52 }
53
54 if (unlikely(STRING_RESIZE(operand1, new_size) == false)) {
55 return false;
56 }
57
58 memcpy(PyString_AS_STRING(*operand1) + operand1_size, PyString_AS_STRING(operand2), operand2_size);
59
60 return true;
61}
62#endif
63
64#if PYTHON_VERSION >= 0x300
65NUITKA_MAY_BE_UNUSED static bool BYTES_ADD_INCREMENTAL(PyObject **operand1, PyObject *operand2) {
66 assert(PyBytes_CheckExact(*operand1));
67 assert(PyBytes_CheckExact(operand2));
68
69 // Buffer of operand2
70 Py_buffer wb;
71 wb.len = -1;
72
73 {
74 NUITKA_MAY_BE_UNUSED int res = PyObject_GetBuffer(operand2, &wb, PyBUF_SIMPLE);
75 // Has to work.
76 assert(res == 0);
77 }
78 assert(wb.len >= 0);
79
80 Py_ssize_t oldsize = PyBytes_GET_SIZE(*operand1);
81
82 if (oldsize > PY_SSIZE_T_MAX - wb.len) {
83 PyErr_NoMemory();
84 PyBuffer_Release(&wb);
85 return false;
86 }
87 if (_PyBytes_Resize(operand1, oldsize + wb.len) < 0) {
88 PyBuffer_Release(&wb);
89 return false;
90 }
91
92 memcpy(PyBytes_AS_STRING(*operand1) + oldsize, wb.buf, wb.len);
93 PyBuffer_Release(&wb);
94 return true;
95}
96#endif
97
98NUITKA_MAY_BE_UNUSED static bool UNICODE_ADD_INCREMENTAL(PyThreadState *tstate, PyObject **operand1,
99 PyObject *operand2) {
100 Py_ssize_t operand2_size = PyUnicode_GET_LENGTH(operand2);
101 if (operand2_size == 0) {
102 return true;
103 }
104
105#if PYTHON_VERSION < 0x300
106 Py_ssize_t operand1_size = PyUnicode_GET_SIZE(*operand1);
107
108 Py_ssize_t new_size = operand1_size + operand2_size;
109
110 if (unlikely(new_size < 0)) {
111 PyErr_Format(PyExc_OverflowError, "strings are too large to concat");
112
113 return false;
114 }
115
116 if (unlikely(PyUnicode_Resize(operand1, new_size) != 0)) {
117 return false;
118 }
119
120 memcpy(PyUnicode_AS_UNICODE(*operand1) + operand1_size, PyUnicode_AS_UNICODE(operand2),
121 operand2_size * sizeof(Py_UNICODE));
122
123 return true;
124#else
125 assert(!PyUnicode_CHECK_INTERNED(*operand1));
126
127 return UNICODE_APPEND(tstate, operand1, operand2);
128#endif
129}
130
131// Part of "Nuitka", an optimizing Python compiler that is compatible and
132// integrates with CPython, but also works on its own.
133//
134// Licensed under the Apache License, Version 2.0 (the "License");
135// you may not use this file except in compliance with the License.
136// You may obtain a copy of the License at
137//
138// http://www.apache.org/licenses/LICENSE-2.0
139//
140// Unless required by applicable law or agreed to in writing, software
141// distributed under the License is distributed on an "AS IS" BASIS,
142// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143// See the License for the specific language governing permissions and
144// limitations under the License.