LCOV - code coverage report
Current view: | top level - Objects - frameobject.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 112 | 688 | 16.3 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 14 | 53 | 26.4 %
|  |  | Branches: | 51 | 395 | 12.9 %

               Branch data     Line data    Source code
           1                 :            : /* Frame object implementation */
           2                 :            :
           3                 :            : #include "Python.h"
           4                 :            : #include "pycore_ceval.h"         // _PyEval_BuiltinsFromGlobals()
           5                 :            : #include "pycore_code.h"          // CO_FAST_LOCAL, etc.
           6                 :            : #include "pycore_function.h"      // _PyFunction_FromConstructor()
           7                 :            : #include "pycore_moduleobject.h"  // _PyModule_GetDict()
           8                 :            : #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
           9                 :            : #include "pycore_opcode.h"        // _PyOpcode_Caches
          10                 :            :
          11                 :            : #include "frameobject.h"          // PyFrameObject
          12                 :            : #include "pycore_frame.h"
          13                 :            : #include "opcode.h"               // EXTENDED_ARG
          14                 :            : #include "structmember.h"         // PyMemberDef
          15                 :            :
          16                 :            : #define OFF(x) offsetof(PyFrameObject, x)
          17                 :            :
          18                 :            : static PyMemberDef frame_memberlist[] = {
          19                 :            :     {"f_trace_lines",   T_BOOL,         OFF(f_trace_lines), 0},
          20                 :            :     {"f_trace_opcodes", T_BOOL,         OFF(f_trace_opcodes), 0},
          21                 :            :     {NULL}      /* Sentinel */
          22                 :            : };
          23                 :            :
          24                 :            :
          25                 :            : static PyObject *
          26                 :          0 : frame_getlocals(PyFrameObject *f, void *closure)
          27                 :            : {
          28         [ #  # ]:          0 :     if (PyFrame_FastToLocalsWithError(f) < 0)
          29                 :          0 :         return NULL;
          30                 :          0 :     PyObject *locals = f->f_frame->f_locals;
          31                 :          0 :     return Py_NewRef(locals);
          32                 :            : }
          33                 :            :
          34                 :            : int
          35                 :     105273 : PyFrame_GetLineNumber(PyFrameObject *f)
          36                 :            : {
          37                 :            :     assert(f != NULL);
          38         [ -  + ]:     105273 :     if (f->f_lineno != 0) {
          39                 :          0 :         return f->f_lineno;
          40                 :            :     }
          41                 :            :     else {
          42                 :     105273 :         return _PyInterpreterFrame_GetLine(f->f_frame);
          43                 :            :     }
          44                 :            : }
          45                 :            :
          46                 :            : static PyObject *
          47                 :          0 : frame_getlineno(PyFrameObject *f, void *closure)
          48                 :            : {
          49                 :          0 :     int lineno = PyFrame_GetLineNumber(f);
          50         [ #  # ]:          0 :     if (lineno < 0) {
          51                 :          0 :         Py_RETURN_NONE;
          52                 :            :     }
          53                 :            :     else {
          54                 :          0 :         return PyLong_FromLong(lineno);
          55                 :            :     }
          56                 :            : }
          57                 :            :
          58                 :            : static PyObject *
          59                 :          0 : frame_getlasti(PyFrameObject *f, void *closure)
          60                 :            : {
          61                 :          0 :     int lasti = _PyInterpreterFrame_LASTI(f->f_frame);
          62         [ #  # ]:          0 :     if (lasti < 0) {
          63                 :          0 :         return PyLong_FromLong(-1);
          64                 :            :     }
          65                 :          0 :     return PyLong_FromLong(lasti * sizeof(_Py_CODEUNIT));
          66                 :            : }
          67                 :            :
          68                 :            : static PyObject *
          69                 :         18 : frame_getglobals(PyFrameObject *f, void *closure)
          70                 :            : {
          71                 :         18 :     PyObject *globals = f->f_frame->f_globals;
          72         [ -  + ]:         18 :     if (globals == NULL) {
          73                 :          0 :         globals = Py_None;
          74                 :            :     }
          75                 :         18 :     return Py_NewRef(globals);
          76                 :            : }
          77                 :            :
          78                 :            : static PyObject *
          79                 :          0 : frame_getbuiltins(PyFrameObject *f, void *closure)
          80                 :            : {
          81                 :          0 :     PyObject *builtins = f->f_frame->f_builtins;
          82         [ #  # ]:          0 :     if (builtins == NULL) {
          83                 :          0 :         builtins = Py_None;
          84                 :            :     }
          85                 :          0 :     return Py_NewRef(builtins);
          86                 :            : }
          87                 :            :
          88                 :            : static PyObject *
          89                 :         36 : frame_getcode(PyFrameObject *f, void *closure)
          90                 :            : {
          91         [ -  + ]:         36 :     if (PySys_Audit("object.__getattr__", "Os", f, "f_code") < 0) {
          92                 :          0 :         return NULL;
          93                 :            :     }
          94                 :         36 :     return (PyObject *)PyFrame_GetCode(f);
          95                 :            : }
          96                 :            :
          97                 :            : static PyObject *
          98                 :          0 : frame_getback(PyFrameObject *f, void *closure)
          99                 :            : {
         100                 :          0 :     PyObject *res = (PyObject *)PyFrame_GetBack(f);
         101         [ #  # ]:          0 :     if (res == NULL) {
         102                 :          0 :         Py_RETURN_NONE;
         103                 :            :     }
         104                 :          0 :     return res;
         105                 :            : }
         106                 :            :
         107                 :            : // Given the index of the effective opcode, scan back to construct the oparg
         108                 :            : // with EXTENDED_ARG. This only works correctly with *unquickened* code,
         109                 :            : // obtained via a call to _PyCode_GetCode!
         110                 :            : static unsigned int
         111                 :          0 : get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i)
         112                 :            : {
         113                 :            :     _Py_CODEUNIT word;
         114                 :          0 :     unsigned int oparg = codestr[i].op.arg;
         115   [ #  #  #  # ]:          0 :     if (i >= 1 && (word = codestr[i-1]).op.code == EXTENDED_ARG) {
         116                 :          0 :         oparg |= word.op.arg << 8;
         117   [ #  #  #  # ]:          0 :         if (i >= 2 && (word = codestr[i-2]).op.code == EXTENDED_ARG) {
         118                 :          0 :             oparg |= word.op.arg << 16;
         119   [ #  #  #  # ]:          0 :             if (i >= 3 && (word = codestr[i-3]).op.code == EXTENDED_ARG) {
         120                 :          0 :                 oparg |= word.op.arg << 24;
         121                 :            :             }
         122                 :            :         }
         123                 :            :     }
         124                 :          0 :     return oparg;
         125                 :            : }
         126                 :            :
         127                 :            : /* Model the evaluation stack, to determine which jumps
         128                 :            :  * are safe and how many values needs to be popped.
         129                 :            :  * The stack is modelled by a 64 integer, treating any
         130                 :            :  * stack that can't fit into 64 bits as "overflowed".
         131                 :            :  */
         132                 :            :
         133                 :            : typedef enum kind {
         134                 :            :     Iterator = 1,
         135                 :            :     Except = 2,
         136                 :            :     Object = 3,
         137                 :            :     Null = 4,
         138                 :            :     Lasti = 5,
         139                 :            : } Kind;
         140                 :            :
         141                 :            : static int
         142                 :          0 : compatible_kind(Kind from, Kind to) {
         143         [ #  # ]:          0 :     if (to == 0) {
         144                 :          0 :         return 0;
         145                 :            :     }
         146         [ #  # ]:          0 :     if (to == Object) {
         147                 :          0 :         return from != Null;
         148                 :            :     }
         149         [ #  # ]:          0 :     if (to == Null) {
         150                 :          0 :         return 1;
         151                 :            :     }
         152                 :          0 :     return from == to;
         153                 :            : }
         154                 :            :
         155                 :            : #define BITS_PER_BLOCK 3
         156                 :            :
         157                 :            : #define UNINITIALIZED -2
         158                 :            : #define OVERFLOWED -1
         159                 :            :
         160                 :            : #define MAX_STACK_ENTRIES (63/BITS_PER_BLOCK)
         161                 :            : #define WILL_OVERFLOW (1ULL<<((MAX_STACK_ENTRIES-1)*BITS_PER_BLOCK))
         162                 :            :
         163                 :            : #define EMPTY_STACK 0
         164                 :            :
         165                 :            : static inline int64_t
         166                 :          0 : push_value(int64_t stack, Kind kind)
         167                 :            : {
         168         [ #  # ]:          0 :     if (((uint64_t)stack) >= WILL_OVERFLOW) {
         169                 :          0 :         return OVERFLOWED;
         170                 :            :     }
         171                 :            :     else {
         172                 :          0 :         return (stack << BITS_PER_BLOCK) | kind;
         173                 :            :     }
         174                 :            : }
         175                 :            :
         176                 :            : static inline int64_t
         177                 :          0 : pop_value(int64_t stack)
         178                 :            : {
         179                 :          0 :     return Py_ARITHMETIC_RIGHT_SHIFT(int64_t, stack, BITS_PER_BLOCK);
         180                 :            : }
         181                 :            :
         182                 :            : #define MASK ((1<<BITS_PER_BLOCK)-1)
         183                 :            :
         184                 :            : static inline Kind
         185                 :          0 : top_of_stack(int64_t stack)
         186                 :            : {
         187                 :          0 :     return stack & MASK;
         188                 :            : }
         189                 :            :
         190                 :            : static inline Kind
         191                 :          0 : peek(int64_t stack, int n)
         192                 :            : {
         193                 :            :     assert(n >= 1);
         194                 :          0 :     return (stack>>(BITS_PER_BLOCK*(n-1))) & MASK;
         195                 :            : }
         196                 :            :
         197                 :            : static Kind
         198                 :          0 : stack_swap(int64_t stack, int n)
         199                 :            : {
         200                 :            :     assert(n >= 1);
         201                 :          0 :     Kind to_swap = peek(stack, n);
         202                 :          0 :     Kind top = top_of_stack(stack);
         203                 :          0 :     int shift = BITS_PER_BLOCK*(n-1);
         204                 :          0 :     int64_t replaced_low = (stack & ~(MASK << shift)) | (top << shift);
         205                 :          0 :     int64_t replaced_top = (replaced_low & ~MASK) | to_swap;
         206                 :          0 :     return replaced_top;
         207                 :            : }
         208                 :            :
         209                 :            : static int64_t
         210                 :          0 : pop_to_level(int64_t stack, int level) {
         211         [ #  # ]:          0 :     if (level == 0) {
         212                 :          0 :         return EMPTY_STACK;
         213                 :            :     }
         214                 :          0 :     int64_t max_item = (1<<BITS_PER_BLOCK) - 1;
         215                 :          0 :     int64_t level_max_stack = max_item << ((level-1) * BITS_PER_BLOCK);
         216         [ #  # ]:          0 :     while (stack > level_max_stack) {
         217                 :          0 :         stack = pop_value(stack);
         218                 :            :     }
         219                 :          0 :     return stack;
         220                 :            : }
         221                 :            :
         222                 :            : #if 0
         223                 :            : /* These functions are useful for debugging the stack marking code */
         224                 :            :
         225                 :            : static char
         226                 :            : tos_char(int64_t stack) {
         227                 :            :     switch(top_of_stack(stack)) {
         228                 :            :         case Iterator:
         229                 :            :             return 'I';
         230                 :            :         case Except:
         231                 :            :             return 'E';
         232                 :            :         case Object:
         233                 :            :             return 'O';
         234                 :            :         case Lasti:
         235                 :            :             return 'L';
         236                 :            :         case Null:
         237                 :            :             return 'N';
         238                 :            :     }
         239                 :            :     return '?';
         240                 :            : }
         241                 :            :
         242                 :            : static void
         243                 :            : print_stack(int64_t stack) {
         244                 :            :     if (stack < 0) {
         245                 :            :         if (stack == UNINITIALIZED) {
         246                 :            :             printf("---");
         247                 :            :         }
         248                 :            :         else if (stack == OVERFLOWED) {
         249                 :            :             printf("OVERFLOWED");
         250                 :            :         }
         251                 :            :         else {
         252                 :            :             printf("??");
         253                 :            :         }
         254                 :            :         return;
         255                 :            :     }
         256                 :            :     while (stack) {
         257                 :            :         printf("%c", tos_char(stack));
         258                 :            :         stack = pop_value(stack);
         259                 :            :     }
         260                 :            : }
         261                 :            :
         262                 :            : static void
         263                 :            : print_stacks(int64_t *stacks, int n) {
         264                 :            :     for (int i = 0; i < n; i++) {
         265                 :            :         printf("%d: ", i);
         266                 :            :         print_stack(stacks[i]);
         267                 :            :         printf("\n");
         268                 :            :     }
         269                 :            : }
         270                 :            :
         271                 :            : #endif
         272                 :            :
         273                 :            : static int64_t *
         274                 :          0 : mark_stacks(PyCodeObject *code_obj, int len)
         275                 :            : {
         276                 :          0 :     PyObject *co_code = _PyCode_GetCode(code_obj);
         277         [ #  # ]:          0 :     if (co_code == NULL) {
         278                 :          0 :         return NULL;
         279                 :            :     }
         280                 :          0 :     _Py_CODEUNIT *code = (_Py_CODEUNIT *)PyBytes_AS_STRING(co_code);
         281         [ #  # ]:          0 :     int64_t *stacks = PyMem_New(int64_t, len+1);
         282                 :            :     int i, j, opcode;
         283                 :            :
         284         [ #  # ]:          0 :     if (stacks == NULL) {
         285                 :          0 :         PyErr_NoMemory();
         286                 :          0 :         Py_DECREF(co_code);
         287                 :          0 :         return NULL;
         288                 :            :     }
         289         [ #  # ]:          0 :     for (int i = 1; i <= len; i++) {
         290                 :          0 :         stacks[i] = UNINITIALIZED;
         291                 :            :     }
         292                 :          0 :     stacks[0] = EMPTY_STACK;
         293         [ #  # ]:          0 :     if (code_obj->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR))
         294                 :            :     {
         295                 :            :         // Generators get sent None while starting:
         296                 :          0 :         stacks[0] = push_value(stacks[0], Object);
         297                 :            :     }
         298                 :          0 :     int todo = 1;
         299         [ #  # ]:          0 :     while (todo) {
         300                 :          0 :         todo = 0;
         301                 :            :         /* Scan instructions */
         302         [ #  # ]:          0 :         for (i = 0; i < len; i++) {
         303                 :          0 :             int64_t next_stack = stacks[i];
         304         [ #  # ]:          0 :             if (next_stack == UNINITIALIZED) {
         305                 :          0 :                 continue;
         306                 :            :             }
         307                 :          0 :             opcode = code[i].op.code;
         308   [ #  #  #  #  :          0 :             switch (opcode) {
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
                       #  # ]
         309                 :          0 :                 case JUMP_IF_FALSE_OR_POP:
         310                 :            :                 case JUMP_IF_TRUE_OR_POP:
         311                 :            :                 case POP_JUMP_IF_FALSE:
         312                 :            :                 case POP_JUMP_IF_TRUE:
         313                 :            :                 {
         314                 :            :                     int64_t target_stack;
         315                 :          0 :                     int j = get_arg(code, i);
         316                 :          0 :                     j += i + 1;
         317                 :            :                     assert(j < len);
         318   [ #  #  #  # ]:          0 :                     if (stacks[j] == UNINITIALIZED && j < i) {
         319                 :          0 :                         todo = 1;
         320                 :            :                     }
         321   [ #  #  #  # ]:          0 :                     if (opcode == JUMP_IF_FALSE_OR_POP ||
         322                 :            :                         opcode == JUMP_IF_TRUE_OR_POP)
         323                 :            :                     {
         324                 :          0 :                         target_stack = next_stack;
         325                 :          0 :                         next_stack = pop_value(next_stack);
         326                 :            :                     }
         327                 :            :                     else {
         328                 :          0 :                         next_stack = pop_value(next_stack);
         329                 :          0 :                         target_stack = next_stack;
         330                 :            :                     }
         331                 :            :                     assert(stacks[j] == UNINITIALIZED || stacks[j] == target_stack);
         332                 :          0 :                     stacks[j] = target_stack;
         333                 :          0 :                     stacks[i+1] = next_stack;
         334                 :          0 :                     break;
         335                 :            :                 }
         336                 :          0 :                 case SEND:
         337                 :          0 :                     j = get_arg(code, i) + i + INLINE_CACHE_ENTRIES_SEND + 1;
         338                 :            :                     assert(j < len);
         339                 :            :                     assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack);
         340                 :          0 :                     stacks[j] = next_stack;
         341                 :          0 :                     stacks[i+1] = next_stack;
         342                 :          0 :                     break;
         343                 :          0 :                 case JUMP_FORWARD:
         344                 :          0 :                     j = get_arg(code, i) + i + 1;
         345                 :            :                     assert(j < len);
         346                 :            :                     assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack);
         347                 :          0 :                     stacks[j] = next_stack;
         348                 :          0 :                     break;
         349                 :          0 :                 case JUMP_BACKWARD:
         350                 :            :                 case JUMP_BACKWARD_NO_INTERRUPT:
         351                 :          0 :                     j = i + 1 - get_arg(code, i);
         352                 :            :                     assert(j >= 0);
         353                 :            :                     assert(j < len);
         354   [ #  #  #  # ]:          0 :                     if (stacks[j] == UNINITIALIZED && j < i) {
         355                 :          0 :                         todo = 1;
         356                 :            :                     }
         357                 :            :                     assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack);
         358                 :          0 :                     stacks[j] = next_stack;
         359                 :          0 :                     break;
         360                 :          0 :                 case COMPARE_AND_BRANCH:
         361                 :          0 :                     next_stack = pop_value(pop_value(next_stack));
         362                 :          0 :                     i++;
         363                 :          0 :                     j = get_arg(code, i) + i + 1;
         364                 :            :                     assert(j < len);
         365                 :            :                     assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack);
         366                 :          0 :                     stacks[j] = next_stack;
         367                 :          0 :                     break;
         368                 :          0 :                 case GET_ITER:
         369                 :            :                 case GET_AITER:
         370                 :          0 :                     next_stack = push_value(pop_value(next_stack), Iterator);
         371                 :          0 :                     stacks[i+1] = next_stack;
         372                 :          0 :                     break;
         373                 :          0 :                 case FOR_ITER:
         374                 :            :                 {
         375                 :          0 :                     int64_t target_stack = push_value(next_stack, Object);
         376                 :          0 :                     stacks[i+1] = target_stack;
         377                 :          0 :                     j = get_arg(code, i) + 1 + INLINE_CACHE_ENTRIES_FOR_ITER + i;
         378                 :            :                     assert(j < len);
         379                 :            :                     assert(stacks[j] == UNINITIALIZED || stacks[j] == target_stack);
         380                 :          0 :                     stacks[j] = target_stack;
         381                 :          0 :                     break;
         382                 :            :                 }
         383                 :          0 :                 case END_ASYNC_FOR:
         384                 :          0 :                     next_stack = pop_value(pop_value(next_stack));
         385                 :          0 :                     stacks[i+1] = next_stack;
         386                 :          0 :                     break;
         387                 :          0 :                 case PUSH_EXC_INFO:
         388                 :          0 :                     next_stack = push_value(next_stack, Except);
         389                 :          0 :                     stacks[i+1] = next_stack;
         390                 :          0 :                     break;
         391                 :          0 :                 case POP_EXCEPT:
         392                 :            :                     assert(top_of_stack(next_stack) == Except);
         393                 :          0 :                     next_stack = pop_value(next_stack);
         394                 :          0 :                     stacks[i+1] = next_stack;
         395                 :          0 :                     break;
         396                 :          0 :                 case RETURN_VALUE:
         397                 :            :                     assert(pop_value(next_stack) == EMPTY_STACK);
         398                 :            :                     assert(top_of_stack(next_stack) == Object);
         399                 :          0 :                     break;
         400                 :          0 :                 case RETURN_CONST:
         401                 :          0 :                     break;
         402                 :          0 :                 case RAISE_VARARGS:
         403                 :          0 :                     break;
         404                 :          0 :                 case RERAISE:
         405                 :            :                     assert(top_of_stack(next_stack) == Except);
         406                 :            :                     /* End of block */
         407                 :          0 :                     break;
         408                 :          0 :                 case PUSH_NULL:
         409                 :          0 :                     next_stack = push_value(next_stack, Null);
         410                 :          0 :                     stacks[i+1] = next_stack;
         411                 :          0 :                     break;
         412                 :          0 :                 case LOAD_GLOBAL:
         413                 :            :                 {
         414                 :          0 :                     int j = get_arg(code, i);
         415         [ #  # ]:          0 :                     if (j & 1) {
         416                 :          0 :                         next_stack = push_value(next_stack, Null);
         417                 :            :                     }
         418                 :          0 :                     next_stack = push_value(next_stack, Object);
         419                 :          0 :                     stacks[i+1] = next_stack;
         420                 :          0 :                     break;
         421                 :            :                 }
         422                 :          0 :                 case LOAD_ATTR:
         423                 :            :                 {
         424                 :            :                     assert(top_of_stack(next_stack) == Object);
         425                 :          0 :                     int j = get_arg(code, i);
         426         [ #  # ]:          0 :                     if (j & 1) {
         427                 :          0 :                         next_stack = pop_value(next_stack);
         428                 :          0 :                         next_stack = push_value(next_stack, Null);
         429                 :          0 :                         next_stack = push_value(next_stack, Object);
         430                 :            :                     }
         431                 :          0 :                     stacks[i+1] = next_stack;
         432                 :          0 :                     break;
         433                 :            :                 }
         434                 :          0 :                 case CALL:
         435                 :            :                 {
         436                 :          0 :                     int args = get_arg(code, i);
         437         [ #  # ]:          0 :                     for (int j = 0; j < args+2; j++) {
         438                 :          0 :                         next_stack = pop_value(next_stack);
         439                 :            :                     }
         440                 :          0 :                     next_stack = push_value(next_stack, Object);
         441                 :          0 :                     stacks[i+1] = next_stack;
         442                 :          0 :                     break;
         443                 :            :                 }
         444                 :          0 :                 case SWAP:
         445                 :            :                 {
         446                 :          0 :                     int n = get_arg(code, i);
         447                 :          0 :                     next_stack = stack_swap(next_stack, n);
         448                 :          0 :                     stacks[i+1] = next_stack;
         449                 :          0 :                     break;
         450                 :            :                 }
         451                 :          0 :                 case COPY:
         452                 :            :                 {
         453                 :          0 :                     int n = get_arg(code, i);
         454                 :          0 :                     next_stack = push_value(next_stack, peek(next_stack, n));
         455                 :          0 :                     stacks[i+1] = next_stack;
         456                 :          0 :                     break;
         457                 :            :                 }
         458                 :          0 :                 default:
         459                 :            :                 {
         460                 :          0 :                     int delta = PyCompile_OpcodeStackEffect(opcode, get_arg(code, i));
         461                 :            :                     assert(delta != PY_INVALID_STACK_EFFECT);
         462         [ #  # ]:          0 :                     while (delta < 0) {
         463                 :          0 :                         next_stack = pop_value(next_stack);
         464                 :          0 :                         delta++;
         465                 :            :                     }
         466         [ #  # ]:          0 :                     while (delta > 0) {
         467                 :          0 :                         next_stack = push_value(next_stack, Object);
         468                 :          0 :                         delta--;
         469                 :            :                     }
         470                 :          0 :                     stacks[i+1] = next_stack;
         471                 :            :                 }
         472                 :            :             }
         473                 :            :         }
         474                 :            :         /* Scan exception table */
         475                 :          0 :         unsigned char *start = (unsigned char *)PyBytes_AS_STRING(code_obj->co_exceptiontable);
         476                 :          0 :         unsigned char *end = start + PyBytes_GET_SIZE(code_obj->co_exceptiontable);
         477                 :          0 :         unsigned char *scan = start;
         478         [ #  # ]:          0 :         while (scan < end) {
         479                 :            :             int start_offset, size, handler;
         480                 :          0 :             scan = parse_varint(scan, &start_offset);
         481                 :            :             assert(start_offset >= 0 && start_offset < len);
         482                 :          0 :             scan = parse_varint(scan, &size);
         483                 :            :             assert(size >= 0 && start_offset+size <= len);
         484                 :          0 :             scan = parse_varint(scan, &handler);
         485                 :            :             assert(handler >= 0 && handler < len);
         486                 :            :             int depth_and_lasti;
         487                 :          0 :             scan = parse_varint(scan, &depth_and_lasti);
         488                 :          0 :             int level = depth_and_lasti >> 1;
         489                 :          0 :             int lasti = depth_and_lasti & 1;
         490         [ #  # ]:          0 :             if (stacks[start_offset] != UNINITIALIZED) {
         491         [ #  # ]:          0 :                 if (stacks[handler] == UNINITIALIZED) {
         492                 :          0 :                     todo = 1;
         493                 :          0 :                     uint64_t target_stack = pop_to_level(stacks[start_offset], level);
         494         [ #  # ]:          0 :                     if (lasti) {
         495                 :          0 :                         target_stack = push_value(target_stack, Lasti);
         496                 :            :                     }
         497                 :          0 :                     target_stack = push_value(target_stack, Except);
         498                 :          0 :                     stacks[handler] = target_stack;
         499                 :            :                 }
         500                 :            :             }
         501                 :            :         }
         502                 :            :     }
         503                 :          0 :     Py_DECREF(co_code);
         504                 :          0 :     return stacks;
         505                 :            : }
         506                 :            :
         507                 :            : static int
         508                 :          0 : compatible_stack(int64_t from_stack, int64_t to_stack)
         509                 :            : {
         510   [ #  #  #  # ]:          0 :     if (from_stack < 0 || to_stack < 0) {
         511                 :          0 :         return 0;
         512                 :            :     }
         513         [ #  # ]:          0 :     while(from_stack > to_stack) {
         514                 :          0 :         from_stack = pop_value(from_stack);
         515                 :            :     }
         516         [ #  # ]:          0 :     while(from_stack) {
         517                 :          0 :         Kind from_top = top_of_stack(from_stack);
         518                 :          0 :         Kind to_top = top_of_stack(to_stack);
         519         [ #  # ]:          0 :         if (!compatible_kind(from_top, to_top)) {
         520                 :          0 :             return 0;
         521                 :            :         }
         522                 :          0 :         from_stack = pop_value(from_stack);
         523                 :          0 :         to_stack = pop_value(to_stack);
         524                 :            :     }
         525                 :          0 :     return to_stack == 0;
         526                 :            : }
         527                 :            :
         528                 :            : static const char *
         529                 :          0 : explain_incompatible_stack(int64_t to_stack)
         530                 :            : {
         531                 :            :     assert(to_stack != 0);
         532         [ #  # ]:          0 :     if (to_stack == OVERFLOWED) {
         533                 :          0 :         return "stack is too deep to analyze";
         534                 :            :     }
         535         [ #  # ]:          0 :     if (to_stack == UNINITIALIZED) {
         536                 :          0 :         return "can't jump into an exception handler, or code may be unreachable";
         537                 :            :     }
         538                 :          0 :     Kind target_kind = top_of_stack(to_stack);
         539   [ #  #  #  #  :          0 :     switch(target_kind) {
                          # ]
         540                 :          0 :         case Except:
         541                 :          0 :             return "can't jump into an 'except' block as there's no exception";
         542                 :          0 :         case Lasti:
         543                 :          0 :             return "can't jump into a re-raising block as there's no location";
         544                 :          0 :         case Object:
         545                 :            :         case Null:
         546                 :          0 :             return "incompatible stacks";
         547                 :          0 :         case Iterator:
         548                 :          0 :             return "can't jump into the body of a for loop";
         549                 :          0 :         default:
         550                 :          0 :             Py_UNREACHABLE();
         551                 :            :     }
         552                 :            : }
         553                 :            :
         554                 :            : static int *
         555                 :          0 : marklines(PyCodeObject *code, int len)
         556                 :            : {
         557                 :            :     PyCodeAddressRange bounds;
         558                 :          0 :     _PyCode_InitAddressRange(code, &bounds);
         559                 :            :     assert (bounds.ar_end == 0);
         560                 :          0 :     int last_line = -1;
         561                 :            :
         562         [ #  # ]:          0 :     int *linestarts = PyMem_New(int, len);
         563         [ #  # ]:          0 :     if (linestarts == NULL) {
         564                 :          0 :         return NULL;
         565                 :            :     }
         566         [ #  # ]:          0 :     for (int i = 0; i < len; i++) {
         567                 :          0 :         linestarts[i] = -1;
         568                 :            :     }
         569                 :            :
         570         [ #  # ]:          0 :     while (_PyLineTable_NextAddressRange(&bounds)) {
         571                 :            :         assert(bounds.ar_start / (int)sizeof(_Py_CODEUNIT) < len);
         572   [ #  #  #  # ]:          0 :         if (bounds.ar_line != last_line && bounds.ar_line != -1) {
         573                 :          0 :             linestarts[bounds.ar_start / sizeof(_Py_CODEUNIT)] = bounds.ar_line;
         574                 :          0 :             last_line = bounds.ar_line;
         575                 :            :         }
         576                 :            :     }
         577                 :          0 :     return linestarts;
         578                 :            : }
         579                 :            :
         580                 :            : static int
         581                 :          0 : first_line_not_before(int *lines, int len, int line)
         582                 :            : {
         583                 :          0 :     int result = INT_MAX;
         584         [ #  # ]:          0 :     for (int i = 0; i < len; i++) {
         585   [ #  #  #  # ]:          0 :         if (lines[i] < result && lines[i] >= line) {
         586                 :          0 :             result = lines[i];
         587                 :            :         }
         588                 :            :     }
         589         [ #  # ]:          0 :     if (result == INT_MAX) {
         590                 :          0 :         return -1;
         591                 :            :     }
         592                 :          0 :     return result;
         593                 :            : }
         594                 :            :
         595                 :            : static PyFrameState
         596                 :          0 : _PyFrame_GetState(PyFrameObject *frame)
         597                 :            : {
         598                 :            :     assert(!_PyFrame_IsIncomplete(frame->f_frame));
         599         [ #  # ]:          0 :     if (frame->f_frame->stacktop == 0) {
         600                 :          0 :         return FRAME_CLEARED;
         601                 :            :     }
         602   [ #  #  #  # ]:          0 :     switch(frame->f_frame->owner) {
         603                 :          0 :         case FRAME_OWNED_BY_GENERATOR:
         604                 :            :         {
         605                 :          0 :             PyGenObject *gen = _PyFrame_GetGenerator(frame->f_frame);
         606                 :          0 :             return gen->gi_frame_state;
         607                 :            :         }
         608                 :          0 :         case FRAME_OWNED_BY_THREAD:
         609                 :            :         {
         610         [ #  # ]:          0 :             if (_PyInterpreterFrame_LASTI(frame->f_frame) < 0) {
         611                 :          0 :                 return FRAME_CREATED;
         612                 :            :             }
         613         [ #  # ]:          0 :             switch (frame->f_frame->prev_instr->op.code)
         614                 :            :             {
         615                 :          0 :                 case COPY_FREE_VARS:
         616                 :            :                 case MAKE_CELL:
         617                 :            :                 case RETURN_GENERATOR:
         618                 :            :                     /* Frame not fully initialized */
         619                 :          0 :                     return FRAME_CREATED;
         620                 :          0 :                 default:
         621                 :          0 :                     return FRAME_EXECUTING;
         622                 :            :             }
         623                 :            :         }
         624                 :          0 :         case FRAME_OWNED_BY_FRAME_OBJECT:
         625                 :          0 :             return FRAME_COMPLETED;
         626                 :            :     }
         627                 :          0 :     Py_UNREACHABLE();
         628                 :            : }
         629                 :            :
         630                 :            : /* Setter for f_lineno - you can set f_lineno from within a trace function in
         631                 :            :  * order to jump to a given line of code, subject to some restrictions.  Most
         632                 :            :  * lines are OK to jump to because they don't make any assumptions about the
         633                 :            :  * state of the stack (obvious because you could remove the line and the code
         634                 :            :  * would still work without any stack errors), but there are some constructs
         635                 :            :  * that limit jumping:
         636                 :            :  *
         637                 :            :  *  o Any exception handlers.
         638                 :            :  *  o 'for' and 'async for' loops can't be jumped into because the
         639                 :            :  *    iterator needs to be on the stack.
         640                 :            :  *  o Jumps cannot be made from within a trace function invoked with a
         641                 :            :  *    'return' or 'exception' event since the eval loop has been exited at
         642                 :            :  *    that time.
         643                 :            :  */
         644                 :            : static int
         645                 :          0 : frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignored))
         646                 :            : {
         647         [ #  # ]:          0 :     if (p_new_lineno == NULL) {
         648                 :          0 :         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
         649                 :          0 :         return -1;
         650                 :            :     }
         651                 :            :     /* f_lineno must be an integer. */
         652         [ #  # ]:          0 :     if (!PyLong_CheckExact(p_new_lineno)) {
         653                 :          0 :         PyErr_SetString(PyExc_ValueError,
         654                 :            :                         "lineno must be an integer");
         655                 :          0 :         return -1;
         656                 :            :     }
         657                 :            :
         658                 :          0 :     PyFrameState state = _PyFrame_GetState(f);
         659                 :            :     /*
         660                 :            :      * This code preserves the historical restrictions on
         661                 :            :      * setting the line number of a frame.
         662                 :            :      * Jumps are forbidden on a 'return' trace event (except after a yield).
         663                 :            :      * Jumps from 'call' trace events are also forbidden.
         664                 :            :      * In addition, jumps are forbidden when not tracing,
         665                 :            :      * as this is a debugging feature.
         666                 :            :      */
         667   [ #  #  #  #  :          0 :     switch(PyThreadState_GET()->tracing_what) {
                          # ]
         668                 :          0 :         case PyTrace_EXCEPTION:
         669                 :          0 :             PyErr_SetString(PyExc_ValueError,
         670                 :            :                 "can only jump from a 'line' trace event");
         671                 :          0 :             return -1;
         672                 :          0 :         case PyTrace_CALL:
         673                 :          0 :             PyErr_Format(PyExc_ValueError,
         674                 :            :                      "can't jump from the 'call' trace event of a new frame");
         675                 :          0 :             return -1;
         676                 :          0 :         case PyTrace_LINE:
         677                 :          0 :             break;
         678                 :          0 :         case PyTrace_RETURN:
         679         [ #  # ]:          0 :             if (state == FRAME_SUSPENDED) {
         680                 :          0 :                 break;
         681                 :            :             }
         682                 :            :             /* fall through */
         683                 :            :         default:
         684                 :          0 :             PyErr_SetString(PyExc_ValueError,
         685                 :            :                 "can only jump from a 'line' trace event");
         686                 :          0 :             return -1;
         687                 :            :     }
         688         [ #  # ]:          0 :     if (!f->f_trace) {
         689                 :          0 :         PyErr_Format(PyExc_ValueError,
         690                 :            :                     "f_lineno can only be set by a trace function");
         691                 :          0 :         return -1;
         692                 :            :     }
         693                 :            :
         694                 :            :     int new_lineno;
         695                 :            :
         696                 :            :     /* Fail if the line falls outside the code block and
         697                 :            :         select first line with actual code. */
         698                 :            :     int overflow;
         699                 :          0 :     long l_new_lineno = PyLong_AsLongAndOverflow(p_new_lineno, &overflow);
         700         [ #  # ]:          0 :     if (overflow
         701                 :            : #if SIZEOF_LONG > SIZEOF_INT
         702         [ #  # ]:          0 :         || l_new_lineno > INT_MAX
         703         [ #  # ]:          0 :         || l_new_lineno < INT_MIN
         704                 :            : #endif
         705                 :            :     ) {
         706                 :          0 :         PyErr_SetString(PyExc_ValueError,
         707                 :            :                         "lineno out of range");
         708                 :          0 :         return -1;
         709                 :            :     }
         710                 :          0 :     new_lineno = (int)l_new_lineno;
         711                 :            :
         712         [ #  # ]:          0 :     if (new_lineno < f->f_frame->f_code->co_firstlineno) {
         713                 :          0 :         PyErr_Format(PyExc_ValueError,
         714                 :            :                     "line %d comes before the current code block",
         715                 :            :                     new_lineno);
         716                 :          0 :         return -1;
         717                 :            :     }
         718                 :            :
         719                 :            :     /* PyCode_NewWithPosOnlyArgs limits co_code to be under INT_MAX so this
         720                 :            :      * should never overflow. */
         721                 :          0 :     int len = (int)Py_SIZE(f->f_frame->f_code);
         722                 :          0 :     int *lines = marklines(f->f_frame->f_code, len);
         723         [ #  # ]:          0 :     if (lines == NULL) {
         724                 :          0 :         return -1;
         725                 :            :     }
         726                 :            :
         727                 :          0 :     new_lineno = first_line_not_before(lines, len, new_lineno);
         728         [ #  # ]:          0 :     if (new_lineno < 0) {
         729                 :          0 :         PyErr_Format(PyExc_ValueError,
         730                 :            :                     "line %d comes after the current code block",
         731                 :            :                     (int)l_new_lineno);
         732                 :          0 :         PyMem_Free(lines);
         733                 :          0 :         return -1;
         734                 :            :     }
         735                 :            :
         736                 :          0 :     int64_t *stacks = mark_stacks(f->f_frame->f_code, len);
         737         [ #  # ]:          0 :     if (stacks == NULL) {
         738                 :          0 :         PyMem_Free(lines);
         739                 :          0 :         return -1;
         740                 :            :     }
         741                 :            :
         742                 :          0 :     int64_t best_stack = OVERFLOWED;
         743                 :          0 :     int best_addr = -1;
         744                 :          0 :     int64_t start_stack = stacks[_PyInterpreterFrame_LASTI(f->f_frame)];
         745                 :          0 :     int err = -1;
         746                 :          0 :     const char *msg = "cannot find bytecode for specified line";
         747         [ #  # ]:          0 :     for (int i = 0; i < len; i++) {
         748         [ #  # ]:          0 :         if (lines[i] == new_lineno) {
         749                 :          0 :             int64_t target_stack = stacks[i];
         750         [ #  # ]:          0 :             if (compatible_stack(start_stack, target_stack)) {
         751                 :          0 :                 err = 0;
         752         [ #  # ]:          0 :                 if (target_stack > best_stack) {
         753                 :          0 :                     best_stack = target_stack;
         754                 :          0 :                     best_addr = i;
         755                 :            :                 }
         756                 :            :             }
         757         [ #  # ]:          0 :             else if (err < 0) {
         758         [ #  # ]:          0 :                 if (start_stack == OVERFLOWED) {
         759                 :          0 :                     msg = "stack to deep to analyze";
         760                 :            :                 }
         761         [ #  # ]:          0 :                 else if (start_stack == UNINITIALIZED) {
         762                 :          0 :                     msg = "can't jump from unreachable code";
         763                 :            :                 }
         764                 :            :                 else {
         765                 :          0 :                     msg = explain_incompatible_stack(target_stack);
         766                 :          0 :                     err = 1;
         767                 :            :                 }
         768                 :            :             }
         769                 :            :         }
         770                 :            :     }
         771                 :          0 :     PyMem_Free(stacks);
         772                 :          0 :     PyMem_Free(lines);
         773         [ #  # ]:          0 :     if (err) {
         774                 :          0 :         PyErr_SetString(PyExc_ValueError, msg);
         775                 :          0 :         return -1;
         776                 :            :     }
         777                 :            :     // Populate any NULL locals that the compiler might have "proven" to exist
         778                 :            :     // in the new location. Rather than crashing or changing co_code, just bind
         779                 :            :     // None instead:
         780                 :          0 :     int unbound = 0;
         781         [ #  # ]:          0 :     for (int i = 0; i < f->f_frame->f_code->co_nlocalsplus; i++) {
         782                 :            :         // Counting every unbound local is overly-cautious, but a full flow
         783                 :            :         // analysis (like we do in the compiler) is probably too expensive:
         784                 :          0 :         unbound += f->f_frame->localsplus[i] == NULL;
         785                 :            :     }
         786         [ #  # ]:          0 :     if (unbound) {
         787                 :          0 :         const char *e = "assigning None to %d unbound local%s";
         788         [ #  # ]:          0 :         const char *s = (unbound == 1) ? "" : "s";
         789         [ #  # ]:          0 :         if (PyErr_WarnFormat(PyExc_RuntimeWarning, 0, e, unbound, s)) {
         790                 :          0 :             return -1;
         791                 :            :         }
         792                 :            :         // Do this in a second pass to avoid writing a bunch of Nones when
         793                 :            :         // warnings are being treated as errors and the previous bit raises:
         794         [ #  # ]:          0 :         for (int i = 0; i < f->f_frame->f_code->co_nlocalsplus; i++) {
         795         [ #  # ]:          0 :             if (f->f_frame->localsplus[i] == NULL) {
         796                 :          0 :                 f->f_frame->localsplus[i] = Py_NewRef(Py_None);
         797                 :          0 :                 unbound--;
         798                 :            :             }
         799                 :            :         }
         800                 :            :         assert(unbound == 0);
         801                 :            :     }
         802         [ #  # ]:          0 :     if (state == FRAME_SUSPENDED) {
         803                 :            :         /* Account for value popped by yield */
         804                 :          0 :         start_stack = pop_value(start_stack);
         805                 :            :     }
         806         [ #  # ]:          0 :     while (start_stack > best_stack) {
         807         [ #  # ]:          0 :         if (top_of_stack(start_stack) == Except) {
         808                 :            :             /* Pop exception stack as well as the evaluation stack */
         809                 :          0 :             PyThreadState *tstate = _PyThreadState_GET();
         810                 :          0 :             _PyErr_StackItem *exc_info = tstate->exc_info;
         811                 :          0 :             PyObject *value = exc_info->exc_value;
         812                 :          0 :             PyObject *exc = _PyFrame_StackPop(f->f_frame);
         813                 :            :             assert(PyExceptionInstance_Check(exc) || exc == Py_None);
         814                 :          0 :             exc_info->exc_value = exc;
         815                 :          0 :             Py_XDECREF(value);
         816                 :            :         }
         817                 :            :         else {
         818                 :          0 :             PyObject *v = _PyFrame_StackPop(f->f_frame);
         819                 :          0 :             Py_XDECREF(v);
         820                 :            :         }
         821                 :          0 :         start_stack = pop_value(start_stack);
         822                 :            :     }
         823                 :            :     /* Finally set the new lasti and return OK. */
         824                 :          0 :     f->f_lineno = 0;
         825                 :          0 :     f->f_frame->prev_instr = _PyCode_CODE(f->f_frame->f_code) + best_addr;
         826                 :          0 :     return 0;
         827                 :            : }
         828                 :            :
         829                 :            : static PyObject *
         830                 :          0 : frame_gettrace(PyFrameObject *f, void *closure)
         831                 :            : {
         832                 :          0 :     PyObject* trace = f->f_trace;
         833         [ #  # ]:          0 :     if (trace == NULL)
         834                 :          0 :         trace = Py_None;
         835                 :          0 :     return Py_NewRef(trace);
         836                 :            : }
         837                 :            :
         838                 :            : static int
         839                 :          0 : frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
         840                 :            : {
         841         [ #  # ]:          0 :     if (v == Py_None) {
         842                 :          0 :         v = NULL;
         843                 :            :     }
         844                 :          0 :     Py_XSETREF(f->f_trace, Py_XNewRef(v));
         845                 :          0 :     return 0;
         846                 :            : }
         847                 :            :
         848                 :            :
         849                 :            : static PyGetSetDef frame_getsetlist[] = {
         850                 :            :     {"f_back",          (getter)frame_getback, NULL, NULL},
         851                 :            :     {"f_locals",        (getter)frame_getlocals, NULL, NULL},
         852                 :            :     {"f_lineno",        (getter)frame_getlineno,
         853                 :            :                     (setter)frame_setlineno, NULL},
         854                 :            :     {"f_trace",         (getter)frame_gettrace, (setter)frame_settrace, NULL},
         855                 :            :     {"f_lasti",         (getter)frame_getlasti, NULL, NULL},
         856                 :            :     {"f_globals",       (getter)frame_getglobals, NULL, NULL},
         857                 :            :     {"f_builtins",      (getter)frame_getbuiltins, NULL, NULL},
         858                 :            :     {"f_code",          (getter)frame_getcode, NULL, NULL},
         859                 :            :     {0}
         860                 :            : };
         861                 :            :
         862                 :            : static void
         863                 :     106583 : frame_dealloc(PyFrameObject *f)
         864                 :            : {
         865                 :            :     /* It is the responsibility of the owning generator/coroutine
         866                 :            :      * to have cleared the generator pointer */
         867                 :            :
         868                 :            :     assert(f->f_frame->owner != FRAME_OWNED_BY_GENERATOR ||
         869                 :            :         _PyFrame_GetGenerator(f->f_frame)->gi_frame_state == FRAME_CLEARED);
         870                 :            :
         871         [ +  + ]:     106583 :     if (_PyObject_GC_IS_TRACKED(f)) {
         872                 :       3459 :         _PyObject_GC_UNTRACK(f);
         873                 :            :     }
         874                 :            :
         875   [ +  -  -  + ]:     106583 :     Py_TRASHCAN_BEGIN(f, frame_dealloc);
         876                 :     106583 :     PyCodeObject *co = NULL;
         877                 :            :
         878                 :            :     /* Kill all local variables including specials, if we own them */
         879         [ +  + ]:     106583 :     if (f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT) {
         880                 :            :         assert(f->f_frame == (_PyInterpreterFrame *)f->_f_frame_data);
         881                 :       3459 :         _PyInterpreterFrame *frame = (_PyInterpreterFrame *)f->_f_frame_data;
         882                 :            :         /* Don't clear code object until the end */
         883                 :       3459 :         co = frame->f_code;
         884                 :       3459 :         frame->f_code = NULL;
         885         [ +  - ]:       3459 :         Py_CLEAR(frame->f_funcobj);
         886         [ +  + ]:       3459 :         Py_CLEAR(frame->f_locals);
         887                 :       3459 :         PyObject **locals = _PyFrame_GetLocalsArray(frame);
         888         [ +  + ]:      12254 :         for (int i = 0; i < frame->stacktop; i++) {
         889         [ +  + ]:       8795 :             Py_CLEAR(locals[i]);
         890                 :            :         }
         891                 :            :     }
         892         [ +  + ]:     106583 :     Py_CLEAR(f->f_back);
         893         [ -  + ]:     106583 :     Py_CLEAR(f->f_trace);
         894                 :     106583 :     PyObject_GC_Del(f);
         895                 :     106583 :     Py_XDECREF(co);
         896         [ +  - ]:     106583 :     Py_TRASHCAN_END;
         897                 :     106583 : }
         898                 :            :
         899                 :            : static int
         900                 :          0 : frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
         901                 :            : {
         902   [ #  #  #  # ]:          0 :     Py_VISIT(f->f_back);
         903   [ #  #  #  # ]:          0 :     Py_VISIT(f->f_trace);
         904         [ #  # ]:          0 :     if (f->f_frame->owner != FRAME_OWNED_BY_FRAME_OBJECT) {
         905                 :          0 :         return 0;
         906                 :            :     }
         907                 :            :     assert(f->f_frame->frame_obj == NULL);
         908                 :          0 :     return _PyFrame_Traverse(f->f_frame, visit, arg);
         909                 :            : }
         910                 :            :
         911                 :            : static int
         912                 :          6 : frame_tp_clear(PyFrameObject *f)
         913                 :            : {
         914         [ -  + ]:          6 :     Py_CLEAR(f->f_trace);
         915                 :            :
         916                 :            :     /* locals and stack */
         917                 :          6 :     PyObject **locals = _PyFrame_GetLocalsArray(f->f_frame);
         918                 :            :     assert(f->f_frame->stacktop >= 0);
         919         [ +  + ]:         24 :     for (int i = 0; i < f->f_frame->stacktop; i++) {
         920         [ +  - ]:         18 :         Py_CLEAR(locals[i]);
         921                 :            :     }
         922                 :          6 :     f->f_frame->stacktop = 0;
         923                 :          6 :     return 0;
         924                 :            : }
         925                 :            :
         926                 :            : static PyObject *
         927                 :        230 : frame_clear(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
         928                 :            : {
         929         [ -  + ]:        230 :     if (f->f_frame->owner == FRAME_OWNED_BY_GENERATOR) {
         930                 :          0 :         PyGenObject *gen = _PyFrame_GetGenerator(f->f_frame);
         931         [ #  # ]:          0 :         if (gen->gi_frame_state == FRAME_EXECUTING) {
         932                 :          0 :             goto running;
         933                 :            :         }
         934                 :          0 :         _PyGen_Finalize((PyObject *)gen);
         935                 :            :     }
         936         [ +  + ]:        230 :     else if (f->f_frame->owner == FRAME_OWNED_BY_THREAD) {
         937                 :        224 :         goto running;
         938                 :            :     }
         939                 :            :     else {
         940                 :            :         assert(f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT);
         941                 :          6 :         (void)frame_tp_clear(f);
         942                 :            :     }
         943                 :          6 :     Py_RETURN_NONE;
         944                 :        224 : running:
         945                 :        224 :     PyErr_SetString(PyExc_RuntimeError,
         946                 :            :                     "cannot clear an executing frame");
         947                 :        224 :     return NULL;
         948                 :            : }
         949                 :            :
         950                 :            : PyDoc_STRVAR(clear__doc__,
         951                 :            : "F.clear(): clear most references held by the frame");
         952                 :            :
         953                 :            : static PyObject *
         954                 :          0 : frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
         955                 :            : {
         956                 :            :     Py_ssize_t res;
         957                 :          0 :     res = offsetof(PyFrameObject, _f_frame_data) + offsetof(_PyInterpreterFrame, localsplus);
         958                 :          0 :     PyCodeObject *code = f->f_frame->f_code;
         959                 :          0 :     res += _PyFrame_NumSlotsForCodeObject(code) * sizeof(PyObject *);
         960                 :          0 :     return PyLong_FromSsize_t(res);
         961                 :            : }
         962                 :            :
         963                 :            : PyDoc_STRVAR(sizeof__doc__,
         964                 :            : "F.__sizeof__() -> size of F in memory, in bytes");
         965                 :            :
         966                 :            : static PyObject *
         967                 :          0 : frame_repr(PyFrameObject *f)
         968                 :            : {
         969                 :          0 :     int lineno = PyFrame_GetLineNumber(f);
         970                 :          0 :     PyCodeObject *code = f->f_frame->f_code;
         971                 :          0 :     return PyUnicode_FromFormat(
         972                 :            :         "<frame at %p, file %R, line %d, code %S>",
         973                 :            :         f, code->co_filename, lineno, code->co_name);
         974                 :            : }
         975                 :            :
         976                 :            : static PyMethodDef frame_methods[] = {
         977                 :            :     {"clear",           (PyCFunction)frame_clear,       METH_NOARGS,
         978                 :            :      clear__doc__},
         979                 :            :     {"__sizeof__",      (PyCFunction)frame_sizeof,      METH_NOARGS,
         980                 :            :      sizeof__doc__},
         981                 :            :     {NULL,              NULL}   /* sentinel */
         982                 :            : };
         983                 :            :
         984                 :            : PyTypeObject PyFrame_Type = {
         985                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
         986                 :            :     "frame",
         987                 :            :     offsetof(PyFrameObject, _f_frame_data) +
         988                 :            :     offsetof(_PyInterpreterFrame, localsplus),
         989                 :            :     sizeof(PyObject *),
         990                 :            :     (destructor)frame_dealloc,                  /* tp_dealloc */
         991                 :            :     0,                                          /* tp_vectorcall_offset */
         992                 :            :     0,                                          /* tp_getattr */
         993                 :            :     0,                                          /* tp_setattr */
         994                 :            :     0,                                          /* tp_as_async */
         995                 :            :     (reprfunc)frame_repr,                       /* tp_repr */
         996                 :            :     0,                                          /* tp_as_number */
         997                 :            :     0,                                          /* tp_as_sequence */
         998                 :            :     0,                                          /* tp_as_mapping */
         999                 :            :     0,                                          /* tp_hash */
        1000                 :            :     0,                                          /* tp_call */
        1001                 :            :     0,                                          /* tp_str */
        1002                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
        1003                 :            :     PyObject_GenericSetAttr,                    /* tp_setattro */
        1004                 :            :     0,                                          /* tp_as_buffer */
        1005                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
        1006                 :            :     0,                                          /* tp_doc */
        1007                 :            :     (traverseproc)frame_traverse,               /* tp_traverse */
        1008                 :            :     (inquiry)frame_tp_clear,                    /* tp_clear */
        1009                 :            :     0,                                          /* tp_richcompare */
        1010                 :            :     0,                                          /* tp_weaklistoffset */
        1011                 :            :     0,                                          /* tp_iter */
        1012                 :            :     0,                                          /* tp_iternext */
        1013                 :            :     frame_methods,                              /* tp_methods */
        1014                 :            :     frame_memberlist,                           /* tp_members */
        1015                 :            :     frame_getsetlist,                           /* tp_getset */
        1016                 :            :     0,                                          /* tp_base */
        1017                 :            :     0,                                          /* tp_dict */
        1018                 :            : };
        1019                 :            :
        1020                 :            : static void
        1021                 :          0 : init_frame(_PyInterpreterFrame *frame, PyFunctionObject *func, PyObject *locals)
        1022                 :            : {
        1023                 :          0 :     PyCodeObject *code = (PyCodeObject *)func->func_code;
        1024                 :          0 :     _PyFrame_Initialize(frame, (PyFunctionObject*)Py_NewRef(func),
        1025                 :            :                         Py_XNewRef(locals), code, 0);
        1026                 :          0 :     frame->previous = NULL;
        1027                 :          0 : }
        1028                 :            :
        1029                 :            : PyFrameObject*
        1030                 :     106583 : _PyFrame_New_NoTrack(PyCodeObject *code)
        1031                 :            : {
        1032                 :            :     CALL_STAT_INC(frame_objects_created);
        1033                 :     106583 :     int slots = code->co_nlocalsplus + code->co_stacksize;
        1034                 :     106583 :     PyFrameObject *f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, slots);
        1035         [ -  + ]:     106583 :     if (f == NULL) {
        1036                 :          0 :         return NULL;
        1037                 :            :     }
        1038                 :     106583 :     f->f_back = NULL;
        1039                 :     106583 :     f->f_trace = NULL;
        1040                 :     106583 :     f->f_trace_lines = 1;
        1041                 :     106583 :     f->f_trace_opcodes = 0;
        1042                 :     106583 :     f->f_fast_as_locals = 0;
        1043                 :     106583 :     f->f_lineno = 0;
        1044                 :     106583 :     return f;
        1045                 :            : }
        1046                 :            :
        1047                 :            : /* Legacy API */
        1048                 :            : PyFrameObject*
        1049                 :          0 : PyFrame_New(PyThreadState *tstate, PyCodeObject *code,
        1050                 :            :             PyObject *globals, PyObject *locals)
        1051                 :            : {
        1052                 :          0 :     PyObject *builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref
        1053         [ #  # ]:          0 :     if (builtins == NULL) {
        1054                 :          0 :         return NULL;
        1055                 :            :     }
        1056                 :          0 :     PyFrameConstructor desc = {
        1057                 :            :         .fc_globals = globals,
        1058                 :            :         .fc_builtins = builtins,
        1059                 :          0 :         .fc_name = code->co_name,
        1060                 :          0 :         .fc_qualname = code->co_name,
        1061                 :            :         .fc_code = (PyObject *)code,
        1062                 :            :         .fc_defaults = NULL,
        1063                 :            :         .fc_kwdefaults = NULL,
        1064                 :            :         .fc_closure = NULL
        1065                 :            :     };
        1066                 :          0 :     PyFunctionObject *func = _PyFunction_FromConstructor(&desc);
        1067         [ #  # ]:          0 :     if (func == NULL) {
        1068                 :          0 :         return NULL;
        1069                 :            :     }
        1070                 :          0 :     PyFrameObject *f = _PyFrame_New_NoTrack(code);
        1071         [ #  # ]:          0 :     if (f == NULL) {
        1072                 :          0 :         Py_DECREF(func);
        1073                 :          0 :         return NULL;
        1074                 :            :     }
        1075                 :          0 :     init_frame((_PyInterpreterFrame *)f->_f_frame_data, func, locals);
        1076                 :          0 :     f->f_frame = (_PyInterpreterFrame *)f->_f_frame_data;
        1077                 :          0 :     f->f_frame->owner = FRAME_OWNED_BY_FRAME_OBJECT;
        1078                 :            :     // This frame needs to be "complete", so pretend that the first RESUME ran:
        1079                 :          0 :     f->f_frame->prev_instr = _PyCode_CODE(code) + code->_co_firsttraceable;
        1080                 :            :     assert(!_PyFrame_IsIncomplete(f->f_frame));
        1081                 :          0 :     Py_DECREF(func);
        1082                 :          0 :     _PyObject_GC_TRACK(f);
        1083                 :          0 :     return f;
        1084                 :            : }
        1085                 :            :
        1086                 :            : static int
        1087                 :          0 : _PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg)
        1088                 :            : {
        1089                 :            :     // This only works when opcode is a non-quickened form:
        1090                 :            :     assert(_PyOpcode_Deopt[opcode] == opcode);
        1091                 :          0 :     int check_oparg = 0;
        1092                 :          0 :     for (_Py_CODEUNIT *instruction = _PyCode_CODE(frame->f_code);
        1093         [ #  # ]:          0 :          instruction < frame->prev_instr; instruction++)
        1094                 :            :     {
        1095                 :          0 :         int check_opcode = _PyOpcode_Deopt[instruction->op.code];
        1096                 :          0 :         check_oparg |= instruction->op.arg;
        1097   [ #  #  #  # ]:          0 :         if (check_opcode == opcode && check_oparg == oparg) {
        1098                 :          0 :             return 1;
        1099                 :            :         }
        1100         [ #  # ]:          0 :         if (check_opcode == EXTENDED_ARG) {
        1101                 :          0 :             check_oparg <<= 8;
        1102                 :            :         }
        1103                 :            :         else {
        1104                 :          0 :             check_oparg = 0;
        1105                 :            :         }
        1106                 :          0 :         instruction += _PyOpcode_Caches[check_opcode];
        1107                 :            :     }
        1108                 :          0 :     return 0;
        1109                 :            : }
        1110                 :            :
        1111                 :            :
        1112                 :            : // Initialize frame free variables if needed
        1113                 :            : static void
        1114                 :        164 : frame_init_get_vars(_PyInterpreterFrame *frame)
        1115                 :            : {
        1116                 :            :     // COPY_FREE_VARS has no quickened forms, so no need to use _PyOpcode_Deopt
        1117                 :            :     // here:
        1118                 :        164 :     PyCodeObject *co = frame->f_code;
        1119                 :        164 :     int lasti = _PyInterpreterFrame_LASTI(frame);
        1120   [ -  +  -  -  :        164 :     if (!(lasti < 0 && _PyCode_CODE(co)->op.code == COPY_FREE_VARS
                       -  - ]
        1121                 :          0 :           && PyFunction_Check(frame->f_funcobj)))
        1122                 :            :     {
        1123                 :            :         /* Free vars are initialized */
        1124                 :        164 :         return;
        1125                 :            :     }
        1126                 :            :
        1127                 :            :     /* Free vars have not been initialized -- Do that */
        1128                 :          0 :     PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure;
        1129                 :          0 :     int offset = PyCode_GetFirstFree(co);
        1130         [ #  # ]:          0 :     for (int i = 0; i < co->co_nfreevars; ++i) {
        1131                 :          0 :         PyObject *o = PyTuple_GET_ITEM(closure, i);
        1132                 :          0 :         frame->localsplus[offset + i] = Py_NewRef(o);
        1133                 :            :     }
        1134                 :            :     // COPY_FREE_VARS doesn't have inline CACHEs, either:
        1135                 :          0 :     frame->prev_instr = _PyCode_CODE(frame->f_code);
        1136                 :            : }
        1137                 :            :
        1138                 :            :
        1139                 :            : static int
        1140                 :          8 : frame_get_var(_PyInterpreterFrame *frame, PyCodeObject *co, int i,
        1141                 :            :               PyObject **pvalue)
        1142                 :            : {
        1143                 :          8 :     _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i);
        1144                 :            :
        1145                 :            :     /* If the namespace is unoptimized, then one of the
        1146                 :            :        following cases applies:
        1147                 :            :        1. It does not contain free variables, because it
        1148                 :            :           uses import * or is a top-level namespace.
        1149                 :            :        2. It is a class namespace.
        1150                 :            :        We don't want to accidentally copy free variables
        1151                 :            :        into the locals dict used by the class.
        1152                 :            :     */
        1153   [ -  +  -  - ]:          8 :     if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) {
        1154                 :          0 :         return 0;
        1155                 :            :     }
        1156                 :            :
        1157                 :          8 :     PyObject *value = frame->localsplus[i];
        1158         [ +  - ]:          8 :     if (frame->stacktop) {
        1159         [ -  + ]:          8 :         if (kind & CO_FAST_FREE) {
        1160                 :            :             // The cell was set by COPY_FREE_VARS.
        1161                 :            :             assert(value != NULL && PyCell_Check(value));
        1162                 :          0 :             value = PyCell_GET(value);
        1163                 :            :         }
        1164         [ -  + ]:          8 :         else if (kind & CO_FAST_CELL) {
        1165                 :            :             // Note that no *_DEREF ops can happen before MAKE_CELL
        1166                 :            :             // executes.  So there's no need to duplicate the work
        1167                 :            :             // that MAKE_CELL would otherwise do later, if it hasn't
        1168                 :            :             // run yet.
        1169         [ #  # ]:          0 :             if (value != NULL) {
        1170   [ #  #  #  # ]:          0 :                 if (PyCell_Check(value) &&
        1171                 :          0 :                         _PyFrame_OpAlreadyRan(frame, MAKE_CELL, i)) {
        1172                 :            :                     // (likely) MAKE_CELL must have executed already.
        1173                 :          0 :                     value = PyCell_GET(value);
        1174                 :            :                 }
        1175                 :            :                 // (likely) Otherwise it it is an arg (kind & CO_FAST_LOCAL),
        1176                 :            :                 // with the initial value set when the frame was created...
        1177                 :            :                 // (unlikely) ...or it was set to some initial value by
        1178                 :            :                 // an earlier call to PyFrame_LocalsToFast().
        1179                 :            :             }
        1180                 :            :         }
        1181                 :            :     }
        1182                 :            :     else {
        1183                 :            :         assert(value == NULL);
        1184                 :            :     }
        1185                 :          8 :     *pvalue = value;
        1186                 :          8 :     return 1;
        1187                 :            : }
        1188                 :            :
        1189                 :            : int
        1190                 :        164 : _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame)
        1191                 :            : {
        1192                 :            :     /* Merge fast locals into f->f_locals */
        1193                 :        164 :     PyObject *locals = frame->f_locals;
        1194         [ +  + ]:        164 :     if (locals == NULL) {
        1195                 :          2 :         locals = frame->f_locals = PyDict_New();
        1196         [ -  + ]:          2 :         if (locals == NULL) {
        1197                 :          0 :             return -1;
        1198                 :            :         }
        1199                 :            :     }
        1200                 :            :
        1201                 :        164 :     frame_init_get_vars(frame);
        1202                 :            :
        1203                 :        164 :     PyCodeObject *co = frame->f_code;
        1204         [ +  + ]:        172 :     for (int i = 0; i < co->co_nlocalsplus; i++) {
        1205                 :            :         PyObject *value;  // borrowed reference
        1206         [ -  + ]:          8 :         if (!frame_get_var(frame, co, i, &value)) {
        1207                 :          0 :             continue;
        1208                 :            :         }
        1209                 :            :
        1210                 :          8 :         PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
        1211         [ +  + ]:          8 :         if (value == NULL) {
        1212         [ +  - ]:          4 :             if (PyObject_DelItem(locals, name) != 0) {
        1213         [ +  - ]:          4 :                 if (PyErr_ExceptionMatches(PyExc_KeyError)) {
        1214                 :          4 :                     PyErr_Clear();
        1215                 :            :                 }
        1216                 :            :                 else {
        1217                 :          0 :                     return -1;
        1218                 :            :                 }
        1219                 :            :             }
        1220                 :            :         }
        1221                 :            :         else {
        1222         [ -  + ]:          4 :             if (PyObject_SetItem(locals, name, value) != 0) {
        1223                 :          0 :                 return -1;
        1224                 :            :             }
        1225                 :            :         }
        1226                 :            :     }
        1227                 :        164 :     return 0;
        1228                 :            : }
        1229                 :            :
        1230                 :            :
        1231                 :            : PyObject *
        1232                 :          0 : PyFrame_GetVar(PyFrameObject *frame_obj, PyObject *name)
        1233                 :            : {
        1234         [ #  # ]:          0 :     if (!PyUnicode_Check(name)) {
        1235                 :          0 :         PyErr_Format(PyExc_TypeError, "name must be str, not %s",
        1236                 :          0 :                      Py_TYPE(name)->tp_name);
        1237                 :          0 :         return NULL;
        1238                 :            :     }
        1239                 :            :
        1240                 :          0 :     _PyInterpreterFrame *frame = frame_obj->f_frame;
        1241                 :          0 :     frame_init_get_vars(frame);
        1242                 :            :
        1243                 :          0 :     PyCodeObject *co = frame->f_code;
        1244         [ #  # ]:          0 :     for (int i = 0; i < co->co_nlocalsplus; i++) {
        1245                 :          0 :         PyObject *var_name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
        1246         [ #  # ]:          0 :         if (!_PyUnicode_Equal(var_name, name)) {
        1247                 :          0 :             continue;
        1248                 :            :         }
        1249                 :            :
        1250                 :            :         PyObject *value;  // borrowed reference
        1251         [ #  # ]:          0 :         if (!frame_get_var(frame, co, i, &value)) {
        1252                 :          0 :             break;
        1253                 :            :         }
        1254         [ #  # ]:          0 :         if (value == NULL) {
        1255                 :          0 :             break;
        1256                 :            :         }
        1257                 :          0 :         return Py_NewRef(value);
        1258                 :            :     }
        1259                 :            :
        1260                 :          0 :     PyErr_Format(PyExc_NameError, "variable %R does not exist", name);
        1261                 :          0 :     return NULL;
        1262                 :            : }
        1263                 :            :
        1264                 :            :
        1265                 :            : PyObject *
        1266                 :          0 : PyFrame_GetVarString(PyFrameObject *frame, const char *name)
        1267                 :            : {
        1268                 :          0 :     PyObject *name_obj = PyUnicode_FromString(name);
        1269         [ #  # ]:          0 :     if (name_obj == NULL) {
        1270                 :          0 :         return NULL;
        1271                 :            :     }
        1272                 :          0 :     PyObject *value = PyFrame_GetVar(frame, name_obj);
        1273                 :          0 :     Py_DECREF(name_obj);
        1274                 :          0 :     return value;
        1275                 :            : }
        1276                 :            :
        1277                 :            :
        1278                 :            : int
        1279                 :          0 : PyFrame_FastToLocalsWithError(PyFrameObject *f)
        1280                 :            : {
        1281                 :            :     assert(!_PyFrame_IsIncomplete(f->f_frame));
        1282         [ #  # ]:          0 :     if (f == NULL) {
        1283                 :          0 :         PyErr_BadInternalCall();
        1284                 :          0 :         return -1;
        1285                 :            :     }
        1286                 :          0 :     int err = _PyFrame_FastToLocalsWithError(f->f_frame);
        1287         [ #  # ]:          0 :     if (err == 0) {
        1288                 :          0 :         f->f_fast_as_locals = 1;
        1289                 :            :     }
        1290                 :          0 :     return err;
        1291                 :            : }
        1292                 :            :
        1293                 :            : void
        1294                 :          0 : PyFrame_FastToLocals(PyFrameObject *f)
        1295                 :            : {
        1296                 :            :     int res;
        1297                 :            :     assert(!_PyFrame_IsIncomplete(f->f_frame));
        1298                 :            :     assert(!PyErr_Occurred());
        1299                 :            :
        1300                 :          0 :     res = PyFrame_FastToLocalsWithError(f);
        1301         [ #  # ]:          0 :     if (res < 0)
        1302                 :          0 :         PyErr_Clear();
        1303                 :          0 : }
        1304                 :            :
        1305                 :            : void
        1306                 :        162 : _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear)
        1307                 :            : {
        1308                 :            :     /* Merge locals into fast locals */
        1309                 :            :     PyObject *locals;
        1310                 :            :     PyObject **fast;
        1311                 :            :     PyCodeObject *co;
        1312                 :        162 :     locals = frame->f_locals;
        1313         [ -  + ]:        162 :     if (locals == NULL) {
        1314                 :          0 :         return;
        1315                 :            :     }
        1316                 :        162 :     fast = _PyFrame_GetLocalsArray(frame);
        1317                 :        162 :     co = frame->f_code;
        1318                 :            :
        1319                 :        162 :     PyObject *exc = PyErr_GetRaisedException();
        1320         [ -  + ]:        162 :     for (int i = 0; i < co->co_nlocalsplus; i++) {
        1321                 :          0 :         _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i);
        1322                 :            :
        1323                 :            :         /* Same test as in PyFrame_FastToLocals() above. */
        1324   [ #  #  #  # ]:          0 :         if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) {
        1325                 :          0 :             continue;
        1326                 :            :         }
        1327                 :          0 :         PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
        1328                 :          0 :         PyObject *value = PyObject_GetItem(locals, name);
        1329                 :            :         /* We only care about NULLs if clear is true. */
        1330         [ #  # ]:          0 :         if (value == NULL) {
        1331                 :          0 :             PyErr_Clear();
        1332         [ #  # ]:          0 :             if (!clear) {
        1333                 :          0 :                 continue;
        1334                 :            :             }
        1335                 :            :         }
        1336                 :          0 :         PyObject *oldvalue = fast[i];
        1337                 :          0 :         PyObject *cell = NULL;
        1338         [ #  # ]:          0 :         if (kind == CO_FAST_FREE) {
        1339                 :            :             // The cell was set when the frame was created from
        1340                 :            :             // the function's closure.
        1341                 :            :             assert(oldvalue != NULL && PyCell_Check(oldvalue));
        1342                 :          0 :             cell = oldvalue;
        1343                 :            :         }
        1344   [ #  #  #  # ]:          0 :         else if (kind & CO_FAST_CELL && oldvalue != NULL) {
        1345                 :            :             /* Same test as in PyFrame_FastToLocals() above. */
        1346   [ #  #  #  # ]:          0 :             if (PyCell_Check(oldvalue) &&
        1347                 :          0 :                     _PyFrame_OpAlreadyRan(frame, MAKE_CELL, i)) {
        1348                 :            :                 // (likely) MAKE_CELL must have executed already.
        1349                 :          0 :                 cell = oldvalue;
        1350                 :            :             }
        1351                 :            :             // (unlikely) Otherwise, it must have been set to some
        1352                 :            :             // initial value by an earlier call to PyFrame_LocalsToFast().
        1353                 :            :         }
        1354         [ #  # ]:          0 :         if (cell != NULL) {
        1355                 :          0 :             oldvalue = PyCell_GET(cell);
        1356         [ #  # ]:          0 :             if (value != oldvalue) {
        1357                 :          0 :                 PyCell_SET(cell, Py_XNewRef(value));
        1358                 :          0 :                 Py_XDECREF(oldvalue);
        1359                 :            :             }
        1360                 :            :         }
        1361         [ #  # ]:          0 :         else if (value != oldvalue) {
        1362         [ #  # ]:          0 :             if (value == NULL) {
        1363                 :            :                 // Probably can't delete this, since the compiler's flow
        1364                 :            :                 // analysis may have already "proven" that it exists here:
        1365                 :          0 :                 const char *e = "assigning None to unbound local %R";
        1366         [ #  # ]:          0 :                 if (PyErr_WarnFormat(PyExc_RuntimeWarning, 0, e, name)) {
        1367                 :            :                     // It's okay if frame_obj is NULL, just try anyways:
        1368                 :          0 :                     PyErr_WriteUnraisable((PyObject *)frame->frame_obj);
        1369                 :            :                 }
        1370                 :          0 :                 value = Py_NewRef(Py_None);
        1371                 :            :             }
        1372                 :          0 :             Py_XSETREF(fast[i], Py_NewRef(value));
        1373                 :            :         }
        1374                 :          0 :         Py_XDECREF(value);
        1375                 :            :     }
        1376                 :        162 :     PyErr_SetRaisedException(exc);
        1377                 :            : }
        1378                 :            :
        1379                 :            : void
        1380                 :          0 : PyFrame_LocalsToFast(PyFrameObject *f, int clear)
        1381                 :            : {
        1382                 :            :     assert(!_PyFrame_IsIncomplete(f->f_frame));
        1383   [ #  #  #  #  :          0 :     if (f && f->f_fast_as_locals && _PyFrame_GetState(f) != FRAME_CLEARED) {
                       #  # ]
        1384                 :          0 :         _PyFrame_LocalsToFast(f->f_frame, clear);
        1385                 :          0 :         f->f_fast_as_locals = 0;
        1386                 :            :     }
        1387                 :          0 : }
        1388                 :            :
        1389                 :            : int
        1390                 :          0 : _PyFrame_IsEntryFrame(PyFrameObject *frame)
        1391                 :            : {
        1392                 :            :     assert(frame != NULL);
        1393                 :          0 :     _PyInterpreterFrame *f = frame->f_frame;
        1394                 :            :     assert(!_PyFrame_IsIncomplete(f));
        1395   [ #  #  #  # ]:          0 :     return f->previous && f->previous->owner == FRAME_OWNED_BY_CSTACK;
        1396                 :            : }
        1397                 :            :
        1398                 :            : PyCodeObject *
        1399                 :        136 : PyFrame_GetCode(PyFrameObject *frame)
        1400                 :            : {
        1401                 :            :     assert(frame != NULL);
        1402                 :            :     assert(!_PyFrame_IsIncomplete(frame->f_frame));
        1403                 :        136 :     PyCodeObject *code = frame->f_frame->f_code;
        1404                 :            :     assert(code != NULL);
        1405                 :        136 :     return (PyCodeObject*)Py_NewRef(code);
        1406                 :            : }
        1407                 :            :
        1408                 :            :
        1409                 :            : PyFrameObject*
        1410                 :         24 : PyFrame_GetBack(PyFrameObject *frame)
        1411                 :            : {
        1412                 :            :     assert(frame != NULL);
        1413                 :            :     assert(!_PyFrame_IsIncomplete(frame->f_frame));
        1414                 :         24 :     PyFrameObject *back = frame->f_back;
        1415         [ +  - ]:         24 :     if (back == NULL) {
        1416                 :         24 :         _PyInterpreterFrame *prev = frame->f_frame->previous;
        1417                 :         24 :         prev = _PyFrame_GetFirstComplete(prev);
        1418         [ +  - ]:         24 :         if (prev) {
        1419                 :         24 :             back = _PyFrame_GetFrameObject(prev);
        1420                 :            :         }
        1421                 :            :     }
        1422                 :         24 :     return (PyFrameObject*)Py_XNewRef(back);
        1423                 :            : }
        1424                 :            :
        1425                 :            : PyObject*
        1426                 :          0 : PyFrame_GetLocals(PyFrameObject *frame)
        1427                 :            : {
        1428                 :            :     assert(!_PyFrame_IsIncomplete(frame->f_frame));
        1429                 :          0 :     return frame_getlocals(frame, NULL);
        1430                 :            : }
        1431                 :            :
        1432                 :            : PyObject*
        1433                 :          0 : PyFrame_GetGlobals(PyFrameObject *frame)
        1434                 :            : {
        1435                 :            :     assert(!_PyFrame_IsIncomplete(frame->f_frame));
        1436                 :          0 :     return frame_getglobals(frame, NULL);
        1437                 :            : }
        1438                 :            :
        1439                 :            : PyObject*
        1440                 :          0 : PyFrame_GetBuiltins(PyFrameObject *frame)
        1441                 :            : {
        1442                 :            :     assert(!_PyFrame_IsIncomplete(frame->f_frame));
        1443                 :          0 :     return frame_getbuiltins(frame, NULL);
        1444                 :            : }
        1445                 :            :
        1446                 :            : int
        1447                 :          0 : PyFrame_GetLasti(PyFrameObject *frame)
        1448                 :            : {
        1449                 :            :     assert(!_PyFrame_IsIncomplete(frame->f_frame));
        1450                 :          0 :     int lasti = _PyInterpreterFrame_LASTI(frame->f_frame);
        1451         [ #  # ]:          0 :     if (lasti < 0) {
        1452                 :          0 :         return -1;
        1453                 :            :     }
        1454                 :          0 :     return lasti * sizeof(_Py_CODEUNIT);
        1455                 :            : }
        1456                 :            :
        1457                 :            : PyObject *
        1458                 :          0 : PyFrame_GetGenerator(PyFrameObject *frame)
        1459                 :            : {
        1460                 :            :     assert(!_PyFrame_IsIncomplete(frame->f_frame));
        1461         [ #  # ]:          0 :     if (frame->f_frame->owner != FRAME_OWNED_BY_GENERATOR) {
        1462                 :          0 :         return NULL;
        1463                 :            :     }
        1464                 :          0 :     PyGenObject *gen = _PyFrame_GetGenerator(frame->f_frame);
        1465                 :          0 :     return Py_NewRef(gen);
        1466                 :            : }
        1467                 :            :
        1468                 :            : PyObject*
        1469                 :     198108 : _PyEval_BuiltinsFromGlobals(PyThreadState *tstate, PyObject *globals)
        1470                 :            : {
        1471                 :     198108 :     PyObject *builtins = PyDict_GetItemWithError(globals, &_Py_ID(__builtins__));
        1472         [ +  - ]:     198108 :     if (builtins) {
        1473         [ +  + ]:     198108 :         if (PyModule_Check(builtins)) {
        1474                 :      22409 :             builtins = _PyModule_GetDict(builtins);
        1475                 :            :             assert(builtins != NULL);
        1476                 :            :         }
        1477                 :     198108 :         return builtins;
        1478                 :            :     }
        1479         [ #  # ]:          0 :     if (PyErr_Occurred()) {
        1480                 :          0 :         return NULL;
        1481                 :            :     }
        1482                 :            :
        1483                 :          0 :     return _PyEval_GetBuiltins(tstate);
        1484                 :            : }

Generated by: LCOV version 1.14