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