Branch data Line data Source code
1 : : /* AST Optimizer */
2 : : #include "Python.h"
3 : : #include "pycore_ast.h" // _PyAST_GetDocString()
4 : : #include "pycore_compile.h" // _PyASTOptimizeState
5 : : #include "pycore_pystate.h" // _PyThreadState_GET()
6 : : #include "pycore_format.h" // F_LJUST
7 : :
8 : :
9 : : static int
10 : 293584 : make_const(expr_ty node, PyObject *val, PyArena *arena)
11 : : {
12 : : // Even if no new value was calculated, make_const may still
13 : : // need to clear an error (e.g. for division by zero)
14 [ + + ]: 293584 : if (val == NULL) {
15 [ - + ]: 140729 : if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) {
16 : 0 : return 0;
17 : : }
18 : 140729 : PyErr_Clear();
19 : 140729 : return 1;
20 : : }
21 [ - + ]: 152855 : if (_PyArena_AddPyObject(arena, val) < 0) {
22 : 0 : Py_DECREF(val);
23 : 0 : return 0;
24 : : }
25 : 152855 : node->kind = Constant_kind;
26 : 152855 : node->v.Constant.kind = NULL;
27 : 152855 : node->v.Constant.value = val;
28 : 152855 : return 1;
29 : : }
30 : :
31 : : #define COPY_NODE(TO, FROM) (memcpy((TO), (FROM), sizeof(struct _expr)))
32 : :
33 : : static int
34 : 37679 : has_starred(asdl_expr_seq *elts)
35 : : {
36 [ + + ]: 37679 : Py_ssize_t n = asdl_seq_LEN(elts);
37 [ + + ]: 95167 : for (Py_ssize_t i = 0; i < n; i++) {
38 : 57507 : expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
39 [ + + ]: 57507 : if (e->kind == Starred_kind) {
40 : 19 : return 1;
41 : : }
42 : : }
43 : 37660 : return 0;
44 : : }
45 : :
46 : :
47 : : static PyObject*
48 : 30 : unary_not(PyObject *v)
49 : : {
50 : 30 : int r = PyObject_IsTrue(v);
51 [ - + ]: 30 : if (r < 0)
52 : 0 : return NULL;
53 : 30 : return PyBool_FromLong(!r);
54 : : }
55 : :
56 : : static int
57 : 81767 : fold_unaryop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
58 : : {
59 : 81767 : expr_ty arg = node->v.UnaryOp.operand;
60 : :
61 [ + + ]: 81767 : if (arg->kind != Constant_kind) {
62 : : /* Fold not into comparison */
63 [ + + + + ]: 55017 : if (node->v.UnaryOp.op == Not && arg->kind == Compare_kind &&
64 [ + - + + ]: 1636 : asdl_seq_LEN(arg->v.Compare.ops) == 1) {
65 : : /* Eq and NotEq are often implemented in terms of one another, so
66 : : folding not (self == other) into self != other breaks implementation
67 : : of !=. Detecting such cases doesn't seem worthwhile.
68 : : Python uses </> for 'is subset'/'is superset' operations on sets.
69 : : They don't satisfy not folding laws. */
70 : 957 : cmpop_ty op = asdl_seq_GET(arg->v.Compare.ops, 0);
71 [ + + + + : 957 : switch (op) {
+ - ]
72 : 29 : case Is:
73 : 29 : op = IsNot;
74 : 29 : break;
75 : 1 : case IsNot:
76 : 1 : op = Is;
77 : 1 : break;
78 : 519 : case In:
79 : 519 : op = NotIn;
80 : 519 : break;
81 : 2 : case NotIn:
82 : 2 : op = In;
83 : 2 : break;
84 : : // The remaining comparison operators can't be safely inverted
85 : 406 : case Eq:
86 : : case NotEq:
87 : : case Lt:
88 : : case LtE:
89 : : case Gt:
90 : : case GtE:
91 : 406 : op = 0; // The AST enums leave "0" free as an "unused" marker
92 : 406 : break;
93 : : // No default case, so the compiler will emit a warning if new
94 : : // comparison operators are added without being handled here
95 : : }
96 [ + + ]: 957 : if (op) {
97 : 551 : asdl_seq_SET(arg->v.Compare.ops, 0, op);
98 : 551 : COPY_NODE(node, arg);
99 : 551 : return 1;
100 : : }
101 : : }
102 : 54466 : return 1;
103 : : }
104 : :
105 : : typedef PyObject *(*unary_op)(PyObject*);
106 : : static const unary_op ops[] = {
107 : : [Invert] = PyNumber_Invert,
108 : : [Not] = unary_not,
109 : : [UAdd] = PyNumber_Positive,
110 : : [USub] = PyNumber_Negative,
111 : : };
112 : 26750 : PyObject *newval = ops[node->v.UnaryOp.op](arg->v.Constant.value);
113 : 26750 : return make_const(node, newval, arena);
114 : : }
115 : :
116 : : /* Check whether a collection doesn't containing too much items (including
117 : : subcollections). This protects from creating a constant that needs
118 : : too much time for calculating a hash.
119 : : "limit" is the maximal number of items.
120 : : Returns the negative number if the total number of items exceeds the
121 : : limit. Otherwise returns the limit minus the total number of items.
122 : : */
123 : :
124 : : static Py_ssize_t
125 : 84 : check_complexity(PyObject *obj, Py_ssize_t limit)
126 : : {
127 [ + + ]: 84 : if (PyTuple_Check(obj)) {
128 : : Py_ssize_t i;
129 : 39 : limit -= PyTuple_GET_SIZE(obj);
130 [ + - + + ]: 85 : for (i = 0; limit >= 0 && i < PyTuple_GET_SIZE(obj); i++) {
131 : 46 : limit = check_complexity(PyTuple_GET_ITEM(obj, i), limit);
132 : : }
133 : 39 : return limit;
134 : : }
135 [ + - - + ]: 45 : else if (PyFrozenSet_Check(obj)) {
136 : 0 : Py_ssize_t i = 0;
137 : : PyObject *item;
138 : : Py_hash_t hash;
139 : 0 : limit -= PySet_GET_SIZE(obj);
140 [ # # # # ]: 0 : while (limit >= 0 && _PySet_NextEntry(obj, &i, &item, &hash)) {
141 : 0 : limit = check_complexity(item, limit);
142 : : }
143 : : }
144 : 45 : return limit;
145 : : }
146 : :
147 : : #define MAX_INT_SIZE 128 /* bits */
148 : : #define MAX_COLLECTION_SIZE 256 /* items */
149 : : #define MAX_STR_SIZE 4096 /* characters */
150 : : #define MAX_TOTAL_ITEMS 1024 /* including nested collections */
151 : :
152 : : static PyObject *
153 : 3774 : safe_multiply(PyObject *v, PyObject *w)
154 : : {
155 [ + + + + : 4599 : if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) {
+ + + - ]
156 : 825 : size_t vbits = _PyLong_NumBits(v);
157 : 825 : size_t wbits = _PyLong_NumBits(w);
158 [ + - - + ]: 825 : if (vbits == (size_t)-1 || wbits == (size_t)-1) {
159 : 0 : return NULL;
160 : : }
161 [ - + ]: 825 : if (vbits + wbits > MAX_INT_SIZE) {
162 : 0 : return NULL;
163 : : }
164 : : }
165 [ + + + + : 2987 : else if (PyLong_Check(v) && (PyTuple_Check(w) || PyFrozenSet_Check(w))) {
+ - - + ]
166 [ + - ]: 42 : Py_ssize_t size = PyTuple_Check(w) ? PyTuple_GET_SIZE(w) :
167 : : PySet_GET_SIZE(w);
168 [ + - ]: 42 : if (size) {
169 : 42 : long n = PyLong_AsLong(v);
170 [ + - + + ]: 42 : if (n < 0 || n > MAX_COLLECTION_SIZE / size) {
171 : 4 : return NULL;
172 : : }
173 [ + - - + ]: 38 : if (n && check_complexity(w, MAX_TOTAL_ITEMS / n) < 0) {
174 : 0 : return NULL;
175 : : }
176 : : }
177 : : }
178 [ + + + + : 4140 : else if (PyLong_Check(v) && (PyUnicode_Check(w) || PyBytes_Check(w))) {
+ + ]
179 [ + + ]: 1427 : Py_ssize_t size = PyUnicode_Check(w) ? PyUnicode_GET_LENGTH(w) :
180 : 464 : PyBytes_GET_SIZE(w);
181 [ + - ]: 1427 : if (size) {
182 : 1427 : long n = PyLong_AsLong(v);
183 [ + - + + ]: 1427 : if (n < 0 || n > MAX_STR_SIZE / size) {
184 : 194 : return NULL;
185 : : }
186 : : }
187 : : }
188 [ + + + + ]: 2917 : else if (PyLong_Check(w) &&
189 [ + - + - : 4227 : (PyTuple_Check(v) || PyFrozenSet_Check(v) ||
+ + ]
190 [ + + ]: 1857 : PyUnicode_Check(v) || PyBytes_Check(v)))
191 : : {
192 : 1428 : return safe_multiply(w, v);
193 : : }
194 : :
195 : 2148 : return PyNumber_Multiply(v, w);
196 : : }
197 : :
198 : : static PyObject *
199 : 1281 : safe_power(PyObject *v, PyObject *w)
200 : : {
201 [ + + + - : 1281 : if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w) > 0) {
+ + + + ]
202 : 1215 : size_t vbits = _PyLong_NumBits(v);
203 : 1215 : size_t wbits = PyLong_AsSize_t(w);
204 [ + - - + ]: 1215 : if (vbits == (size_t)-1 || wbits == (size_t)-1) {
205 : 0 : return NULL;
206 : : }
207 [ + + ]: 1215 : if (vbits > MAX_INT_SIZE / wbits) {
208 : 222 : return NULL;
209 : : }
210 : : }
211 : :
212 : 1059 : return PyNumber_Power(v, w, Py_None);
213 : : }
214 : :
215 : : static PyObject *
216 : 1388 : safe_lshift(PyObject *v, PyObject *w)
217 : : {
218 [ + - + - : 1388 : if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) {
+ + + + ]
219 : 1342 : size_t vbits = _PyLong_NumBits(v);
220 : 1342 : size_t wbits = PyLong_AsSize_t(w);
221 [ + - + + ]: 1342 : if (vbits == (size_t)-1 || wbits == (size_t)-1) {
222 : 2 : return NULL;
223 : : }
224 [ + + + + ]: 1340 : if (wbits > MAX_INT_SIZE || vbits > MAX_INT_SIZE - wbits) {
225 : 68 : return NULL;
226 : : }
227 : : }
228 : :
229 : 1318 : return PyNumber_Lshift(v, w);
230 : : }
231 : :
232 : : static PyObject *
233 : 147 : safe_mod(PyObject *v, PyObject *w)
234 : : {
235 [ + + - + ]: 147 : if (PyUnicode_Check(v) || PyBytes_Check(v)) {
236 : 114 : return NULL;
237 : : }
238 : :
239 : 33 : return PyNumber_Remainder(v, w);
240 : : }
241 : :
242 : :
243 : : static expr_ty
244 : 64085 : parse_literal(PyObject *fmt, Py_ssize_t *ppos, PyArena *arena)
245 : : {
246 : 64085 : const void *data = PyUnicode_DATA(fmt);
247 : 64085 : int kind = PyUnicode_KIND(fmt);
248 : 64085 : Py_ssize_t size = PyUnicode_GET_LENGTH(fmt);
249 : : Py_ssize_t start, pos;
250 : 64085 : int has_percents = 0;
251 : 64085 : start = pos = *ppos;
252 [ + + ]: 338217 : while (pos < size) {
253 [ + + ]: 323362 : if (PyUnicode_READ(kind, data, pos) != '%') {
254 : 274086 : pos++;
255 : : }
256 [ + + + + ]: 49276 : else if (pos+1 < size && PyUnicode_READ(kind, data, pos+1) == '%') {
257 : 46 : has_percents = 1;
258 : 46 : pos += 2;
259 : : }
260 : : else {
261 : : break;
262 : : }
263 : : }
264 : 64085 : *ppos = pos;
265 [ + + ]: 64085 : if (pos == start) {
266 : 39076 : return NULL;
267 : : }
268 : 25009 : PyObject *str = PyUnicode_Substring(fmt, start, pos);
269 : : /* str = str.replace('%%', '%') */
270 [ + - + + ]: 25009 : if (str && has_percents) {
271 : : _Py_DECLARE_STR(percent, "%");
272 : : _Py_DECLARE_STR(dbl_percent, "%%");
273 : 31 : Py_SETREF(str, PyUnicode_Replace(str, &_Py_STR(dbl_percent),
274 : : &_Py_STR(percent), -1));
275 : : }
276 [ - + ]: 25009 : if (!str) {
277 : 0 : return NULL;
278 : : }
279 : :
280 [ - + ]: 25009 : if (_PyArena_AddPyObject(arena, str) < 0) {
281 : 0 : Py_DECREF(str);
282 : 0 : return NULL;
283 : : }
284 : 25009 : return _PyAST_Constant(str, NULL, -1, -1, -1, -1, arena);
285 : : }
286 : :
287 : : #define MAXDIGITS 3
288 : :
289 : : static int
290 : 49227 : simple_format_arg_parse(PyObject *fmt, Py_ssize_t *ppos,
291 : : int *spec, int *flags, int *width, int *prec)
292 : : {
293 : 49227 : Py_ssize_t pos = *ppos, len = PyUnicode_GET_LENGTH(fmt);
294 : : Py_UCS4 ch;
295 : :
296 : : #define NEXTC do { \
297 : : if (pos >= len) { \
298 : : return 0; \
299 : : } \
300 : : ch = PyUnicode_READ_CHAR(fmt, pos); \
301 : : pos++; \
302 : : } while (0)
303 : :
304 : 49227 : *flags = 0;
305 : : while (1) {
306 [ + + ]: 106854 : NEXTC;
307 [ + + + + : 106853 : switch (ch) {
+ + + ]
308 : 11544 : case '-': *flags |= F_LJUST; continue;
309 : 11446 : case '+': *flags |= F_SIGN; continue;
310 : 11428 : case ' ': *flags |= F_BLANK; continue;
311 : 11600 : case '#': *flags |= F_ALT; continue;
312 : 11608 : case '0': *flags |= F_ZERO; continue;
313 : 1 : case 'z': *flags |= F_NO_NEG_0; continue;
314 : : }
315 : 49226 : break;
316 : : }
317 [ + + + + ]: 49226 : if ('0' <= ch && ch <= '9') {
318 : 15060 : *width = 0;
319 : 15060 : int digits = 0;
320 [ + + + + ]: 38398 : while ('0' <= ch && ch <= '9') {
321 : 23360 : *width = *width * 10 + (ch - '0');
322 [ - + ]: 23360 : NEXTC;
323 [ + + ]: 23360 : if (++digits >= MAXDIGITS) {
324 : 22 : return 0;
325 : : }
326 : : }
327 : : }
328 : :
329 [ + + ]: 49204 : if (ch == '.') {
330 [ - + ]: 18028 : NEXTC;
331 : 18028 : *prec = 0;
332 [ + + + + ]: 18028 : if ('0' <= ch && ch <= '9') {
333 : 13117 : int digits = 0;
334 [ + - + + ]: 29500 : while ('0' <= ch && ch <= '9') {
335 : 16383 : *prec = *prec * 10 + (ch - '0');
336 [ - + ]: 16383 : NEXTC;
337 [ - + ]: 16383 : if (++digits >= MAXDIGITS) {
338 : 0 : return 0;
339 : : }
340 : : }
341 : : }
342 : : }
343 : 49204 : *spec = ch;
344 : 49204 : *ppos = pos;
345 : 49204 : return 1;
346 : :
347 : : #undef NEXTC
348 : : }
349 : :
350 : : static expr_ty
351 : 49227 : parse_format(PyObject *fmt, Py_ssize_t *ppos, expr_ty arg, PyArena *arena)
352 : : {
353 : 49227 : int spec, flags, width = -1, prec = -1;
354 [ + + ]: 49227 : if (!simple_format_arg_parse(fmt, ppos, &spec, &flags, &width, &prec)) {
355 : : // Unsupported format.
356 : 23 : return NULL;
357 : : }
358 [ + + + + : 49204 : if (spec == 's' || spec == 'r' || spec == 'a') {
+ + ]
359 : 27960 : char buf[1 + MAXDIGITS + 1 + MAXDIGITS + 1], *p = buf;
360 [ + + + + ]: 27960 : if (!(flags & F_LJUST) && width > 0) {
361 : 1311 : *p++ = '>';
362 : : }
363 [ + + ]: 27960 : if (width >= 0) {
364 : 2693 : p += snprintf(p, MAXDIGITS + 1, "%d", width);
365 : : }
366 [ + + ]: 27960 : if (prec >= 0) {
367 : 3169 : p += snprintf(p, MAXDIGITS + 2, ".%d", prec);
368 : : }
369 : 27960 : expr_ty format_spec = NULL;
370 [ + + ]: 27960 : if (p != buf) {
371 : 3846 : PyObject *str = PyUnicode_FromString(buf);
372 [ - + ]: 3846 : if (str == NULL) {
373 : 0 : return NULL;
374 : : }
375 [ - + ]: 3846 : if (_PyArena_AddPyObject(arena, str) < 0) {
376 : 0 : Py_DECREF(str);
377 : 0 : return NULL;
378 : : }
379 : 3846 : format_spec = _PyAST_Constant(str, NULL, -1, -1, -1, -1, arena);
380 [ - + ]: 3846 : if (format_spec == NULL) {
381 : 0 : return NULL;
382 : : }
383 : : }
384 : 27960 : return _PyAST_FormattedValue(arg, spec, format_spec,
385 : : arg->lineno, arg->col_offset,
386 : : arg->end_lineno, arg->end_col_offset,
387 : : arena);
388 : : }
389 : : // Unsupported format.
390 : 21244 : return NULL;
391 : : }
392 : :
393 : : static int
394 : 36125 : optimize_format(expr_ty node, PyObject *fmt, asdl_expr_seq *elts, PyArena *arena)
395 : : {
396 : 36125 : Py_ssize_t pos = 0;
397 : 36125 : Py_ssize_t cnt = 0;
398 [ + - ]: 36125 : asdl_expr_seq *seq = _Py_asdl_expr_seq_new(asdl_seq_LEN(elts) * 2 + 1, arena);
399 [ - + ]: 36125 : if (!seq) {
400 : 0 : return 0;
401 : : }
402 : 36125 : seq->size = 0;
403 : :
404 : 27960 : while (1) {
405 : 64085 : expr_ty lit = parse_literal(fmt, &pos, arena);
406 [ + + ]: 64085 : if (lit) {
407 : 25009 : asdl_seq_SET(seq, seq->size++, lit);
408 : : }
409 [ - + ]: 39076 : else if (PyErr_Occurred()) {
410 : 0 : return 0;
411 : : }
412 : :
413 [ + + ]: 64085 : if (pos >= PyUnicode_GET_LENGTH(fmt)) {
414 : 14855 : break;
415 : : }
416 [ + - + + ]: 49230 : if (cnt >= asdl_seq_LEN(elts)) {
417 : : // More format units than items.
418 : 3 : return 1;
419 : : }
420 : : assert(PyUnicode_READ_CHAR(fmt, pos) == '%');
421 : 49227 : pos++;
422 : 49227 : expr_ty expr = parse_format(fmt, &pos, asdl_seq_GET(elts, cnt), arena);
423 : 49227 : cnt++;
424 [ + + ]: 49227 : if (!expr) {
425 : 21267 : return !PyErr_Occurred();
426 : : }
427 : 27960 : asdl_seq_SET(seq, seq->size++, expr);
428 : : }
429 [ + - + + ]: 14855 : if (cnt < asdl_seq_LEN(elts)) {
430 : : // More items than format units.
431 : 1 : return 1;
432 : : }
433 : 14854 : expr_ty res = _PyAST_JoinedStr(seq,
434 : : node->lineno, node->col_offset,
435 : : node->end_lineno, node->end_col_offset,
436 : : arena);
437 [ - + ]: 14854 : if (!res) {
438 : 0 : return 0;
439 : : }
440 : 14854 : COPY_NODE(node, res);
441 : : // PySys_FormatStderr("format = %R\n", fmt);
442 : 14854 : return 1;
443 : : }
444 : :
445 : : static int
446 : 218005 : fold_binop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
447 : : {
448 : : expr_ty lhs, rhs;
449 : 218005 : lhs = node->v.BinOp.left;
450 : 218005 : rhs = node->v.BinOp.right;
451 [ + + ]: 218005 : if (lhs->kind != Constant_kind) {
452 : 139116 : return 1;
453 : : }
454 : 78889 : PyObject *lv = lhs->v.Constant.value;
455 : :
456 [ + + ]: 78889 : if (node->v.BinOp.op == Mod &&
457 [ + + + + ]: 88958 : rhs->kind == Tuple_kind &&
458 [ + + ]: 72288 : PyUnicode_Check(lv) &&
459 : 36139 : !has_starred(rhs->v.Tuple.elts))
460 : : {
461 : 36125 : return optimize_format(node, lv, rhs->v.Tuple.elts, arena);
462 : : }
463 : :
464 [ + + ]: 42764 : if (rhs->kind != Constant_kind) {
465 : 34227 : return 1;
466 : : }
467 : :
468 : 8537 : PyObject *rv = rhs->v.Constant.value;
469 : 8537 : PyObject *newval = NULL;
470 : :
471 [ + + + + : 8537 : switch (node->v.BinOp.op) {
+ + + + +
+ + + -
- ]
472 : 1954 : case Add:
473 : 1954 : newval = PyNumber_Add(lv, rv);
474 : 1954 : break;
475 : 714 : case Sub:
476 : 714 : newval = PyNumber_Subtract(lv, rv);
477 : 714 : break;
478 : 2346 : case Mult:
479 : 2346 : newval = safe_multiply(lv, rv);
480 : 2346 : break;
481 : 558 : case Div:
482 : 558 : newval = PyNumber_TrueDivide(lv, rv);
483 : 558 : break;
484 : 75 : case FloorDiv:
485 : 75 : newval = PyNumber_FloorDivide(lv, rv);
486 : 75 : break;
487 : 147 : case Mod:
488 : 147 : newval = safe_mod(lv, rv);
489 : 147 : break;
490 : 1281 : case Pow:
491 : 1281 : newval = safe_power(lv, rv);
492 : 1281 : break;
493 : 1388 : case LShift:
494 : 1388 : newval = safe_lshift(lv, rv);
495 : 1388 : break;
496 : 23 : case RShift:
497 : 23 : newval = PyNumber_Rshift(lv, rv);
498 : 23 : break;
499 : 31 : case BitOr:
500 : 31 : newval = PyNumber_Or(lv, rv);
501 : 31 : break;
502 : 10 : case BitXor:
503 : 10 : newval = PyNumber_Xor(lv, rv);
504 : 10 : break;
505 : 10 : case BitAnd:
506 : 10 : newval = PyNumber_And(lv, rv);
507 : 10 : break;
508 : : // No builtin constants implement the following operators
509 : 0 : case MatMult:
510 : 0 : return 1;
511 : : // No default case, so the compiler will emit a warning if new binary
512 : : // operators are added without being handled here
513 : : }
514 : :
515 : 8537 : return make_const(node, newval, arena);
516 : : }
517 : :
518 : : static PyObject*
519 : 257924 : make_const_tuple(asdl_expr_seq *elts)
520 : : {
521 [ + + + + ]: 981205 : for (int i = 0; i < asdl_seq_LEN(elts); i++) {
522 : 862964 : expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
523 [ + + ]: 862964 : if (e->kind != Constant_kind) {
524 : 139683 : return NULL;
525 : : }
526 : : }
527 : :
528 [ + + ]: 118241 : PyObject *newval = PyTuple_New(asdl_seq_LEN(elts));
529 [ - + ]: 118241 : if (newval == NULL) {
530 : 0 : return NULL;
531 : : }
532 : :
533 [ + + + + ]: 825122 : for (int i = 0; i < asdl_seq_LEN(elts); i++) {
534 : 706881 : expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
535 : 706881 : PyObject *v = e->v.Constant.value;
536 : 706881 : Py_INCREF(v);
537 : 706881 : PyTuple_SET_ITEM(newval, i, v);
538 : : }
539 : 118241 : return newval;
540 : : }
541 : :
542 : : static int
543 : 297413 : fold_tuple(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
544 : : {
545 : : PyObject *newval;
546 : :
547 [ + + ]: 297413 : if (node->v.Tuple.ctx != Load)
548 : 41921 : return 1;
549 : :
550 : 255492 : newval = make_const_tuple(node->v.Tuple.elts);
551 : 255492 : return make_const(node, newval, arena);
552 : : }
553 : :
554 : : static int
555 : 187346 : fold_subscr(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
556 : : {
557 : : PyObject *newval;
558 : : expr_ty arg, idx;
559 : :
560 : 187346 : arg = node->v.Subscript.value;
561 : 187346 : idx = node->v.Subscript.slice;
562 [ + + ]: 187346 : if (node->v.Subscript.ctx != Load ||
563 [ + + ]: 154196 : arg->kind != Constant_kind ||
564 [ + + ]: 228 : idx->kind != Constant_kind)
565 : : {
566 : 187217 : return 1;
567 : : }
568 : :
569 : 129 : newval = PyObject_GetItem(arg->v.Constant.value, idx->v.Constant.value);
570 : 129 : return make_const(node, newval, arena);
571 : : }
572 : :
573 : : /* Change literal list or set of constants into constant
574 : : tuple or frozenset respectively. Change literal list of
575 : : non-constants into tuple.
576 : : Used for right operand of "in" and "not in" tests and for iterable
577 : : in "for" loop and comprehensions.
578 : : */
579 : : static int
580 : 101939 : fold_iter(expr_ty arg, PyArena *arena, _PyASTOptimizeState *state)
581 : : {
582 : : PyObject *newval;
583 [ + + ]: 101939 : if (arg->kind == List_kind) {
584 : : /* First change a list into tuple. */
585 : 1540 : asdl_expr_seq *elts = arg->v.List.elts;
586 [ + + ]: 1540 : if (has_starred(elts)) {
587 : 5 : return 1;
588 : : }
589 : 1535 : expr_context_ty ctx = arg->v.List.ctx;
590 : 1535 : arg->kind = Tuple_kind;
591 : 1535 : arg->v.Tuple.elts = elts;
592 : 1535 : arg->v.Tuple.ctx = ctx;
593 : : /* Try to create a constant tuple. */
594 : 1535 : newval = make_const_tuple(elts);
595 : : }
596 [ + + ]: 100399 : else if (arg->kind == Set_kind) {
597 : 897 : newval = make_const_tuple(arg->v.Set.elts);
598 [ + + ]: 897 : if (newval) {
599 : 752 : Py_SETREF(newval, PyFrozenSet_New(newval));
600 : : }
601 : : }
602 : : else {
603 : 99502 : return 1;
604 : : }
605 : 2432 : return make_const(arg, newval, arena);
606 : : }
607 : :
608 : : static int
609 : 207275 : fold_compare(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
610 : : {
611 : : asdl_int_seq *ops;
612 : : asdl_expr_seq *args;
613 : : Py_ssize_t i;
614 : :
615 : 207275 : ops = node->v.Compare.ops;
616 : 207275 : args = node->v.Compare.comparators;
617 : : /* Change literal list or set in 'in' or 'not in' into
618 : : tuple or frozenset respectively. */
619 [ + - ]: 207275 : i = asdl_seq_LEN(ops) - 1;
620 : 207275 : int op = asdl_seq_GET(ops, i);
621 [ + + + + ]: 207275 : if (op == In || op == NotIn) {
622 [ - + ]: 37606 : if (!fold_iter((expr_ty)asdl_seq_GET(args, i), arena, state)) {
623 : 0 : return 0;
624 : : }
625 : : }
626 : 207275 : return 1;
627 : : }
628 : :
629 : : static int astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
630 : : static int astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
631 : : static int astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
632 : : static int astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
633 : : static int astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
634 : : static int astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
635 : : static int astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
636 : : static int astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
637 : : static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
638 : : static int astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
639 : : static int astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
640 : :
641 : : #define CALL(FUNC, TYPE, ARG) \
642 : : if (!FUNC((ARG), ctx_, state)) \
643 : : return 0;
644 : :
645 : : #define CALL_OPT(FUNC, TYPE, ARG) \
646 : : if ((ARG) != NULL && !FUNC((ARG), ctx_, state)) \
647 : : return 0;
648 : :
649 : : #define CALL_SEQ(FUNC, TYPE, ARG) { \
650 : : int i; \
651 : : asdl_ ## TYPE ## _seq *seq = (ARG); /* avoid variable capture */ \
652 : : for (i = 0; i < asdl_seq_LEN(seq); i++) { \
653 : : TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
654 : : if (elt != NULL && !FUNC(elt, ctx_, state)) \
655 : : return 0; \
656 : : } \
657 : : }
658 : :
659 : :
660 : : static int
661 : 334602 : astfold_body(asdl_stmt_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state)
662 : : {
663 : 334602 : int docstring = _PyAST_GetDocString(stmts) != NULL;
664 [ + - - + : 1903460 : CALL_SEQ(astfold_stmt, stmt, stmts);
+ + + + ]
665 [ + + - + ]: 334602 : if (!docstring && _PyAST_GetDocString(stmts) != NULL) {
666 : 0 : stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
667 : 0 : asdl_expr_seq *values = _Py_asdl_expr_seq_new(1, ctx_);
668 [ # # ]: 0 : if (!values) {
669 : 0 : return 0;
670 : : }
671 : 0 : asdl_seq_SET(values, 0, st->v.Expr.value);
672 : 0 : expr_ty expr = _PyAST_JoinedStr(values, st->lineno, st->col_offset,
673 : : st->end_lineno, st->end_col_offset,
674 : : ctx_);
675 [ # # ]: 0 : if (!expr) {
676 : 0 : return 0;
677 : : }
678 : 0 : st->v.Expr.value = expr;
679 : : }
680 : 334602 : return 1;
681 : : }
682 : :
683 : : static int
684 : 114073 : astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
685 : : {
686 [ + + + - : 114073 : switch (node_->kind) {
- ]
687 : 38581 : case Module_kind:
688 [ - + ]: 38581 : CALL(astfold_body, asdl_seq, node_->v.Module.body);
689 : 38581 : break;
690 : 4151 : case Interactive_kind:
691 [ + - + + : 8355 : CALL_SEQ(astfold_stmt, stmt, node_->v.Interactive.body);
+ - + + ]
692 : 4143 : break;
693 : 71341 : case Expression_kind:
694 [ - + ]: 71341 : CALL(astfold_expr, expr_ty, node_->v.Expression.body);
695 : 71341 : break;
696 : : // The following top level nodes don't participate in constant folding
697 : 0 : case FunctionType_kind:
698 : 0 : break;
699 : : // No default case, so the compiler will emit a warning if new top level
700 : : // compilation nodes are added without being handled here
701 : : }
702 : 114065 : return 1;
703 : : }
704 : :
705 : : static int
706 : 12035282 : astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
707 : : {
708 [ + + ]: 12035282 : if (++state->recursion_depth > state->recursion_limit) {
709 : 8 : PyErr_SetString(PyExc_RecursionError,
710 : : "maximum recursion depth exceeded during compilation");
711 : 8 : return 0;
712 : : }
713 [ + + + + : 12035274 : switch (node_->kind) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + - ]
714 : 57513 : case BoolOp_kind:
715 [ + - - + : 180746 : CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values);
+ - + + ]
716 : 57513 : break;
717 : 223811 : case BinOp_kind:
718 [ + + ]: 223811 : CALL(astfold_expr, expr_ty, node_->v.BinOp.left);
719 [ - + ]: 218005 : CALL(astfold_expr, expr_ty, node_->v.BinOp.right);
720 [ - + ]: 218005 : CALL(fold_binop, expr_ty, node_);
721 : 218005 : break;
722 : 81767 : case UnaryOp_kind:
723 [ - + ]: 81767 : CALL(astfold_expr, expr_ty, node_->v.UnaryOp.operand);
724 [ - + ]: 81767 : CALL(fold_unaryop, expr_ty, node_);
725 : 81767 : break;
726 : 34511 : case Lambda_kind:
727 [ - + ]: 34511 : CALL(astfold_arguments, arguments_ty, node_->v.Lambda.args);
728 [ - + ]: 34511 : CALL(astfold_expr, expr_ty, node_->v.Lambda.body);
729 : 34511 : break;
730 : 9775 : case IfExp_kind:
731 [ - + ]: 9775 : CALL(astfold_expr, expr_ty, node_->v.IfExp.test);
732 [ - + ]: 9775 : CALL(astfold_expr, expr_ty, node_->v.IfExp.body);
733 [ - + ]: 9775 : CALL(astfold_expr, expr_ty, node_->v.IfExp.orelse);
734 : 9775 : break;
735 : 32216 : case Dict_kind:
736 [ + + - + : 649911 : CALL_SEQ(astfold_expr, expr, node_->v.Dict.keys);
+ - + + ]
737 [ + - - + : 649911 : CALL_SEQ(astfold_expr, expr, node_->v.Dict.values);
+ - + + ]
738 : 32216 : break;
739 : 2568 : case Set_kind:
740 [ + - - + : 12097 : CALL_SEQ(astfold_expr, expr, node_->v.Set.elts);
+ - + + ]
741 : 2568 : break;
742 : 8510 : case ListComp_kind:
743 [ - + ]: 8510 : CALL(astfold_expr, expr_ty, node_->v.ListComp.elt);
744 [ + - - + : 17302 : CALL_SEQ(astfold_comprehension, comprehension, node_->v.ListComp.generators);
+ - + + ]
745 : 8510 : break;
746 : 465 : case SetComp_kind:
747 [ - + ]: 465 : CALL(astfold_expr, expr_ty, node_->v.SetComp.elt);
748 [ + - - + : 981 : CALL_SEQ(astfold_comprehension, comprehension, node_->v.SetComp.generators);
+ - + + ]
749 : 465 : break;
750 : 1169 : case DictComp_kind:
751 [ - + ]: 1169 : CALL(astfold_expr, expr_ty, node_->v.DictComp.key);
752 [ - + ]: 1169 : CALL(astfold_expr, expr_ty, node_->v.DictComp.value);
753 [ + - - + : 2385 : CALL_SEQ(astfold_comprehension, comprehension, node_->v.DictComp.generators);
+ - + + ]
754 : 1169 : break;
755 : 7708 : case GeneratorExp_kind:
756 [ - + ]: 7708 : CALL(astfold_expr, expr_ty, node_->v.GeneratorExp.elt);
757 [ + - - + : 15643 : CALL_SEQ(astfold_comprehension, comprehension, node_->v.GeneratorExp.generators);
+ - + + ]
758 : 7708 : break;
759 : 1722 : case Await_kind:
760 [ - + ]: 1722 : CALL(astfold_expr, expr_ty, node_->v.Await.value);
761 : 1722 : break;
762 : 11411 : case Yield_kind:
763 [ + + - + ]: 11411 : CALL_OPT(astfold_expr, expr_ty, node_->v.Yield.value);
764 : 11411 : break;
765 : 1896 : case YieldFrom_kind:
766 [ - + ]: 1896 : CALL(astfold_expr, expr_ty, node_->v.YieldFrom.value);
767 : 1896 : break;
768 : 207275 : case Compare_kind:
769 [ - + ]: 207275 : CALL(astfold_expr, expr_ty, node_->v.Compare.left);
770 [ + - - + : 417275 : CALL_SEQ(astfold_expr, expr, node_->v.Compare.comparators);
+ - + + ]
771 [ - + ]: 207275 : CALL(fold_compare, expr_ty, node_);
772 : 207275 : break;
773 : 1119993 : case Call_kind:
774 [ + + ]: 1119993 : CALL(astfold_expr, expr_ty, node_->v.Call.func);
775 [ + - - + : 2528796 : CALL_SEQ(astfold_expr, expr, node_->v.Call.args);
+ + + + ]
776 [ + - - + : 1247686 : CALL_SEQ(astfold_keyword, keyword, node_->v.Call.keywords);
+ + + + ]
777 : 1114193 : break;
778 : 91478 : case FormattedValue_kind:
779 [ - + ]: 91478 : CALL(astfold_expr, expr_ty, node_->v.FormattedValue.value);
780 [ + + - + ]: 91478 : CALL_OPT(astfold_expr, expr_ty, node_->v.FormattedValue.format_spec);
781 : 91478 : break;
782 : 15500 : case JoinedStr_kind:
783 [ + - - + : 201673 : CALL_SEQ(astfold_expr, expr, node_->v.JoinedStr.values);
+ - + + ]
784 : 15500 : break;
785 : 1323017 : case Attribute_kind:
786 [ + + ]: 1323017 : CALL(astfold_expr, expr_ty, node_->v.Attribute.value);
787 : 1317217 : break;
788 : 193149 : case Subscript_kind:
789 [ + + ]: 193149 : CALL(astfold_expr, expr_ty, node_->v.Subscript.value);
790 [ - + ]: 187346 : CALL(astfold_expr, expr_ty, node_->v.Subscript.slice);
791 [ - + ]: 187346 : CALL(fold_subscr, expr_ty, node_);
792 : 187346 : break;
793 : 9995 : case Starred_kind:
794 [ - + ]: 9995 : CALL(astfold_expr, expr_ty, node_->v.Starred.value);
795 : 9995 : break;
796 : 30614 : case Slice_kind:
797 [ + + - + ]: 30614 : CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.lower);
798 [ + + - + ]: 30614 : CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.upper);
799 [ + + - + ]: 30614 : CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step);
800 : 30614 : break;
801 : 64723 : case List_kind:
802 [ + - - + : 582691 : CALL_SEQ(astfold_expr, expr, node_->v.List.elts);
+ + + + ]
803 : 64723 : break;
804 : 297413 : case Tuple_kind:
805 [ + - - + : 1476329 : CALL_SEQ(astfold_expr, expr, node_->v.Tuple.elts);
+ + + + ]
806 [ - + ]: 297413 : CALL(fold_tuple, expr_ty, node_);
807 : 297413 : break;
808 : 4639390 : case Name_kind:
809 [ + + + + ]: 8624227 : if (node_->v.Name.ctx == Load &&
810 : 3984837 : _PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) {
811 : 244 : state->recursion_depth--;
812 : 244 : return make_const(node_, PyBool_FromLong(!state->optimize), ctx_);
813 : : }
814 : 4639146 : break;
815 : 747 : case NamedExpr_kind:
816 [ - + ]: 747 : CALL(astfold_expr, expr_ty, node_->v.NamedExpr.value);
817 : 747 : break;
818 : 3566938 : case Constant_kind:
819 : : // Already a constant, nothing further to do
820 : 3566938 : break;
821 : : // No default case, so the compiler will emit a warning if new expression
822 : : // kinds are added without being handled here
823 : : }
824 : 12011821 : state->recursion_depth--;
825 : 12011821 : return 1;
826 : : }
827 : :
828 : : static int
829 : 134583 : astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
830 : : {
831 [ - + ]: 134583 : CALL(astfold_expr, expr_ty, node_->value);
832 : 134583 : return 1;
833 : : }
834 : :
835 : : static int
836 : 18459 : astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
837 : : {
838 [ - + ]: 18459 : CALL(astfold_expr, expr_ty, node_->target);
839 [ - + ]: 18459 : CALL(astfold_expr, expr_ty, node_->iter);
840 [ + - - + : 22669 : CALL_SEQ(astfold_expr, expr, node_->ifs);
+ - + + ]
841 : :
842 [ - + ]: 18459 : CALL(fold_iter, expr_ty, node_->iter);
843 : 18459 : return 1;
844 : : }
845 : :
846 : : static int
847 : 293154 : astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
848 : : {
849 [ + - - + : 311913 : CALL_SEQ(astfold_arg, arg, node_->posonlyargs);
+ - + + ]
850 [ + - - + : 887456 : CALL_SEQ(astfold_arg, arg, node_->args);
+ - + + ]
851 [ + + - + ]: 293154 : CALL_OPT(astfold_arg, arg_ty, node_->vararg);
852 [ + - - + : 309828 : CALL_SEQ(astfold_arg, arg, node_->kwonlyargs);
+ - + + ]
853 [ + + - + : 309828 : CALL_SEQ(astfold_expr, expr, node_->kw_defaults);
+ - + + ]
854 [ + + - + ]: 293154 : CALL_OPT(astfold_arg, arg_ty, node_->kwarg);
855 [ + - - + : 358429 : CALL_SEQ(astfold_expr, expr, node_->defaults);
+ - + + ]
856 : 293154 : return 1;
857 : : }
858 : :
859 : : static int
860 : 677348 : astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
861 : : {
862 [ + + ]: 677348 : if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) {
863 [ + + - + ]: 675241 : CALL_OPT(astfold_expr, expr_ty, node_->annotation);
864 : : }
865 : 677348 : return 1;
866 : : }
867 : :
868 : : static int
869 : 2594945 : astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
870 : : {
871 [ - + ]: 2594945 : if (++state->recursion_depth > state->recursion_limit) {
872 : 0 : PyErr_SetString(PyExc_RecursionError,
873 : : "maximum recursion depth exceeded during compilation");
874 : 0 : return 0;
875 : : }
876 [ + + + + : 2594945 : switch (node_->kind) {
+ + + + +
+ + + + +
+ + + + +
+ + - ]
877 : 256350 : case FunctionDef_kind:
878 [ - + ]: 256350 : CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args);
879 [ - + ]: 256350 : CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body);
880 [ + - - + : 280245 : CALL_SEQ(astfold_expr, expr, node_->v.FunctionDef.decorator_list);
+ + + + ]
881 [ + + ]: 256350 : if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) {
882 [ + + - + ]: 254966 : CALL_OPT(astfold_expr, expr_ty, node_->v.FunctionDef.returns);
883 : : }
884 : 256350 : break;
885 : 2293 : case AsyncFunctionDef_kind:
886 [ - + ]: 2293 : CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args);
887 [ - + ]: 2293 : CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body);
888 [ + - - + : 2493 : CALL_SEQ(astfold_expr, expr, node_->v.AsyncFunctionDef.decorator_list);
+ + + + ]
889 [ + + ]: 2293 : if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) {
890 [ + + - + ]: 1948 : CALL_OPT(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.returns);
891 : : }
892 : 2293 : break;
893 : 37378 : case ClassDef_kind:
894 [ + - - + : 69305 : CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.bases);
+ + + + ]
895 [ + - - + : 38468 : CALL_SEQ(astfold_keyword, keyword, node_->v.ClassDef.keywords);
+ + + + ]
896 [ - + ]: 37378 : CALL(astfold_body, asdl_seq, node_->v.ClassDef.body);
897 [ + - - + : 39024 : CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.decorator_list);
+ + + + ]
898 : 37378 : break;
899 : 210332 : case Return_kind:
900 [ + + - + ]: 210332 : CALL_OPT(astfold_expr, expr_ty, node_->v.Return.value);
901 : 210332 : break;
902 : 6337 : case Delete_kind:
903 [ + - - + : 13537 : CALL_SEQ(astfold_expr, expr, node_->v.Delete.targets);
+ - + + ]
904 : 6337 : break;
905 : 631307 : case Assign_kind:
906 [ + - - + : 1268970 : CALL_SEQ(astfold_expr, expr, node_->v.Assign.targets);
+ - + + ]
907 [ - + ]: 631307 : CALL(astfold_expr, expr_ty, node_->v.Assign.value);
908 : 631307 : break;
909 : 21379 : case AugAssign_kind:
910 [ - + ]: 21379 : CALL(astfold_expr, expr_ty, node_->v.AugAssign.target);
911 [ - + ]: 21379 : CALL(astfold_expr, expr_ty, node_->v.AugAssign.value);
912 : 21379 : break;
913 : 9873 : case AnnAssign_kind:
914 [ - + ]: 9873 : CALL(astfold_expr, expr_ty, node_->v.AnnAssign.target);
915 [ + + ]: 9873 : if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) {
916 [ - + ]: 8929 : CALL(astfold_expr, expr_ty, node_->v.AnnAssign.annotation);
917 : : }
918 [ + + - + ]: 9873 : CALL_OPT(astfold_expr, expr_ty, node_->v.AnnAssign.value);
919 : 9873 : break;
920 : 45874 : case For_kind:
921 [ - + ]: 45874 : CALL(astfold_expr, expr_ty, node_->v.For.target);
922 [ - + ]: 45874 : CALL(astfold_expr, expr_ty, node_->v.For.iter);
923 [ + - - + : 140644 : CALL_SEQ(astfold_stmt, stmt, node_->v.For.body);
+ - + + ]
924 [ + - - + : 47475 : CALL_SEQ(astfold_stmt, stmt, node_->v.For.orelse);
+ + + + ]
925 : :
926 [ - + ]: 45874 : CALL(fold_iter, expr_ty, node_->v.For.iter);
927 : 45874 : break;
928 : 81 : case AsyncFor_kind:
929 [ - + ]: 81 : CALL(astfold_expr, expr_ty, node_->v.AsyncFor.target);
930 [ - + ]: 81 : CALL(astfold_expr, expr_ty, node_->v.AsyncFor.iter);
931 [ + - - + : 167 : CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncFor.body);
+ - + + ]
932 [ + - - + : 98 : CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncFor.orelse);
+ + + + ]
933 : 81 : break;
934 : 9861 : case While_kind:
935 [ - + ]: 9861 : CALL(astfold_expr, expr_ty, node_->v.While.test);
936 [ + - - + : 42085 : CALL_SEQ(astfold_stmt, stmt, node_->v.While.body);
+ - + + ]
937 [ + - - + : 10099 : CALL_SEQ(astfold_stmt, stmt, node_->v.While.orelse);
+ + + + ]
938 : 9861 : break;
939 : 482970 : case If_kind:
940 [ - + ]: 482970 : CALL(astfold_expr, expr_ty, node_->v.If.test);
941 [ + - - + : 1104921 : CALL_SEQ(astfold_stmt, stmt, node_->v.If.body);
+ - + + ]
942 [ + - - + : 591335 : CALL_SEQ(astfold_stmt, stmt, node_->v.If.orelse);
+ + + + ]
943 : 482970 : break;
944 : 20594 : case With_kind:
945 [ + - - + : 41564 : CALL_SEQ(astfold_withitem, withitem, node_->v.With.items);
+ - + + ]
946 [ + - - + : 60182 : CALL_SEQ(astfold_stmt, stmt, node_->v.With.body);
+ - + + ]
947 : 20594 : break;
948 : 225 : case AsyncWith_kind:
949 [ + - - + : 458 : CALL_SEQ(astfold_withitem, withitem, node_->v.AsyncWith.items);
+ - + + ]
950 [ + - - + : 598 : CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncWith.body);
+ - + + ]
951 : 225 : break;
952 : 52393 : case Raise_kind:
953 [ + + - + ]: 52393 : CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.exc);
954 [ + + - + ]: 52393 : CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.cause);
955 : 52393 : break;
956 : 39394 : case Try_kind:
957 [ + - - + : 97419 : CALL_SEQ(astfold_stmt, stmt, node_->v.Try.body);
+ - + + ]
958 [ + - - + : 75726 : CALL_SEQ(astfold_excepthandler, excepthandler, node_->v.Try.handlers);
+ + + + ]
959 [ + - - + : 46652 : CALL_SEQ(astfold_stmt, stmt, node_->v.Try.orelse);
+ + + + ]
960 [ + - - + : 46510 : CALL_SEQ(astfold_stmt, stmt, node_->v.Try.finalbody);
+ + + + ]
961 : 39394 : break;
962 : 108 : case TryStar_kind:
963 [ + - - + : 218 : CALL_SEQ(astfold_stmt, stmt, node_->v.TryStar.body);
+ - + + ]
964 [ + - - + : 236 : CALL_SEQ(astfold_excepthandler, excepthandler, node_->v.TryStar.handlers);
+ - + + ]
965 [ + - - + : 152 : CALL_SEQ(astfold_stmt, stmt, node_->v.TryStar.orelse);
+ + + + ]
966 [ + - - + : 133 : CALL_SEQ(astfold_stmt, stmt, node_->v.TryStar.finalbody);
+ + + + ]
967 : 108 : break;
968 : 8461 : case Assert_kind:
969 [ - + ]: 8461 : CALL(astfold_expr, expr_ty, node_->v.Assert.test);
970 [ + + - + ]: 8461 : CALL_OPT(astfold_expr, expr_ty, node_->v.Assert.msg);
971 : 8461 : break;
972 : 647198 : case Expr_kind:
973 [ + + ]: 647198 : CALL(astfold_expr, expr_ty, node_->v.Expr.value);
974 : 647190 : break;
975 : 685 : case Match_kind:
976 [ - + ]: 685 : CALL(astfold_expr, expr_ty, node_->v.Match.subject);
977 [ + - - + : 1679 : CALL_SEQ(astfold_match_case, match_case, node_->v.Match.cases);
+ - + + ]
978 : 685 : break;
979 : : // The following statements don't contain any subexpressions to be folded
980 : 111852 : case Import_kind:
981 : : case ImportFrom_kind:
982 : : case Global_kind:
983 : : case Nonlocal_kind:
984 : : case Pass_kind:
985 : : case Break_kind:
986 : : case Continue_kind:
987 : 111852 : break;
988 : : // No default case, so the compiler will emit a warning if new statement
989 : : // kinds are added without being handled here
990 : : }
991 : 2594937 : state->recursion_depth--;
992 : 2594937 : return 1;
993 : : }
994 : :
995 : : static int
996 : 36460 : astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
997 : : {
998 [ + - ]: 36460 : switch (node_->kind) {
999 : 36460 : case ExceptHandler_kind:
1000 [ + + - + ]: 36460 : CALL_OPT(astfold_expr, expr_ty, node_->v.ExceptHandler.type);
1001 [ + - - + : 85440 : CALL_SEQ(astfold_stmt, stmt, node_->v.ExceptHandler.body);
+ - + + ]
1002 : 36460 : break;
1003 : : // No default case, so the compiler will emit a warning if new handler
1004 : : // kinds are added without being handled here
1005 : : }
1006 : 36460 : return 1;
1007 : : }
1008 : :
1009 : : static int
1010 : 21203 : astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
1011 : : {
1012 [ - + ]: 21203 : CALL(astfold_expr, expr_ty, node_->context_expr);
1013 [ + + - + ]: 21203 : CALL_OPT(astfold_expr, expr_ty, node_->optional_vars);
1014 : 21203 : return 1;
1015 : : }
1016 : :
1017 : : static int
1018 : 2800 : astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
1019 : : {
1020 : : // Currently, this is really only used to form complex/negative numeric
1021 : : // constants in MatchValue and MatchMapping nodes
1022 : : // We still recurse into all subexpressions and subpatterns anyway
1023 [ - + ]: 2800 : if (++state->recursion_depth > state->recursion_limit) {
1024 : 0 : PyErr_SetString(PyExc_RecursionError,
1025 : : "maximum recursion depth exceeded during compilation");
1026 : 0 : return 0;
1027 : : }
1028 [ + + + + : 2800 : switch (node_->kind) {
+ + + +
- ]
1029 : 777 : case MatchValue_kind:
1030 [ - + ]: 777 : CALL(astfold_expr, expr_ty, node_->v.MatchValue.value);
1031 : 777 : break;
1032 : 39 : case MatchSingleton_kind:
1033 : 39 : break;
1034 : 455 : case MatchSequence_kind:
1035 [ + - - + : 1327 : CALL_SEQ(astfold_pattern, pattern, node_->v.MatchSequence.patterns);
+ + + + ]
1036 : 455 : break;
1037 : 272 : case MatchMapping_kind:
1038 [ + - - + : 539 : CALL_SEQ(astfold_expr, expr, node_->v.MatchMapping.keys);
+ + + + ]
1039 [ + - - + : 539 : CALL_SEQ(astfold_pattern, pattern, node_->v.MatchMapping.patterns);
+ + + + ]
1040 : 272 : break;
1041 : 188 : case MatchClass_kind:
1042 [ - + ]: 188 : CALL(astfold_expr, expr_ty, node_->v.MatchClass.cls);
1043 [ + - - + : 383 : CALL_SEQ(astfold_pattern, pattern, node_->v.MatchClass.patterns);
+ + + + ]
1044 [ + - - + : 268 : CALL_SEQ(astfold_pattern, pattern, node_->v.MatchClass.kwd_patterns);
+ + + + ]
1045 : 188 : break;
1046 : 103 : case MatchStar_kind:
1047 : 103 : break;
1048 : 855 : case MatchAs_kind:
1049 [ + + ]: 855 : if (node_->v.MatchAs.pattern) {
1050 [ - + ]: 93 : CALL(astfold_pattern, pattern_ty, node_->v.MatchAs.pattern);
1051 : : }
1052 : 855 : break;
1053 : 111 : case MatchOr_kind:
1054 [ + - - + : 410 : CALL_SEQ(astfold_pattern, pattern, node_->v.MatchOr.patterns);
+ - + + ]
1055 : 111 : break;
1056 : : // No default case, so the compiler will emit a warning if new pattern
1057 : : // kinds are added without being handled here
1058 : : }
1059 : 2800 : state->recursion_depth--;
1060 : 2800 : return 1;
1061 : : }
1062 : :
1063 : : static int
1064 : 994 : astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
1065 : : {
1066 [ - + ]: 994 : CALL(astfold_pattern, expr_ty, node_->pattern);
1067 [ + + - + ]: 994 : CALL_OPT(astfold_expr, expr_ty, node_->guard);
1068 [ + - - + : 2098 : CALL_SEQ(astfold_stmt, stmt, node_->body);
+ - + + ]
1069 : 994 : return 1;
1070 : : }
1071 : :
1072 : : #undef CALL
1073 : : #undef CALL_OPT
1074 : : #undef CALL_SEQ
1075 : :
1076 : : /* See comments in symtable.c. */
1077 : : #define COMPILER_STACK_FRAME_SCALE 3
1078 : :
1079 : : int
1080 : 114073 : _PyAST_Optimize(mod_ty mod, PyArena *arena, _PyASTOptimizeState *state)
1081 : : {
1082 : : PyThreadState *tstate;
1083 : 114073 : int recursion_limit = Py_GetRecursionLimit();
1084 : : int starting_recursion_depth;
1085 : :
1086 : : /* Setup recursion depth check counters */
1087 : 114073 : tstate = _PyThreadState_GET();
1088 [ - + ]: 114073 : if (!tstate) {
1089 : 0 : return 0;
1090 : : }
1091 : : /* Be careful here to prevent overflow. */
1092 : 114073 : int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining;
1093 : 114073 : starting_recursion_depth = (recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
1094 [ + - ]: 114073 : recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth;
1095 : 114073 : state->recursion_depth = starting_recursion_depth;
1096 : 114073 : state->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
1097 [ + - ]: 114073 : recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit;
1098 : :
1099 : 114073 : int ret = astfold_mod(mod, arena, state);
1100 : : assert(ret || PyErr_Occurred());
1101 : :
1102 : : /* Check that the recursion depth counting balanced correctly */
1103 [ + + - + ]: 114073 : if (ret && state->recursion_depth != starting_recursion_depth) {
1104 : 0 : PyErr_Format(PyExc_SystemError,
1105 : : "AST optimizer recursion depth mismatch (before=%d, after=%d)",
1106 : : starting_recursion_depth, state->recursion_depth);
1107 : 0 : return 0;
1108 : : }
1109 : :
1110 : 114073 : return ret;
1111 : : }
|