LCOV - code coverage report
Current view: top level - Python - ast_opt.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 625 673 92.9 %
Date: 2022-07-07 18:19:46 Functions: 32 32 100.0 %

          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      294951 : 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      294951 :     if (val == NULL) {
      15      141719 :         if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) {
      16           0 :             return 0;
      17             :         }
      18      141719 :         PyErr_Clear();
      19      141719 :         return 1;
      20             :     }
      21      153232 :     if (_PyArena_AddPyObject(arena, val) < 0) {
      22           0 :         Py_DECREF(val);
      23           0 :         return 0;
      24             :     }
      25      153232 :     node->kind = Constant_kind;
      26      153232 :     node->v.Constant.kind = NULL;
      27      153232 :     node->v.Constant.value = val;
      28      153232 :     return 1;
      29             : }
      30             : 
      31             : #define COPY_NODE(TO, FROM) (memcpy((TO), (FROM), sizeof(struct _expr)))
      32             : 
      33             : static int
      34       37707 : has_starred(asdl_expr_seq *elts)
      35             : {
      36       37707 :     Py_ssize_t n = asdl_seq_LEN(elts);
      37       95243 :     for (Py_ssize_t i = 0; i < n; i++) {
      38       57555 :         expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
      39       57555 :         if (e->kind == Starred_kind) {
      40          19 :             return 1;
      41             :         }
      42             :     }
      43       37688 :     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       82317 : fold_unaryop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
      58             : {
      59       82317 :     expr_ty arg = node->v.UnaryOp.operand;
      60             : 
      61       82317 :     if (arg->kind != Constant_kind) {
      62             :         /* Fold not into comparison */
      63       55473 :         if (node->v.UnaryOp.op == Not && arg->kind == Compare_kind &&
      64        1653 :                 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         975 :             cmpop_ty op = asdl_seq_GET(arg->v.Compare.ops, 0);
      71         975 :             switch (op) {
      72          28 :             case Is:
      73          28 :                 op = IsNot;
      74          28 :                 break;
      75           1 :             case IsNot:
      76           1 :                 op = Is;
      77           1 :                 break;
      78         542 :             case In:
      79         542 :                 op = NotIn;
      80         542 :                 break;
      81           2 :             case NotIn:
      82           2 :                 op = In;
      83           2 :                 break;
      84             :             // The remaining comparison operators can't be safely inverted
      85         402 :             case Eq:
      86             :             case NotEq:
      87             :             case Lt:
      88             :             case LtE:
      89             :             case Gt:
      90             :             case GtE:
      91         402 :                 op = 0; // The AST enums leave "0" free as an "unused" marker
      92         402 :                 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         975 :             if (op) {
      97         573 :                 asdl_seq_SET(arg->v.Compare.ops, 0, op);
      98         573 :                 COPY_NODE(node, arg);
      99         573 :                 return 1;
     100             :             }
     101             :         }
     102       54900 :         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       26844 :     PyObject *newval = ops[node->v.UnaryOp.op](arg->v.Constant.value);
     113       26844 :     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        3764 : safe_multiply(PyObject *v, PyObject *w)
     154             : {
     155        4587 :     if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) {
     156         823 :         size_t vbits = _PyLong_NumBits(v);
     157         823 :         size_t wbits = _PyLong_NumBits(w);
     158         823 :         if (vbits == (size_t)-1 || wbits == (size_t)-1) {
     159           0 :             return NULL;
     160             :         }
     161         823 :         if (vbits + wbits > MAX_INT_SIZE) {
     162           0 :             return NULL;
     163             :         }
     164             :     }
     165        2979 :     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           0 :                                              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        4129 :     else if (PyLong_Check(v) && (PyUnicode_Check(w) || PyBytes_Check(w))) {
     179        1423 :         Py_ssize_t size = PyUnicode_Check(w) ? PyUnicode_GET_LENGTH(w) :
     180         464 :                                                PyBytes_GET_SIZE(w);
     181        1423 :         if (size) {
     182        1423 :             long n = PyLong_AsLong(v);
     183        1423 :             if (n < 0 || n > MAX_STR_SIZE / size) {
     184         193 :                 return NULL;
     185             :             }
     186             :         }
     187             :     }
     188        2909 :     else if (PyLong_Check(w) &&
     189        4215 :              (PyTuple_Check(v) || PyFrozenSet_Check(v) ||
     190        1853 :               PyUnicode_Check(v) || PyBytes_Check(v)))
     191             :     {
     192        1424 :         return safe_multiply(w, v);
     193             :     }
     194             : 
     195        2143 :     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        1390 : safe_lshift(PyObject *v, PyObject *w)
     217             : {
     218        1390 :     if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) {
     219        1345 :         size_t vbits = _PyLong_NumBits(v);
     220        1345 :         size_t wbits = PyLong_AsSize_t(w);
     221        1345 :         if (vbits == (size_t)-1 || wbits == (size_t)-1) {
     222           2 :             return NULL;
     223             :         }
     224        1343 :         if (wbits > MAX_INT_SIZE || vbits > MAX_INT_SIZE - wbits) {
     225          75 :             return NULL;
     226             :         }
     227             :     }
     228             : 
     229        1313 :     return PyNumber_Lshift(v, w);
     230             : }
     231             : 
     232             : static PyObject *
     233         146 : safe_mod(PyObject *v, PyObject *w)
     234             : {
     235         146 :     if (PyUnicode_Check(v) || PyBytes_Check(v)) {
     236         113 :         return NULL;
     237             :     }
     238             : 
     239          33 :     return PyNumber_Remainder(v, w);
     240             : }
     241             : 
     242             : 
     243             : static expr_ty
     244       64173 : parse_literal(PyObject *fmt, Py_ssize_t *ppos, PyArena *arena)
     245             : {
     246       64173 :     const void *data = PyUnicode_DATA(fmt);
     247       64173 :     int kind = PyUnicode_KIND(fmt);
     248       64173 :     Py_ssize_t size = PyUnicode_GET_LENGTH(fmt);
     249             :     Py_ssize_t start, pos;
     250       64173 :     int has_percents = 0;
     251       64173 :     start = pos = *ppos;
     252      339305 :     while (pos < size) {
     253      324425 :         if (PyUnicode_READ(kind, data, pos) != '%') {
     254      275086 :             pos++;
     255             :         }
     256       49339 :         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       64173 :     *ppos = pos;
     265       64173 :     if (pos == start) {
     266       39069 :         return NULL;
     267             :     }
     268       25104 :     PyObject *str = PyUnicode_Substring(fmt, start, pos);
     269             :     /* str = str.replace('%%', '%') */
     270       25104 :     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       25104 :     if (!str) {
     277           0 :         return NULL;
     278             :     }
     279             : 
     280       25104 :     if (_PyArena_AddPyObject(arena, str) < 0) {
     281           0 :         Py_DECREF(str);
     282           0 :         return NULL;
     283             :     }
     284       25104 :     return _PyAST_Constant(str, NULL, -1, -1, -1, -1, arena);
     285             : }
     286             : 
     287             : #define MAXDIGITS 3
     288             : 
     289             : static int
     290       49290 : simple_format_arg_parse(PyObject *fmt, Py_ssize_t *ppos,
     291             :                         int *spec, int *flags, int *width, int *prec)
     292             : {
     293       49290 :     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       49290 :     *flags = 0;
     305             :     while (1) {
     306      106922 :         NEXTC;
     307      106921 :         switch (ch) {
     308       11543 :             case '-': *flags |= F_LJUST; continue;
     309       11446 :             case '+': *flags |= F_SIGN; continue;
     310       11428 :             case ' ': *flags |= F_BLANK; continue;
     311       11607 :             case '#': *flags |= F_ALT; continue;
     312       11607 :             case '0': *flags |= F_ZERO; continue;
     313           1 :             case 'z': *flags |= F_NO_NEG_0; continue;
     314             :         }
     315       49289 :         break;
     316             :     }
     317       49289 :     if ('0' <= ch && ch <= '9') {
     318       15057 :         *width = 0;
     319       15057 :         int digits = 0;
     320       38390 :         while ('0' <= ch && ch <= '9') {
     321       23355 :             *width = *width * 10 + (ch - '0');
     322       23355 :             NEXTC;
     323       23355 :             if (++digits >= MAXDIGITS) {
     324          22 :                 return 0;
     325             :             }
     326             :         }
     327             :     }
     328             : 
     329       49267 :     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       49267 :     *spec = ch;
     344       49267 :     *ppos = pos;
     345       49267 :     return 1;
     346             : 
     347             : #undef NEXTC
     348             : }
     349             : 
     350             : static expr_ty
     351       49290 : parse_format(PyObject *fmt, Py_ssize_t *ppos, expr_ty arg, PyArena *arena)
     352             : {
     353       49290 :     int spec, flags, width = -1, prec = -1;
     354       49290 :     if (!simple_format_arg_parse(fmt, ppos, &spec, &flags, &width, &prec)) {
     355             :         // Unsupported format.
     356          23 :         return NULL;
     357             :     }
     358       49267 :     if (spec == 's' || spec == 'r' || spec == 'a') {
     359       28019 :         char buf[1 + MAXDIGITS + 1 + MAXDIGITS + 1], *p = buf;
     360       28019 :         if (!(flags & F_LJUST) && width > 0) {
     361        1311 :             *p++ = '>';
     362             :         }
     363       28019 :         if (width >= 0) {
     364        2692 :             p += snprintf(p, MAXDIGITS + 1, "%d", width);
     365             :         }
     366       28019 :         if (prec >= 0) {
     367        3169 :             p += snprintf(p, MAXDIGITS + 2, ".%d", prec);
     368             :         }
     369       28019 :         expr_ty format_spec = NULL;
     370       28019 :         if (p != buf) {
     371        3845 :             PyObject *str = PyUnicode_FromString(buf);
     372        3845 :             if (str == NULL) {
     373           0 :                 return NULL;
     374             :             }
     375        3845 :             if (_PyArena_AddPyObject(arena, str) < 0) {
     376           0 :                 Py_DECREF(str);
     377           0 :                 return NULL;
     378             :             }
     379        3845 :             format_spec = _PyAST_Constant(str, NULL, -1, -1, -1, -1, arena);
     380        3845 :             if (format_spec == NULL) {
     381           0 :                 return NULL;
     382             :             }
     383             :         }
     384       28019 :         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       21248 :     return NULL;
     391             : }
     392             : 
     393             : static int
     394       36154 : optimize_format(expr_ty node, PyObject *fmt, asdl_expr_seq *elts, PyArena *arena)
     395             : {
     396       36154 :     Py_ssize_t pos = 0;
     397       36154 :     Py_ssize_t cnt = 0;
     398       36154 :     asdl_expr_seq *seq = _Py_asdl_expr_seq_new(asdl_seq_LEN(elts) * 2 + 1, arena);
     399       36154 :     if (!seq) {
     400           0 :         return 0;
     401             :     }
     402       36154 :     seq->size = 0;
     403             : 
     404       28019 :     while (1) {
     405       64173 :         expr_ty lit = parse_literal(fmt, &pos, arena);
     406       64173 :         if (lit) {
     407       25104 :             asdl_seq_SET(seq, seq->size++, lit);
     408             :         }
     409       39069 :         else if (PyErr_Occurred()) {
     410           0 :             return 0;
     411             :         }
     412             : 
     413       64173 :         if (pos >= PyUnicode_GET_LENGTH(fmt)) {
     414       14880 :             break;
     415             :         }
     416       49293 :         if (cnt >= asdl_seq_LEN(elts)) {
     417             :             // More format units than items.
     418           3 :             return 1;
     419             :         }
     420       49290 :         assert(PyUnicode_READ_CHAR(fmt, pos) == '%');
     421       49290 :         pos++;
     422       49290 :         expr_ty expr = parse_format(fmt, &pos, asdl_seq_GET(elts, cnt), arena);
     423       49290 :         cnt++;
     424       49290 :         if (!expr) {
     425       21271 :             return !PyErr_Occurred();
     426             :         }
     427       28019 :         asdl_seq_SET(seq, seq->size++, expr);
     428             :     }
     429       14880 :     if (cnt < asdl_seq_LEN(elts)) {
     430             :         // More items than format units.
     431           1 :         return 1;
     432             :     }
     433       14879 :     expr_ty res = _PyAST_JoinedStr(seq,
     434             :                                    node->lineno, node->col_offset,
     435             :                                    node->end_lineno, node->end_col_offset,
     436             :                                    arena);
     437       14879 :     if (!res) {
     438           0 :         return 0;
     439             :     }
     440       14879 :     COPY_NODE(node, res);
     441             : //     PySys_FormatStderr("format = %R\n", fmt);
     442       14879 :     return 1;
     443             : }
     444             : 
     445             : static int
     446      217687 : fold_binop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
     447             : {
     448             :     expr_ty lhs, rhs;
     449      217687 :     lhs = node->v.BinOp.left;
     450      217687 :     rhs = node->v.BinOp.right;
     451      217687 :     if (lhs->kind != Constant_kind) {
     452      138935 :         return 1;
     453             :     }
     454       78752 :     PyObject *lv = lhs->v.Constant.value;
     455             : 
     456       78752 :     if (node->v.BinOp.op == Mod &&
     457       89043 :         rhs->kind == Tuple_kind &&
     458       72346 :         PyUnicode_Check(lv) &&
     459       36168 :         !has_starred(rhs->v.Tuple.elts))
     460             :     {
     461       36154 :         return optimize_format(node, lv, rhs->v.Tuple.elts, arena);
     462             :     }
     463             : 
     464       42598 :     if (rhs->kind != Constant_kind) {
     465       34073 :         return 1;
     466             :     }
     467             : 
     468        8525 :     PyObject *rv = rhs->v.Constant.value;
     469        8525 :     PyObject *newval = NULL;
     470             : 
     471        8525 :     switch (node->v.BinOp.op) {
     472        1955 :     case Add:
     473        1955 :         newval = PyNumber_Add(lv, rv);
     474        1955 :         break;
     475         707 :     case Sub:
     476         707 :         newval = PyNumber_Subtract(lv, rv);
     477         707 :         break;
     478        2340 :     case Mult:
     479        2340 :         newval = safe_multiply(lv, rv);
     480        2340 :         break;
     481         557 :     case Div:
     482         557 :         newval = PyNumber_TrueDivide(lv, rv);
     483         557 :         break;
     484          75 :     case FloorDiv:
     485          75 :         newval = PyNumber_FloorDivide(lv, rv);
     486          75 :         break;
     487         146 :     case Mod:
     488         146 :         newval = safe_mod(lv, rv);
     489         146 :         break;
     490        1281 :     case Pow:
     491        1281 :         newval = safe_power(lv, rv);
     492        1281 :         break;
     493        1390 :     case LShift:
     494        1390 :         newval = safe_lshift(lv, rv);
     495        1390 :         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        8525 :     return make_const(node, newval, arena);
     516             : }
     517             : 
     518             : static PyObject*
     519      259209 : make_const_tuple(asdl_expr_seq *elts)
     520             : {
     521      982524 :     for (int i = 0; i < asdl_seq_LEN(elts); i++) {
     522      863984 :         expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
     523      863984 :         if (e->kind != Constant_kind) {
     524      140669 :             return NULL;
     525             :         }
     526             :     }
     527             : 
     528      118540 :     PyObject *newval = PyTuple_New(asdl_seq_LEN(elts));
     529      118540 :     if (newval == NULL) {
     530           0 :         return NULL;
     531             :     }
     532             : 
     533      825457 :     for (int i = 0; i < asdl_seq_LEN(elts); i++) {
     534      706917 :         expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
     535      706917 :         PyObject *v = e->v.Constant.value;
     536      706917 :         Py_INCREF(v);
     537      706917 :         PyTuple_SET_ITEM(newval, i, v);
     538             :     }
     539      118540 :     return newval;
     540             : }
     541             : 
     542             : static int
     543      298999 : fold_tuple(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
     544             : {
     545             :     PyObject *newval;
     546             : 
     547      298999 :     if (node->v.Tuple.ctx != Load)
     548       42225 :         return 1;
     549             : 
     550      256774 :     newval = make_const_tuple(node->v.Tuple.elts);
     551      256774 :     return make_const(node, newval, arena);
     552             : }
     553             : 
     554             : static int
     555      188091 : fold_subscr(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
     556             : {
     557             :     PyObject *newval;
     558             :     expr_ty arg, idx;
     559             : 
     560      188091 :     arg = node->v.Subscript.value;
     561      188091 :     idx = node->v.Subscript.slice;
     562      188091 :     if (node->v.Subscript.ctx != Load ||
     563      154813 :             arg->kind != Constant_kind ||
     564         228 :             idx->kind != Constant_kind)
     565             :     {
     566      187962 :         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      102699 : fold_iter(expr_ty arg, PyArena *arena, _PyASTOptimizeState *state)
     581             : {
     582             :     PyObject *newval;
     583      102699 :     if (arg->kind == List_kind) {
     584             :         /* First change a list into tuple. */
     585        1539 :         asdl_expr_seq *elts = arg->v.List.elts;
     586        1539 :         if (has_starred(elts)) {
     587           5 :             return 1;
     588             :         }
     589        1534 :         expr_context_ty ctx = arg->v.List.ctx;
     590        1534 :         arg->kind = Tuple_kind;
     591        1534 :         arg->v.Tuple.elts = elts;
     592        1534 :         arg->v.Tuple.ctx = ctx;
     593             :         /* Try to create a constant tuple. */
     594        1534 :         newval = make_const_tuple(elts);
     595             :     }
     596      101160 :     else if (arg->kind == Set_kind) {
     597         901 :         newval = make_const_tuple(arg->v.Set.elts);
     598         901 :         if (newval) {
     599         757 :             Py_SETREF(newval, PyFrozenSet_New(newval));
     600             :         }
     601             :     }
     602             :     else {
     603      100259 :         return 1;
     604             :     }
     605        2435 :     return make_const(arg, newval, arena);
     606             : }
     607             : 
     608             : static int
     609      208220 : 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      208220 :     ops = node->v.Compare.ops;
     616      208220 :     args = node->v.Compare.comparators;
     617             :     /* Change literal list or set in 'in' or 'not in' into
     618             :        tuple or frozenset respectively. */
     619      208220 :     i = asdl_seq_LEN(ops) - 1;
     620      208220 :     int op = asdl_seq_GET(ops, i);
     621      208220 :     if (op == In || op == NotIn) {
     622       37814 :         if (!fold_iter((expr_ty)asdl_seq_GET(args, i), arena, state)) {
     623           0 :             return 0;
     624             :         }
     625             :     }
     626      208220 :     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      337037 : astfold_body(asdl_stmt_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state)
     662             : {
     663      337037 :     int docstring = _PyAST_GetDocString(stmts) != NULL;
     664     1916840 :     CALL_SEQ(astfold_stmt, stmt, stmts);
     665      337037 :     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      337037 :     return 1;
     681             : }
     682             : 
     683             : static int
     684      115120 : astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
     685             : {
     686      115120 :     switch (node_->kind) {
     687       38551 :     case Module_kind:
     688       38551 :         CALL(astfold_body, asdl_seq, node_->v.Module.body);
     689       38551 :         break;
     690        4146 :     case Interactive_kind:
     691        8353 :         CALL_SEQ(astfold_stmt, stmt, node_->v.Interactive.body);
     692        4146 :         break;
     693       72423 :     case Expression_kind:
     694       72423 :         CALL(astfold_expr, expr_ty, node_->v.Expression.body);
     695       72423 :         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      115120 :     return 1;
     703             : }
     704             : 
     705             : static int
     706    12058800 : astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
     707             : {
     708    12058800 :     if (++state->recursion_depth > state->recursion_limit) {
     709           0 :         PyErr_SetString(PyExc_RecursionError,
     710             :                         "maximum recursion depth exceeded during compilation");
     711           0 :         return 0;
     712             :     }
     713    12058800 :     switch (node_->kind) {
     714       57844 :     case BoolOp_kind:
     715      181778 :         CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values);
     716       57844 :         break;
     717      217687 :     case BinOp_kind:
     718      217687 :         CALL(astfold_expr, expr_ty, node_->v.BinOp.left);
     719      217687 :         CALL(astfold_expr, expr_ty, node_->v.BinOp.right);
     720      217687 :         CALL(fold_binop, expr_ty, node_);
     721      217687 :         break;
     722       82317 :     case UnaryOp_kind:
     723       82317 :         CALL(astfold_expr, expr_ty, node_->v.UnaryOp.operand);
     724       82317 :         CALL(fold_unaryop, expr_ty, node_);
     725       82317 :         break;
     726       34809 :     case Lambda_kind:
     727       34809 :         CALL(astfold_arguments, arguments_ty, node_->v.Lambda.args);
     728       34809 :         CALL(astfold_expr, expr_ty, node_->v.Lambda.body);
     729       34809 :         break;
     730        9792 :     case IfExp_kind:
     731        9792 :         CALL(astfold_expr, expr_ty, node_->v.IfExp.test);
     732        9792 :         CALL(astfold_expr, expr_ty, node_->v.IfExp.body);
     733        9792 :         CALL(astfold_expr, expr_ty, node_->v.IfExp.orelse);
     734        9792 :         break;
     735       32238 :     case Dict_kind:
     736      649915 :         CALL_SEQ(astfold_expr, expr, node_->v.Dict.keys);
     737      649915 :         CALL_SEQ(astfold_expr, expr, node_->v.Dict.values);
     738       32238 :         break;
     739        2570 :     case Set_kind:
     740       12065 :         CALL_SEQ(astfold_expr, expr, node_->v.Set.elts);
     741        2570 :         break;
     742        8575 :     case ListComp_kind:
     743        8575 :         CALL(astfold_expr, expr_ty, node_->v.ListComp.elt);
     744       17442 :         CALL_SEQ(astfold_comprehension, comprehension, node_->v.ListComp.generators);
     745        8575 :         break;
     746         462 :     case SetComp_kind:
     747         462 :         CALL(astfold_expr, expr_ty, node_->v.SetComp.elt);
     748         975 :         CALL_SEQ(astfold_comprehension, comprehension, node_->v.SetComp.generators);
     749         462 :         break;
     750        1173 :     case DictComp_kind:
     751        1173 :         CALL(astfold_expr, expr_ty, node_->v.DictComp.key);
     752        1173 :         CALL(astfold_expr, expr_ty, node_->v.DictComp.value);
     753        2393 :         CALL_SEQ(astfold_comprehension, comprehension, node_->v.DictComp.generators);
     754        1173 :         break;
     755        7752 :     case GeneratorExp_kind:
     756        7752 :         CALL(astfold_expr, expr_ty, node_->v.GeneratorExp.elt);
     757       15738 :         CALL_SEQ(astfold_comprehension, comprehension, node_->v.GeneratorExp.generators);
     758        7752 :         break;
     759        1732 :     case Await_kind:
     760        1732 :         CALL(astfold_expr, expr_ty, node_->v.Await.value);
     761        1732 :         break;
     762       11503 :     case Yield_kind:
     763       11503 :         CALL_OPT(astfold_expr, expr_ty, node_->v.Yield.value);
     764       11503 :         break;
     765        1916 :     case YieldFrom_kind:
     766        1916 :         CALL(astfold_expr, expr_ty, node_->v.YieldFrom.value);
     767        1916 :         break;
     768      208220 :     case Compare_kind:
     769      208220 :         CALL(astfold_expr, expr_ty, node_->v.Compare.left);
     770      419157 :         CALL_SEQ(astfold_expr, expr, node_->v.Compare.comparators);
     771      208220 :         CALL(fold_compare, expr_ty, node_);
     772      208220 :         break;
     773     1119770 :     case Call_kind:
     774     1119770 :         CALL(astfold_expr, expr_ty, node_->v.Call.func);
     775     2540810 :         CALL_SEQ(astfold_expr, expr, node_->v.Call.args);
     776     1253510 :         CALL_SEQ(astfold_keyword, keyword, node_->v.Call.keywords);
     777     1119770 :         break;
     778       91547 :     case FormattedValue_kind:
     779       91547 :         CALL(astfold_expr, expr_ty, node_->v.FormattedValue.value);
     780       91547 :         CALL_OPT(astfold_expr, expr_ty, node_->v.FormattedValue.format_spec);
     781       91547 :         break;
     782       15530 :     case JoinedStr_kind:
     783      201853 :         CALL_SEQ(astfold_expr, expr, node_->v.JoinedStr.values);
     784       15530 :         break;
     785     1321820 :     case Attribute_kind:
     786     1321820 :         CALL(astfold_expr, expr_ty, node_->v.Attribute.value);
     787     1321820 :         break;
     788      188091 :     case Subscript_kind:
     789      188091 :         CALL(astfold_expr, expr_ty, node_->v.Subscript.value);
     790      188091 :         CALL(astfold_expr, expr_ty, node_->v.Subscript.slice);
     791      188091 :         CALL(fold_subscr, expr_ty, node_);
     792      188091 :         break;
     793       10031 :     case Starred_kind:
     794       10031 :         CALL(astfold_expr, expr_ty, node_->v.Starred.value);
     795       10031 :         break;
     796       30876 :     case Slice_kind:
     797       30876 :         CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.lower);
     798       30876 :         CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.upper);
     799       30876 :         CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step);
     800       30876 :         break;
     801       65000 :     case List_kind:
     802      584325 :         CALL_SEQ(astfold_expr, expr, node_->v.List.elts);
     803       65000 :         break;
     804      298999 :     case Tuple_kind:
     805     1481340 :         CALL_SEQ(astfold_expr, expr, node_->v.Tuple.elts);
     806      298999 :         CALL(fold_tuple, expr_ty, node_);
     807      298999 :         break;
     808     4662710 :     case Name_kind:
     809     8666160 :         if (node_->v.Name.ctx == Load &&
     810     4003460 :                 _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     4662460 :         break;
     815         799 :     case NamedExpr_kind:
     816         799 :         CALL(astfold_expr, expr_ty, node_->v.NamedExpr.value);
     817         799 :         break;
     818     3575090 :     case Constant_kind:
     819             :         // Already a constant, nothing further to do
     820     3575090 :         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    12058600 :     state->recursion_depth--;
     825    12058600 :     return 1;
     826             : }
     827             : 
     828             : static int
     829      134884 : astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
     830             : {
     831      134884 :     CALL(astfold_expr, expr_ty, node_->value);
     832      134884 :     return 1;
     833             : }
     834             : 
     835             : static int
     836       18586 : astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
     837             : {
     838       18586 :     CALL(astfold_expr, expr_ty, node_->target);
     839       18586 :     CALL(astfold_expr, expr_ty, node_->iter);
     840       22859 :     CALL_SEQ(astfold_expr, expr, node_->ifs);
     841             : 
     842       18586 :     CALL(fold_iter, expr_ty, node_->iter);
     843       18586 :     return 1;
     844             : }
     845             : 
     846             : static int
     847      295551 : astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
     848             : {
     849      314187 :     CALL_SEQ(astfold_arg, arg, node_->posonlyargs);
     850      895422 :     CALL_SEQ(astfold_arg, arg, node_->args);
     851      295551 :     CALL_OPT(astfold_arg, arg_ty, node_->vararg);
     852      312024 :     CALL_SEQ(astfold_arg, arg, node_->kwonlyargs);
     853      312024 :     CALL_SEQ(astfold_expr, expr, node_->kw_defaults);
     854      295551 :     CALL_OPT(astfold_arg, arg_ty, node_->kwarg);
     855      361455 :     CALL_SEQ(astfold_expr, expr, node_->defaults);
     856      295551 :     return 1;
     857             : }
     858             : 
     859             : static int
     860      682424 : astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
     861             : {
     862      682424 :     if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) {
     863      680317 :         CALL_OPT(astfold_expr, expr_ty, node_->annotation);
     864             :     }
     865      682424 :     return 1;
     866             : }
     867             : 
     868             : static int
     869     2611280 : astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
     870             : {
     871     2611280 :     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     2611280 :     switch (node_->kind) {
     877      258405 :     case FunctionDef_kind:
     878      258405 :         CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args);
     879      258405 :         CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body);
     880      282592 :         CALL_SEQ(astfold_expr, expr, node_->v.FunctionDef.decorator_list);
     881      258405 :         if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) {
     882      257021 :             CALL_OPT(astfold_expr, expr_ty, node_->v.FunctionDef.returns);
     883             :         }
     884      258405 :         break;
     885        2337 :     case AsyncFunctionDef_kind:
     886        2337 :         CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args);
     887        2337 :         CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body);
     888        2557 :         CALL_SEQ(astfold_expr, expr, node_->v.AsyncFunctionDef.decorator_list);
     889        2337 :         if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) {
     890        1992 :             CALL_OPT(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.returns);
     891             :         }
     892        2337 :         break;
     893       37744 :     case ClassDef_kind:
     894       70049 :         CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.bases);
     895       38887 :         CALL_SEQ(astfold_keyword, keyword, node_->v.ClassDef.keywords);
     896       37744 :         CALL(astfold_body, asdl_seq, node_->v.ClassDef.body);
     897       39385 :         CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.decorator_list);
     898       37744 :         break;
     899      212344 :     case Return_kind:
     900      212344 :         CALL_OPT(astfold_expr, expr_ty, node_->v.Return.value);
     901      212344 :         break;
     902        6454 :     case Delete_kind:
     903       13763 :         CALL_SEQ(astfold_expr, expr, node_->v.Delete.targets);
     904        6454 :         break;
     905      635579 :     case Assign_kind:
     906     1277550 :         CALL_SEQ(astfold_expr, expr, node_->v.Assign.targets);
     907      635579 :         CALL(astfold_expr, expr_ty, node_->v.Assign.value);
     908      635579 :         break;
     909       21479 :     case AugAssign_kind:
     910       21479 :         CALL(astfold_expr, expr_ty, node_->v.AugAssign.target);
     911       21479 :         CALL(astfold_expr, expr_ty, node_->v.AugAssign.value);
     912       21479 :         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       46299 :     case For_kind:
     921       46299 :         CALL(astfold_expr, expr_ty, node_->v.For.target);
     922       46299 :         CALL(astfold_expr, expr_ty, node_->v.For.iter);
     923      141560 :         CALL_SEQ(astfold_stmt, stmt, node_->v.For.body);
     924       47912 :         CALL_SEQ(astfold_stmt, stmt, node_->v.For.orelse);
     925             : 
     926       46299 :         CALL(fold_iter, expr_ty, node_->v.For.iter);
     927       46299 :         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        9951 :     case While_kind:
     935        9951 :         CALL(astfold_expr, expr_ty, node_->v.While.test);
     936       42284 :         CALL_SEQ(astfold_stmt, stmt, node_->v.While.body);
     937       10189 :         CALL_SEQ(astfold_stmt, stmt, node_->v.While.orelse);
     938        9951 :         break;
     939      484759 :     case If_kind:
     940      484759 :         CALL(astfold_expr, expr_ty, node_->v.If.test);
     941     1109200 :         CALL_SEQ(astfold_stmt, stmt, node_->v.If.body);
     942      593876 :         CALL_SEQ(astfold_stmt, stmt, node_->v.If.orelse);
     943      484759 :         break;
     944       20632 :     case With_kind:
     945       41642 :         CALL_SEQ(astfold_withitem, withitem, node_->v.With.items);
     946       60171 :         CALL_SEQ(astfold_stmt, stmt, node_->v.With.body);
     947       20632 :         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       52709 :     case Raise_kind:
     953       52709 :         CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.exc);
     954       52709 :         CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.cause);
     955       52709 :         break;
     956       39926 :     case Try_kind:
     957       98716 :         CALL_SEQ(astfold_stmt, stmt, node_->v.Try.body);
     958       76768 :         CALL_SEQ(astfold_excepthandler, excepthandler, node_->v.Try.handlers);
     959       47347 :         CALL_SEQ(astfold_stmt, stmt, node_->v.Try.orelse);
     960       47069 :         CALL_SEQ(astfold_stmt, stmt, node_->v.Try.finalbody);
     961       39926 :         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        8436 :     case Assert_kind:
     969        8436 :         CALL(astfold_expr, expr_ty, node_->v.Assert.test);
     970        8436 :         CALL_OPT(astfold_expr, expr_ty, node_->v.Assert.msg);
     971        8436 :         break;
     972      650331 :     case Expr_kind:
     973      650331 :         CALL(astfold_expr, expr_ty, node_->v.Expr.value);
     974      650331 :         break;
     975         682 :     case Match_kind:
     976         682 :         CALL(astfold_expr, expr_ty, node_->v.Match.subject);
     977        1669 :         CALL_SEQ(astfold_match_case, match_case, node_->v.Match.cases);
     978         682 :         break;
     979             :     // The following statements don't contain any subexpressions to be folded
     980      112922 :     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      112922 :         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     2611280 :     state->recursion_depth--;
     992     2611280 :     return 1;
     993             : }
     994             : 
     995             : static int
     996       36970 : astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
     997             : {
     998       36970 :     switch (node_->kind) {
     999       36970 :     case ExceptHandler_kind:
    1000       36970 :         CALL_OPT(astfold_expr, expr_ty, node_->v.ExceptHandler.type);
    1001       86587 :         CALL_SEQ(astfold_stmt, stmt, node_->v.ExceptHandler.body);
    1002       36970 :         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       36970 :     return 1;
    1007             : }
    1008             : 
    1009             : static int
    1010       21243 : astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
    1011             : {
    1012       21243 :     CALL(astfold_expr, expr_ty, node_->context_expr);
    1013       21243 :     CALL_OPT(astfold_expr, expr_ty, node_->optional_vars);
    1014       21243 :     return 1;
    1015             : }
    1016             : 
    1017             : static int
    1018        2786 : 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        2786 :     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        2786 :     switch (node_->kind) {
    1029         773 :         case MatchValue_kind:
    1030         773 :             CALL(astfold_expr, expr_ty, node_->v.MatchValue.value);
    1031         773 :             break;
    1032          39 :         case MatchSingleton_kind:
    1033          39 :             break;
    1034         450 :         case MatchSequence_kind:
    1035        1317 :             CALL_SEQ(astfold_pattern, pattern, node_->v.MatchSequence.patterns);
    1036         450 :             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         186 :         case MatchClass_kind:
    1042         186 :             CALL(astfold_expr, expr_ty, node_->v.MatchClass.cls);
    1043         381 :             CALL_SEQ(astfold_pattern, pattern, node_->v.MatchClass.patterns);
    1044         264 :             CALL_SEQ(astfold_pattern, pattern, node_->v.MatchClass.kwd_patterns);
    1045         186 :             break;
    1046         102 :         case MatchStar_kind:
    1047         102 :             break;
    1048         853 :         case MatchAs_kind:
    1049         853 :             if (node_->v.MatchAs.pattern) {
    1050          93 :                 CALL(astfold_pattern, pattern_ty, node_->v.MatchAs.pattern);
    1051             :             }
    1052         853 :             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        2786 :     state->recursion_depth--;
    1060        2786 :     return 1;
    1061             : }
    1062             : 
    1063             : static int
    1064         987 : astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
    1065             : {
    1066         987 :     CALL(astfold_pattern, expr_ty, node_->pattern);
    1067         987 :     CALL_OPT(astfold_expr, expr_ty, node_->guard);
    1068        2084 :     CALL_SEQ(astfold_stmt, stmt, node_->body);
    1069         987 :     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      115120 : _PyAST_Optimize(mod_ty mod, PyArena *arena, _PyASTOptimizeState *state)
    1081             : {
    1082             :     PyThreadState *tstate;
    1083      115120 :     int recursion_limit = Py_GetRecursionLimit();
    1084             :     int starting_recursion_depth;
    1085             : 
    1086             :     /* Setup recursion depth check counters */
    1087      115120 :     tstate = _PyThreadState_GET();
    1088      115120 :     if (!tstate) {
    1089           0 :         return 0;
    1090             :     }
    1091             :     /* Be careful here to prevent overflow. */
    1092      115120 :     int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining;
    1093      115120 :     starting_recursion_depth = (recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
    1094      115120 :         recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth;
    1095      115120 :     state->recursion_depth = starting_recursion_depth;
    1096      115120 :     state->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
    1097      115120 :         recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit;
    1098             : 
    1099      115120 :     int ret = astfold_mod(mod, arena, state);
    1100      115120 :     assert(ret || PyErr_Occurred());
    1101             : 
    1102             :     /* Check that the recursion depth counting balanced correctly */
    1103      115120 :     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      115120 :     return ret;
    1111             : }

Generated by: LCOV version 1.14