Branch data Line data Source code
1 : : #include <stdbool.h>
2 : :
3 : : #include "Python.h"
4 : : #include "opcode.h"
5 : : #include "structmember.h" // PyMemberDef
6 : : #include "pycore_code.h" // _PyCodeConstructor
7 : : #include "pycore_frame.h" // FRAME_SPECIALS_SIZE
8 : : #include "pycore_interp.h" // PyInterpreterState.co_extra_freefuncs
9 : : #include "pycore_opcode.h" // _PyOpcode_Deopt
10 : : #include "pycore_pystate.h" // _PyInterpreterState_GET()
11 : : #include "pycore_tuple.h" // _PyTuple_ITEMS()
12 : : #include "clinic/codeobject.c.h"
13 : :
14 : : static PyObject* code_repr(PyCodeObject *co);
15 : :
16 : : static const char *
17 : 0 : code_event_name(PyCodeEvent event) {
18 [ # # # ]: 0 : switch (event) {
19 : : #define CASE(op) \
20 : : case PY_CODE_EVENT_##op: \
21 : : return "PY_CODE_EVENT_" #op;
22 : 0 : PY_FOREACH_CODE_EVENT(CASE)
23 : : #undef CASE
24 : : }
25 : 0 : Py_UNREACHABLE();
26 : : }
27 : :
28 : : static void
29 : 58177 : notify_code_watchers(PyCodeEvent event, PyCodeObject *co)
30 : : {
31 : : assert(Py_REFCNT(co) > 0);
32 : 58177 : PyInterpreterState *interp = _PyInterpreterState_GET();
33 : : assert(interp->_initialized);
34 : 58177 : uint8_t bits = interp->active_code_watchers;
35 : 58177 : int i = 0;
36 [ - + ]: 58177 : while (bits) {
37 : : assert(i < CODE_MAX_WATCHERS);
38 [ # # ]: 0 : if (bits & 1) {
39 : 0 : PyCode_WatchCallback cb = interp->code_watchers[i];
40 : : // callback must be non-null if the watcher bit is set
41 : : assert(cb != NULL);
42 [ # # ]: 0 : if (cb(event, co) < 0) {
43 : : // Don't risk resurrecting the object if an unraisablehook keeps
44 : : // a reference; pass a string as context.
45 : 0 : PyObject *context = NULL;
46 : 0 : PyObject *repr = code_repr(co);
47 [ # # ]: 0 : if (repr) {
48 : 0 : context = PyUnicode_FromFormat(
49 : : "%s watcher callback for %U",
50 : : code_event_name(event), repr);
51 : 0 : Py_DECREF(repr);
52 : : }
53 [ # # ]: 0 : if (context == NULL) {
54 : 0 : context = Py_NewRef(Py_None);
55 : : }
56 : 0 : PyErr_WriteUnraisable(context);
57 : 0 : Py_DECREF(context);
58 : : }
59 : : }
60 : 0 : i++;
61 : 0 : bits >>= 1;
62 : : }
63 : 58177 : }
64 : :
65 : : int
66 : 0 : PyCode_AddWatcher(PyCode_WatchCallback callback)
67 : : {
68 : 0 : PyInterpreterState *interp = _PyInterpreterState_GET();
69 : : assert(interp->_initialized);
70 : :
71 [ # # ]: 0 : for (int i = 0; i < CODE_MAX_WATCHERS; i++) {
72 [ # # ]: 0 : if (!interp->code_watchers[i]) {
73 : 0 : interp->code_watchers[i] = callback;
74 : 0 : interp->active_code_watchers |= (1 << i);
75 : 0 : return i;
76 : : }
77 : : }
78 : :
79 : 0 : PyErr_SetString(PyExc_RuntimeError, "no more code watcher IDs available");
80 : 0 : return -1;
81 : : }
82 : :
83 : : static inline int
84 : 0 : validate_watcher_id(PyInterpreterState *interp, int watcher_id)
85 : : {
86 [ # # # # ]: 0 : if (watcher_id < 0 || watcher_id >= CODE_MAX_WATCHERS) {
87 : 0 : PyErr_Format(PyExc_ValueError, "Invalid code watcher ID %d", watcher_id);
88 : 0 : return -1;
89 : : }
90 [ # # ]: 0 : if (!interp->code_watchers[watcher_id]) {
91 : 0 : PyErr_Format(PyExc_ValueError, "No code watcher set for ID %d", watcher_id);
92 : 0 : return -1;
93 : : }
94 : 0 : return 0;
95 : : }
96 : :
97 : : int
98 : 0 : PyCode_ClearWatcher(int watcher_id)
99 : : {
100 : 0 : PyInterpreterState *interp = _PyInterpreterState_GET();
101 : : assert(interp->_initialized);
102 [ # # ]: 0 : if (validate_watcher_id(interp, watcher_id) < 0) {
103 : 0 : return -1;
104 : : }
105 : 0 : interp->code_watchers[watcher_id] = NULL;
106 : 0 : interp->active_code_watchers &= ~(1 << watcher_id);
107 : 0 : return 0;
108 : : }
109 : :
110 : : /******************
111 : : * generic helpers
112 : : ******************/
113 : :
114 : : /* all_name_chars(s): true iff s matches [a-zA-Z0-9_]* */
115 : : static int
116 : 96601 : all_name_chars(PyObject *o)
117 : : {
118 : : const unsigned char *s, *e;
119 : :
120 [ + + ]: 96601 : if (!PyUnicode_IS_ASCII(o))
121 : 76 : return 0;
122 : :
123 : 96525 : s = PyUnicode_1BYTE_DATA(o);
124 : 96525 : e = s + PyUnicode_GET_LENGTH(o);
125 [ + + ]: 739447 : for (; s != e; s++) {
126 [ + + + + ]: 681856 : if (!Py_ISALNUM(*s) && *s != '_')
127 : 38934 : return 0;
128 : : }
129 : 57591 : return 1;
130 : : }
131 : :
132 : : static int
133 : 64508 : intern_strings(PyObject *tuple)
134 : : {
135 : : Py_ssize_t i;
136 : :
137 [ + + ]: 354525 : for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
138 : 290017 : PyObject *v = PyTuple_GET_ITEM(tuple, i);
139 [ + - - + ]: 290017 : if (v == NULL || !PyUnicode_CheckExact(v)) {
140 : 0 : PyErr_SetString(PyExc_SystemError,
141 : : "non-string found in code slot");
142 : 0 : return -1;
143 : : }
144 : 290017 : PyUnicode_InternInPlace(&_PyTuple_ITEMS(tuple)[i]);
145 : : }
146 : 64508 : return 0;
147 : : }
148 : :
149 : : /* Intern selected string constants */
150 : : static int
151 : 44314 : intern_string_constants(PyObject *tuple, int *modified)
152 : : {
153 [ + + ]: 236957 : for (Py_ssize_t i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
154 : 192643 : PyObject *v = PyTuple_GET_ITEM(tuple, i);
155 [ + + ]: 192643 : if (PyUnicode_CheckExact(v)) {
156 [ - + ]: 96601 : if (PyUnicode_READY(v) == -1) {
157 : 0 : return -1;
158 : : }
159 : :
160 [ + + ]: 96601 : if (all_name_chars(v)) {
161 : 57591 : PyObject *w = v;
162 : 57591 : PyUnicode_InternInPlace(&v);
163 [ + + ]: 57591 : if (w != v) {
164 : 5572 : PyTuple_SET_ITEM(tuple, i, v);
165 [ + + ]: 5572 : if (modified) {
166 : 86 : *modified = 1;
167 : : }
168 : : }
169 : : }
170 : : }
171 [ + + ]: 96042 : else if (PyTuple_CheckExact(v)) {
172 [ - + ]: 11939 : if (intern_string_constants(v, NULL) < 0) {
173 : 0 : return -1;
174 : : }
175 : : }
176 [ + + ]: 84103 : else if (PyFrozenSet_CheckExact(v)) {
177 : 121 : PyObject *w = v;
178 : 121 : PyObject *tmp = PySequence_Tuple(v);
179 [ - + ]: 121 : if (tmp == NULL) {
180 : 0 : return -1;
181 : : }
182 : 121 : int tmp_modified = 0;
183 [ - + ]: 121 : if (intern_string_constants(tmp, &tmp_modified) < 0) {
184 : 0 : Py_DECREF(tmp);
185 : 0 : return -1;
186 : : }
187 [ + + ]: 121 : if (tmp_modified) {
188 : 33 : v = PyFrozenSet_New(tmp);
189 [ - + ]: 33 : if (v == NULL) {
190 : 0 : Py_DECREF(tmp);
191 : 0 : return -1;
192 : : }
193 : :
194 : 33 : PyTuple_SET_ITEM(tuple, i, v);
195 : 33 : Py_DECREF(w);
196 [ - + ]: 33 : if (modified) {
197 : 0 : *modified = 1;
198 : : }
199 : : }
200 : 121 : Py_DECREF(tmp);
201 : : }
202 : : }
203 : 44314 : return 0;
204 : : }
205 : :
206 : : /* Return a shallow copy of a tuple that is
207 : : guaranteed to contain exact strings, by converting string subclasses
208 : : to exact strings and complaining if a non-string is found. */
209 : : static PyObject*
210 : 0 : validate_and_copy_tuple(PyObject *tup)
211 : : {
212 : : PyObject *newtuple;
213 : : PyObject *item;
214 : : Py_ssize_t i, len;
215 : :
216 : 0 : len = PyTuple_GET_SIZE(tup);
217 : 0 : newtuple = PyTuple_New(len);
218 [ # # ]: 0 : if (newtuple == NULL)
219 : 0 : return NULL;
220 : :
221 [ # # ]: 0 : for (i = 0; i < len; i++) {
222 : 0 : item = PyTuple_GET_ITEM(tup, i);
223 [ # # ]: 0 : if (PyUnicode_CheckExact(item)) {
224 : 0 : Py_INCREF(item);
225 : : }
226 [ # # ]: 0 : else if (!PyUnicode_Check(item)) {
227 : 0 : PyErr_Format(
228 : : PyExc_TypeError,
229 : : "name tuples must contain only "
230 : : "strings, not '%.500s'",
231 : 0 : Py_TYPE(item)->tp_name);
232 : 0 : Py_DECREF(newtuple);
233 : 0 : return NULL;
234 : : }
235 : : else {
236 : 0 : item = _PyUnicode_Copy(item);
237 [ # # ]: 0 : if (item == NULL) {
238 : 0 : Py_DECREF(newtuple);
239 : 0 : return NULL;
240 : : }
241 : : }
242 : 0 : PyTuple_SET_ITEM(newtuple, i, item);
243 : : }
244 : :
245 : 0 : return newtuple;
246 : : }
247 : :
248 : : static int
249 : 7647 : init_co_cached(PyCodeObject *self) {
250 [ + + ]: 7647 : if (self->_co_cached == NULL) {
251 : 7646 : self->_co_cached = PyMem_New(_PyCoCached, 1);
252 [ - + ]: 7646 : if (self->_co_cached == NULL) {
253 : 0 : PyErr_NoMemory();
254 : 0 : return -1;
255 : : }
256 : 7646 : self->_co_cached->_co_code = NULL;
257 : 7646 : self->_co_cached->_co_cellvars = NULL;
258 : 7646 : self->_co_cached->_co_freevars = NULL;
259 : 7646 : self->_co_cached->_co_varnames = NULL;
260 : : }
261 : 7647 : return 0;
262 : :
263 : : }
264 : : /******************
265 : : * _PyCode_New()
266 : : ******************/
267 : :
268 : : // This is also used in compile.c.
269 : : void
270 : 25043 : _Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind,
271 : : PyObject *names, PyObject *kinds)
272 : : {
273 : 25043 : PyTuple_SET_ITEM(names, offset, Py_NewRef(name));
274 : 25043 : _PyLocals_SetKind(kinds, offset, kind);
275 : 25043 : }
276 : :
277 : : static void
278 : 58303 : get_localsplus_counts(PyObject *names, PyObject *kinds,
279 : : int *pnlocals, int *pncellvars,
280 : : int *pnfreevars)
281 : : {
282 : 58303 : int nlocals = 0;
283 : 58303 : int ncellvars = 0;
284 : 58303 : int nfreevars = 0;
285 : 58303 : Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names);
286 [ + + ]: 230825 : for (int i = 0; i < nlocalsplus; i++) {
287 : 172522 : _PyLocals_Kind kind = _PyLocals_GetKind(kinds, i);
288 [ + + ]: 172522 : if (kind & CO_FAST_LOCAL) {
289 : 164364 : nlocals += 1;
290 [ + + ]: 164364 : if (kind & CO_FAST_CELL) {
291 : 2052 : ncellvars += 1;
292 : : }
293 : : }
294 [ + + ]: 8158 : else if (kind & CO_FAST_CELL) {
295 : 2392 : ncellvars += 1;
296 : : }
297 [ + - ]: 5766 : else if (kind & CO_FAST_FREE) {
298 : 5766 : nfreevars += 1;
299 : : }
300 : : }
301 [ + - ]: 58303 : if (pnlocals != NULL) {
302 : 58303 : *pnlocals = nlocals;
303 : : }
304 [ + + ]: 58303 : if (pncellvars != NULL) {
305 : 29166 : *pncellvars = ncellvars;
306 : : }
307 [ + + ]: 58303 : if (pnfreevars != NULL) {
308 : 29166 : *pnfreevars = nfreevars;
309 : : }
310 : 58303 : }
311 : :
312 : : static PyObject *
313 : 3 : get_localsplus_names(PyCodeObject *co, _PyLocals_Kind kind, int num)
314 : : {
315 : 3 : PyObject *names = PyTuple_New(num);
316 [ - + ]: 3 : if (names == NULL) {
317 : 0 : return NULL;
318 : : }
319 : 3 : int index = 0;
320 [ - + ]: 3 : for (int offset = 0; offset < co->co_nlocalsplus; offset++) {
321 : 0 : _PyLocals_Kind k = _PyLocals_GetKind(co->co_localspluskinds, offset);
322 [ # # ]: 0 : if ((k & kind) == 0) {
323 : 0 : continue;
324 : : }
325 : : assert(index < num);
326 : 0 : PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, offset);
327 : 0 : PyTuple_SET_ITEM(names, index, Py_NewRef(name));
328 : 0 : index += 1;
329 : : }
330 : : assert(index == num);
331 : 3 : return names;
332 : : }
333 : :
334 : : int
335 : 29137 : _PyCode_Validate(struct _PyCodeConstructor *con)
336 : : {
337 : : /* Check argument types */
338 [ + - + - ]: 29137 : if (con->argcount < con->posonlyargcount || con->posonlyargcount < 0 ||
339 [ + - ]: 29137 : con->kwonlyargcount < 0 ||
340 [ + - + - ]: 29137 : con->stacksize < 0 || con->flags < 0 ||
341 [ + - + - ]: 29137 : con->code == NULL || !PyBytes_Check(con->code) ||
342 [ + - + - ]: 29137 : con->consts == NULL || !PyTuple_Check(con->consts) ||
343 [ + - + - ]: 29137 : con->names == NULL || !PyTuple_Check(con->names) ||
344 [ + - + - ]: 29137 : con->localsplusnames == NULL || !PyTuple_Check(con->localsplusnames) ||
345 [ + - + - : 58274 : con->localspluskinds == NULL || !PyBytes_Check(con->localspluskinds) ||
+ - ]
346 : 29137 : PyTuple_GET_SIZE(con->localsplusnames)
347 : 29137 : != PyBytes_GET_SIZE(con->localspluskinds) ||
348 [ + - + - ]: 29137 : con->name == NULL || !PyUnicode_Check(con->name) ||
349 [ + - + - ]: 29137 : con->qualname == NULL || !PyUnicode_Check(con->qualname) ||
350 [ + - + - ]: 29137 : con->filename == NULL || !PyUnicode_Check(con->filename) ||
351 [ + - + - ]: 29137 : con->linetable == NULL || !PyBytes_Check(con->linetable) ||
352 [ + - - + ]: 29137 : con->exceptiontable == NULL || !PyBytes_Check(con->exceptiontable)
353 : : ) {
354 : 0 : PyErr_BadInternalCall();
355 : 0 : return -1;
356 : : }
357 : :
358 : : /* Make sure that code is indexable with an int, this is
359 : : a long running assumption in ceval.c and many parts of
360 : : the interpreter. */
361 [ - + ]: 29137 : if (PyBytes_GET_SIZE(con->code) > INT_MAX) {
362 : 0 : PyErr_SetString(PyExc_OverflowError,
363 : : "code: co_code larger than INT_MAX");
364 : 0 : return -1;
365 : : }
366 [ + - ]: 29137 : if (PyBytes_GET_SIZE(con->code) % sizeof(_Py_CODEUNIT) != 0 ||
367 [ - + ]: 29137 : !_Py_IS_ALIGNED(PyBytes_AS_STRING(con->code), sizeof(_Py_CODEUNIT))
368 : : ) {
369 : 0 : PyErr_SetString(PyExc_ValueError, "code: co_code is malformed");
370 : 0 : return -1;
371 : : }
372 : :
373 : : /* Ensure that the co_varnames has enough names to cover the arg counts.
374 : : * Note that totalargs = nlocals - nplainlocals. We check nplainlocals
375 : : * here to avoid the possibility of overflow (however remote). */
376 : : int nlocals;
377 : 29137 : get_localsplus_counts(con->localsplusnames, con->localspluskinds,
378 : : &nlocals, NULL, NULL);
379 : 29137 : int nplainlocals = nlocals -
380 : 29137 : con->argcount -
381 : 29137 : con->kwonlyargcount -
382 : 29137 : ((con->flags & CO_VARARGS) != 0) -
383 : 29137 : ((con->flags & CO_VARKEYWORDS) != 0);
384 [ - + ]: 29137 : if (nplainlocals < 0) {
385 : 0 : PyErr_SetString(PyExc_ValueError, "code: co_varnames is too small");
386 : 0 : return -1;
387 : : }
388 : :
389 : 29137 : return 0;
390 : : }
391 : :
392 : : extern void _PyCode_Quicken(PyCodeObject *code);
393 : :
394 : : static void
395 : 29166 : init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
396 : : {
397 : 29166 : int nlocalsplus = (int)PyTuple_GET_SIZE(con->localsplusnames);
398 : : int nlocals, ncellvars, nfreevars;
399 : 29166 : get_localsplus_counts(con->localsplusnames, con->localspluskinds,
400 : : &nlocals, &ncellvars, &nfreevars);
401 : :
402 : 29166 : co->co_filename = Py_NewRef(con->filename);
403 : 29166 : co->co_name = Py_NewRef(con->name);
404 : 29166 : co->co_qualname = Py_NewRef(con->qualname);
405 : 29166 : co->co_flags = con->flags;
406 : :
407 : 29166 : co->co_firstlineno = con->firstlineno;
408 : 29166 : co->co_linetable = Py_NewRef(con->linetable);
409 : :
410 : 29166 : co->co_consts = Py_NewRef(con->consts);
411 : 29166 : co->co_names = Py_NewRef(con->names);
412 : :
413 : 29166 : co->co_localsplusnames = Py_NewRef(con->localsplusnames);
414 : 29166 : co->co_localspluskinds = Py_NewRef(con->localspluskinds);
415 : :
416 : 29166 : co->co_argcount = con->argcount;
417 : 29166 : co->co_posonlyargcount = con->posonlyargcount;
418 : 29166 : co->co_kwonlyargcount = con->kwonlyargcount;
419 : :
420 : 29166 : co->co_stacksize = con->stacksize;
421 : :
422 : 29166 : co->co_exceptiontable = Py_NewRef(con->exceptiontable);
423 : :
424 : : /* derived values */
425 : 29166 : co->co_nlocalsplus = nlocalsplus;
426 : 29166 : co->co_nlocals = nlocals;
427 : 29166 : co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE;
428 : 29166 : co->co_ncellvars = ncellvars;
429 : 29166 : co->co_nfreevars = nfreevars;
430 : 29166 : co->co_version = _Py_next_func_version;
431 [ + - ]: 29166 : if (_Py_next_func_version != 0) {
432 : 29166 : _Py_next_func_version++;
433 : : }
434 : : /* not set */
435 : 29166 : co->co_weakreflist = NULL;
436 : 29166 : co->co_extra = NULL;
437 : 29166 : co->_co_cached = NULL;
438 : :
439 : 29166 : co->_co_linearray_entry_size = 0;
440 : 29166 : co->_co_linearray = NULL;
441 : 29166 : memcpy(_PyCode_CODE(co), PyBytes_AS_STRING(con->code),
442 : 29166 : PyBytes_GET_SIZE(con->code));
443 : 29166 : int entry_point = 0;
444 [ + - ]: 36820 : while (entry_point < Py_SIZE(co) &&
445 [ + + ]: 36820 : _PyCode_CODE(co)[entry_point].op.code != RESUME) {
446 : 7654 : entry_point++;
447 : : }
448 : 29166 : co->_co_firsttraceable = entry_point;
449 : 29166 : _PyCode_Quicken(co);
450 : 29166 : notify_code_watchers(PY_CODE_EVENT_CREATE, co);
451 : 29166 : }
452 : :
453 : : static int
454 : 127368 : scan_varint(const uint8_t *ptr)
455 : : {
456 : 127368 : unsigned int read = *ptr++;
457 : 127368 : unsigned int val = read & 63;
458 : 127368 : unsigned int shift = 0;
459 [ + + ]: 127905 : while (read & 64) {
460 : 537 : read = *ptr++;
461 : 537 : shift += 6;
462 : 537 : val |= (read & 63) << shift;
463 : : }
464 : 127368 : return val;
465 : : }
466 : :
467 : : static int
468 : 127368 : scan_signed_varint(const uint8_t *ptr)
469 : : {
470 : 127368 : unsigned int uval = scan_varint(ptr);
471 [ + + ]: 127368 : if (uval & 1) {
472 : 3346 : return -(int)(uval >> 1);
473 : : }
474 : : else {
475 : 124022 : return uval >> 1;
476 : : }
477 : : }
478 : :
479 : : static int
480 : 1165360 : get_line_delta(const uint8_t *ptr)
481 : : {
482 : 1165360 : int code = ((*ptr) >> 3) & 15;
483 [ + + + + : 1165360 : switch (code) {
+ + ]
484 : 3355 : case PY_CODE_LOCATION_INFO_NONE:
485 : 3355 : return 0;
486 : 127368 : case PY_CODE_LOCATION_INFO_NO_COLUMNS:
487 : : case PY_CODE_LOCATION_INFO_LONG:
488 : 127368 : return scan_signed_varint(ptr+1);
489 : 63585 : case PY_CODE_LOCATION_INFO_ONE_LINE0:
490 : 63585 : return 0;
491 : 235412 : case PY_CODE_LOCATION_INFO_ONE_LINE1:
492 : 235412 : return 1;
493 : 8829 : case PY_CODE_LOCATION_INFO_ONE_LINE2:
494 : 8829 : return 2;
495 : 726811 : default:
496 : : /* Same line */
497 : 726811 : return 0;
498 : : }
499 : : }
500 : :
501 : : static PyObject *
502 : 0 : remove_column_info(PyObject *locations)
503 : : {
504 : 0 : int offset = 0;
505 : 0 : const uint8_t *data = (const uint8_t *)PyBytes_AS_STRING(locations);
506 : 0 : PyObject *res = PyBytes_FromStringAndSize(NULL, 32);
507 [ # # ]: 0 : if (res == NULL) {
508 : 0 : PyErr_NoMemory();
509 : 0 : return NULL;
510 : : }
511 : 0 : uint8_t *output = (uint8_t *)PyBytes_AS_STRING(res);
512 [ # # ]: 0 : while (offset < PyBytes_GET_SIZE(locations)) {
513 : 0 : Py_ssize_t write_offset = output - (uint8_t *)PyBytes_AS_STRING(res);
514 [ # # ]: 0 : if (write_offset + 16 >= PyBytes_GET_SIZE(res)) {
515 [ # # ]: 0 : if (_PyBytes_Resize(&res, PyBytes_GET_SIZE(res) * 2) < 0) {
516 : 0 : return NULL;
517 : : }
518 : 0 : output = (uint8_t *)PyBytes_AS_STRING(res) + write_offset;
519 : : }
520 : 0 : int code = (data[offset] >> 3) & 15;
521 [ # # ]: 0 : if (code == PY_CODE_LOCATION_INFO_NONE) {
522 : 0 : *output++ = data[offset];
523 : : }
524 : : else {
525 : 0 : int blength = (data[offset] & 7)+1;
526 : 0 : output += write_location_entry_start(
527 : : output, PY_CODE_LOCATION_INFO_NO_COLUMNS, blength);
528 : 0 : int ldelta = get_line_delta(&data[offset]);
529 : 0 : output += write_signed_varint(output, ldelta);
530 : : }
531 : 0 : offset++;
532 [ # # ]: 0 : while (offset < PyBytes_GET_SIZE(locations) &&
533 [ # # ]: 0 : (data[offset] & 128) == 0) {
534 : 0 : offset++;
535 : : }
536 : : }
537 : 0 : Py_ssize_t write_offset = output - (uint8_t *)PyBytes_AS_STRING(res);
538 [ # # ]: 0 : if (_PyBytes_Resize(&res, write_offset)) {
539 : 0 : return NULL;
540 : : }
541 : 0 : return res;
542 : : }
543 : :
544 : : /* The caller is responsible for ensuring that the given data is valid. */
545 : :
546 : : PyCodeObject *
547 : 29166 : _PyCode_New(struct _PyCodeConstructor *con)
548 : : {
549 : : /* Ensure that strings are ready Unicode string */
550 [ - + ]: 29166 : if (PyUnicode_READY(con->name) < 0) {
551 : 0 : return NULL;
552 : : }
553 [ - + ]: 29166 : if (PyUnicode_READY(con->qualname) < 0) {
554 : 0 : return NULL;
555 : : }
556 [ - + ]: 29166 : if (PyUnicode_READY(con->filename) < 0) {
557 : 0 : return NULL;
558 : : }
559 : :
560 [ - + ]: 29166 : if (intern_strings(con->names) < 0) {
561 : 0 : return NULL;
562 : : }
563 [ - + ]: 29166 : if (intern_string_constants(con->consts, NULL) < 0) {
564 : 0 : return NULL;
565 : : }
566 [ - + ]: 29166 : if (intern_strings(con->localsplusnames) < 0) {
567 : 0 : return NULL;
568 : : }
569 : :
570 : 29166 : PyObject *replacement_locations = NULL;
571 : : // Compact the linetable if we are opted out of debug
572 : : // ranges.
573 [ - + ]: 29166 : if (!_Py_GetConfig()->code_debug_ranges) {
574 : 0 : replacement_locations = remove_column_info(con->linetable);
575 [ # # ]: 0 : if (replacement_locations == NULL) {
576 : 0 : return NULL;
577 : : }
578 : 0 : con->linetable = replacement_locations;
579 : : }
580 : :
581 : 29166 : Py_ssize_t size = PyBytes_GET_SIZE(con->code) / sizeof(_Py_CODEUNIT);
582 : 29166 : PyCodeObject *co = PyObject_NewVar(PyCodeObject, &PyCode_Type, size);
583 [ - + ]: 29166 : if (co == NULL) {
584 : 0 : Py_XDECREF(replacement_locations);
585 : 0 : PyErr_NoMemory();
586 : 0 : return NULL;
587 : : }
588 : 29166 : init_code(co, con);
589 : 29166 : Py_XDECREF(replacement_locations);
590 : 29166 : return co;
591 : : }
592 : :
593 : :
594 : : /******************
595 : : * the legacy "constructors"
596 : : ******************/
597 : :
598 : : PyCodeObject *
599 : 1 : PyUnstable_Code_NewWithPosOnlyArgs(
600 : : int argcount, int posonlyargcount, int kwonlyargcount,
601 : : int nlocals, int stacksize, int flags,
602 : : PyObject *code, PyObject *consts, PyObject *names,
603 : : PyObject *varnames, PyObject *freevars, PyObject *cellvars,
604 : : PyObject *filename, PyObject *name,
605 : : PyObject *qualname, int firstlineno,
606 : : PyObject *linetable,
607 : : PyObject *exceptiontable)
608 : : {
609 : 1 : PyCodeObject *co = NULL;
610 : 1 : PyObject *localsplusnames = NULL;
611 : 1 : PyObject *localspluskinds = NULL;
612 : :
613 [ + - + - : 1 : if (varnames == NULL || !PyTuple_Check(varnames) ||
+ - ]
614 [ + - + - ]: 1 : cellvars == NULL || !PyTuple_Check(cellvars) ||
615 [ - + ]: 1 : freevars == NULL || !PyTuple_Check(freevars)
616 : : ) {
617 : 0 : PyErr_BadInternalCall();
618 : 0 : return NULL;
619 : : }
620 : :
621 : : // Set the "fast locals plus" info.
622 : 1 : int nvarnames = (int)PyTuple_GET_SIZE(varnames);
623 : 1 : int ncellvars = (int)PyTuple_GET_SIZE(cellvars);
624 : 1 : int nfreevars = (int)PyTuple_GET_SIZE(freevars);
625 : 1 : int nlocalsplus = nvarnames + ncellvars + nfreevars;
626 : 1 : localsplusnames = PyTuple_New(nlocalsplus);
627 [ - + ]: 1 : if (localsplusnames == NULL) {
628 : 0 : goto error;
629 : : }
630 : 1 : localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
631 [ - + ]: 1 : if (localspluskinds == NULL) {
632 : 0 : goto error;
633 : : }
634 : 1 : int offset = 0;
635 [ - + ]: 1 : for (int i = 0; i < nvarnames; i++, offset++) {
636 : 0 : PyObject *name = PyTuple_GET_ITEM(varnames, i);
637 : 0 : _Py_set_localsplus_info(offset, name, CO_FAST_LOCAL,
638 : : localsplusnames, localspluskinds);
639 : : }
640 [ - + ]: 1 : for (int i = 0; i < ncellvars; i++, offset++) {
641 : 0 : PyObject *name = PyTuple_GET_ITEM(cellvars, i);
642 : 0 : int argoffset = -1;
643 [ # # ]: 0 : for (int j = 0; j < nvarnames; j++) {
644 : 0 : int cmp = PyUnicode_Compare(PyTuple_GET_ITEM(varnames, j),
645 : : name);
646 : : assert(!PyErr_Occurred());
647 [ # # ]: 0 : if (cmp == 0) {
648 : 0 : argoffset = j;
649 : 0 : break;
650 : : }
651 : : }
652 [ # # ]: 0 : if (argoffset >= 0) {
653 : : // Merge the localsplus indices.
654 : 0 : nlocalsplus -= 1;
655 : 0 : offset -= 1;
656 : 0 : _PyLocals_Kind kind = _PyLocals_GetKind(localspluskinds, argoffset);
657 : 0 : _PyLocals_SetKind(localspluskinds, argoffset, kind | CO_FAST_CELL);
658 : 0 : continue;
659 : : }
660 : 0 : _Py_set_localsplus_info(offset, name, CO_FAST_CELL,
661 : : localsplusnames, localspluskinds);
662 : : }
663 [ - + ]: 1 : for (int i = 0; i < nfreevars; i++, offset++) {
664 : 0 : PyObject *name = PyTuple_GET_ITEM(freevars, i);
665 : 0 : _Py_set_localsplus_info(offset, name, CO_FAST_FREE,
666 : : localsplusnames, localspluskinds);
667 : : }
668 : : // If any cells were args then nlocalsplus will have shrunk.
669 [ - + ]: 1 : if (nlocalsplus != PyTuple_GET_SIZE(localsplusnames)) {
670 [ # # ]: 0 : if (_PyTuple_Resize(&localsplusnames, nlocalsplus) < 0
671 [ # # ]: 0 : || _PyBytes_Resize(&localspluskinds, nlocalsplus) < 0) {
672 : 0 : goto error;
673 : : }
674 : : }
675 : :
676 : 1 : struct _PyCodeConstructor con = {
677 : : .filename = filename,
678 : : .name = name,
679 : : .qualname = qualname,
680 : : .flags = flags,
681 : :
682 : : .code = code,
683 : : .firstlineno = firstlineno,
684 : : .linetable = linetable,
685 : :
686 : : .consts = consts,
687 : : .names = names,
688 : :
689 : : .localsplusnames = localsplusnames,
690 : : .localspluskinds = localspluskinds,
691 : :
692 : : .argcount = argcount,
693 : : .posonlyargcount = posonlyargcount,
694 : : .kwonlyargcount = kwonlyargcount,
695 : :
696 : : .stacksize = stacksize,
697 : :
698 : : .exceptiontable = exceptiontable,
699 : : };
700 : :
701 [ - + ]: 1 : if (_PyCode_Validate(&con) < 0) {
702 : 0 : goto error;
703 : : }
704 : : assert(PyBytes_GET_SIZE(code) % sizeof(_Py_CODEUNIT) == 0);
705 : : assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(code), sizeof(_Py_CODEUNIT)));
706 [ - + ]: 1 : if (nlocals != PyTuple_GET_SIZE(varnames)) {
707 : 0 : PyErr_SetString(PyExc_ValueError,
708 : : "code: co_nlocals != len(co_varnames)");
709 : 0 : goto error;
710 : : }
711 : :
712 : 1 : co = _PyCode_New(&con);
713 [ + - ]: 1 : if (co == NULL) {
714 : 0 : goto error;
715 : : }
716 : :
717 : 1 : error:
718 : 1 : Py_XDECREF(localsplusnames);
719 : 1 : Py_XDECREF(localspluskinds);
720 : 1 : return co;
721 : : }
722 : :
723 : : PyCodeObject *
724 : 0 : PyUnstable_Code_New(int argcount, int kwonlyargcount,
725 : : int nlocals, int stacksize, int flags,
726 : : PyObject *code, PyObject *consts, PyObject *names,
727 : : PyObject *varnames, PyObject *freevars, PyObject *cellvars,
728 : : PyObject *filename, PyObject *name, PyObject *qualname,
729 : : int firstlineno,
730 : : PyObject *linetable,
731 : : PyObject *exceptiontable)
732 : : {
733 : 0 : return PyCode_NewWithPosOnlyArgs(argcount, 0, kwonlyargcount, nlocals,
734 : : stacksize, flags, code, consts, names,
735 : : varnames, freevars, cellvars, filename,
736 : : name, qualname, firstlineno,
737 : : linetable,
738 : : exceptiontable);
739 : : }
740 : :
741 : : // NOTE: When modifying the construction of PyCode_NewEmpty, please also change
742 : : // test.test_code.CodeLocationTest.test_code_new_empty to keep it in sync!
743 : :
744 : : static const uint8_t assert0[6] = {
745 : : RESUME, 0,
746 : : LOAD_ASSERTION_ERROR, 0,
747 : : RAISE_VARARGS, 1
748 : : };
749 : :
750 : : static const uint8_t linetable[2] = {
751 : : (1 << 7) // New entry.
752 : : | (PY_CODE_LOCATION_INFO_NO_COLUMNS << 3)
753 : : | (3 - 1), // Three code units.
754 : : 0, // Offset from co_firstlineno.
755 : : };
756 : :
757 : : PyCodeObject *
758 : 0 : PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
759 : : {
760 : 0 : PyObject *nulltuple = NULL;
761 : 0 : PyObject *filename_ob = NULL;
762 : 0 : PyObject *funcname_ob = NULL;
763 : 0 : PyObject *code_ob = NULL;
764 : 0 : PyObject *linetable_ob = NULL;
765 : 0 : PyCodeObject *result = NULL;
766 : :
767 : 0 : nulltuple = PyTuple_New(0);
768 [ # # ]: 0 : if (nulltuple == NULL) {
769 : 0 : goto failed;
770 : : }
771 : 0 : funcname_ob = PyUnicode_FromString(funcname);
772 [ # # ]: 0 : if (funcname_ob == NULL) {
773 : 0 : goto failed;
774 : : }
775 : 0 : filename_ob = PyUnicode_DecodeFSDefault(filename);
776 [ # # ]: 0 : if (filename_ob == NULL) {
777 : 0 : goto failed;
778 : : }
779 : 0 : code_ob = PyBytes_FromStringAndSize((const char *)assert0, 6);
780 [ # # ]: 0 : if (code_ob == NULL) {
781 : 0 : goto failed;
782 : : }
783 : 0 : linetable_ob = PyBytes_FromStringAndSize((const char *)linetable, 2);
784 [ # # ]: 0 : if (linetable_ob == NULL) {
785 : 0 : goto failed;
786 : : }
787 : :
788 : : #define emptystring (PyObject *)&_Py_SINGLETON(bytes_empty)
789 : 0 : struct _PyCodeConstructor con = {
790 : : .filename = filename_ob,
791 : : .name = funcname_ob,
792 : : .qualname = funcname_ob,
793 : : .code = code_ob,
794 : : .firstlineno = firstlineno,
795 : : .linetable = linetable_ob,
796 : : .consts = nulltuple,
797 : : .names = nulltuple,
798 : : .localsplusnames = nulltuple,
799 : : .localspluskinds = emptystring,
800 : : .exceptiontable = emptystring,
801 : : .stacksize = 1,
802 : : };
803 : 0 : result = _PyCode_New(&con);
804 : :
805 : 0 : failed:
806 : 0 : Py_XDECREF(nulltuple);
807 : 0 : Py_XDECREF(funcname_ob);
808 : 0 : Py_XDECREF(filename_ob);
809 : 0 : Py_XDECREF(code_ob);
810 : 0 : Py_XDECREF(linetable_ob);
811 : 0 : return result;
812 : : }
813 : :
814 : :
815 : : /******************
816 : : * source location tracking (co_lines/co_positions)
817 : : ******************/
818 : :
819 : : /* Use co_linetable to compute the line number from a bytecode index, addrq. See
820 : : lnotab_notes.txt for the details of the lnotab representation.
821 : : */
822 : :
823 : : int
824 : 0 : _PyCode_CreateLineArray(PyCodeObject *co)
825 : : {
826 : : assert(co->_co_linearray == NULL);
827 : : PyCodeAddressRange bounds;
828 : : int size;
829 : 0 : int max_line = 0;
830 : 0 : _PyCode_InitAddressRange(co, &bounds);
831 [ # # ]: 0 : while(_PyLineTable_NextAddressRange(&bounds)) {
832 [ # # ]: 0 : if (bounds.ar_line > max_line) {
833 : 0 : max_line = bounds.ar_line;
834 : : }
835 : : }
836 [ # # ]: 0 : if (max_line < (1 << 15)) {
837 : 0 : size = 2;
838 : : }
839 : : else {
840 : 0 : size = 4;
841 : : }
842 : 0 : co->_co_linearray = PyMem_Malloc(Py_SIZE(co)*size);
843 [ # # ]: 0 : if (co->_co_linearray == NULL) {
844 : 0 : PyErr_NoMemory();
845 : 0 : return -1;
846 : : }
847 : 0 : co->_co_linearray_entry_size = size;
848 : 0 : _PyCode_InitAddressRange(co, &bounds);
849 [ # # ]: 0 : while(_PyLineTable_NextAddressRange(&bounds)) {
850 : 0 : int start = bounds.ar_start / sizeof(_Py_CODEUNIT);
851 : 0 : int end = bounds.ar_end / sizeof(_Py_CODEUNIT);
852 [ # # ]: 0 : for (int index = start; index < end; index++) {
853 : : assert(index < (int)Py_SIZE(co));
854 [ # # ]: 0 : if (size == 2) {
855 : : assert(((int16_t)bounds.ar_line) == bounds.ar_line);
856 : 0 : ((int16_t *)co->_co_linearray)[index] = bounds.ar_line;
857 : : }
858 : : else {
859 : : assert(size == 4);
860 : 0 : ((int32_t *)co->_co_linearray)[index] = bounds.ar_line;
861 : : }
862 : : }
863 : : }
864 : 0 : return 0;
865 : : }
866 : :
867 : : int
868 : 105273 : PyCode_Addr2Line(PyCodeObject *co, int addrq)
869 : : {
870 [ - + ]: 105273 : if (addrq < 0) {
871 : 0 : return co->co_firstlineno;
872 : : }
873 : : assert(addrq >= 0 && addrq < _PyCode_NBYTES(co));
874 [ - + ]: 105273 : if (co->_co_linearray) {
875 : 0 : return _PyCode_LineNumberFromArray(co, addrq / sizeof(_Py_CODEUNIT));
876 : : }
877 : : PyCodeAddressRange bounds;
878 : 105273 : _PyCode_InitAddressRange(co, &bounds);
879 : 105273 : return _PyCode_CheckLineNumber(addrq, &bounds);
880 : : }
881 : :
882 : : void
883 : 105291 : _PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range)
884 : : {
885 : 105291 : range->opaque.lo_next = (const uint8_t *)linetable;
886 : 105291 : range->opaque.limit = range->opaque.lo_next + length;
887 : 105291 : range->ar_start = -1;
888 : 105291 : range->ar_end = 0;
889 : 105291 : range->opaque.computed_line = firstlineno;
890 : 105291 : range->ar_line = -1;
891 : 105291 : }
892 : :
893 : : int
894 : 105291 : _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds)
895 : : {
896 : : assert(co->co_linetable != NULL);
897 : 105291 : const char *linetable = PyBytes_AS_STRING(co->co_linetable);
898 : 105291 : Py_ssize_t length = PyBytes_GET_SIZE(co->co_linetable);
899 : 105291 : _PyLineTable_InitAddressRange(linetable, length, co->co_firstlineno, bounds);
900 : 105291 : return bounds->ar_line;
901 : : }
902 : :
903 : : /* Update *bounds to describe the first and one-past-the-last instructions in
904 : : the same line as lasti. Return the number of that line, or -1 if lasti is out of bounds. */
905 : : int
906 : 105273 : _PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds)
907 : : {
908 [ + + ]: 1270633 : while (bounds->ar_end <= lasti) {
909 [ - + ]: 1165360 : if (!_PyLineTable_NextAddressRange(bounds)) {
910 : 0 : return -1;
911 : : }
912 : : }
913 [ - + ]: 105273 : while (bounds->ar_start > lasti) {
914 [ # # ]: 0 : if (!_PyLineTable_PreviousAddressRange(bounds)) {
915 : 0 : return -1;
916 : : }
917 : : }
918 : 105273 : return bounds->ar_line;
919 : : }
920 : :
921 : : static int
922 : 1165360 : is_no_line_marker(uint8_t b)
923 : : {
924 : 1165360 : return (b >> 3) == 0x1f;
925 : : }
926 : :
927 : :
928 : : #define ASSERT_VALID_BOUNDS(bounds) \
929 : : assert(bounds->opaque.lo_next <= bounds->opaque.limit && \
930 : : (bounds->ar_line == -1 || bounds->ar_line == bounds->opaque.computed_line) && \
931 : : (bounds->opaque.lo_next == bounds->opaque.limit || \
932 : : (*bounds->opaque.lo_next) & 128))
933 : :
934 : : static int
935 : 1165360 : next_code_delta(PyCodeAddressRange *bounds)
936 : : {
937 : : assert((*bounds->opaque.lo_next) & 128);
938 : 1165360 : return (((*bounds->opaque.lo_next) & 7) + 1) * sizeof(_Py_CODEUNIT);
939 : : }
940 : :
941 : : static int
942 : 0 : previous_code_delta(PyCodeAddressRange *bounds)
943 : : {
944 [ # # ]: 0 : if (bounds->ar_start == 0) {
945 : : // If we looking at the first entry, the
946 : : // "previous" entry has an implicit length of 1.
947 : 0 : return 1;
948 : : }
949 : 0 : const uint8_t *ptr = bounds->opaque.lo_next-1;
950 [ # # ]: 0 : while (((*ptr) & 128) == 0) {
951 : 0 : ptr--;
952 : : }
953 : 0 : return (((*ptr) & 7) + 1) * sizeof(_Py_CODEUNIT);
954 : : }
955 : :
956 : : static int
957 : 3015 : read_byte(PyCodeAddressRange *bounds)
958 : : {
959 : 3015 : return *bounds->opaque.lo_next++;
960 : : }
961 : :
962 : : static int
963 : 612 : read_varint(PyCodeAddressRange *bounds)
964 : : {
965 : 612 : unsigned int read = read_byte(bounds);
966 : 612 : unsigned int val = read & 63;
967 : 612 : unsigned int shift = 0;
968 [ + + ]: 621 : while (read & 64) {
969 : 9 : read = read_byte(bounds);
970 : 9 : shift += 6;
971 : 9 : val |= (read & 63) << shift;
972 : : }
973 : 612 : return val;
974 : : }
975 : :
976 : : static int
977 : 153 : read_signed_varint(PyCodeAddressRange *bounds)
978 : : {
979 : 153 : unsigned int uval = read_varint(bounds);
980 [ + + ]: 153 : if (uval & 1) {
981 : 45 : return -(int)(uval >> 1);
982 : : }
983 : : else {
984 : 108 : return uval >> 1;
985 : : }
986 : : }
987 : :
988 : : static void
989 : 0 : retreat(PyCodeAddressRange *bounds)
990 : : {
991 : : ASSERT_VALID_BOUNDS(bounds);
992 : : assert(bounds->ar_start >= 0);
993 : : do {
994 : 0 : bounds->opaque.lo_next--;
995 [ # # ]: 0 : } while (((*bounds->opaque.lo_next) & 128) == 0);
996 : 0 : bounds->opaque.computed_line -= get_line_delta(bounds->opaque.lo_next);
997 : 0 : bounds->ar_end = bounds->ar_start;
998 : 0 : bounds->ar_start -= previous_code_delta(bounds);
999 [ # # ]: 0 : if (is_no_line_marker(bounds->opaque.lo_next[-1])) {
1000 : 0 : bounds->ar_line = -1;
1001 : : }
1002 : : else {
1003 : 0 : bounds->ar_line = bounds->opaque.computed_line;
1004 : : }
1005 : : ASSERT_VALID_BOUNDS(bounds);
1006 : 0 : }
1007 : :
1008 : : static void
1009 : 1165360 : advance(PyCodeAddressRange *bounds)
1010 : : {
1011 : : ASSERT_VALID_BOUNDS(bounds);
1012 : 1165360 : bounds->opaque.computed_line += get_line_delta(bounds->opaque.lo_next);
1013 [ + + ]: 1165360 : if (is_no_line_marker(*bounds->opaque.lo_next)) {
1014 : 3355 : bounds->ar_line = -1;
1015 : : }
1016 : : else {
1017 : 1162005 : bounds->ar_line = bounds->opaque.computed_line;
1018 : : }
1019 : 1165360 : bounds->ar_start = bounds->ar_end;
1020 : 1165360 : bounds->ar_end += next_code_delta(bounds);
1021 : : do {
1022 : 3013894 : bounds->opaque.lo_next++;
1023 : 6027747 : } while (bounds->opaque.lo_next < bounds->opaque.limit &&
1024 [ + + + + ]: 3013894 : ((*bounds->opaque.lo_next) & 128) == 0);
1025 : : ASSERT_VALID_BOUNDS(bounds);
1026 : 1165360 : }
1027 : :
1028 : : static void
1029 : 1053 : advance_with_locations(PyCodeAddressRange *bounds, int *endline, int *column, int *endcolumn)
1030 : : {
1031 : : ASSERT_VALID_BOUNDS(bounds);
1032 : 1053 : int first_byte = read_byte(bounds);
1033 : 1053 : int code = (first_byte >> 3) & 15;
1034 : 1053 : bounds->ar_start = bounds->ar_end;
1035 : 1053 : bounds->ar_end = bounds->ar_start + ((first_byte & 7) + 1) * sizeof(_Py_CODEUNIT);
1036 [ - + - + : 1053 : switch(code) {
+ ]
1037 : 0 : case PY_CODE_LOCATION_INFO_NONE:
1038 : 0 : bounds->ar_line = *endline = -1;
1039 : 0 : *column = *endcolumn = -1;
1040 : 0 : break;
1041 : 153 : case PY_CODE_LOCATION_INFO_LONG:
1042 : : {
1043 : 153 : bounds->opaque.computed_line += read_signed_varint(bounds);
1044 : 153 : bounds->ar_line = bounds->opaque.computed_line;
1045 : 153 : *endline = bounds->ar_line + read_varint(bounds);
1046 : 153 : *column = read_varint(bounds)-1;
1047 : 153 : *endcolumn = read_varint(bounds)-1;
1048 : 153 : break;
1049 : : }
1050 : 0 : case PY_CODE_LOCATION_INFO_NO_COLUMNS:
1051 : : {
1052 : : /* No column */
1053 : 0 : bounds->opaque.computed_line += read_signed_varint(bounds);
1054 : 0 : *endline = bounds->ar_line = bounds->opaque.computed_line;
1055 : 0 : *column = *endcolumn = -1;
1056 : 0 : break;
1057 : : }
1058 : 441 : case PY_CODE_LOCATION_INFO_ONE_LINE0:
1059 : : case PY_CODE_LOCATION_INFO_ONE_LINE1:
1060 : : case PY_CODE_LOCATION_INFO_ONE_LINE2:
1061 : : {
1062 : : /* one line form */
1063 : 441 : int line_delta = code - 10;
1064 : 441 : bounds->opaque.computed_line += line_delta;
1065 : 441 : *endline = bounds->ar_line = bounds->opaque.computed_line;
1066 : 441 : *column = read_byte(bounds);
1067 : 441 : *endcolumn = read_byte(bounds);
1068 : 441 : break;
1069 : : }
1070 : 459 : default:
1071 : : {
1072 : : /* Short forms */
1073 : 459 : int second_byte = read_byte(bounds);
1074 : : assert((second_byte & 128) == 0);
1075 : 459 : *endline = bounds->ar_line = bounds->opaque.computed_line;
1076 : 459 : *column = code << 3 | (second_byte >> 4);
1077 : 459 : *endcolumn = *column + (second_byte & 15);
1078 : : }
1079 : : }
1080 : : ASSERT_VALID_BOUNDS(bounds);
1081 : 1053 : }
1082 : : int
1083 : 0 : PyCode_Addr2Location(PyCodeObject *co, int addrq,
1084 : : int *start_line, int *start_column,
1085 : : int *end_line, int *end_column)
1086 : : {
1087 [ # # ]: 0 : if (addrq < 0) {
1088 : 0 : *start_line = *end_line = co->co_firstlineno;
1089 : 0 : *start_column = *end_column = 0;
1090 : 0 : return 1;
1091 : : }
1092 : : assert(addrq >= 0 && addrq < _PyCode_NBYTES(co));
1093 : : PyCodeAddressRange bounds;
1094 : 0 : _PyCode_InitAddressRange(co, &bounds);
1095 : 0 : _PyCode_CheckLineNumber(addrq, &bounds);
1096 : 0 : retreat(&bounds);
1097 : 0 : advance_with_locations(&bounds, end_line, start_column, end_column);
1098 : 0 : *start_line = bounds.ar_line;
1099 : 0 : return 1;
1100 : : }
1101 : :
1102 : :
1103 : : static inline int
1104 : 1166413 : at_end(PyCodeAddressRange *bounds) {
1105 : 1166413 : return bounds->opaque.lo_next >= bounds->opaque.limit;
1106 : : }
1107 : :
1108 : : int
1109 : 0 : _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range)
1110 : : {
1111 [ # # ]: 0 : if (range->ar_start <= 0) {
1112 : 0 : return 0;
1113 : : }
1114 : 0 : retreat(range);
1115 : : assert(range->ar_end > range->ar_start);
1116 : 0 : return 1;
1117 : : }
1118 : :
1119 : : int
1120 : 1165360 : _PyLineTable_NextAddressRange(PyCodeAddressRange *range)
1121 : : {
1122 [ - + ]: 1165360 : if (at_end(range)) {
1123 : 0 : return 0;
1124 : : }
1125 : 1165360 : advance(range);
1126 : : assert(range->ar_end > range->ar_start);
1127 : 1165360 : return 1;
1128 : : }
1129 : :
1130 : : static int
1131 : 0 : emit_pair(PyObject **bytes, int *offset, int a, int b)
1132 : : {
1133 : 0 : Py_ssize_t len = PyBytes_GET_SIZE(*bytes);
1134 [ # # ]: 0 : if (*offset + 2 >= len) {
1135 [ # # ]: 0 : if (_PyBytes_Resize(bytes, len * 2) < 0)
1136 : 0 : return 0;
1137 : : }
1138 : 0 : unsigned char *lnotab = (unsigned char *) PyBytes_AS_STRING(*bytes);
1139 : 0 : lnotab += *offset;
1140 : 0 : *lnotab++ = a;
1141 : 0 : *lnotab++ = b;
1142 : 0 : *offset += 2;
1143 : 0 : return 1;
1144 : : }
1145 : :
1146 : : static int
1147 : 0 : emit_delta(PyObject **bytes, int bdelta, int ldelta, int *offset)
1148 : : {
1149 [ # # ]: 0 : while (bdelta > 255) {
1150 [ # # ]: 0 : if (!emit_pair(bytes, offset, 255, 0)) {
1151 : 0 : return 0;
1152 : : }
1153 : 0 : bdelta -= 255;
1154 : : }
1155 [ # # ]: 0 : while (ldelta > 127) {
1156 [ # # ]: 0 : if (!emit_pair(bytes, offset, bdelta, 127)) {
1157 : 0 : return 0;
1158 : : }
1159 : 0 : bdelta = 0;
1160 : 0 : ldelta -= 127;
1161 : : }
1162 [ # # ]: 0 : while (ldelta < -128) {
1163 [ # # ]: 0 : if (!emit_pair(bytes, offset, bdelta, -128)) {
1164 : 0 : return 0;
1165 : : }
1166 : 0 : bdelta = 0;
1167 : 0 : ldelta += 128;
1168 : : }
1169 : 0 : return emit_pair(bytes, offset, bdelta, ldelta);
1170 : : }
1171 : :
1172 : : static PyObject *
1173 : 0 : decode_linetable(PyCodeObject *code)
1174 : : {
1175 : : PyCodeAddressRange bounds;
1176 : : PyObject *bytes;
1177 : 0 : int table_offset = 0;
1178 : 0 : int code_offset = 0;
1179 : 0 : int line = code->co_firstlineno;
1180 : 0 : bytes = PyBytes_FromStringAndSize(NULL, 64);
1181 [ # # ]: 0 : if (bytes == NULL) {
1182 : 0 : return NULL;
1183 : : }
1184 : 0 : _PyCode_InitAddressRange(code, &bounds);
1185 [ # # ]: 0 : while (_PyLineTable_NextAddressRange(&bounds)) {
1186 [ # # ]: 0 : if (bounds.opaque.computed_line != line) {
1187 : 0 : int bdelta = bounds.ar_start - code_offset;
1188 : 0 : int ldelta = bounds.opaque.computed_line - line;
1189 [ # # ]: 0 : if (!emit_delta(&bytes, bdelta, ldelta, &table_offset)) {
1190 : 0 : Py_DECREF(bytes);
1191 : 0 : return NULL;
1192 : : }
1193 : 0 : code_offset = bounds.ar_start;
1194 : 0 : line = bounds.opaque.computed_line;
1195 : : }
1196 : : }
1197 : 0 : _PyBytes_Resize(&bytes, table_offset);
1198 : 0 : return bytes;
1199 : : }
1200 : :
1201 : :
1202 : : typedef struct {
1203 : : PyObject_HEAD
1204 : : PyCodeObject *li_code;
1205 : : PyCodeAddressRange li_line;
1206 : : } lineiterator;
1207 : :
1208 : :
1209 : : static void
1210 : 0 : lineiter_dealloc(lineiterator *li)
1211 : : {
1212 : 0 : Py_DECREF(li->li_code);
1213 : 0 : Py_TYPE(li)->tp_free(li);
1214 : 0 : }
1215 : :
1216 : : static PyObject *
1217 : 11516 : _source_offset_converter(int *value) {
1218 [ - + ]: 11516 : if (*value == -1) {
1219 : 0 : Py_RETURN_NONE;
1220 : : }
1221 : 11516 : return PyLong_FromLong(*value);
1222 : : }
1223 : :
1224 : : static PyObject *
1225 : 0 : lineiter_next(lineiterator *li)
1226 : : {
1227 : 0 : PyCodeAddressRange *bounds = &li->li_line;
1228 [ # # ]: 0 : if (!_PyLineTable_NextAddressRange(bounds)) {
1229 : 0 : return NULL;
1230 : : }
1231 : 0 : int start = bounds->ar_start;
1232 : 0 : int line = bounds->ar_line;
1233 : : // Merge overlapping entries:
1234 [ # # ]: 0 : while (_PyLineTable_NextAddressRange(bounds)) {
1235 [ # # ]: 0 : if (bounds->ar_line != line) {
1236 : 0 : _PyLineTable_PreviousAddressRange(bounds);
1237 : 0 : break;
1238 : : }
1239 : : }
1240 : 0 : return Py_BuildValue("iiO&", start, bounds->ar_end,
1241 : : _source_offset_converter, &line);
1242 : : }
1243 : :
1244 : : PyTypeObject _PyLineIterator = {
1245 : : PyVarObject_HEAD_INIT(&PyType_Type, 0)
1246 : : "line_iterator", /* tp_name */
1247 : : sizeof(lineiterator), /* tp_basicsize */
1248 : : 0, /* tp_itemsize */
1249 : : /* methods */
1250 : : (destructor)lineiter_dealloc, /* tp_dealloc */
1251 : : 0, /* tp_vectorcall_offset */
1252 : : 0, /* tp_getattr */
1253 : : 0, /* tp_setattr */
1254 : : 0, /* tp_as_async */
1255 : : 0, /* tp_repr */
1256 : : 0, /* tp_as_number */
1257 : : 0, /* tp_as_sequence */
1258 : : 0, /* tp_as_mapping */
1259 : : 0, /* tp_hash */
1260 : : 0, /* tp_call */
1261 : : 0, /* tp_str */
1262 : : 0, /* tp_getattro */
1263 : : 0, /* tp_setattro */
1264 : : 0, /* tp_as_buffer */
1265 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1266 : : 0, /* tp_doc */
1267 : : 0, /* tp_traverse */
1268 : : 0, /* tp_clear */
1269 : : 0, /* tp_richcompare */
1270 : : 0, /* tp_weaklistoffset */
1271 : : PyObject_SelfIter, /* tp_iter */
1272 : : (iternextfunc)lineiter_next, /* tp_iternext */
1273 : : 0, /* tp_methods */
1274 : : 0, /* tp_members */
1275 : : 0, /* tp_getset */
1276 : : 0, /* tp_base */
1277 : : 0, /* tp_dict */
1278 : : 0, /* tp_descr_get */
1279 : : 0, /* tp_descr_set */
1280 : : 0, /* tp_dictoffset */
1281 : : 0, /* tp_init */
1282 : : 0, /* tp_alloc */
1283 : : 0, /* tp_new */
1284 : : PyObject_Del, /* tp_free */
1285 : : };
1286 : :
1287 : : static lineiterator *
1288 : 0 : new_linesiterator(PyCodeObject *code)
1289 : : {
1290 : 0 : lineiterator *li = (lineiterator *)PyType_GenericAlloc(&_PyLineIterator, 0);
1291 [ # # ]: 0 : if (li == NULL) {
1292 : 0 : return NULL;
1293 : : }
1294 : 0 : li->li_code = (PyCodeObject*)Py_NewRef(code);
1295 : 0 : _PyCode_InitAddressRange(code, &li->li_line);
1296 : 0 : return li;
1297 : : }
1298 : :
1299 : : /* co_positions iterator object. */
1300 : : typedef struct {
1301 : : PyObject_HEAD
1302 : : PyCodeObject* pi_code;
1303 : : PyCodeAddressRange pi_range;
1304 : : int pi_offset;
1305 : : int pi_endline;
1306 : : int pi_column;
1307 : : int pi_endcolumn;
1308 : : } positionsiterator;
1309 : :
1310 : : static void
1311 : 18 : positionsiter_dealloc(positionsiterator* pi)
1312 : : {
1313 : 18 : Py_DECREF(pi->pi_code);
1314 : 18 : Py_TYPE(pi)->tp_free(pi);
1315 : 18 : }
1316 : :
1317 : : static PyObject*
1318 : 2879 : positionsiter_next(positionsiterator* pi)
1319 : : {
1320 [ + + ]: 2879 : if (pi->pi_offset >= pi->pi_range.ar_end) {
1321 : : assert(pi->pi_offset == pi->pi_range.ar_end);
1322 [ - + ]: 1053 : if (at_end(&pi->pi_range)) {
1323 : 0 : return NULL;
1324 : : }
1325 : 1053 : advance_with_locations(&pi->pi_range, &pi->pi_endline, &pi->pi_column, &pi->pi_endcolumn);
1326 : : }
1327 : 2879 : pi->pi_offset += 2;
1328 : 2879 : return Py_BuildValue("(O&O&O&O&)",
1329 : : _source_offset_converter, &pi->pi_range.ar_line,
1330 : : _source_offset_converter, &pi->pi_endline,
1331 : : _source_offset_converter, &pi->pi_column,
1332 : : _source_offset_converter, &pi->pi_endcolumn);
1333 : : }
1334 : :
1335 : : PyTypeObject _PyPositionsIterator = {
1336 : : PyVarObject_HEAD_INIT(&PyType_Type, 0)
1337 : : "positions_iterator", /* tp_name */
1338 : : sizeof(positionsiterator), /* tp_basicsize */
1339 : : 0, /* tp_itemsize */
1340 : : /* methods */
1341 : : (destructor)positionsiter_dealloc, /* tp_dealloc */
1342 : : 0, /* tp_vectorcall_offset */
1343 : : 0, /* tp_getattr */
1344 : : 0, /* tp_setattr */
1345 : : 0, /* tp_as_async */
1346 : : 0, /* tp_repr */
1347 : : 0, /* tp_as_number */
1348 : : 0, /* tp_as_sequence */
1349 : : 0, /* tp_as_mapping */
1350 : : 0, /* tp_hash */
1351 : : 0, /* tp_call */
1352 : : 0, /* tp_str */
1353 : : 0, /* tp_getattro */
1354 : : 0, /* tp_setattro */
1355 : : 0, /* tp_as_buffer */
1356 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1357 : : 0, /* tp_doc */
1358 : : 0, /* tp_traverse */
1359 : : 0, /* tp_clear */
1360 : : 0, /* tp_richcompare */
1361 : : 0, /* tp_weaklistoffset */
1362 : : PyObject_SelfIter, /* tp_iter */
1363 : : (iternextfunc)positionsiter_next, /* tp_iternext */
1364 : : 0, /* tp_methods */
1365 : : 0, /* tp_members */
1366 : : 0, /* tp_getset */
1367 : : 0, /* tp_base */
1368 : : 0, /* tp_dict */
1369 : : 0, /* tp_descr_get */
1370 : : 0, /* tp_descr_set */
1371 : : 0, /* tp_dictoffset */
1372 : : 0, /* tp_init */
1373 : : 0, /* tp_alloc */
1374 : : 0, /* tp_new */
1375 : : PyObject_Del, /* tp_free */
1376 : : };
1377 : :
1378 : : static PyObject*
1379 : 18 : code_positionsiterator(PyCodeObject* code, PyObject* Py_UNUSED(args))
1380 : : {
1381 : 18 : positionsiterator* pi = (positionsiterator*)PyType_GenericAlloc(&_PyPositionsIterator, 0);
1382 [ - + ]: 18 : if (pi == NULL) {
1383 : 0 : return NULL;
1384 : : }
1385 : 18 : pi->pi_code = (PyCodeObject*)Py_NewRef(code);
1386 : 18 : _PyCode_InitAddressRange(code, &pi->pi_range);
1387 : 18 : pi->pi_offset = pi->pi_range.ar_end;
1388 : 18 : return (PyObject*)pi;
1389 : : }
1390 : :
1391 : :
1392 : : /******************
1393 : : * "extra" frame eval info (see PEP 523)
1394 : : ******************/
1395 : :
1396 : : /* Holder for co_extra information */
1397 : : typedef struct {
1398 : : Py_ssize_t ce_size;
1399 : : void *ce_extras[1];
1400 : : } _PyCodeObjectExtra;
1401 : :
1402 : :
1403 : : int
1404 : 0 : PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
1405 : : {
1406 [ # # ]: 0 : if (!PyCode_Check(code)) {
1407 : 0 : PyErr_BadInternalCall();
1408 : 0 : return -1;
1409 : : }
1410 : :
1411 : 0 : PyCodeObject *o = (PyCodeObject*) code;
1412 : 0 : _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra;
1413 : :
1414 [ # # # # : 0 : if (co_extra == NULL || index < 0 || co_extra->ce_size <= index) {
# # ]
1415 : 0 : *extra = NULL;
1416 : 0 : return 0;
1417 : : }
1418 : :
1419 : 0 : *extra = co_extra->ce_extras[index];
1420 : 0 : return 0;
1421 : : }
1422 : :
1423 : :
1424 : : int
1425 : 0 : PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
1426 : : {
1427 : 0 : PyInterpreterState *interp = _PyInterpreterState_GET();
1428 : :
1429 [ # # # # ]: 0 : if (!PyCode_Check(code) || index < 0 ||
1430 [ # # ]: 0 : index >= interp->co_extra_user_count) {
1431 : 0 : PyErr_BadInternalCall();
1432 : 0 : return -1;
1433 : : }
1434 : :
1435 : 0 : PyCodeObject *o = (PyCodeObject*) code;
1436 : 0 : _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra *) o->co_extra;
1437 : :
1438 [ # # # # ]: 0 : if (co_extra == NULL || co_extra->ce_size <= index) {
1439 [ # # ]: 0 : Py_ssize_t i = (co_extra == NULL ? 0 : co_extra->ce_size);
1440 : 0 : co_extra = PyMem_Realloc(
1441 : : co_extra,
1442 : 0 : sizeof(_PyCodeObjectExtra) +
1443 : 0 : (interp->co_extra_user_count-1) * sizeof(void*));
1444 [ # # ]: 0 : if (co_extra == NULL) {
1445 : 0 : return -1;
1446 : : }
1447 [ # # ]: 0 : for (; i < interp->co_extra_user_count; i++) {
1448 : 0 : co_extra->ce_extras[i] = NULL;
1449 : : }
1450 : 0 : co_extra->ce_size = interp->co_extra_user_count;
1451 : 0 : o->co_extra = co_extra;
1452 : : }
1453 : :
1454 [ # # ]: 0 : if (co_extra->ce_extras[index] != NULL) {
1455 : 0 : freefunc free = interp->co_extra_freefuncs[index];
1456 [ # # ]: 0 : if (free != NULL) {
1457 : 0 : free(co_extra->ce_extras[index]);
1458 : : }
1459 : : }
1460 : :
1461 : 0 : co_extra->ce_extras[index] = extra;
1462 : 0 : return 0;
1463 : : }
1464 : :
1465 : :
1466 : : /******************
1467 : : * other PyCodeObject accessor functions
1468 : : ******************/
1469 : :
1470 : : static PyObject *
1471 : 0 : get_cached_locals(PyCodeObject *co, PyObject **cached_field,
1472 : : _PyLocals_Kind kind, int num)
1473 : : {
1474 : : assert(cached_field != NULL);
1475 : : assert(co->_co_cached != NULL);
1476 [ # # ]: 0 : if (*cached_field != NULL) {
1477 : 0 : return Py_NewRef(*cached_field);
1478 : : }
1479 : : assert(*cached_field == NULL);
1480 : 0 : PyObject *varnames = get_localsplus_names(co, kind, num);
1481 [ # # ]: 0 : if (varnames == NULL) {
1482 : 0 : return NULL;
1483 : : }
1484 : 0 : *cached_field = Py_NewRef(varnames);
1485 : 0 : return varnames;
1486 : : }
1487 : :
1488 : : PyObject *
1489 : 0 : _PyCode_GetVarnames(PyCodeObject *co)
1490 : : {
1491 [ # # ]: 0 : if (init_co_cached(co)) {
1492 : 0 : return NULL;
1493 : : }
1494 : 0 : return get_cached_locals(co, &co->_co_cached->_co_varnames, CO_FAST_LOCAL, co->co_nlocals);
1495 : : }
1496 : :
1497 : : PyObject *
1498 : 0 : PyCode_GetVarnames(PyCodeObject *code)
1499 : : {
1500 : 0 : return _PyCode_GetVarnames(code);
1501 : : }
1502 : :
1503 : : PyObject *
1504 : 0 : _PyCode_GetCellvars(PyCodeObject *co)
1505 : : {
1506 [ # # ]: 0 : if (init_co_cached(co)) {
1507 : 0 : return NULL;
1508 : : }
1509 : 0 : return get_cached_locals(co, &co->_co_cached->_co_cellvars, CO_FAST_CELL, co->co_ncellvars);
1510 : : }
1511 : :
1512 : : PyObject *
1513 : 0 : PyCode_GetCellvars(PyCodeObject *code)
1514 : : {
1515 : 0 : return _PyCode_GetCellvars(code);
1516 : : }
1517 : :
1518 : : PyObject *
1519 : 0 : _PyCode_GetFreevars(PyCodeObject *co)
1520 : : {
1521 [ # # ]: 0 : if (init_co_cached(co)) {
1522 : 0 : return NULL;
1523 : : }
1524 : 0 : return get_cached_locals(co, &co->_co_cached->_co_freevars, CO_FAST_FREE, co->co_nfreevars);
1525 : : }
1526 : :
1527 : : PyObject *
1528 : 0 : PyCode_GetFreevars(PyCodeObject *code)
1529 : : {
1530 : 0 : return _PyCode_GetFreevars(code);
1531 : : }
1532 : :
1533 : : static void
1534 : 10734 : deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len)
1535 : : {
1536 [ + + ]: 459509 : for (int i = 0; i < len; i++) {
1537 : 448775 : _Py_CODEUNIT instruction = instructions[i];
1538 : 448775 : int opcode = _PyOpcode_Deopt[instruction.op.code];
1539 : 448775 : int caches = _PyOpcode_Caches[opcode];
1540 : 448775 : instructions[i].op.code = opcode;
1541 [ + + ]: 1051516 : while (caches--) {
1542 : 602741 : instructions[++i].op.code = CACHE;
1543 : 602741 : instructions[i].op.arg = 0;
1544 : : }
1545 : : }
1546 : 10734 : }
1547 : :
1548 : : PyObject *
1549 : 7647 : _PyCode_GetCode(PyCodeObject *co)
1550 : : {
1551 [ - + ]: 7647 : if (init_co_cached(co)) {
1552 : 0 : return NULL;
1553 : : }
1554 [ + + ]: 7647 : if (co->_co_cached->_co_code != NULL) {
1555 : 1 : return Py_NewRef(co->_co_cached->_co_code);
1556 : : }
1557 : 7646 : PyObject *code = PyBytes_FromStringAndSize((const char *)_PyCode_CODE(co),
1558 : 7646 : _PyCode_NBYTES(co));
1559 [ - + ]: 7646 : if (code == NULL) {
1560 : 0 : return NULL;
1561 : : }
1562 : 7646 : deopt_code((_Py_CODEUNIT *)PyBytes_AS_STRING(code), Py_SIZE(co));
1563 : : assert(co->_co_cached->_co_code == NULL);
1564 : 7646 : co->_co_cached->_co_code = Py_NewRef(code);
1565 : 7646 : return code;
1566 : : }
1567 : :
1568 : : PyObject *
1569 : 0 : PyCode_GetCode(PyCodeObject *co)
1570 : : {
1571 : 0 : return _PyCode_GetCode(co);
1572 : : }
1573 : :
1574 : : /******************
1575 : : * PyCode_Type
1576 : : ******************/
1577 : :
1578 : : /*[clinic input]
1579 : : class code "PyCodeObject *" "&PyCode_Type"
1580 : : [clinic start generated code]*/
1581 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=78aa5d576683bb4b]*/
1582 : :
1583 : : /*[clinic input]
1584 : : @classmethod
1585 : : code.__new__ as code_new
1586 : :
1587 : : argcount: int
1588 : : posonlyargcount: int
1589 : : kwonlyargcount: int
1590 : : nlocals: int
1591 : : stacksize: int
1592 : : flags: int
1593 : : codestring as code: object(subclass_of="&PyBytes_Type")
1594 : : constants as consts: object(subclass_of="&PyTuple_Type")
1595 : : names: object(subclass_of="&PyTuple_Type")
1596 : : varnames: object(subclass_of="&PyTuple_Type")
1597 : : filename: unicode
1598 : : name: unicode
1599 : : qualname: unicode
1600 : : firstlineno: int
1601 : : linetable: object(subclass_of="&PyBytes_Type")
1602 : : exceptiontable: object(subclass_of="&PyBytes_Type")
1603 : : freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = ()
1604 : : cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = ()
1605 : : /
1606 : :
1607 : : Create a code object. Not for the faint of heart.
1608 : : [clinic start generated code]*/
1609 : :
1610 : : static PyObject *
1611 : 0 : code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount,
1612 : : int kwonlyargcount, int nlocals, int stacksize, int flags,
1613 : : PyObject *code, PyObject *consts, PyObject *names,
1614 : : PyObject *varnames, PyObject *filename, PyObject *name,
1615 : : PyObject *qualname, int firstlineno, PyObject *linetable,
1616 : : PyObject *exceptiontable, PyObject *freevars,
1617 : : PyObject *cellvars)
1618 : : /*[clinic end generated code: output=069fa20d299f9dda input=e31da3c41ad8064a]*/
1619 : : {
1620 : 0 : PyObject *co = NULL;
1621 : 0 : PyObject *ournames = NULL;
1622 : 0 : PyObject *ourvarnames = NULL;
1623 : 0 : PyObject *ourfreevars = NULL;
1624 : 0 : PyObject *ourcellvars = NULL;
1625 : :
1626 [ # # ]: 0 : if (PySys_Audit("code.__new__", "OOOiiiiii",
1627 : : code, filename, name, argcount, posonlyargcount,
1628 : : kwonlyargcount, nlocals, stacksize, flags) < 0) {
1629 : 0 : goto cleanup;
1630 : : }
1631 : :
1632 [ # # ]: 0 : if (argcount < 0) {
1633 : 0 : PyErr_SetString(
1634 : : PyExc_ValueError,
1635 : : "code: argcount must not be negative");
1636 : 0 : goto cleanup;
1637 : : }
1638 : :
1639 [ # # ]: 0 : if (posonlyargcount < 0) {
1640 : 0 : PyErr_SetString(
1641 : : PyExc_ValueError,
1642 : : "code: posonlyargcount must not be negative");
1643 : 0 : goto cleanup;
1644 : : }
1645 : :
1646 [ # # ]: 0 : if (kwonlyargcount < 0) {
1647 : 0 : PyErr_SetString(
1648 : : PyExc_ValueError,
1649 : : "code: kwonlyargcount must not be negative");
1650 : 0 : goto cleanup;
1651 : : }
1652 [ # # ]: 0 : if (nlocals < 0) {
1653 : 0 : PyErr_SetString(
1654 : : PyExc_ValueError,
1655 : : "code: nlocals must not be negative");
1656 : 0 : goto cleanup;
1657 : : }
1658 : :
1659 : 0 : ournames = validate_and_copy_tuple(names);
1660 [ # # ]: 0 : if (ournames == NULL)
1661 : 0 : goto cleanup;
1662 : 0 : ourvarnames = validate_and_copy_tuple(varnames);
1663 [ # # ]: 0 : if (ourvarnames == NULL)
1664 : 0 : goto cleanup;
1665 [ # # ]: 0 : if (freevars)
1666 : 0 : ourfreevars = validate_and_copy_tuple(freevars);
1667 : : else
1668 : 0 : ourfreevars = PyTuple_New(0);
1669 [ # # ]: 0 : if (ourfreevars == NULL)
1670 : 0 : goto cleanup;
1671 [ # # ]: 0 : if (cellvars)
1672 : 0 : ourcellvars = validate_and_copy_tuple(cellvars);
1673 : : else
1674 : 0 : ourcellvars = PyTuple_New(0);
1675 [ # # ]: 0 : if (ourcellvars == NULL)
1676 : 0 : goto cleanup;
1677 : :
1678 : 0 : co = (PyObject *)PyCode_NewWithPosOnlyArgs(argcount, posonlyargcount,
1679 : : kwonlyargcount,
1680 : : nlocals, stacksize, flags,
1681 : : code, consts, ournames,
1682 : : ourvarnames, ourfreevars,
1683 : : ourcellvars, filename,
1684 : : name, qualname, firstlineno,
1685 : : linetable,
1686 : : exceptiontable
1687 : : );
1688 : 0 : cleanup:
1689 : 0 : Py_XDECREF(ournames);
1690 : 0 : Py_XDECREF(ourvarnames);
1691 : 0 : Py_XDECREF(ourfreevars);
1692 : 0 : Py_XDECREF(ourcellvars);
1693 : 0 : return co;
1694 : : }
1695 : :
1696 : : static void
1697 : 29011 : code_dealloc(PyCodeObject *co)
1698 : : {
1699 : : assert(Py_REFCNT(co) == 0);
1700 : 29011 : Py_SET_REFCNT(co, 1);
1701 : 29011 : notify_code_watchers(PY_CODE_EVENT_DESTROY, co);
1702 [ - + ]: 29011 : if (Py_REFCNT(co) > 1) {
1703 : 0 : Py_SET_REFCNT(co, Py_REFCNT(co) - 1);
1704 : 0 : return;
1705 : : }
1706 : 29011 : Py_SET_REFCNT(co, 0);
1707 : :
1708 [ - + ]: 29011 : if (co->co_extra != NULL) {
1709 : 0 : PyInterpreterState *interp = _PyInterpreterState_GET();
1710 : 0 : _PyCodeObjectExtra *co_extra = co->co_extra;
1711 : :
1712 [ # # ]: 0 : for (Py_ssize_t i = 0; i < co_extra->ce_size; i++) {
1713 : 0 : freefunc free_extra = interp->co_extra_freefuncs[i];
1714 : :
1715 [ # # ]: 0 : if (free_extra != NULL) {
1716 : 0 : free_extra(co_extra->ce_extras[i]);
1717 : : }
1718 : : }
1719 : :
1720 : 0 : PyMem_Free(co_extra);
1721 : : }
1722 : :
1723 : 29011 : Py_XDECREF(co->co_consts);
1724 : 29011 : Py_XDECREF(co->co_names);
1725 : 29011 : Py_XDECREF(co->co_localsplusnames);
1726 : 29011 : Py_XDECREF(co->co_localspluskinds);
1727 : 29011 : Py_XDECREF(co->co_filename);
1728 : 29011 : Py_XDECREF(co->co_name);
1729 : 29011 : Py_XDECREF(co->co_qualname);
1730 : 29011 : Py_XDECREF(co->co_linetable);
1731 : 29011 : Py_XDECREF(co->co_exceptiontable);
1732 [ + + ]: 29011 : if (co->_co_cached != NULL) {
1733 : 7563 : Py_XDECREF(co->_co_cached->_co_code);
1734 : 7563 : Py_XDECREF(co->_co_cached->_co_cellvars);
1735 : 7563 : Py_XDECREF(co->_co_cached->_co_freevars);
1736 : 7563 : Py_XDECREF(co->_co_cached->_co_varnames);
1737 : 7563 : PyMem_Free(co->_co_cached);
1738 : : }
1739 [ - + ]: 29011 : if (co->co_weakreflist != NULL) {
1740 : 0 : PyObject_ClearWeakRefs((PyObject*)co);
1741 : : }
1742 [ - + ]: 29011 : if (co->_co_linearray) {
1743 : 0 : PyMem_Free(co->_co_linearray);
1744 : : }
1745 : 29011 : PyObject_Free(co);
1746 : : }
1747 : :
1748 : : static PyObject *
1749 : 0 : code_repr(PyCodeObject *co)
1750 : : {
1751 : : int lineno;
1752 [ # # ]: 0 : if (co->co_firstlineno != 0)
1753 : 0 : lineno = co->co_firstlineno;
1754 : : else
1755 : 0 : lineno = -1;
1756 [ # # # # ]: 0 : if (co->co_filename && PyUnicode_Check(co->co_filename)) {
1757 : 0 : return PyUnicode_FromFormat(
1758 : : "<code object %U at %p, file \"%U\", line %d>",
1759 : : co->co_name, co, co->co_filename, lineno);
1760 : : } else {
1761 : 0 : return PyUnicode_FromFormat(
1762 : : "<code object %U at %p, file ???, line %d>",
1763 : : co->co_name, co, lineno);
1764 : : }
1765 : : }
1766 : :
1767 : : static PyObject *
1768 : 4 : code_richcompare(PyObject *self, PyObject *other, int op)
1769 : : {
1770 : : PyCodeObject *co, *cp;
1771 : : int eq;
1772 : : PyObject *consts1, *consts2;
1773 : : PyObject *res;
1774 : :
1775 [ - + - - : 8 : if ((op != Py_EQ && op != Py_NE) ||
+ - ]
1776 [ - + ]: 8 : !PyCode_Check(self) ||
1777 : 4 : !PyCode_Check(other)) {
1778 : 0 : Py_RETURN_NOTIMPLEMENTED;
1779 : : }
1780 : :
1781 : 4 : co = (PyCodeObject *)self;
1782 : 4 : cp = (PyCodeObject *)other;
1783 : :
1784 : 4 : eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
1785 [ - + ]: 4 : if (!eq) goto unequal;
1786 : 4 : eq = co->co_argcount == cp->co_argcount;
1787 [ - + ]: 4 : if (!eq) goto unequal;
1788 : 4 : eq = co->co_posonlyargcount == cp->co_posonlyargcount;
1789 [ - + ]: 4 : if (!eq) goto unequal;
1790 : 4 : eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
1791 [ - + ]: 4 : if (!eq) goto unequal;
1792 : 4 : eq = co->co_flags == cp->co_flags;
1793 [ - + ]: 4 : if (!eq) goto unequal;
1794 : 4 : eq = co->co_firstlineno == cp->co_firstlineno;
1795 [ - + ]: 4 : if (!eq) goto unequal;
1796 : 4 : eq = Py_SIZE(co) == Py_SIZE(cp);
1797 [ - + ]: 4 : if (!eq) {
1798 : 0 : goto unequal;
1799 : : }
1800 [ + + ]: 64 : for (int i = 0; i < Py_SIZE(co); i++) {
1801 : 60 : _Py_CODEUNIT co_instr = _PyCode_CODE(co)[i];
1802 : 60 : _Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i];
1803 : 60 : co_instr.op.code = _PyOpcode_Deopt[co_instr.op.code];
1804 : 60 : cp_instr.op.code = _PyOpcode_Deopt[cp_instr.op.code];
1805 : 60 : eq = co_instr.cache == cp_instr.cache;
1806 [ - + ]: 60 : if (!eq) {
1807 : 0 : goto unequal;
1808 : : }
1809 : 60 : i += _PyOpcode_Caches[co_instr.op.code];
1810 : : }
1811 : :
1812 : : /* compare constants */
1813 : 4 : consts1 = _PyCode_ConstantKey(co->co_consts);
1814 [ - + ]: 4 : if (!consts1)
1815 : 0 : return NULL;
1816 : 4 : consts2 = _PyCode_ConstantKey(cp->co_consts);
1817 [ - + ]: 4 : if (!consts2) {
1818 : 0 : Py_DECREF(consts1);
1819 : 0 : return NULL;
1820 : : }
1821 : 4 : eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
1822 : 4 : Py_DECREF(consts1);
1823 : 4 : Py_DECREF(consts2);
1824 [ - + ]: 4 : if (eq <= 0) goto unequal;
1825 : :
1826 : 4 : eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
1827 [ - + ]: 4 : if (eq <= 0) goto unequal;
1828 : 4 : eq = PyObject_RichCompareBool(co->co_localsplusnames,
1829 : : cp->co_localsplusnames, Py_EQ);
1830 [ - + ]: 4 : if (eq <= 0) goto unequal;
1831 : 4 : eq = PyObject_RichCompareBool(co->co_linetable, cp->co_linetable, Py_EQ);
1832 [ - + ]: 4 : if (eq <= 0) {
1833 : 0 : goto unequal;
1834 : : }
1835 : 4 : eq = PyObject_RichCompareBool(co->co_exceptiontable,
1836 : : cp->co_exceptiontable, Py_EQ);
1837 [ - + ]: 4 : if (eq <= 0) {
1838 : 0 : goto unequal;
1839 : : }
1840 : :
1841 [ + - ]: 4 : if (op == Py_EQ)
1842 : 4 : res = Py_True;
1843 : : else
1844 : 0 : res = Py_False;
1845 : 4 : goto done;
1846 : :
1847 : 0 : unequal:
1848 [ # # ]: 0 : if (eq < 0)
1849 : 0 : return NULL;
1850 [ # # ]: 0 : if (op == Py_NE)
1851 : 0 : res = Py_True;
1852 : : else
1853 : 0 : res = Py_False;
1854 : :
1855 : 4 : done:
1856 : 4 : return Py_NewRef(res);
1857 : : }
1858 : :
1859 : : static Py_hash_t
1860 : 65528 : code_hash(PyCodeObject *co)
1861 : : {
1862 : 65528 : Py_uhash_t uhash = 20221211;
1863 : : #define SCRAMBLE_IN(H) do { \
1864 : : uhash ^= (Py_uhash_t)(H); \
1865 : : uhash *= _PyHASH_MULTIPLIER; \
1866 : : } while (0)
1867 : : #define SCRAMBLE_IN_HASH(EXPR) do { \
1868 : : Py_hash_t h = PyObject_Hash(EXPR); \
1869 : : if (h == -1) { \
1870 : : return -1; \
1871 : : } \
1872 : : SCRAMBLE_IN(h); \
1873 : : } while (0)
1874 : :
1875 [ - + ]: 65528 : SCRAMBLE_IN_HASH(co->co_name);
1876 [ - + ]: 65528 : SCRAMBLE_IN_HASH(co->co_consts);
1877 [ - + ]: 65528 : SCRAMBLE_IN_HASH(co->co_names);
1878 [ - + ]: 65528 : SCRAMBLE_IN_HASH(co->co_localsplusnames);
1879 [ - + ]: 65528 : SCRAMBLE_IN_HASH(co->co_linetable);
1880 [ - + ]: 65528 : SCRAMBLE_IN_HASH(co->co_exceptiontable);
1881 : 65528 : SCRAMBLE_IN(co->co_argcount);
1882 : 65528 : SCRAMBLE_IN(co->co_posonlyargcount);
1883 : 65528 : SCRAMBLE_IN(co->co_kwonlyargcount);
1884 : 65528 : SCRAMBLE_IN(co->co_flags);
1885 : 65528 : SCRAMBLE_IN(co->co_firstlineno);
1886 : 65528 : SCRAMBLE_IN(Py_SIZE(co));
1887 [ + + ]: 2446583 : for (int i = 0; i < Py_SIZE(co); i++) {
1888 : 2381055 : int deop = _PyOpcode_Deopt[_PyCode_CODE(co)[i].op.code];
1889 : 2381055 : SCRAMBLE_IN(deop);
1890 : 2381055 : SCRAMBLE_IN(_PyCode_CODE(co)[i].op.arg);
1891 : 2381055 : i += _PyOpcode_Caches[deop];
1892 : : }
1893 [ - + ]: 65528 : if ((Py_hash_t)uhash == -1) {
1894 : 0 : return -2;
1895 : : }
1896 : 65528 : return (Py_hash_t)uhash;
1897 : : }
1898 : :
1899 : :
1900 : : #define OFF(x) offsetof(PyCodeObject, x)
1901 : :
1902 : : static PyMemberDef code_memberlist[] = {
1903 : : {"co_argcount", T_INT, OFF(co_argcount), READONLY},
1904 : : {"co_posonlyargcount", T_INT, OFF(co_posonlyargcount), READONLY},
1905 : : {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY},
1906 : : {"co_stacksize", T_INT, OFF(co_stacksize), READONLY},
1907 : : {"co_flags", T_INT, OFF(co_flags), READONLY},
1908 : : {"co_nlocals", T_INT, OFF(co_nlocals), READONLY},
1909 : : {"co_consts", T_OBJECT, OFF(co_consts), READONLY},
1910 : : {"co_names", T_OBJECT, OFF(co_names), READONLY},
1911 : : {"co_filename", T_OBJECT, OFF(co_filename), READONLY},
1912 : : {"co_name", T_OBJECT, OFF(co_name), READONLY},
1913 : : {"co_qualname", T_OBJECT, OFF(co_qualname), READONLY},
1914 : : {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY},
1915 : : {"co_linetable", T_OBJECT, OFF(co_linetable), READONLY},
1916 : : {"co_exceptiontable", T_OBJECT, OFF(co_exceptiontable), READONLY},
1917 : : {NULL} /* Sentinel */
1918 : : };
1919 : :
1920 : :
1921 : : static PyObject *
1922 : 0 : code_getlnotab(PyCodeObject *code, void *closure)
1923 : : {
1924 : 0 : return decode_linetable(code);
1925 : : }
1926 : :
1927 : : static PyObject *
1928 : 0 : code_getvarnames(PyCodeObject *code, void *closure)
1929 : : {
1930 : 0 : return _PyCode_GetVarnames(code);
1931 : : }
1932 : :
1933 : : static PyObject *
1934 : 0 : code_getcellvars(PyCodeObject *code, void *closure)
1935 : : {
1936 : 0 : return _PyCode_GetCellvars(code);
1937 : : }
1938 : :
1939 : : static PyObject *
1940 : 0 : code_getfreevars(PyCodeObject *code, void *closure)
1941 : : {
1942 : 0 : return _PyCode_GetFreevars(code);
1943 : : }
1944 : :
1945 : : static PyObject *
1946 : 0 : code_getcodeadaptive(PyCodeObject *code, void *closure)
1947 : : {
1948 : 0 : return PyBytes_FromStringAndSize(code->co_code_adaptive,
1949 : 0 : _PyCode_NBYTES(code));
1950 : : }
1951 : :
1952 : : static PyObject *
1953 : 0 : code_getcode(PyCodeObject *code, void *closure)
1954 : : {
1955 : 0 : return _PyCode_GetCode(code);
1956 : : }
1957 : :
1958 : : static PyGetSetDef code_getsetlist[] = {
1959 : : {"co_lnotab", (getter)code_getlnotab, NULL, NULL},
1960 : : {"_co_code_adaptive", (getter)code_getcodeadaptive, NULL, NULL},
1961 : : // The following old names are kept for backward compatibility.
1962 : : {"co_varnames", (getter)code_getvarnames, NULL, NULL},
1963 : : {"co_cellvars", (getter)code_getcellvars, NULL, NULL},
1964 : : {"co_freevars", (getter)code_getfreevars, NULL, NULL},
1965 : : {"co_code", (getter)code_getcode, NULL, NULL},
1966 : : {0}
1967 : : };
1968 : :
1969 : :
1970 : : static PyObject *
1971 : 0 : code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args))
1972 : : {
1973 : 0 : size_t res = _PyObject_VAR_SIZE(Py_TYPE(co), Py_SIZE(co));
1974 : 0 : _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra;
1975 [ # # ]: 0 : if (co_extra != NULL) {
1976 : 0 : res += sizeof(_PyCodeObjectExtra);
1977 : 0 : res += ((size_t)co_extra->ce_size - 1) * sizeof(co_extra->ce_extras[0]);
1978 : : }
1979 : 0 : return PyLong_FromSize_t(res);
1980 : : }
1981 : :
1982 : : static PyObject *
1983 : 0 : code_linesiterator(PyCodeObject *code, PyObject *Py_UNUSED(args))
1984 : : {
1985 : 0 : return (PyObject *)new_linesiterator(code);
1986 : : }
1987 : :
1988 : : /*[clinic input]
1989 : : code.replace
1990 : :
1991 : : *
1992 : : co_argcount: int(c_default="self->co_argcount") = -1
1993 : : co_posonlyargcount: int(c_default="self->co_posonlyargcount") = -1
1994 : : co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = -1
1995 : : co_nlocals: int(c_default="self->co_nlocals") = -1
1996 : : co_stacksize: int(c_default="self->co_stacksize") = -1
1997 : : co_flags: int(c_default="self->co_flags") = -1
1998 : : co_firstlineno: int(c_default="self->co_firstlineno") = -1
1999 : : co_code: PyBytesObject(c_default="NULL") = None
2000 : : co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = None
2001 : : co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = None
2002 : : co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = None
2003 : : co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None
2004 : : co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None
2005 : : co_filename: unicode(c_default="self->co_filename") = None
2006 : : co_name: unicode(c_default="self->co_name") = None
2007 : : co_qualname: unicode(c_default="self->co_qualname") = None
2008 : : co_linetable: PyBytesObject(c_default="(PyBytesObject *)self->co_linetable") = None
2009 : : co_exceptiontable: PyBytesObject(c_default="(PyBytesObject *)self->co_exceptiontable") = None
2010 : :
2011 : : Return a copy of the code object with new values for the specified fields.
2012 : : [clinic start generated code]*/
2013 : :
2014 : : static PyObject *
2015 : 1 : code_replace_impl(PyCodeObject *self, int co_argcount,
2016 : : int co_posonlyargcount, int co_kwonlyargcount,
2017 : : int co_nlocals, int co_stacksize, int co_flags,
2018 : : int co_firstlineno, PyBytesObject *co_code,
2019 : : PyObject *co_consts, PyObject *co_names,
2020 : : PyObject *co_varnames, PyObject *co_freevars,
2021 : : PyObject *co_cellvars, PyObject *co_filename,
2022 : : PyObject *co_name, PyObject *co_qualname,
2023 : : PyBytesObject *co_linetable,
2024 : : PyBytesObject *co_exceptiontable)
2025 : : /*[clinic end generated code: output=b6cd9988391d5711 input=f6f68e03571f8d7c]*/
2026 : : {
2027 : : #define CHECK_INT_ARG(ARG) \
2028 : : if (ARG < 0) { \
2029 : : PyErr_SetString(PyExc_ValueError, \
2030 : : #ARG " must be a positive integer"); \
2031 : : return NULL; \
2032 : : }
2033 : :
2034 [ - + ]: 1 : CHECK_INT_ARG(co_argcount);
2035 [ - + ]: 1 : CHECK_INT_ARG(co_posonlyargcount);
2036 [ - + ]: 1 : CHECK_INT_ARG(co_kwonlyargcount);
2037 [ - + ]: 1 : CHECK_INT_ARG(co_nlocals);
2038 [ - + ]: 1 : CHECK_INT_ARG(co_stacksize);
2039 [ - + ]: 1 : CHECK_INT_ARG(co_flags);
2040 [ - + ]: 1 : CHECK_INT_ARG(co_firstlineno);
2041 : :
2042 : : #undef CHECK_INT_ARG
2043 : :
2044 : 1 : PyObject *code = NULL;
2045 [ + - ]: 1 : if (co_code == NULL) {
2046 : 1 : code = _PyCode_GetCode(self);
2047 [ - + ]: 1 : if (code == NULL) {
2048 : 0 : return NULL;
2049 : : }
2050 : 1 : co_code = (PyBytesObject *)code;
2051 : : }
2052 : :
2053 [ - + ]: 1 : if (PySys_Audit("code.__new__", "OOOiiiiii",
2054 : : co_code, co_filename, co_name, co_argcount,
2055 : : co_posonlyargcount, co_kwonlyargcount, co_nlocals,
2056 : : co_stacksize, co_flags) < 0) {
2057 : 0 : return NULL;
2058 : : }
2059 : :
2060 : 1 : PyCodeObject *co = NULL;
2061 : 1 : PyObject *varnames = NULL;
2062 : 1 : PyObject *cellvars = NULL;
2063 : 1 : PyObject *freevars = NULL;
2064 [ + - ]: 1 : if (co_varnames == NULL) {
2065 : 1 : varnames = get_localsplus_names(self, CO_FAST_LOCAL, self->co_nlocals);
2066 [ - + ]: 1 : if (varnames == NULL) {
2067 : 0 : goto error;
2068 : : }
2069 : 1 : co_varnames = varnames;
2070 : : }
2071 [ + - ]: 1 : if (co_cellvars == NULL) {
2072 : 1 : cellvars = get_localsplus_names(self, CO_FAST_CELL, self->co_ncellvars);
2073 [ - + ]: 1 : if (cellvars == NULL) {
2074 : 0 : goto error;
2075 : : }
2076 : 1 : co_cellvars = cellvars;
2077 : : }
2078 [ + - ]: 1 : if (co_freevars == NULL) {
2079 : 1 : freevars = get_localsplus_names(self, CO_FAST_FREE, self->co_nfreevars);
2080 [ - + ]: 1 : if (freevars == NULL) {
2081 : 0 : goto error;
2082 : : }
2083 : 1 : co_freevars = freevars;
2084 : : }
2085 : :
2086 : 1 : co = PyCode_NewWithPosOnlyArgs(
2087 : : co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals,
2088 : : co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names,
2089 : : co_varnames, co_freevars, co_cellvars, co_filename, co_name,
2090 : : co_qualname, co_firstlineno,
2091 : : (PyObject*)co_linetable, (PyObject*)co_exceptiontable);
2092 : :
2093 : 1 : error:
2094 : 1 : Py_XDECREF(code);
2095 : 1 : Py_XDECREF(varnames);
2096 : 1 : Py_XDECREF(cellvars);
2097 : 1 : Py_XDECREF(freevars);
2098 : 1 : return (PyObject *)co;
2099 : : }
2100 : :
2101 : : /*[clinic input]
2102 : : code._varname_from_oparg
2103 : :
2104 : : oparg: int
2105 : :
2106 : : (internal-only) Return the local variable name for the given oparg.
2107 : :
2108 : : WARNING: this method is for internal use only and may change or go away.
2109 : : [clinic start generated code]*/
2110 : :
2111 : : static PyObject *
2112 : 0 : code__varname_from_oparg_impl(PyCodeObject *self, int oparg)
2113 : : /*[clinic end generated code: output=1fd1130413184206 input=c5fa3ee9bac7d4ca]*/
2114 : : {
2115 : 0 : PyObject *name = PyTuple_GetItem(self->co_localsplusnames, oparg);
2116 [ # # ]: 0 : if (name == NULL) {
2117 : 0 : return NULL;
2118 : : }
2119 : 0 : return Py_NewRef(name);
2120 : : }
2121 : :
2122 : : /* XXX code objects need to participate in GC? */
2123 : :
2124 : : static struct PyMethodDef code_methods[] = {
2125 : : {"__sizeof__", (PyCFunction)code_sizeof, METH_NOARGS},
2126 : : {"co_lines", (PyCFunction)code_linesiterator, METH_NOARGS},
2127 : : {"co_positions", (PyCFunction)code_positionsiterator, METH_NOARGS},
2128 : : CODE_REPLACE_METHODDEF
2129 : : CODE__VARNAME_FROM_OPARG_METHODDEF
2130 : : {NULL, NULL} /* sentinel */
2131 : : };
2132 : :
2133 : :
2134 : : PyTypeObject PyCode_Type = {
2135 : : PyVarObject_HEAD_INIT(&PyType_Type, 0)
2136 : : "code",
2137 : : offsetof(PyCodeObject, co_code_adaptive),
2138 : : sizeof(_Py_CODEUNIT),
2139 : : (destructor)code_dealloc, /* tp_dealloc */
2140 : : 0, /* tp_vectorcall_offset */
2141 : : 0, /* tp_getattr */
2142 : : 0, /* tp_setattr */
2143 : : 0, /* tp_as_async */
2144 : : (reprfunc)code_repr, /* tp_repr */
2145 : : 0, /* tp_as_number */
2146 : : 0, /* tp_as_sequence */
2147 : : 0, /* tp_as_mapping */
2148 : : (hashfunc)code_hash, /* tp_hash */
2149 : : 0, /* tp_call */
2150 : : 0, /* tp_str */
2151 : : PyObject_GenericGetAttr, /* tp_getattro */
2152 : : 0, /* tp_setattro */
2153 : : 0, /* tp_as_buffer */
2154 : : Py_TPFLAGS_DEFAULT, /* tp_flags */
2155 : : code_new__doc__, /* tp_doc */
2156 : : 0, /* tp_traverse */
2157 : : 0, /* tp_clear */
2158 : : code_richcompare, /* tp_richcompare */
2159 : : offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */
2160 : : 0, /* tp_iter */
2161 : : 0, /* tp_iternext */
2162 : : code_methods, /* tp_methods */
2163 : : code_memberlist, /* tp_members */
2164 : : code_getsetlist, /* tp_getset */
2165 : : 0, /* tp_base */
2166 : : 0, /* tp_dict */
2167 : : 0, /* tp_descr_get */
2168 : : 0, /* tp_descr_set */
2169 : : 0, /* tp_dictoffset */
2170 : : 0, /* tp_init */
2171 : : 0, /* tp_alloc */
2172 : : code_new, /* tp_new */
2173 : : };
2174 : :
2175 : :
2176 : : /******************
2177 : : * other API
2178 : : ******************/
2179 : :
2180 : : PyObject*
2181 : 234505 : _PyCode_ConstantKey(PyObject *op)
2182 : : {
2183 : : PyObject *key;
2184 : :
2185 : : /* Py_None and Py_Ellipsis are singletons. */
2186 [ + + + + ]: 234505 : if (op == Py_None || op == Py_Ellipsis
2187 [ + + ]: 226397 : || PyLong_CheckExact(op)
2188 [ + + ]: 210704 : || PyUnicode_CheckExact(op)
2189 : : /* code_richcompare() uses _PyCode_ConstantKey() internally */
2190 [ + + ]: 77545 : || PyCode_Check(op))
2191 : : {
2192 : : /* Objects of these types are always different from object of other
2193 : : * type and from tuples. */
2194 : 172400 : key = Py_NewRef(op);
2195 : : }
2196 [ + + + + ]: 62105 : else if (PyBool_Check(op) || PyBytes_CheckExact(op)) {
2197 : : /* Make booleans different from integers 0 and 1.
2198 : : * Avoid BytesWarning from comparing bytes with strings. */
2199 : 28515 : key = PyTuple_Pack(2, Py_TYPE(op), op);
2200 : : }
2201 [ + + ]: 33590 : else if (PyFloat_CheckExact(op)) {
2202 : 1797 : double d = PyFloat_AS_DOUBLE(op);
2203 : : /* all we need is to make the tuple different in either the 0.0
2204 : : * or -0.0 case from all others, just to avoid the "coercion".
2205 : : */
2206 [ + + + + ]: 1797 : if (d == 0.0 && copysign(1.0, d) < 0.0)
2207 : 101 : key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
2208 : : else
2209 : 1696 : key = PyTuple_Pack(2, Py_TYPE(op), op);
2210 : : }
2211 [ + + ]: 31793 : else if (PyComplex_CheckExact(op)) {
2212 : : Py_complex z;
2213 : : int real_negzero, imag_negzero;
2214 : : /* For the complex case we must make complex(x, 0.)
2215 : : different from complex(x, -0.) and complex(0., y)
2216 : : different from complex(-0., y), for any x and y.
2217 : : All four complex zeros must be distinguished.*/
2218 : 6 : z = PyComplex_AsCComplex(op);
2219 [ + + - + ]: 6 : real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
2220 [ - + - - ]: 6 : imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
2221 : : /* use True, False and None singleton as tags for the real and imag
2222 : : * sign, to make tuples different */
2223 [ - + - - ]: 6 : if (real_negzero && imag_negzero) {
2224 : 0 : key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True);
2225 : : }
2226 [ - + ]: 6 : else if (imag_negzero) {
2227 : 0 : key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False);
2228 : : }
2229 [ - + ]: 6 : else if (real_negzero) {
2230 : 0 : key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
2231 : : }
2232 : : else {
2233 : 6 : key = PyTuple_Pack(2, Py_TYPE(op), op);
2234 : : }
2235 : : }
2236 [ + + ]: 31787 : else if (PyTuple_CheckExact(op)) {
2237 : : Py_ssize_t i, len;
2238 : : PyObject *tuple;
2239 : :
2240 : 31707 : len = PyTuple_GET_SIZE(op);
2241 : 31707 : tuple = PyTuple_New(len);
2242 [ - + ]: 31707 : if (tuple == NULL)
2243 : 0 : return NULL;
2244 : :
2245 [ + + ]: 166660 : for (i=0; i < len; i++) {
2246 : : PyObject *item, *item_key;
2247 : :
2248 : 134953 : item = PyTuple_GET_ITEM(op, i);
2249 : 134953 : item_key = _PyCode_ConstantKey(item);
2250 [ - + ]: 134953 : if (item_key == NULL) {
2251 : 0 : Py_DECREF(tuple);
2252 : 0 : return NULL;
2253 : : }
2254 : :
2255 : 134953 : PyTuple_SET_ITEM(tuple, i, item_key);
2256 : : }
2257 : :
2258 : 31707 : key = PyTuple_Pack(2, tuple, op);
2259 : 31707 : Py_DECREF(tuple);
2260 : : }
2261 [ + - ]: 80 : else if (PyFrozenSet_CheckExact(op)) {
2262 : 80 : Py_ssize_t pos = 0;
2263 : : PyObject *item;
2264 : : Py_hash_t hash;
2265 : : Py_ssize_t i, len;
2266 : : PyObject *tuple, *set;
2267 : :
2268 : 80 : len = PySet_GET_SIZE(op);
2269 : 80 : tuple = PyTuple_New(len);
2270 [ - + ]: 80 : if (tuple == NULL)
2271 : 0 : return NULL;
2272 : :
2273 : 80 : i = 0;
2274 [ + + ]: 344 : while (_PySet_NextEntry(op, &pos, &item, &hash)) {
2275 : : PyObject *item_key;
2276 : :
2277 : 264 : item_key = _PyCode_ConstantKey(item);
2278 [ - + ]: 264 : if (item_key == NULL) {
2279 : 0 : Py_DECREF(tuple);
2280 : 0 : return NULL;
2281 : : }
2282 : :
2283 : : assert(i < len);
2284 : 264 : PyTuple_SET_ITEM(tuple, i, item_key);
2285 : 264 : i++;
2286 : : }
2287 : 80 : set = PyFrozenSet_New(tuple);
2288 : 80 : Py_DECREF(tuple);
2289 [ - + ]: 80 : if (set == NULL)
2290 : 0 : return NULL;
2291 : :
2292 : 80 : key = PyTuple_Pack(2, set, op);
2293 : 80 : Py_DECREF(set);
2294 : 80 : return key;
2295 : : }
2296 : : else {
2297 : : /* for other types, use the object identifier as a unique identifier
2298 : : * to ensure that they are seen as unequal. */
2299 : 0 : PyObject *obj_id = PyLong_FromVoidPtr(op);
2300 [ # # ]: 0 : if (obj_id == NULL)
2301 : 0 : return NULL;
2302 : :
2303 : 0 : key = PyTuple_Pack(2, obj_id, op);
2304 : 0 : Py_DECREF(obj_id);
2305 : : }
2306 : 234425 : return key;
2307 : : }
2308 : :
2309 : : void
2310 : 3088 : _PyStaticCode_Fini(PyCodeObject *co)
2311 : : {
2312 : 3088 : deopt_code(_PyCode_CODE(co), Py_SIZE(co));
2313 : 3088 : PyMem_Free(co->co_extra);
2314 [ - + ]: 3088 : if (co->_co_cached != NULL) {
2315 [ # # ]: 0 : Py_CLEAR(co->_co_cached->_co_code);
2316 [ # # ]: 0 : Py_CLEAR(co->_co_cached->_co_cellvars);
2317 [ # # ]: 0 : Py_CLEAR(co->_co_cached->_co_freevars);
2318 [ # # ]: 0 : Py_CLEAR(co->_co_cached->_co_varnames);
2319 : 0 : PyMem_Free(co->_co_cached);
2320 : 0 : co->_co_cached = NULL;
2321 : : }
2322 : 3088 : co->co_extra = NULL;
2323 [ - + ]: 3088 : if (co->co_weakreflist != NULL) {
2324 : 0 : PyObject_ClearWeakRefs((PyObject *)co);
2325 : 0 : co->co_weakreflist = NULL;
2326 : : }
2327 [ - + ]: 3088 : if (co->_co_linearray) {
2328 : 0 : PyMem_Free(co->_co_linearray);
2329 : 0 : co->_co_linearray = NULL;
2330 : : }
2331 : 3088 : }
2332 : :
2333 : : int
2334 : 3088 : _PyStaticCode_Init(PyCodeObject *co)
2335 : : {
2336 : 3088 : int res = intern_strings(co->co_names);
2337 [ - + ]: 3088 : if (res < 0) {
2338 : 0 : return -1;
2339 : : }
2340 : 3088 : res = intern_string_constants(co->co_consts, NULL);
2341 [ - + ]: 3088 : if (res < 0) {
2342 : 0 : return -1;
2343 : : }
2344 : 3088 : res = intern_strings(co->co_localsplusnames);
2345 [ - + ]: 3088 : if (res < 0) {
2346 : 0 : return -1;
2347 : : }
2348 : 3088 : _PyCode_Quicken(co);
2349 : 3088 : return 0;
2350 : : }
2351 : :
2352 : : #define MAX_CODE_UNITS_PER_LOC_ENTRY 8
2353 : :
2354 : : PyCodeObject *
2355 : 29 : _Py_MakeShimCode(const _PyShimCodeDef *codedef)
2356 : : {
2357 : 29 : PyObject *name = NULL;
2358 : 29 : PyObject *co_code = NULL;
2359 : 29 : PyObject *lines = NULL;
2360 : 29 : PyCodeObject *codeobj = NULL;
2361 : 29 : uint8_t *loc_table = NULL;
2362 : :
2363 : 29 : name = _PyUnicode_FromASCII(codedef->cname, strlen(codedef->cname));
2364 [ - + ]: 29 : if (name == NULL) {
2365 : 0 : goto cleanup;
2366 : : }
2367 : 29 : co_code = PyBytes_FromStringAndSize(
2368 : 29 : (const char *)codedef->code, codedef->codelen);
2369 [ - + ]: 29 : if (co_code == NULL) {
2370 : 0 : goto cleanup;
2371 : : }
2372 : 29 : int code_units = codedef->codelen / sizeof(_Py_CODEUNIT);
2373 : 29 : int loc_entries = (code_units + MAX_CODE_UNITS_PER_LOC_ENTRY - 1) /
2374 : : MAX_CODE_UNITS_PER_LOC_ENTRY;
2375 : 29 : loc_table = PyMem_Malloc(loc_entries);
2376 [ - + ]: 29 : if (loc_table == NULL) {
2377 : 0 : PyErr_NoMemory();
2378 : 0 : goto cleanup;
2379 : : }
2380 [ - + ]: 29 : for (int i = 0; i < loc_entries-1; i++) {
2381 : 0 : loc_table[i] = 0x80 | (PY_CODE_LOCATION_INFO_NONE << 3) | 7;
2382 : 0 : code_units -= MAX_CODE_UNITS_PER_LOC_ENTRY;
2383 : : }
2384 : : assert(loc_entries > 0);
2385 : : assert(code_units > 0 && code_units <= MAX_CODE_UNITS_PER_LOC_ENTRY);
2386 : 29 : loc_table[loc_entries-1] = 0x80 |
2387 : 29 : (PY_CODE_LOCATION_INFO_NONE << 3) | (code_units-1);
2388 : 29 : lines = PyBytes_FromStringAndSize((const char *)loc_table, loc_entries);
2389 : 29 : PyMem_Free(loc_table);
2390 [ - + ]: 29 : if (lines == NULL) {
2391 : 0 : goto cleanup;
2392 : : }
2393 : : _Py_DECLARE_STR(shim_name, "<shim>");
2394 : 29 : struct _PyCodeConstructor con = {
2395 : : .filename = &_Py_STR(shim_name),
2396 : : .name = name,
2397 : : .qualname = name,
2398 : : .flags = CO_NEWLOCALS | CO_OPTIMIZED,
2399 : :
2400 : : .code = co_code,
2401 : : .firstlineno = 1,
2402 : : .linetable = lines,
2403 : :
2404 : : .consts = (PyObject *)&_Py_SINGLETON(tuple_empty),
2405 : : .names = (PyObject *)&_Py_SINGLETON(tuple_empty),
2406 : :
2407 : : .localsplusnames = (PyObject *)&_Py_SINGLETON(tuple_empty),
2408 : : .localspluskinds = (PyObject *)&_Py_SINGLETON(bytes_empty),
2409 : :
2410 : : .argcount = 0,
2411 : : .posonlyargcount = 0,
2412 : : .kwonlyargcount = 0,
2413 : :
2414 : 29 : .stacksize = codedef->stacksize,
2415 : :
2416 : : .exceptiontable = (PyObject *)&_Py_SINGLETON(bytes_empty),
2417 : : };
2418 : :
2419 : 29 : codeobj = _PyCode_New(&con);
2420 : 29 : cleanup:
2421 : 29 : Py_XDECREF(name);
2422 : 29 : Py_XDECREF(co_code);
2423 : 29 : Py_XDECREF(lines);
2424 : 29 : return codeobj;
2425 : : }
|