Skip to content

Commit 89fe067

Browse files
committed
move binop folding to cfg
1 parent 7d0521d commit 89fe067

File tree

2 files changed

+239
-167
lines changed

2 files changed

+239
-167
lines changed

Python/ast_opt.c

+1-167
Original file line numberDiff line numberDiff line change
@@ -144,121 +144,6 @@ fold_unaryop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
144144
limit. Otherwise returns the limit minus the total number of items.
145145
*/
146146

147-
static Py_ssize_t
148-
check_complexity(PyObject *obj, Py_ssize_t limit)
149-
{
150-
if (PyTuple_Check(obj)) {
151-
Py_ssize_t i;
152-
limit -= PyTuple_GET_SIZE(obj);
153-
for (i = 0; limit >= 0 && i < PyTuple_GET_SIZE(obj); i++) {
154-
limit = check_complexity(PyTuple_GET_ITEM(obj, i), limit);
155-
}
156-
return limit;
157-
}
158-
return limit;
159-
}
160-
161-
#define MAX_INT_SIZE 128 /* bits */
162-
#define MAX_COLLECTION_SIZE 256 /* items */
163-
#define MAX_STR_SIZE 4096 /* characters */
164-
#define MAX_TOTAL_ITEMS 1024 /* including nested collections */
165-
166-
static PyObject *
167-
safe_multiply(PyObject *v, PyObject *w)
168-
{
169-
if (PyLong_Check(v) && PyLong_Check(w) &&
170-
!_PyLong_IsZero((PyLongObject *)v) && !_PyLong_IsZero((PyLongObject *)w)
171-
) {
172-
int64_t vbits = _PyLong_NumBits(v);
173-
int64_t wbits = _PyLong_NumBits(w);
174-
assert(vbits >= 0);
175-
assert(wbits >= 0);
176-
if (vbits + wbits > MAX_INT_SIZE) {
177-
return NULL;
178-
}
179-
}
180-
else if (PyLong_Check(v) && PyTuple_Check(w)) {
181-
Py_ssize_t size = PyTuple_GET_SIZE(w);
182-
if (size) {
183-
long n = PyLong_AsLong(v);
184-
if (n < 0 || n > MAX_COLLECTION_SIZE / size) {
185-
return NULL;
186-
}
187-
if (n && check_complexity(w, MAX_TOTAL_ITEMS / n) < 0) {
188-
return NULL;
189-
}
190-
}
191-
}
192-
else if (PyLong_Check(v) && (PyUnicode_Check(w) || PyBytes_Check(w))) {
193-
Py_ssize_t size = PyUnicode_Check(w) ? PyUnicode_GET_LENGTH(w) :
194-
PyBytes_GET_SIZE(w);
195-
if (size) {
196-
long n = PyLong_AsLong(v);
197-
if (n < 0 || n > MAX_STR_SIZE / size) {
198-
return NULL;
199-
}
200-
}
201-
}
202-
else if (PyLong_Check(w) &&
203-
(PyTuple_Check(v) || PyUnicode_Check(v) || PyBytes_Check(v)))
204-
{
205-
return safe_multiply(w, v);
206-
}
207-
208-
return PyNumber_Multiply(v, w);
209-
}
210-
211-
static PyObject *
212-
safe_power(PyObject *v, PyObject *w)
213-
{
214-
if (PyLong_Check(v) && PyLong_Check(w) &&
215-
!_PyLong_IsZero((PyLongObject *)v) && _PyLong_IsPositive((PyLongObject *)w)
216-
) {
217-
int64_t vbits = _PyLong_NumBits(v);
218-
size_t wbits = PyLong_AsSize_t(w);
219-
assert(vbits >= 0);
220-
if (wbits == (size_t)-1) {
221-
return NULL;
222-
}
223-
if ((uint64_t)vbits > MAX_INT_SIZE / wbits) {
224-
return NULL;
225-
}
226-
}
227-
228-
return PyNumber_Power(v, w, Py_None);
229-
}
230-
231-
static PyObject *
232-
safe_lshift(PyObject *v, PyObject *w)
233-
{
234-
if (PyLong_Check(v) && PyLong_Check(w) &&
235-
!_PyLong_IsZero((PyLongObject *)v) && !_PyLong_IsZero((PyLongObject *)w)
236-
) {
237-
int64_t vbits = _PyLong_NumBits(v);
238-
size_t wbits = PyLong_AsSize_t(w);
239-
assert(vbits >= 0);
240-
if (wbits == (size_t)-1) {
241-
return NULL;
242-
}
243-
if (wbits > MAX_INT_SIZE || (uint64_t)vbits > MAX_INT_SIZE - wbits) {
244-
return NULL;
245-
}
246-
}
247-
248-
return PyNumber_Lshift(v, w);
249-
}
250-
251-
static PyObject *
252-
safe_mod(PyObject *v, PyObject *w)
253-
{
254-
if (PyUnicode_Check(v) || PyBytes_Check(v)) {
255-
return NULL;
256-
}
257-
258-
return PyNumber_Remainder(v, w);
259-
}
260-
261-
262147
static expr_ty
263148
parse_literal(PyObject *fmt, Py_ssize_t *ppos, PyArena *arena)
264149
{
@@ -478,58 +363,7 @@ fold_binop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
478363
return optimize_format(node, lv, rhs->v.Tuple.elts, arena);
479364
}
480365

481-
if (rhs->kind != Constant_kind) {
482-
return 1;
483-
}
484-
485-
PyObject *rv = rhs->v.Constant.value;
486-
PyObject *newval = NULL;
487-
488-
switch (node->v.BinOp.op) {
489-
case Add:
490-
newval = PyNumber_Add(lv, rv);
491-
break;
492-
case Sub:
493-
newval = PyNumber_Subtract(lv, rv);
494-
break;
495-
case Mult:
496-
newval = safe_multiply(lv, rv);
497-
break;
498-
case Div:
499-
newval = PyNumber_TrueDivide(lv, rv);
500-
break;
501-
case FloorDiv:
502-
newval = PyNumber_FloorDivide(lv, rv);
503-
break;
504-
case Mod:
505-
newval = safe_mod(lv, rv);
506-
break;
507-
case Pow:
508-
newval = safe_power(lv, rv);
509-
break;
510-
case LShift:
511-
newval = safe_lshift(lv, rv);
512-
break;
513-
case RShift:
514-
newval = PyNumber_Rshift(lv, rv);
515-
break;
516-
case BitOr:
517-
newval = PyNumber_Or(lv, rv);
518-
break;
519-
case BitXor:
520-
newval = PyNumber_Xor(lv, rv);
521-
break;
522-
case BitAnd:
523-
newval = PyNumber_And(lv, rv);
524-
break;
525-
// No builtin constants implement the following operators
526-
case MatMult:
527-
return 1;
528-
// No default case, so the compiler will emit a warning if new binary
529-
// operators are added without being handled here
530-
}
531-
532-
return make_const(node, newval, arena);
366+
return 1;
533367
}
534368

535369
static PyObject*

0 commit comments

Comments
 (0)