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