LCOV - code coverage report
Current view: top level - Python - ast_opt.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 625 670 93.3 %
Date: 2022-07-20 13:12:14 Functions: 32 32 100.0 %
Branches: 771 1063 72.5 %

           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                 :            : }

Generated by: LCOV version 1.14