17db96d56Sopenharmony_ci/* AST Optimizer */ 27db96d56Sopenharmony_ci#include "Python.h" 37db96d56Sopenharmony_ci#include "pycore_ast.h" // _PyAST_GetDocString() 47db96d56Sopenharmony_ci#include "pycore_compile.h" // _PyASTOptimizeState 57db96d56Sopenharmony_ci#include "pycore_pystate.h" // _PyThreadState_GET() 67db96d56Sopenharmony_ci#include "pycore_format.h" // F_LJUST 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_cistatic int 107db96d56Sopenharmony_cimake_const(expr_ty node, PyObject *val, PyArena *arena) 117db96d56Sopenharmony_ci{ 127db96d56Sopenharmony_ci // Even if no new value was calculated, make_const may still 137db96d56Sopenharmony_ci // need to clear an error (e.g. for division by zero) 147db96d56Sopenharmony_ci if (val == NULL) { 157db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) { 167db96d56Sopenharmony_ci return 0; 177db96d56Sopenharmony_ci } 187db96d56Sopenharmony_ci PyErr_Clear(); 197db96d56Sopenharmony_ci return 1; 207db96d56Sopenharmony_ci } 217db96d56Sopenharmony_ci if (_PyArena_AddPyObject(arena, val) < 0) { 227db96d56Sopenharmony_ci Py_DECREF(val); 237db96d56Sopenharmony_ci return 0; 247db96d56Sopenharmony_ci } 257db96d56Sopenharmony_ci node->kind = Constant_kind; 267db96d56Sopenharmony_ci node->v.Constant.kind = NULL; 277db96d56Sopenharmony_ci node->v.Constant.value = val; 287db96d56Sopenharmony_ci return 1; 297db96d56Sopenharmony_ci} 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ci#define COPY_NODE(TO, FROM) (memcpy((TO), (FROM), sizeof(struct _expr))) 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_cistatic int 347db96d56Sopenharmony_cihas_starred(asdl_expr_seq *elts) 357db96d56Sopenharmony_ci{ 367db96d56Sopenharmony_ci Py_ssize_t n = asdl_seq_LEN(elts); 377db96d56Sopenharmony_ci for (Py_ssize_t i = 0; i < n; i++) { 387db96d56Sopenharmony_ci expr_ty e = (expr_ty)asdl_seq_GET(elts, i); 397db96d56Sopenharmony_ci if (e->kind == Starred_kind) { 407db96d56Sopenharmony_ci return 1; 417db96d56Sopenharmony_ci } 427db96d56Sopenharmony_ci } 437db96d56Sopenharmony_ci return 0; 447db96d56Sopenharmony_ci} 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_cistatic PyObject* 487db96d56Sopenharmony_ciunary_not(PyObject *v) 497db96d56Sopenharmony_ci{ 507db96d56Sopenharmony_ci int r = PyObject_IsTrue(v); 517db96d56Sopenharmony_ci if (r < 0) 527db96d56Sopenharmony_ci return NULL; 537db96d56Sopenharmony_ci return PyBool_FromLong(!r); 547db96d56Sopenharmony_ci} 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_cistatic int 577db96d56Sopenharmony_cifold_unaryop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) 587db96d56Sopenharmony_ci{ 597db96d56Sopenharmony_ci expr_ty arg = node->v.UnaryOp.operand; 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_ci if (arg->kind != Constant_kind) { 627db96d56Sopenharmony_ci /* Fold not into comparison */ 637db96d56Sopenharmony_ci if (node->v.UnaryOp.op == Not && arg->kind == Compare_kind && 647db96d56Sopenharmony_ci asdl_seq_LEN(arg->v.Compare.ops) == 1) { 657db96d56Sopenharmony_ci /* Eq and NotEq are often implemented in terms of one another, so 667db96d56Sopenharmony_ci folding not (self == other) into self != other breaks implementation 677db96d56Sopenharmony_ci of !=. Detecting such cases doesn't seem worthwhile. 687db96d56Sopenharmony_ci Python uses </> for 'is subset'/'is superset' operations on sets. 697db96d56Sopenharmony_ci They don't satisfy not folding laws. */ 707db96d56Sopenharmony_ci cmpop_ty op = asdl_seq_GET(arg->v.Compare.ops, 0); 717db96d56Sopenharmony_ci switch (op) { 727db96d56Sopenharmony_ci case Is: 737db96d56Sopenharmony_ci op = IsNot; 747db96d56Sopenharmony_ci break; 757db96d56Sopenharmony_ci case IsNot: 767db96d56Sopenharmony_ci op = Is; 777db96d56Sopenharmony_ci break; 787db96d56Sopenharmony_ci case In: 797db96d56Sopenharmony_ci op = NotIn; 807db96d56Sopenharmony_ci break; 817db96d56Sopenharmony_ci case NotIn: 827db96d56Sopenharmony_ci op = In; 837db96d56Sopenharmony_ci break; 847db96d56Sopenharmony_ci // The remaining comparison operators can't be safely inverted 857db96d56Sopenharmony_ci case Eq: 867db96d56Sopenharmony_ci case NotEq: 877db96d56Sopenharmony_ci case Lt: 887db96d56Sopenharmony_ci case LtE: 897db96d56Sopenharmony_ci case Gt: 907db96d56Sopenharmony_ci case GtE: 917db96d56Sopenharmony_ci op = 0; // The AST enums leave "0" free as an "unused" marker 927db96d56Sopenharmony_ci break; 937db96d56Sopenharmony_ci // No default case, so the compiler will emit a warning if new 947db96d56Sopenharmony_ci // comparison operators are added without being handled here 957db96d56Sopenharmony_ci } 967db96d56Sopenharmony_ci if (op) { 977db96d56Sopenharmony_ci asdl_seq_SET(arg->v.Compare.ops, 0, op); 987db96d56Sopenharmony_ci COPY_NODE(node, arg); 997db96d56Sopenharmony_ci return 1; 1007db96d56Sopenharmony_ci } 1017db96d56Sopenharmony_ci } 1027db96d56Sopenharmony_ci return 1; 1037db96d56Sopenharmony_ci } 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ci typedef PyObject *(*unary_op)(PyObject*); 1067db96d56Sopenharmony_ci static const unary_op ops[] = { 1077db96d56Sopenharmony_ci [Invert] = PyNumber_Invert, 1087db96d56Sopenharmony_ci [Not] = unary_not, 1097db96d56Sopenharmony_ci [UAdd] = PyNumber_Positive, 1107db96d56Sopenharmony_ci [USub] = PyNumber_Negative, 1117db96d56Sopenharmony_ci }; 1127db96d56Sopenharmony_ci PyObject *newval = ops[node->v.UnaryOp.op](arg->v.Constant.value); 1137db96d56Sopenharmony_ci return make_const(node, newval, arena); 1147db96d56Sopenharmony_ci} 1157db96d56Sopenharmony_ci 1167db96d56Sopenharmony_ci/* Check whether a collection doesn't containing too much items (including 1177db96d56Sopenharmony_ci subcollections). This protects from creating a constant that needs 1187db96d56Sopenharmony_ci too much time for calculating a hash. 1197db96d56Sopenharmony_ci "limit" is the maximal number of items. 1207db96d56Sopenharmony_ci Returns the negative number if the total number of items exceeds the 1217db96d56Sopenharmony_ci limit. Otherwise returns the limit minus the total number of items. 1227db96d56Sopenharmony_ci*/ 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_cistatic Py_ssize_t 1257db96d56Sopenharmony_cicheck_complexity(PyObject *obj, Py_ssize_t limit) 1267db96d56Sopenharmony_ci{ 1277db96d56Sopenharmony_ci if (PyTuple_Check(obj)) { 1287db96d56Sopenharmony_ci Py_ssize_t i; 1297db96d56Sopenharmony_ci limit -= PyTuple_GET_SIZE(obj); 1307db96d56Sopenharmony_ci for (i = 0; limit >= 0 && i < PyTuple_GET_SIZE(obj); i++) { 1317db96d56Sopenharmony_ci limit = check_complexity(PyTuple_GET_ITEM(obj, i), limit); 1327db96d56Sopenharmony_ci } 1337db96d56Sopenharmony_ci return limit; 1347db96d56Sopenharmony_ci } 1357db96d56Sopenharmony_ci else if (PyFrozenSet_Check(obj)) { 1367db96d56Sopenharmony_ci Py_ssize_t i = 0; 1377db96d56Sopenharmony_ci PyObject *item; 1387db96d56Sopenharmony_ci Py_hash_t hash; 1397db96d56Sopenharmony_ci limit -= PySet_GET_SIZE(obj); 1407db96d56Sopenharmony_ci while (limit >= 0 && _PySet_NextEntry(obj, &i, &item, &hash)) { 1417db96d56Sopenharmony_ci limit = check_complexity(item, limit); 1427db96d56Sopenharmony_ci } 1437db96d56Sopenharmony_ci } 1447db96d56Sopenharmony_ci return limit; 1457db96d56Sopenharmony_ci} 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_ci#define MAX_INT_SIZE 128 /* bits */ 1487db96d56Sopenharmony_ci#define MAX_COLLECTION_SIZE 256 /* items */ 1497db96d56Sopenharmony_ci#define MAX_STR_SIZE 4096 /* characters */ 1507db96d56Sopenharmony_ci#define MAX_TOTAL_ITEMS 1024 /* including nested collections */ 1517db96d56Sopenharmony_ci 1527db96d56Sopenharmony_cistatic PyObject * 1537db96d56Sopenharmony_cisafe_multiply(PyObject *v, PyObject *w) 1547db96d56Sopenharmony_ci{ 1557db96d56Sopenharmony_ci if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) { 1567db96d56Sopenharmony_ci size_t vbits = _PyLong_NumBits(v); 1577db96d56Sopenharmony_ci size_t wbits = _PyLong_NumBits(w); 1587db96d56Sopenharmony_ci if (vbits == (size_t)-1 || wbits == (size_t)-1) { 1597db96d56Sopenharmony_ci return NULL; 1607db96d56Sopenharmony_ci } 1617db96d56Sopenharmony_ci if (vbits + wbits > MAX_INT_SIZE) { 1627db96d56Sopenharmony_ci return NULL; 1637db96d56Sopenharmony_ci } 1647db96d56Sopenharmony_ci } 1657db96d56Sopenharmony_ci else if (PyLong_Check(v) && (PyTuple_Check(w) || PyFrozenSet_Check(w))) { 1667db96d56Sopenharmony_ci Py_ssize_t size = PyTuple_Check(w) ? PyTuple_GET_SIZE(w) : 1677db96d56Sopenharmony_ci PySet_GET_SIZE(w); 1687db96d56Sopenharmony_ci if (size) { 1697db96d56Sopenharmony_ci long n = PyLong_AsLong(v); 1707db96d56Sopenharmony_ci if (n < 0 || n > MAX_COLLECTION_SIZE / size) { 1717db96d56Sopenharmony_ci return NULL; 1727db96d56Sopenharmony_ci } 1737db96d56Sopenharmony_ci if (n && check_complexity(w, MAX_TOTAL_ITEMS / n) < 0) { 1747db96d56Sopenharmony_ci return NULL; 1757db96d56Sopenharmony_ci } 1767db96d56Sopenharmony_ci } 1777db96d56Sopenharmony_ci } 1787db96d56Sopenharmony_ci else if (PyLong_Check(v) && (PyUnicode_Check(w) || PyBytes_Check(w))) { 1797db96d56Sopenharmony_ci Py_ssize_t size = PyUnicode_Check(w) ? PyUnicode_GET_LENGTH(w) : 1807db96d56Sopenharmony_ci PyBytes_GET_SIZE(w); 1817db96d56Sopenharmony_ci if (size) { 1827db96d56Sopenharmony_ci long n = PyLong_AsLong(v); 1837db96d56Sopenharmony_ci if (n < 0 || n > MAX_STR_SIZE / size) { 1847db96d56Sopenharmony_ci return NULL; 1857db96d56Sopenharmony_ci } 1867db96d56Sopenharmony_ci } 1877db96d56Sopenharmony_ci } 1887db96d56Sopenharmony_ci else if (PyLong_Check(w) && 1897db96d56Sopenharmony_ci (PyTuple_Check(v) || PyFrozenSet_Check(v) || 1907db96d56Sopenharmony_ci PyUnicode_Check(v) || PyBytes_Check(v))) 1917db96d56Sopenharmony_ci { 1927db96d56Sopenharmony_ci return safe_multiply(w, v); 1937db96d56Sopenharmony_ci } 1947db96d56Sopenharmony_ci 1957db96d56Sopenharmony_ci return PyNumber_Multiply(v, w); 1967db96d56Sopenharmony_ci} 1977db96d56Sopenharmony_ci 1987db96d56Sopenharmony_cistatic PyObject * 1997db96d56Sopenharmony_cisafe_power(PyObject *v, PyObject *w) 2007db96d56Sopenharmony_ci{ 2017db96d56Sopenharmony_ci if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w) > 0) { 2027db96d56Sopenharmony_ci size_t vbits = _PyLong_NumBits(v); 2037db96d56Sopenharmony_ci size_t wbits = PyLong_AsSize_t(w); 2047db96d56Sopenharmony_ci if (vbits == (size_t)-1 || wbits == (size_t)-1) { 2057db96d56Sopenharmony_ci return NULL; 2067db96d56Sopenharmony_ci } 2077db96d56Sopenharmony_ci if (vbits > MAX_INT_SIZE / wbits) { 2087db96d56Sopenharmony_ci return NULL; 2097db96d56Sopenharmony_ci } 2107db96d56Sopenharmony_ci } 2117db96d56Sopenharmony_ci 2127db96d56Sopenharmony_ci return PyNumber_Power(v, w, Py_None); 2137db96d56Sopenharmony_ci} 2147db96d56Sopenharmony_ci 2157db96d56Sopenharmony_cistatic PyObject * 2167db96d56Sopenharmony_cisafe_lshift(PyObject *v, PyObject *w) 2177db96d56Sopenharmony_ci{ 2187db96d56Sopenharmony_ci if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) { 2197db96d56Sopenharmony_ci size_t vbits = _PyLong_NumBits(v); 2207db96d56Sopenharmony_ci size_t wbits = PyLong_AsSize_t(w); 2217db96d56Sopenharmony_ci if (vbits == (size_t)-1 || wbits == (size_t)-1) { 2227db96d56Sopenharmony_ci return NULL; 2237db96d56Sopenharmony_ci } 2247db96d56Sopenharmony_ci if (wbits > MAX_INT_SIZE || vbits > MAX_INT_SIZE - wbits) { 2257db96d56Sopenharmony_ci return NULL; 2267db96d56Sopenharmony_ci } 2277db96d56Sopenharmony_ci } 2287db96d56Sopenharmony_ci 2297db96d56Sopenharmony_ci return PyNumber_Lshift(v, w); 2307db96d56Sopenharmony_ci} 2317db96d56Sopenharmony_ci 2327db96d56Sopenharmony_cistatic PyObject * 2337db96d56Sopenharmony_cisafe_mod(PyObject *v, PyObject *w) 2347db96d56Sopenharmony_ci{ 2357db96d56Sopenharmony_ci if (PyUnicode_Check(v) || PyBytes_Check(v)) { 2367db96d56Sopenharmony_ci return NULL; 2377db96d56Sopenharmony_ci } 2387db96d56Sopenharmony_ci 2397db96d56Sopenharmony_ci return PyNumber_Remainder(v, w); 2407db96d56Sopenharmony_ci} 2417db96d56Sopenharmony_ci 2427db96d56Sopenharmony_ci 2437db96d56Sopenharmony_cistatic expr_ty 2447db96d56Sopenharmony_ciparse_literal(PyObject *fmt, Py_ssize_t *ppos, PyArena *arena) 2457db96d56Sopenharmony_ci{ 2467db96d56Sopenharmony_ci const void *data = PyUnicode_DATA(fmt); 2477db96d56Sopenharmony_ci int kind = PyUnicode_KIND(fmt); 2487db96d56Sopenharmony_ci Py_ssize_t size = PyUnicode_GET_LENGTH(fmt); 2497db96d56Sopenharmony_ci Py_ssize_t start, pos; 2507db96d56Sopenharmony_ci int has_percents = 0; 2517db96d56Sopenharmony_ci start = pos = *ppos; 2527db96d56Sopenharmony_ci while (pos < size) { 2537db96d56Sopenharmony_ci if (PyUnicode_READ(kind, data, pos) != '%') { 2547db96d56Sopenharmony_ci pos++; 2557db96d56Sopenharmony_ci } 2567db96d56Sopenharmony_ci else if (pos+1 < size && PyUnicode_READ(kind, data, pos+1) == '%') { 2577db96d56Sopenharmony_ci has_percents = 1; 2587db96d56Sopenharmony_ci pos += 2; 2597db96d56Sopenharmony_ci } 2607db96d56Sopenharmony_ci else { 2617db96d56Sopenharmony_ci break; 2627db96d56Sopenharmony_ci } 2637db96d56Sopenharmony_ci } 2647db96d56Sopenharmony_ci *ppos = pos; 2657db96d56Sopenharmony_ci if (pos == start) { 2667db96d56Sopenharmony_ci return NULL; 2677db96d56Sopenharmony_ci } 2687db96d56Sopenharmony_ci PyObject *str = PyUnicode_Substring(fmt, start, pos); 2697db96d56Sopenharmony_ci /* str = str.replace('%%', '%') */ 2707db96d56Sopenharmony_ci if (str && has_percents) { 2717db96d56Sopenharmony_ci _Py_DECLARE_STR(percent, "%"); 2727db96d56Sopenharmony_ci _Py_DECLARE_STR(dbl_percent, "%%"); 2737db96d56Sopenharmony_ci Py_SETREF(str, PyUnicode_Replace(str, &_Py_STR(dbl_percent), 2747db96d56Sopenharmony_ci &_Py_STR(percent), -1)); 2757db96d56Sopenharmony_ci } 2767db96d56Sopenharmony_ci if (!str) { 2777db96d56Sopenharmony_ci return NULL; 2787db96d56Sopenharmony_ci } 2797db96d56Sopenharmony_ci 2807db96d56Sopenharmony_ci if (_PyArena_AddPyObject(arena, str) < 0) { 2817db96d56Sopenharmony_ci Py_DECREF(str); 2827db96d56Sopenharmony_ci return NULL; 2837db96d56Sopenharmony_ci } 2847db96d56Sopenharmony_ci return _PyAST_Constant(str, NULL, -1, -1, -1, -1, arena); 2857db96d56Sopenharmony_ci} 2867db96d56Sopenharmony_ci 2877db96d56Sopenharmony_ci#define MAXDIGITS 3 2887db96d56Sopenharmony_ci 2897db96d56Sopenharmony_cistatic int 2907db96d56Sopenharmony_cisimple_format_arg_parse(PyObject *fmt, Py_ssize_t *ppos, 2917db96d56Sopenharmony_ci int *spec, int *flags, int *width, int *prec) 2927db96d56Sopenharmony_ci{ 2937db96d56Sopenharmony_ci Py_ssize_t pos = *ppos, len = PyUnicode_GET_LENGTH(fmt); 2947db96d56Sopenharmony_ci Py_UCS4 ch; 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ci#define NEXTC do { \ 2977db96d56Sopenharmony_ci if (pos >= len) { \ 2987db96d56Sopenharmony_ci return 0; \ 2997db96d56Sopenharmony_ci } \ 3007db96d56Sopenharmony_ci ch = PyUnicode_READ_CHAR(fmt, pos); \ 3017db96d56Sopenharmony_ci pos++; \ 3027db96d56Sopenharmony_ci} while (0) 3037db96d56Sopenharmony_ci 3047db96d56Sopenharmony_ci *flags = 0; 3057db96d56Sopenharmony_ci while (1) { 3067db96d56Sopenharmony_ci NEXTC; 3077db96d56Sopenharmony_ci switch (ch) { 3087db96d56Sopenharmony_ci case '-': *flags |= F_LJUST; continue; 3097db96d56Sopenharmony_ci case '+': *flags |= F_SIGN; continue; 3107db96d56Sopenharmony_ci case ' ': *flags |= F_BLANK; continue; 3117db96d56Sopenharmony_ci case '#': *flags |= F_ALT; continue; 3127db96d56Sopenharmony_ci case '0': *flags |= F_ZERO; continue; 3137db96d56Sopenharmony_ci } 3147db96d56Sopenharmony_ci break; 3157db96d56Sopenharmony_ci } 3167db96d56Sopenharmony_ci if ('0' <= ch && ch <= '9') { 3177db96d56Sopenharmony_ci *width = 0; 3187db96d56Sopenharmony_ci int digits = 0; 3197db96d56Sopenharmony_ci while ('0' <= ch && ch <= '9') { 3207db96d56Sopenharmony_ci *width = *width * 10 + (ch - '0'); 3217db96d56Sopenharmony_ci NEXTC; 3227db96d56Sopenharmony_ci if (++digits >= MAXDIGITS) { 3237db96d56Sopenharmony_ci return 0; 3247db96d56Sopenharmony_ci } 3257db96d56Sopenharmony_ci } 3267db96d56Sopenharmony_ci } 3277db96d56Sopenharmony_ci 3287db96d56Sopenharmony_ci if (ch == '.') { 3297db96d56Sopenharmony_ci NEXTC; 3307db96d56Sopenharmony_ci *prec = 0; 3317db96d56Sopenharmony_ci if ('0' <= ch && ch <= '9') { 3327db96d56Sopenharmony_ci int digits = 0; 3337db96d56Sopenharmony_ci while ('0' <= ch && ch <= '9') { 3347db96d56Sopenharmony_ci *prec = *prec * 10 + (ch - '0'); 3357db96d56Sopenharmony_ci NEXTC; 3367db96d56Sopenharmony_ci if (++digits >= MAXDIGITS) { 3377db96d56Sopenharmony_ci return 0; 3387db96d56Sopenharmony_ci } 3397db96d56Sopenharmony_ci } 3407db96d56Sopenharmony_ci } 3417db96d56Sopenharmony_ci } 3427db96d56Sopenharmony_ci *spec = ch; 3437db96d56Sopenharmony_ci *ppos = pos; 3447db96d56Sopenharmony_ci return 1; 3457db96d56Sopenharmony_ci 3467db96d56Sopenharmony_ci#undef NEXTC 3477db96d56Sopenharmony_ci} 3487db96d56Sopenharmony_ci 3497db96d56Sopenharmony_cistatic expr_ty 3507db96d56Sopenharmony_ciparse_format(PyObject *fmt, Py_ssize_t *ppos, expr_ty arg, PyArena *arena) 3517db96d56Sopenharmony_ci{ 3527db96d56Sopenharmony_ci int spec, flags, width = -1, prec = -1; 3537db96d56Sopenharmony_ci if (!simple_format_arg_parse(fmt, ppos, &spec, &flags, &width, &prec)) { 3547db96d56Sopenharmony_ci // Unsupported format. 3557db96d56Sopenharmony_ci return NULL; 3567db96d56Sopenharmony_ci } 3577db96d56Sopenharmony_ci if (spec == 's' || spec == 'r' || spec == 'a') { 3587db96d56Sopenharmony_ci char buf[1 + MAXDIGITS + 1 + MAXDIGITS + 1], *p = buf; 3597db96d56Sopenharmony_ci if (!(flags & F_LJUST) && width > 0) { 3607db96d56Sopenharmony_ci *p++ = '>'; 3617db96d56Sopenharmony_ci } 3627db96d56Sopenharmony_ci if (width >= 0) { 3637db96d56Sopenharmony_ci p += snprintf(p, MAXDIGITS + 1, "%d", width); 3647db96d56Sopenharmony_ci } 3657db96d56Sopenharmony_ci if (prec >= 0) { 3667db96d56Sopenharmony_ci p += snprintf(p, MAXDIGITS + 2, ".%d", prec); 3677db96d56Sopenharmony_ci } 3687db96d56Sopenharmony_ci expr_ty format_spec = NULL; 3697db96d56Sopenharmony_ci if (p != buf) { 3707db96d56Sopenharmony_ci PyObject *str = PyUnicode_FromString(buf); 3717db96d56Sopenharmony_ci if (str == NULL) { 3727db96d56Sopenharmony_ci return NULL; 3737db96d56Sopenharmony_ci } 3747db96d56Sopenharmony_ci if (_PyArena_AddPyObject(arena, str) < 0) { 3757db96d56Sopenharmony_ci Py_DECREF(str); 3767db96d56Sopenharmony_ci return NULL; 3777db96d56Sopenharmony_ci } 3787db96d56Sopenharmony_ci format_spec = _PyAST_Constant(str, NULL, -1, -1, -1, -1, arena); 3797db96d56Sopenharmony_ci if (format_spec == NULL) { 3807db96d56Sopenharmony_ci return NULL; 3817db96d56Sopenharmony_ci } 3827db96d56Sopenharmony_ci } 3837db96d56Sopenharmony_ci return _PyAST_FormattedValue(arg, spec, format_spec, 3847db96d56Sopenharmony_ci arg->lineno, arg->col_offset, 3857db96d56Sopenharmony_ci arg->end_lineno, arg->end_col_offset, 3867db96d56Sopenharmony_ci arena); 3877db96d56Sopenharmony_ci } 3887db96d56Sopenharmony_ci // Unsupported format. 3897db96d56Sopenharmony_ci return NULL; 3907db96d56Sopenharmony_ci} 3917db96d56Sopenharmony_ci 3927db96d56Sopenharmony_cistatic int 3937db96d56Sopenharmony_cioptimize_format(expr_ty node, PyObject *fmt, asdl_expr_seq *elts, PyArena *arena) 3947db96d56Sopenharmony_ci{ 3957db96d56Sopenharmony_ci Py_ssize_t pos = 0; 3967db96d56Sopenharmony_ci Py_ssize_t cnt = 0; 3977db96d56Sopenharmony_ci asdl_expr_seq *seq = _Py_asdl_expr_seq_new(asdl_seq_LEN(elts) * 2 + 1, arena); 3987db96d56Sopenharmony_ci if (!seq) { 3997db96d56Sopenharmony_ci return 0; 4007db96d56Sopenharmony_ci } 4017db96d56Sopenharmony_ci seq->size = 0; 4027db96d56Sopenharmony_ci 4037db96d56Sopenharmony_ci while (1) { 4047db96d56Sopenharmony_ci expr_ty lit = parse_literal(fmt, &pos, arena); 4057db96d56Sopenharmony_ci if (lit) { 4067db96d56Sopenharmony_ci asdl_seq_SET(seq, seq->size++, lit); 4077db96d56Sopenharmony_ci } 4087db96d56Sopenharmony_ci else if (PyErr_Occurred()) { 4097db96d56Sopenharmony_ci return 0; 4107db96d56Sopenharmony_ci } 4117db96d56Sopenharmony_ci 4127db96d56Sopenharmony_ci if (pos >= PyUnicode_GET_LENGTH(fmt)) { 4137db96d56Sopenharmony_ci break; 4147db96d56Sopenharmony_ci } 4157db96d56Sopenharmony_ci if (cnt >= asdl_seq_LEN(elts)) { 4167db96d56Sopenharmony_ci // More format units than items. 4177db96d56Sopenharmony_ci return 1; 4187db96d56Sopenharmony_ci } 4197db96d56Sopenharmony_ci assert(PyUnicode_READ_CHAR(fmt, pos) == '%'); 4207db96d56Sopenharmony_ci pos++; 4217db96d56Sopenharmony_ci expr_ty expr = parse_format(fmt, &pos, asdl_seq_GET(elts, cnt), arena); 4227db96d56Sopenharmony_ci cnt++; 4237db96d56Sopenharmony_ci if (!expr) { 4247db96d56Sopenharmony_ci return !PyErr_Occurred(); 4257db96d56Sopenharmony_ci } 4267db96d56Sopenharmony_ci asdl_seq_SET(seq, seq->size++, expr); 4277db96d56Sopenharmony_ci } 4287db96d56Sopenharmony_ci if (cnt < asdl_seq_LEN(elts)) { 4297db96d56Sopenharmony_ci // More items than format units. 4307db96d56Sopenharmony_ci return 1; 4317db96d56Sopenharmony_ci } 4327db96d56Sopenharmony_ci expr_ty res = _PyAST_JoinedStr(seq, 4337db96d56Sopenharmony_ci node->lineno, node->col_offset, 4347db96d56Sopenharmony_ci node->end_lineno, node->end_col_offset, 4357db96d56Sopenharmony_ci arena); 4367db96d56Sopenharmony_ci if (!res) { 4377db96d56Sopenharmony_ci return 0; 4387db96d56Sopenharmony_ci } 4397db96d56Sopenharmony_ci COPY_NODE(node, res); 4407db96d56Sopenharmony_ci// PySys_FormatStderr("format = %R\n", fmt); 4417db96d56Sopenharmony_ci return 1; 4427db96d56Sopenharmony_ci} 4437db96d56Sopenharmony_ci 4447db96d56Sopenharmony_cistatic int 4457db96d56Sopenharmony_cifold_binop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) 4467db96d56Sopenharmony_ci{ 4477db96d56Sopenharmony_ci expr_ty lhs, rhs; 4487db96d56Sopenharmony_ci lhs = node->v.BinOp.left; 4497db96d56Sopenharmony_ci rhs = node->v.BinOp.right; 4507db96d56Sopenharmony_ci if (lhs->kind != Constant_kind) { 4517db96d56Sopenharmony_ci return 1; 4527db96d56Sopenharmony_ci } 4537db96d56Sopenharmony_ci PyObject *lv = lhs->v.Constant.value; 4547db96d56Sopenharmony_ci 4557db96d56Sopenharmony_ci if (node->v.BinOp.op == Mod && 4567db96d56Sopenharmony_ci rhs->kind == Tuple_kind && 4577db96d56Sopenharmony_ci PyUnicode_Check(lv) && 4587db96d56Sopenharmony_ci !has_starred(rhs->v.Tuple.elts)) 4597db96d56Sopenharmony_ci { 4607db96d56Sopenharmony_ci return optimize_format(node, lv, rhs->v.Tuple.elts, arena); 4617db96d56Sopenharmony_ci } 4627db96d56Sopenharmony_ci 4637db96d56Sopenharmony_ci if (rhs->kind != Constant_kind) { 4647db96d56Sopenharmony_ci return 1; 4657db96d56Sopenharmony_ci } 4667db96d56Sopenharmony_ci 4677db96d56Sopenharmony_ci PyObject *rv = rhs->v.Constant.value; 4687db96d56Sopenharmony_ci PyObject *newval = NULL; 4697db96d56Sopenharmony_ci 4707db96d56Sopenharmony_ci switch (node->v.BinOp.op) { 4717db96d56Sopenharmony_ci case Add: 4727db96d56Sopenharmony_ci newval = PyNumber_Add(lv, rv); 4737db96d56Sopenharmony_ci break; 4747db96d56Sopenharmony_ci case Sub: 4757db96d56Sopenharmony_ci newval = PyNumber_Subtract(lv, rv); 4767db96d56Sopenharmony_ci break; 4777db96d56Sopenharmony_ci case Mult: 4787db96d56Sopenharmony_ci newval = safe_multiply(lv, rv); 4797db96d56Sopenharmony_ci break; 4807db96d56Sopenharmony_ci case Div: 4817db96d56Sopenharmony_ci newval = PyNumber_TrueDivide(lv, rv); 4827db96d56Sopenharmony_ci break; 4837db96d56Sopenharmony_ci case FloorDiv: 4847db96d56Sopenharmony_ci newval = PyNumber_FloorDivide(lv, rv); 4857db96d56Sopenharmony_ci break; 4867db96d56Sopenharmony_ci case Mod: 4877db96d56Sopenharmony_ci newval = safe_mod(lv, rv); 4887db96d56Sopenharmony_ci break; 4897db96d56Sopenharmony_ci case Pow: 4907db96d56Sopenharmony_ci newval = safe_power(lv, rv); 4917db96d56Sopenharmony_ci break; 4927db96d56Sopenharmony_ci case LShift: 4937db96d56Sopenharmony_ci newval = safe_lshift(lv, rv); 4947db96d56Sopenharmony_ci break; 4957db96d56Sopenharmony_ci case RShift: 4967db96d56Sopenharmony_ci newval = PyNumber_Rshift(lv, rv); 4977db96d56Sopenharmony_ci break; 4987db96d56Sopenharmony_ci case BitOr: 4997db96d56Sopenharmony_ci newval = PyNumber_Or(lv, rv); 5007db96d56Sopenharmony_ci break; 5017db96d56Sopenharmony_ci case BitXor: 5027db96d56Sopenharmony_ci newval = PyNumber_Xor(lv, rv); 5037db96d56Sopenharmony_ci break; 5047db96d56Sopenharmony_ci case BitAnd: 5057db96d56Sopenharmony_ci newval = PyNumber_And(lv, rv); 5067db96d56Sopenharmony_ci break; 5077db96d56Sopenharmony_ci // No builtin constants implement the following operators 5087db96d56Sopenharmony_ci case MatMult: 5097db96d56Sopenharmony_ci return 1; 5107db96d56Sopenharmony_ci // No default case, so the compiler will emit a warning if new binary 5117db96d56Sopenharmony_ci // operators are added without being handled here 5127db96d56Sopenharmony_ci } 5137db96d56Sopenharmony_ci 5147db96d56Sopenharmony_ci return make_const(node, newval, arena); 5157db96d56Sopenharmony_ci} 5167db96d56Sopenharmony_ci 5177db96d56Sopenharmony_cistatic PyObject* 5187db96d56Sopenharmony_cimake_const_tuple(asdl_expr_seq *elts) 5197db96d56Sopenharmony_ci{ 5207db96d56Sopenharmony_ci for (int i = 0; i < asdl_seq_LEN(elts); i++) { 5217db96d56Sopenharmony_ci expr_ty e = (expr_ty)asdl_seq_GET(elts, i); 5227db96d56Sopenharmony_ci if (e->kind != Constant_kind) { 5237db96d56Sopenharmony_ci return NULL; 5247db96d56Sopenharmony_ci } 5257db96d56Sopenharmony_ci } 5267db96d56Sopenharmony_ci 5277db96d56Sopenharmony_ci PyObject *newval = PyTuple_New(asdl_seq_LEN(elts)); 5287db96d56Sopenharmony_ci if (newval == NULL) { 5297db96d56Sopenharmony_ci return NULL; 5307db96d56Sopenharmony_ci } 5317db96d56Sopenharmony_ci 5327db96d56Sopenharmony_ci for (int i = 0; i < asdl_seq_LEN(elts); i++) { 5337db96d56Sopenharmony_ci expr_ty e = (expr_ty)asdl_seq_GET(elts, i); 5347db96d56Sopenharmony_ci PyObject *v = e->v.Constant.value; 5357db96d56Sopenharmony_ci Py_INCREF(v); 5367db96d56Sopenharmony_ci PyTuple_SET_ITEM(newval, i, v); 5377db96d56Sopenharmony_ci } 5387db96d56Sopenharmony_ci return newval; 5397db96d56Sopenharmony_ci} 5407db96d56Sopenharmony_ci 5417db96d56Sopenharmony_cistatic int 5427db96d56Sopenharmony_cifold_tuple(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) 5437db96d56Sopenharmony_ci{ 5447db96d56Sopenharmony_ci PyObject *newval; 5457db96d56Sopenharmony_ci 5467db96d56Sopenharmony_ci if (node->v.Tuple.ctx != Load) 5477db96d56Sopenharmony_ci return 1; 5487db96d56Sopenharmony_ci 5497db96d56Sopenharmony_ci newval = make_const_tuple(node->v.Tuple.elts); 5507db96d56Sopenharmony_ci return make_const(node, newval, arena); 5517db96d56Sopenharmony_ci} 5527db96d56Sopenharmony_ci 5537db96d56Sopenharmony_cistatic int 5547db96d56Sopenharmony_cifold_subscr(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) 5557db96d56Sopenharmony_ci{ 5567db96d56Sopenharmony_ci PyObject *newval; 5577db96d56Sopenharmony_ci expr_ty arg, idx; 5587db96d56Sopenharmony_ci 5597db96d56Sopenharmony_ci arg = node->v.Subscript.value; 5607db96d56Sopenharmony_ci idx = node->v.Subscript.slice; 5617db96d56Sopenharmony_ci if (node->v.Subscript.ctx != Load || 5627db96d56Sopenharmony_ci arg->kind != Constant_kind || 5637db96d56Sopenharmony_ci idx->kind != Constant_kind) 5647db96d56Sopenharmony_ci { 5657db96d56Sopenharmony_ci return 1; 5667db96d56Sopenharmony_ci } 5677db96d56Sopenharmony_ci 5687db96d56Sopenharmony_ci newval = PyObject_GetItem(arg->v.Constant.value, idx->v.Constant.value); 5697db96d56Sopenharmony_ci return make_const(node, newval, arena); 5707db96d56Sopenharmony_ci} 5717db96d56Sopenharmony_ci 5727db96d56Sopenharmony_ci/* Change literal list or set of constants into constant 5737db96d56Sopenharmony_ci tuple or frozenset respectively. Change literal list of 5747db96d56Sopenharmony_ci non-constants into tuple. 5757db96d56Sopenharmony_ci Used for right operand of "in" and "not in" tests and for iterable 5767db96d56Sopenharmony_ci in "for" loop and comprehensions. 5777db96d56Sopenharmony_ci*/ 5787db96d56Sopenharmony_cistatic int 5797db96d56Sopenharmony_cifold_iter(expr_ty arg, PyArena *arena, _PyASTOptimizeState *state) 5807db96d56Sopenharmony_ci{ 5817db96d56Sopenharmony_ci PyObject *newval; 5827db96d56Sopenharmony_ci if (arg->kind == List_kind) { 5837db96d56Sopenharmony_ci /* First change a list into tuple. */ 5847db96d56Sopenharmony_ci asdl_expr_seq *elts = arg->v.List.elts; 5857db96d56Sopenharmony_ci if (has_starred(elts)) { 5867db96d56Sopenharmony_ci return 1; 5877db96d56Sopenharmony_ci } 5887db96d56Sopenharmony_ci expr_context_ty ctx = arg->v.List.ctx; 5897db96d56Sopenharmony_ci arg->kind = Tuple_kind; 5907db96d56Sopenharmony_ci arg->v.Tuple.elts = elts; 5917db96d56Sopenharmony_ci arg->v.Tuple.ctx = ctx; 5927db96d56Sopenharmony_ci /* Try to create a constant tuple. */ 5937db96d56Sopenharmony_ci newval = make_const_tuple(elts); 5947db96d56Sopenharmony_ci } 5957db96d56Sopenharmony_ci else if (arg->kind == Set_kind) { 5967db96d56Sopenharmony_ci newval = make_const_tuple(arg->v.Set.elts); 5977db96d56Sopenharmony_ci if (newval) { 5987db96d56Sopenharmony_ci Py_SETREF(newval, PyFrozenSet_New(newval)); 5997db96d56Sopenharmony_ci } 6007db96d56Sopenharmony_ci } 6017db96d56Sopenharmony_ci else { 6027db96d56Sopenharmony_ci return 1; 6037db96d56Sopenharmony_ci } 6047db96d56Sopenharmony_ci return make_const(arg, newval, arena); 6057db96d56Sopenharmony_ci} 6067db96d56Sopenharmony_ci 6077db96d56Sopenharmony_cistatic int 6087db96d56Sopenharmony_cifold_compare(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) 6097db96d56Sopenharmony_ci{ 6107db96d56Sopenharmony_ci asdl_int_seq *ops; 6117db96d56Sopenharmony_ci asdl_expr_seq *args; 6127db96d56Sopenharmony_ci Py_ssize_t i; 6137db96d56Sopenharmony_ci 6147db96d56Sopenharmony_ci ops = node->v.Compare.ops; 6157db96d56Sopenharmony_ci args = node->v.Compare.comparators; 6167db96d56Sopenharmony_ci /* Change literal list or set in 'in' or 'not in' into 6177db96d56Sopenharmony_ci tuple or frozenset respectively. */ 6187db96d56Sopenharmony_ci i = asdl_seq_LEN(ops) - 1; 6197db96d56Sopenharmony_ci int op = asdl_seq_GET(ops, i); 6207db96d56Sopenharmony_ci if (op == In || op == NotIn) { 6217db96d56Sopenharmony_ci if (!fold_iter((expr_ty)asdl_seq_GET(args, i), arena, state)) { 6227db96d56Sopenharmony_ci return 0; 6237db96d56Sopenharmony_ci } 6247db96d56Sopenharmony_ci } 6257db96d56Sopenharmony_ci return 1; 6267db96d56Sopenharmony_ci} 6277db96d56Sopenharmony_ci 6287db96d56Sopenharmony_cistatic int astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); 6297db96d56Sopenharmony_cistatic int astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); 6307db96d56Sopenharmony_cistatic int astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); 6317db96d56Sopenharmony_cistatic int astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); 6327db96d56Sopenharmony_cistatic int astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); 6337db96d56Sopenharmony_cistatic int astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); 6347db96d56Sopenharmony_cistatic int astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); 6357db96d56Sopenharmony_cistatic int astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); 6367db96d56Sopenharmony_cistatic int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); 6377db96d56Sopenharmony_cistatic int astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); 6387db96d56Sopenharmony_cistatic int astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); 6397db96d56Sopenharmony_ci 6407db96d56Sopenharmony_ci#define CALL(FUNC, TYPE, ARG) \ 6417db96d56Sopenharmony_ci if (!FUNC((ARG), ctx_, state)) \ 6427db96d56Sopenharmony_ci return 0; 6437db96d56Sopenharmony_ci 6447db96d56Sopenharmony_ci#define CALL_OPT(FUNC, TYPE, ARG) \ 6457db96d56Sopenharmony_ci if ((ARG) != NULL && !FUNC((ARG), ctx_, state)) \ 6467db96d56Sopenharmony_ci return 0; 6477db96d56Sopenharmony_ci 6487db96d56Sopenharmony_ci#define CALL_SEQ(FUNC, TYPE, ARG) { \ 6497db96d56Sopenharmony_ci int i; \ 6507db96d56Sopenharmony_ci asdl_ ## TYPE ## _seq *seq = (ARG); /* avoid variable capture */ \ 6517db96d56Sopenharmony_ci for (i = 0; i < asdl_seq_LEN(seq); i++) { \ 6527db96d56Sopenharmony_ci TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ 6537db96d56Sopenharmony_ci if (elt != NULL && !FUNC(elt, ctx_, state)) \ 6547db96d56Sopenharmony_ci return 0; \ 6557db96d56Sopenharmony_ci } \ 6567db96d56Sopenharmony_ci} 6577db96d56Sopenharmony_ci 6587db96d56Sopenharmony_ci 6597db96d56Sopenharmony_cistatic int 6607db96d56Sopenharmony_ciastfold_body(asdl_stmt_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state) 6617db96d56Sopenharmony_ci{ 6627db96d56Sopenharmony_ci int docstring = _PyAST_GetDocString(stmts) != NULL; 6637db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, stmts); 6647db96d56Sopenharmony_ci if (!docstring && _PyAST_GetDocString(stmts) != NULL) { 6657db96d56Sopenharmony_ci stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0); 6667db96d56Sopenharmony_ci asdl_expr_seq *values = _Py_asdl_expr_seq_new(1, ctx_); 6677db96d56Sopenharmony_ci if (!values) { 6687db96d56Sopenharmony_ci return 0; 6697db96d56Sopenharmony_ci } 6707db96d56Sopenharmony_ci asdl_seq_SET(values, 0, st->v.Expr.value); 6717db96d56Sopenharmony_ci expr_ty expr = _PyAST_JoinedStr(values, st->lineno, st->col_offset, 6727db96d56Sopenharmony_ci st->end_lineno, st->end_col_offset, 6737db96d56Sopenharmony_ci ctx_); 6747db96d56Sopenharmony_ci if (!expr) { 6757db96d56Sopenharmony_ci return 0; 6767db96d56Sopenharmony_ci } 6777db96d56Sopenharmony_ci st->v.Expr.value = expr; 6787db96d56Sopenharmony_ci } 6797db96d56Sopenharmony_ci return 1; 6807db96d56Sopenharmony_ci} 6817db96d56Sopenharmony_ci 6827db96d56Sopenharmony_cistatic int 6837db96d56Sopenharmony_ciastfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) 6847db96d56Sopenharmony_ci{ 6857db96d56Sopenharmony_ci switch (node_->kind) { 6867db96d56Sopenharmony_ci case Module_kind: 6877db96d56Sopenharmony_ci CALL(astfold_body, asdl_seq, node_->v.Module.body); 6887db96d56Sopenharmony_ci break; 6897db96d56Sopenharmony_ci case Interactive_kind: 6907db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.Interactive.body); 6917db96d56Sopenharmony_ci break; 6927db96d56Sopenharmony_ci case Expression_kind: 6937db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Expression.body); 6947db96d56Sopenharmony_ci break; 6957db96d56Sopenharmony_ci // The following top level nodes don't participate in constant folding 6967db96d56Sopenharmony_ci case FunctionType_kind: 6977db96d56Sopenharmony_ci break; 6987db96d56Sopenharmony_ci // No default case, so the compiler will emit a warning if new top level 6997db96d56Sopenharmony_ci // compilation nodes are added without being handled here 7007db96d56Sopenharmony_ci } 7017db96d56Sopenharmony_ci return 1; 7027db96d56Sopenharmony_ci} 7037db96d56Sopenharmony_ci 7047db96d56Sopenharmony_cistatic int 7057db96d56Sopenharmony_ciastfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) 7067db96d56Sopenharmony_ci{ 7077db96d56Sopenharmony_ci if (++state->recursion_depth > state->recursion_limit) { 7087db96d56Sopenharmony_ci PyErr_SetString(PyExc_RecursionError, 7097db96d56Sopenharmony_ci "maximum recursion depth exceeded during compilation"); 7107db96d56Sopenharmony_ci return 0; 7117db96d56Sopenharmony_ci } 7127db96d56Sopenharmony_ci switch (node_->kind) { 7137db96d56Sopenharmony_ci case BoolOp_kind: 7147db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values); 7157db96d56Sopenharmony_ci break; 7167db96d56Sopenharmony_ci case BinOp_kind: 7177db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.BinOp.left); 7187db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.BinOp.right); 7197db96d56Sopenharmony_ci CALL(fold_binop, expr_ty, node_); 7207db96d56Sopenharmony_ci break; 7217db96d56Sopenharmony_ci case UnaryOp_kind: 7227db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.UnaryOp.operand); 7237db96d56Sopenharmony_ci CALL(fold_unaryop, expr_ty, node_); 7247db96d56Sopenharmony_ci break; 7257db96d56Sopenharmony_ci case Lambda_kind: 7267db96d56Sopenharmony_ci CALL(astfold_arguments, arguments_ty, node_->v.Lambda.args); 7277db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Lambda.body); 7287db96d56Sopenharmony_ci break; 7297db96d56Sopenharmony_ci case IfExp_kind: 7307db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.IfExp.test); 7317db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.IfExp.body); 7327db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.IfExp.orelse); 7337db96d56Sopenharmony_ci break; 7347db96d56Sopenharmony_ci case Dict_kind: 7357db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.Dict.keys); 7367db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.Dict.values); 7377db96d56Sopenharmony_ci break; 7387db96d56Sopenharmony_ci case Set_kind: 7397db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.Set.elts); 7407db96d56Sopenharmony_ci break; 7417db96d56Sopenharmony_ci case ListComp_kind: 7427db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.ListComp.elt); 7437db96d56Sopenharmony_ci CALL_SEQ(astfold_comprehension, comprehension, node_->v.ListComp.generators); 7447db96d56Sopenharmony_ci break; 7457db96d56Sopenharmony_ci case SetComp_kind: 7467db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.SetComp.elt); 7477db96d56Sopenharmony_ci CALL_SEQ(astfold_comprehension, comprehension, node_->v.SetComp.generators); 7487db96d56Sopenharmony_ci break; 7497db96d56Sopenharmony_ci case DictComp_kind: 7507db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.DictComp.key); 7517db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.DictComp.value); 7527db96d56Sopenharmony_ci CALL_SEQ(astfold_comprehension, comprehension, node_->v.DictComp.generators); 7537db96d56Sopenharmony_ci break; 7547db96d56Sopenharmony_ci case GeneratorExp_kind: 7557db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.GeneratorExp.elt); 7567db96d56Sopenharmony_ci CALL_SEQ(astfold_comprehension, comprehension, node_->v.GeneratorExp.generators); 7577db96d56Sopenharmony_ci break; 7587db96d56Sopenharmony_ci case Await_kind: 7597db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Await.value); 7607db96d56Sopenharmony_ci break; 7617db96d56Sopenharmony_ci case Yield_kind: 7627db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.Yield.value); 7637db96d56Sopenharmony_ci break; 7647db96d56Sopenharmony_ci case YieldFrom_kind: 7657db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.YieldFrom.value); 7667db96d56Sopenharmony_ci break; 7677db96d56Sopenharmony_ci case Compare_kind: 7687db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Compare.left); 7697db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.Compare.comparators); 7707db96d56Sopenharmony_ci CALL(fold_compare, expr_ty, node_); 7717db96d56Sopenharmony_ci break; 7727db96d56Sopenharmony_ci case Call_kind: 7737db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Call.func); 7747db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.Call.args); 7757db96d56Sopenharmony_ci CALL_SEQ(astfold_keyword, keyword, node_->v.Call.keywords); 7767db96d56Sopenharmony_ci break; 7777db96d56Sopenharmony_ci case FormattedValue_kind: 7787db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.FormattedValue.value); 7797db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.FormattedValue.format_spec); 7807db96d56Sopenharmony_ci break; 7817db96d56Sopenharmony_ci case JoinedStr_kind: 7827db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.JoinedStr.values); 7837db96d56Sopenharmony_ci break; 7847db96d56Sopenharmony_ci case Attribute_kind: 7857db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Attribute.value); 7867db96d56Sopenharmony_ci break; 7877db96d56Sopenharmony_ci case Subscript_kind: 7887db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Subscript.value); 7897db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Subscript.slice); 7907db96d56Sopenharmony_ci CALL(fold_subscr, expr_ty, node_); 7917db96d56Sopenharmony_ci break; 7927db96d56Sopenharmony_ci case Starred_kind: 7937db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Starred.value); 7947db96d56Sopenharmony_ci break; 7957db96d56Sopenharmony_ci case Slice_kind: 7967db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.lower); 7977db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.upper); 7987db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step); 7997db96d56Sopenharmony_ci break; 8007db96d56Sopenharmony_ci case List_kind: 8017db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.List.elts); 8027db96d56Sopenharmony_ci break; 8037db96d56Sopenharmony_ci case Tuple_kind: 8047db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.Tuple.elts); 8057db96d56Sopenharmony_ci CALL(fold_tuple, expr_ty, node_); 8067db96d56Sopenharmony_ci break; 8077db96d56Sopenharmony_ci case Name_kind: 8087db96d56Sopenharmony_ci if (node_->v.Name.ctx == Load && 8097db96d56Sopenharmony_ci _PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) { 8107db96d56Sopenharmony_ci state->recursion_depth--; 8117db96d56Sopenharmony_ci return make_const(node_, PyBool_FromLong(!state->optimize), ctx_); 8127db96d56Sopenharmony_ci } 8137db96d56Sopenharmony_ci break; 8147db96d56Sopenharmony_ci case NamedExpr_kind: 8157db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.NamedExpr.value); 8167db96d56Sopenharmony_ci break; 8177db96d56Sopenharmony_ci case Constant_kind: 8187db96d56Sopenharmony_ci // Already a constant, nothing further to do 8197db96d56Sopenharmony_ci break; 8207db96d56Sopenharmony_ci // No default case, so the compiler will emit a warning if new expression 8217db96d56Sopenharmony_ci // kinds are added without being handled here 8227db96d56Sopenharmony_ci } 8237db96d56Sopenharmony_ci state->recursion_depth--; 8247db96d56Sopenharmony_ci return 1; 8257db96d56Sopenharmony_ci} 8267db96d56Sopenharmony_ci 8277db96d56Sopenharmony_cistatic int 8287db96d56Sopenharmony_ciastfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) 8297db96d56Sopenharmony_ci{ 8307db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->value); 8317db96d56Sopenharmony_ci return 1; 8327db96d56Sopenharmony_ci} 8337db96d56Sopenharmony_ci 8347db96d56Sopenharmony_cistatic int 8357db96d56Sopenharmony_ciastfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) 8367db96d56Sopenharmony_ci{ 8377db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->target); 8387db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->iter); 8397db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->ifs); 8407db96d56Sopenharmony_ci 8417db96d56Sopenharmony_ci CALL(fold_iter, expr_ty, node_->iter); 8427db96d56Sopenharmony_ci return 1; 8437db96d56Sopenharmony_ci} 8447db96d56Sopenharmony_ci 8457db96d56Sopenharmony_cistatic int 8467db96d56Sopenharmony_ciastfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) 8477db96d56Sopenharmony_ci{ 8487db96d56Sopenharmony_ci CALL_SEQ(astfold_arg, arg, node_->posonlyargs); 8497db96d56Sopenharmony_ci CALL_SEQ(astfold_arg, arg, node_->args); 8507db96d56Sopenharmony_ci CALL_OPT(astfold_arg, arg_ty, node_->vararg); 8517db96d56Sopenharmony_ci CALL_SEQ(astfold_arg, arg, node_->kwonlyargs); 8527db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->kw_defaults); 8537db96d56Sopenharmony_ci CALL_OPT(astfold_arg, arg_ty, node_->kwarg); 8547db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->defaults); 8557db96d56Sopenharmony_ci return 1; 8567db96d56Sopenharmony_ci} 8577db96d56Sopenharmony_ci 8587db96d56Sopenharmony_cistatic int 8597db96d56Sopenharmony_ciastfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) 8607db96d56Sopenharmony_ci{ 8617db96d56Sopenharmony_ci if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { 8627db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->annotation); 8637db96d56Sopenharmony_ci } 8647db96d56Sopenharmony_ci return 1; 8657db96d56Sopenharmony_ci} 8667db96d56Sopenharmony_ci 8677db96d56Sopenharmony_cistatic int 8687db96d56Sopenharmony_ciastfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) 8697db96d56Sopenharmony_ci{ 8707db96d56Sopenharmony_ci if (++state->recursion_depth > state->recursion_limit) { 8717db96d56Sopenharmony_ci PyErr_SetString(PyExc_RecursionError, 8727db96d56Sopenharmony_ci "maximum recursion depth exceeded during compilation"); 8737db96d56Sopenharmony_ci return 0; 8747db96d56Sopenharmony_ci } 8757db96d56Sopenharmony_ci switch (node_->kind) { 8767db96d56Sopenharmony_ci case FunctionDef_kind: 8777db96d56Sopenharmony_ci CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args); 8787db96d56Sopenharmony_ci CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body); 8797db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.FunctionDef.decorator_list); 8807db96d56Sopenharmony_ci if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { 8817db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.FunctionDef.returns); 8827db96d56Sopenharmony_ci } 8837db96d56Sopenharmony_ci break; 8847db96d56Sopenharmony_ci case AsyncFunctionDef_kind: 8857db96d56Sopenharmony_ci CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args); 8867db96d56Sopenharmony_ci CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body); 8877db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.AsyncFunctionDef.decorator_list); 8887db96d56Sopenharmony_ci if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { 8897db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.AsyncFunctionDef.returns); 8907db96d56Sopenharmony_ci } 8917db96d56Sopenharmony_ci break; 8927db96d56Sopenharmony_ci case ClassDef_kind: 8937db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.bases); 8947db96d56Sopenharmony_ci CALL_SEQ(astfold_keyword, keyword, node_->v.ClassDef.keywords); 8957db96d56Sopenharmony_ci CALL(astfold_body, asdl_seq, node_->v.ClassDef.body); 8967db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.decorator_list); 8977db96d56Sopenharmony_ci break; 8987db96d56Sopenharmony_ci case Return_kind: 8997db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.Return.value); 9007db96d56Sopenharmony_ci break; 9017db96d56Sopenharmony_ci case Delete_kind: 9027db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.Delete.targets); 9037db96d56Sopenharmony_ci break; 9047db96d56Sopenharmony_ci case Assign_kind: 9057db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.Assign.targets); 9067db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Assign.value); 9077db96d56Sopenharmony_ci break; 9087db96d56Sopenharmony_ci case AugAssign_kind: 9097db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.AugAssign.target); 9107db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.AugAssign.value); 9117db96d56Sopenharmony_ci break; 9127db96d56Sopenharmony_ci case AnnAssign_kind: 9137db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.AnnAssign.target); 9147db96d56Sopenharmony_ci if (!(state->ff_features & CO_FUTURE_ANNOTATIONS)) { 9157db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.AnnAssign.annotation); 9167db96d56Sopenharmony_ci } 9177db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.AnnAssign.value); 9187db96d56Sopenharmony_ci break; 9197db96d56Sopenharmony_ci case For_kind: 9207db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.For.target); 9217db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.For.iter); 9227db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.For.body); 9237db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.For.orelse); 9247db96d56Sopenharmony_ci 9257db96d56Sopenharmony_ci CALL(fold_iter, expr_ty, node_->v.For.iter); 9267db96d56Sopenharmony_ci break; 9277db96d56Sopenharmony_ci case AsyncFor_kind: 9287db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.AsyncFor.target); 9297db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.AsyncFor.iter); 9307db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncFor.body); 9317db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncFor.orelse); 9327db96d56Sopenharmony_ci break; 9337db96d56Sopenharmony_ci case While_kind: 9347db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.While.test); 9357db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.While.body); 9367db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.While.orelse); 9377db96d56Sopenharmony_ci break; 9387db96d56Sopenharmony_ci case If_kind: 9397db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.If.test); 9407db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.If.body); 9417db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.If.orelse); 9427db96d56Sopenharmony_ci break; 9437db96d56Sopenharmony_ci case With_kind: 9447db96d56Sopenharmony_ci CALL_SEQ(astfold_withitem, withitem, node_->v.With.items); 9457db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.With.body); 9467db96d56Sopenharmony_ci break; 9477db96d56Sopenharmony_ci case AsyncWith_kind: 9487db96d56Sopenharmony_ci CALL_SEQ(astfold_withitem, withitem, node_->v.AsyncWith.items); 9497db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncWith.body); 9507db96d56Sopenharmony_ci break; 9517db96d56Sopenharmony_ci case Raise_kind: 9527db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.exc); 9537db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.cause); 9547db96d56Sopenharmony_ci break; 9557db96d56Sopenharmony_ci case Try_kind: 9567db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.Try.body); 9577db96d56Sopenharmony_ci CALL_SEQ(astfold_excepthandler, excepthandler, node_->v.Try.handlers); 9587db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.Try.orelse); 9597db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.Try.finalbody); 9607db96d56Sopenharmony_ci break; 9617db96d56Sopenharmony_ci case TryStar_kind: 9627db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.TryStar.body); 9637db96d56Sopenharmony_ci CALL_SEQ(astfold_excepthandler, excepthandler, node_->v.TryStar.handlers); 9647db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.TryStar.orelse); 9657db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.TryStar.finalbody); 9667db96d56Sopenharmony_ci break; 9677db96d56Sopenharmony_ci case Assert_kind: 9687db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Assert.test); 9697db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.Assert.msg); 9707db96d56Sopenharmony_ci break; 9717db96d56Sopenharmony_ci case Expr_kind: 9727db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Expr.value); 9737db96d56Sopenharmony_ci break; 9747db96d56Sopenharmony_ci case Match_kind: 9757db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.Match.subject); 9767db96d56Sopenharmony_ci CALL_SEQ(astfold_match_case, match_case, node_->v.Match.cases); 9777db96d56Sopenharmony_ci break; 9787db96d56Sopenharmony_ci // The following statements don't contain any subexpressions to be folded 9797db96d56Sopenharmony_ci case Import_kind: 9807db96d56Sopenharmony_ci case ImportFrom_kind: 9817db96d56Sopenharmony_ci case Global_kind: 9827db96d56Sopenharmony_ci case Nonlocal_kind: 9837db96d56Sopenharmony_ci case Pass_kind: 9847db96d56Sopenharmony_ci case Break_kind: 9857db96d56Sopenharmony_ci case Continue_kind: 9867db96d56Sopenharmony_ci break; 9877db96d56Sopenharmony_ci // No default case, so the compiler will emit a warning if new statement 9887db96d56Sopenharmony_ci // kinds are added without being handled here 9897db96d56Sopenharmony_ci } 9907db96d56Sopenharmony_ci state->recursion_depth--; 9917db96d56Sopenharmony_ci return 1; 9927db96d56Sopenharmony_ci} 9937db96d56Sopenharmony_ci 9947db96d56Sopenharmony_cistatic int 9957db96d56Sopenharmony_ciastfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) 9967db96d56Sopenharmony_ci{ 9977db96d56Sopenharmony_ci switch (node_->kind) { 9987db96d56Sopenharmony_ci case ExceptHandler_kind: 9997db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->v.ExceptHandler.type); 10007db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->v.ExceptHandler.body); 10017db96d56Sopenharmony_ci break; 10027db96d56Sopenharmony_ci // No default case, so the compiler will emit a warning if new handler 10037db96d56Sopenharmony_ci // kinds are added without being handled here 10047db96d56Sopenharmony_ci } 10057db96d56Sopenharmony_ci return 1; 10067db96d56Sopenharmony_ci} 10077db96d56Sopenharmony_ci 10087db96d56Sopenharmony_cistatic int 10097db96d56Sopenharmony_ciastfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) 10107db96d56Sopenharmony_ci{ 10117db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->context_expr); 10127db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->optional_vars); 10137db96d56Sopenharmony_ci return 1; 10147db96d56Sopenharmony_ci} 10157db96d56Sopenharmony_ci 10167db96d56Sopenharmony_cistatic int 10177db96d56Sopenharmony_ciastfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) 10187db96d56Sopenharmony_ci{ 10197db96d56Sopenharmony_ci // Currently, this is really only used to form complex/negative numeric 10207db96d56Sopenharmony_ci // constants in MatchValue and MatchMapping nodes 10217db96d56Sopenharmony_ci // We still recurse into all subexpressions and subpatterns anyway 10227db96d56Sopenharmony_ci if (++state->recursion_depth > state->recursion_limit) { 10237db96d56Sopenharmony_ci PyErr_SetString(PyExc_RecursionError, 10247db96d56Sopenharmony_ci "maximum recursion depth exceeded during compilation"); 10257db96d56Sopenharmony_ci return 0; 10267db96d56Sopenharmony_ci } 10277db96d56Sopenharmony_ci switch (node_->kind) { 10287db96d56Sopenharmony_ci case MatchValue_kind: 10297db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.MatchValue.value); 10307db96d56Sopenharmony_ci break; 10317db96d56Sopenharmony_ci case MatchSingleton_kind: 10327db96d56Sopenharmony_ci break; 10337db96d56Sopenharmony_ci case MatchSequence_kind: 10347db96d56Sopenharmony_ci CALL_SEQ(astfold_pattern, pattern, node_->v.MatchSequence.patterns); 10357db96d56Sopenharmony_ci break; 10367db96d56Sopenharmony_ci case MatchMapping_kind: 10377db96d56Sopenharmony_ci CALL_SEQ(astfold_expr, expr, node_->v.MatchMapping.keys); 10387db96d56Sopenharmony_ci CALL_SEQ(astfold_pattern, pattern, node_->v.MatchMapping.patterns); 10397db96d56Sopenharmony_ci break; 10407db96d56Sopenharmony_ci case MatchClass_kind: 10417db96d56Sopenharmony_ci CALL(astfold_expr, expr_ty, node_->v.MatchClass.cls); 10427db96d56Sopenharmony_ci CALL_SEQ(astfold_pattern, pattern, node_->v.MatchClass.patterns); 10437db96d56Sopenharmony_ci CALL_SEQ(astfold_pattern, pattern, node_->v.MatchClass.kwd_patterns); 10447db96d56Sopenharmony_ci break; 10457db96d56Sopenharmony_ci case MatchStar_kind: 10467db96d56Sopenharmony_ci break; 10477db96d56Sopenharmony_ci case MatchAs_kind: 10487db96d56Sopenharmony_ci if (node_->v.MatchAs.pattern) { 10497db96d56Sopenharmony_ci CALL(astfold_pattern, pattern_ty, node_->v.MatchAs.pattern); 10507db96d56Sopenharmony_ci } 10517db96d56Sopenharmony_ci break; 10527db96d56Sopenharmony_ci case MatchOr_kind: 10537db96d56Sopenharmony_ci CALL_SEQ(astfold_pattern, pattern, node_->v.MatchOr.patterns); 10547db96d56Sopenharmony_ci break; 10557db96d56Sopenharmony_ci // No default case, so the compiler will emit a warning if new pattern 10567db96d56Sopenharmony_ci // kinds are added without being handled here 10577db96d56Sopenharmony_ci } 10587db96d56Sopenharmony_ci state->recursion_depth--; 10597db96d56Sopenharmony_ci return 1; 10607db96d56Sopenharmony_ci} 10617db96d56Sopenharmony_ci 10627db96d56Sopenharmony_cistatic int 10637db96d56Sopenharmony_ciastfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) 10647db96d56Sopenharmony_ci{ 10657db96d56Sopenharmony_ci CALL(astfold_pattern, expr_ty, node_->pattern); 10667db96d56Sopenharmony_ci CALL_OPT(astfold_expr, expr_ty, node_->guard); 10677db96d56Sopenharmony_ci CALL_SEQ(astfold_stmt, stmt, node_->body); 10687db96d56Sopenharmony_ci return 1; 10697db96d56Sopenharmony_ci} 10707db96d56Sopenharmony_ci 10717db96d56Sopenharmony_ci#undef CALL 10727db96d56Sopenharmony_ci#undef CALL_OPT 10737db96d56Sopenharmony_ci#undef CALL_SEQ 10747db96d56Sopenharmony_ci 10757db96d56Sopenharmony_ci/* See comments in symtable.c. */ 10767db96d56Sopenharmony_ci#define COMPILER_STACK_FRAME_SCALE 3 10777db96d56Sopenharmony_ci 10787db96d56Sopenharmony_ciint 10797db96d56Sopenharmony_ci_PyAST_Optimize(mod_ty mod, PyArena *arena, _PyASTOptimizeState *state) 10807db96d56Sopenharmony_ci{ 10817db96d56Sopenharmony_ci PyThreadState *tstate; 10827db96d56Sopenharmony_ci int recursion_limit = Py_GetRecursionLimit(); 10837db96d56Sopenharmony_ci int starting_recursion_depth; 10847db96d56Sopenharmony_ci 10857db96d56Sopenharmony_ci /* Setup recursion depth check counters */ 10867db96d56Sopenharmony_ci tstate = _PyThreadState_GET(); 10877db96d56Sopenharmony_ci if (!tstate) { 10887db96d56Sopenharmony_ci return 0; 10897db96d56Sopenharmony_ci } 10907db96d56Sopenharmony_ci /* Be careful here to prevent overflow. */ 10917db96d56Sopenharmony_ci int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining; 10927db96d56Sopenharmony_ci starting_recursion_depth = (recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? 10937db96d56Sopenharmony_ci recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth; 10947db96d56Sopenharmony_ci state->recursion_depth = starting_recursion_depth; 10957db96d56Sopenharmony_ci state->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? 10967db96d56Sopenharmony_ci recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; 10977db96d56Sopenharmony_ci 10987db96d56Sopenharmony_ci int ret = astfold_mod(mod, arena, state); 10997db96d56Sopenharmony_ci assert(ret || PyErr_Occurred()); 11007db96d56Sopenharmony_ci 11017db96d56Sopenharmony_ci /* Check that the recursion depth counting balanced correctly */ 11027db96d56Sopenharmony_ci if (ret && state->recursion_depth != starting_recursion_depth) { 11037db96d56Sopenharmony_ci PyErr_Format(PyExc_SystemError, 11047db96d56Sopenharmony_ci "AST optimizer recursion depth mismatch (before=%d, after=%d)", 11057db96d56Sopenharmony_ci starting_recursion_depth, state->recursion_depth); 11067db96d56Sopenharmony_ci return 0; 11077db96d56Sopenharmony_ci } 11087db96d56Sopenharmony_ci 11097db96d56Sopenharmony_ci return ret; 11107db96d56Sopenharmony_ci} 1111