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