LCOV - code coverage report
Current view: top level - Objects - frameobject.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 574 670 85.7 %
Date: 2022-07-20 13:12:14 Functions: 47 50 94.0 %
Branches: 295 387 76.2 %

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

Generated by: LCOV version 1.14