Branch data Line data Source code
1 : : #include <stdbool.h>
2 : :
3 : : #include "Python.h"
4 : : #include "opcode.h"
5 : : #include "structmember.h" // PyMemberDef
6 : : #include "pycore_code.h" // _PyCodeConstructor
7 : : #include "pycore_frame.h" // FRAME_SPECIALS_SIZE
8 : : #include "pycore_interp.h" // PyInterpreterState.co_extra_freefuncs
9 : : #include "pycore_opcode.h" // _PyOpcode_Deopt
10 : : #include "pycore_pystate.h" // _PyInterpreterState_GET()
11 : : #include "pycore_tuple.h" // _PyTuple_ITEMS()
12 : : #include "clinic/codeobject.c.h"
13 : :
14 : :
15 : : /******************
16 : : * generic helpers
17 : : ******************/
18 : :
19 : : /* all_name_chars(s): true iff s matches [a-zA-Z0-9_]* */
20 : : static int
21 : 31142948 : all_name_chars(PyObject *o)
22 : : {
23 : : const unsigned char *s, *e;
24 : :
25 [ + + ]: 31142948 : if (!PyUnicode_IS_ASCII(o))
26 : 226410 : return 0;
27 : :
28 : 30916538 : s = PyUnicode_1BYTE_DATA(o);
29 : 30916538 : e = s + PyUnicode_GET_LENGTH(o);
30 [ + + ]: 234343590 : for (; s != e; s++) {
31 [ + + + + ]: 216239154 : if (!Py_ISALNUM(*s) && *s != '_')
32 : 12812102 : return 0;
33 : : }
34 : 18104436 : return 1;
35 : : }
36 : :
37 : : static int
38 : 19815022 : intern_strings(PyObject *tuple)
39 : : {
40 : : Py_ssize_t i;
41 : :
42 [ + + ]: 113236381 : for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
43 : 93421359 : PyObject *v = PyTuple_GET_ITEM(tuple, i);
44 [ + - - + ]: 93421359 : 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 : 93421359 : PyUnicode_InternInPlace(&_PyTuple_ITEMS(tuple)[i]);
50 : : }
51 : 19815022 : return 0;
52 : : }
53 : :
54 : : /* Intern selected string constants */
55 : : static int
56 : 14211460 : intern_string_constants(PyObject *tuple, int *modified)
57 : : {
58 [ + + ]: 77766131 : for (Py_ssize_t i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
59 : 63554671 : PyObject *v = PyTuple_GET_ITEM(tuple, i);
60 [ + + ]: 63554671 : if (PyUnicode_CheckExact(v)) {
61 [ - + ]: 31142948 : if (PyUnicode_READY(v) == -1) {
62 : 0 : return -1;
63 : : }
64 : :
65 [ + + ]: 31142948 : if (all_name_chars(v)) {
66 : 18104436 : PyObject *w = v;
67 : 18104436 : PyUnicode_InternInPlace(&v);
68 [ + + ]: 18104436 : if (w != v) {
69 : 270115 : PyTuple_SET_ITEM(tuple, i, v);
70 [ + + ]: 270115 : if (modified) {
71 : 3308 : *modified = 1;
72 : : }
73 : : }
74 : : }
75 : : }
76 [ + + ]: 32411723 : else if (PyTuple_CheckExact(v)) {
77 [ - + ]: 4274868 : if (intern_string_constants(v, NULL) < 0) {
78 : 0 : return -1;
79 : : }
80 : : }
81 [ + + ]: 28136855 : else if (PyFrozenSet_CheckExact(v)) {
82 : 29081 : PyObject *w = v;
83 : 29081 : PyObject *tmp = PySequence_Tuple(v);
84 [ - + ]: 29081 : if (tmp == NULL) {
85 : 0 : return -1;
86 : : }
87 : 29081 : int tmp_modified = 0;
88 [ - + ]: 29081 : if (intern_string_constants(tmp, &tmp_modified) < 0) {
89 : 0 : Py_DECREF(tmp);
90 : 0 : return -1;
91 : : }
92 [ + + ]: 29081 : if (tmp_modified) {
93 : 792 : v = PyFrozenSet_New(tmp);
94 [ - + ]: 792 : if (v == NULL) {
95 : 0 : Py_DECREF(tmp);
96 : 0 : return -1;
97 : : }
98 : :
99 : 792 : PyTuple_SET_ITEM(tuple, i, v);
100 : 792 : Py_DECREF(w);
101 [ - + ]: 792 : if (modified) {
102 : 0 : *modified = 1;
103 : : }
104 : : }
105 : 29081 : Py_DECREF(tmp);
106 : : }
107 : : }
108 : 14211460 : 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 : 1131519 : _Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind,
161 : : PyObject *names, PyObject *kinds)
162 : : {
163 : 1131519 : Py_INCREF(name);
164 : 1131519 : PyTuple_SET_ITEM(names, offset, name);
165 : 1131519 : _PyLocals_SetKind(kinds, offset, kind);
166 : 1131519 : }
167 : :
168 : : static void
169 : 15014748 : get_localsplus_counts(PyObject *names, PyObject *kinds,
170 : : int *pnlocals, int *pnplaincellvars, int *pncellvars,
171 : : int *pnfreevars)
172 : : {
173 : 15014748 : int nlocals = 0;
174 : 15014748 : int nplaincellvars = 0;
175 : 15014748 : int ncellvars = 0;
176 : 15014748 : int nfreevars = 0;
177 : 15014748 : Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names);
178 [ + + ]: 62789698 : for (int i = 0; i < nlocalsplus; i++) {
179 : 47774950 : _PyLocals_Kind kind = _PyLocals_GetKind(kinds, i);
180 [ + + ]: 47774950 : if (kind & CO_FAST_LOCAL) {
181 : 44896042 : nlocals += 1;
182 [ + + ]: 44896042 : if (kind & CO_FAST_CELL) {
183 : 701452 : ncellvars += 1;
184 : : }
185 : : }
186 [ + + ]: 2878908 : else if (kind & CO_FAST_CELL) {
187 : 820178 : ncellvars += 1;
188 : 820178 : nplaincellvars += 1;
189 : : }
190 [ + - ]: 2058730 : else if (kind & CO_FAST_FREE) {
191 : 2058730 : nfreevars += 1;
192 : : }
193 : : }
194 [ + - ]: 15014748 : if (pnlocals != NULL) {
195 : 15014748 : *pnlocals = nlocals;
196 : : }
197 [ + + ]: 15014748 : if (pnplaincellvars != NULL) {
198 : 7507388 : *pnplaincellvars = nplaincellvars;
199 : : }
200 [ + + ]: 15014748 : if (pncellvars != NULL) {
201 : 7507388 : *pncellvars = ncellvars;
202 : : }
203 [ + + ]: 15014748 : if (pnfreevars != NULL) {
204 : 7507388 : *pnfreevars = nfreevars;
205 : : }
206 : 15014748 : }
207 : :
208 : : static PyObject *
209 : 6263 : get_localsplus_names(PyCodeObject *co, _PyLocals_Kind kind, int num)
210 : : {
211 : 6263 : PyObject *names = PyTuple_New(num);
212 [ - + ]: 6263 : if (names == NULL) {
213 : 0 : return NULL;
214 : : }
215 : 6263 : int index = 0;
216 [ + + ]: 23430 : for (int offset = 0; offset < co->co_nlocalsplus; offset++) {
217 : 17167 : _PyLocals_Kind k = _PyLocals_GetKind(co->co_localspluskinds, offset);
218 [ + + ]: 17167 : if ((k & kind) == 0) {
219 : 1286 : continue;
220 : : }
221 : : assert(index < num);
222 : 15881 : PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, offset);
223 : 15881 : Py_INCREF(name);
224 : 15881 : PyTuple_SET_ITEM(names, index, name);
225 : 15881 : index += 1;
226 : : }
227 : : assert(index == num);
228 : 6263 : return names;
229 : : }
230 : :
231 : : int
232 : 7507360 : _PyCode_Validate(struct _PyCodeConstructor *con)
233 : : {
234 : : /* Check argument types */
235 [ + - + - ]: 7507360 : if (con->argcount < con->posonlyargcount || con->posonlyargcount < 0 ||
236 [ + - ]: 7507360 : con->kwonlyargcount < 0 ||
237 [ + - + - ]: 7507360 : con->stacksize < 0 || con->flags < 0 ||
238 [ + - + - ]: 7507360 : con->code == NULL || !PyBytes_Check(con->code) ||
239 [ + - + - ]: 7507360 : con->consts == NULL || !PyTuple_Check(con->consts) ||
240 [ + - + - ]: 7507360 : con->names == NULL || !PyTuple_Check(con->names) ||
241 [ + - + - ]: 7507360 : con->localsplusnames == NULL || !PyTuple_Check(con->localsplusnames) ||
242 [ + - + - : 15014720 : con->localspluskinds == NULL || !PyBytes_Check(con->localspluskinds) ||
+ - ]
243 : 7507360 : PyTuple_GET_SIZE(con->localsplusnames)
244 : 7507360 : != PyBytes_GET_SIZE(con->localspluskinds) ||
245 [ + - + - ]: 7507360 : con->name == NULL || !PyUnicode_Check(con->name) ||
246 [ + - + - ]: 7507360 : con->qualname == NULL || !PyUnicode_Check(con->qualname) ||
247 [ + - + - ]: 7507360 : con->filename == NULL || !PyUnicode_Check(con->filename) ||
248 [ + - + - ]: 7507360 : con->linetable == NULL || !PyBytes_Check(con->linetable) ||
249 [ + - - + ]: 7507360 : 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 [ - + ]: 7507360 : 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 [ + - ]: 7507360 : if (PyBytes_GET_SIZE(con->code) % sizeof(_Py_CODEUNIT) != 0 ||
264 [ - + ]: 7507360 : !_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 : 7507360 : get_localsplus_counts(con->localsplusnames, con->localspluskinds,
275 : : &nlocals, NULL, NULL, NULL);
276 : 7507360 : int nplainlocals = nlocals -
277 : 7507360 : con->argcount -
278 : 7507360 : con->kwonlyargcount -
279 : 7507360 : ((con->flags & CO_VARARGS) != 0) -
280 : 7507360 : ((con->flags & CO_VARKEYWORDS) != 0);
281 [ - + ]: 7507360 : if (nplainlocals < 0) {
282 : 0 : PyErr_SetString(PyExc_ValueError, "code: co_varnames is too small");
283 : 0 : return -1;
284 : : }
285 : :
286 : 7507360 : return 0;
287 : : }
288 : :
289 : : static void
290 : 7507388 : init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
291 : : {
292 : 7507388 : int nlocalsplus = (int)PyTuple_GET_SIZE(con->localsplusnames);
293 : : int nlocals, nplaincellvars, ncellvars, nfreevars;
294 : 7507388 : get_localsplus_counts(con->localsplusnames, con->localspluskinds,
295 : : &nlocals, &nplaincellvars, &ncellvars, &nfreevars);
296 : :
297 : 7507388 : Py_INCREF(con->filename);
298 : 7507388 : co->co_filename = con->filename;
299 : 7507388 : Py_INCREF(con->name);
300 : 7507388 : co->co_name = con->name;
301 : 7507388 : Py_INCREF(con->qualname);
302 : 7507388 : co->co_qualname = con->qualname;
303 : 7507388 : co->co_flags = con->flags;
304 : :
305 : 7507388 : co->co_firstlineno = con->firstlineno;
306 : 7507388 : Py_INCREF(con->linetable);
307 : 7507388 : co->co_linetable = con->linetable;
308 : :
309 : 7507388 : Py_INCREF(con->consts);
310 : 7507388 : co->co_consts = con->consts;
311 : 7507388 : Py_INCREF(con->names);
312 : 7507388 : co->co_names = con->names;
313 : :
314 : 7507388 : Py_INCREF(con->localsplusnames);
315 : 7507388 : co->co_localsplusnames = con->localsplusnames;
316 : 7507388 : Py_INCREF(con->localspluskinds);
317 : 7507388 : co->co_localspluskinds = con->localspluskinds;
318 : :
319 : 7507388 : co->co_argcount = con->argcount;
320 : 7507388 : co->co_posonlyargcount = con->posonlyargcount;
321 : 7507388 : co->co_kwonlyargcount = con->kwonlyargcount;
322 : :
323 : 7507388 : co->co_stacksize = con->stacksize;
324 : :
325 : 7507388 : Py_INCREF(con->exceptiontable);
326 : 7507388 : co->co_exceptiontable = con->exceptiontable;
327 : :
328 : : /* derived values */
329 : 7507388 : co->co_nlocalsplus = nlocalsplus;
330 : 7507388 : co->co_nlocals = nlocals;
331 : 7507388 : co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE;
332 : 7507388 : co->co_nplaincellvars = nplaincellvars;
333 : 7507388 : co->co_ncellvars = ncellvars;
334 : 7507388 : co->co_nfreevars = nfreevars;
335 : :
336 : : /* not set */
337 : 7507388 : co->co_weakreflist = NULL;
338 : 7507388 : co->co_extra = NULL;
339 : 7507388 : co->_co_code = NULL;
340 : :
341 : 7507388 : co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE;
342 : 7507388 : co->_co_linearray_entry_size = 0;
343 : 7507388 : co->_co_linearray = NULL;
344 : 7507388 : memcpy(_PyCode_CODE(co), PyBytes_AS_STRING(con->code),
345 : 7507388 : PyBytes_GET_SIZE(con->code));
346 : 7507388 : int entry_point = 0;
347 [ + - ]: 9736353 : while (entry_point < Py_SIZE(co) &&
348 [ + + ]: 9736353 : _Py_OPCODE(_PyCode_CODE(co)[entry_point]) != RESUME) {
349 : 2228965 : entry_point++;
350 : : }
351 : 7507388 : co->_co_firsttraceable = entry_point;
352 : 7507388 : }
353 : :
354 : : static int
355 : 81666099 : scan_varint(const uint8_t *ptr)
356 : : {
357 : 81666099 : unsigned int read = *ptr++;
358 : 81666099 : unsigned int val = read & 63;
359 : 81666099 : unsigned int shift = 0;
360 [ + + ]: 83259104 : while (read & 64) {
361 : 1593005 : read = *ptr++;
362 : 1593005 : shift += 6;
363 : 1593005 : val |= (read & 63) << shift;
364 : : }
365 : 81666099 : return val;
366 : : }
367 : :
368 : : static int
369 : 81666099 : scan_signed_varint(const uint8_t *ptr)
370 : : {
371 : 81666099 : unsigned int uval = scan_varint(ptr);
372 [ + + ]: 81666099 : if (uval & 1) {
373 : 7431382 : return -(int)(uval >> 1);
374 : : }
375 : : else {
376 : 74234717 : return uval >> 1;
377 : : }
378 : : }
379 : :
380 : : static int
381 : 402423723 : get_line_delta(const uint8_t *ptr)
382 : : {
383 : 402423723 : int code = ((*ptr) >> 3) & 15;
384 [ + + + + : 402423723 : switch (code) {
+ + ]
385 : 2269101 : case PY_CODE_LOCATION_INFO_NONE:
386 : 2269101 : return 0;
387 : 81666099 : case PY_CODE_LOCATION_INFO_NO_COLUMNS:
388 : : case PY_CODE_LOCATION_INFO_LONG:
389 : 81666099 : return scan_signed_varint(ptr+1);
390 : 83129095 : case PY_CODE_LOCATION_INFO_ONE_LINE0:
391 : 83129095 : return 0;
392 : 46077257 : case PY_CODE_LOCATION_INFO_ONE_LINE1:
393 : 46077257 : return 1;
394 : 9033886 : case PY_CODE_LOCATION_INFO_ONE_LINE2:
395 : 9033886 : return 2;
396 : 180248285 : default:
397 : : /* Same line */
398 : 180248285 : return 0;
399 : : }
400 : : }
401 : :
402 : : static PyObject *
403 : 3417 : remove_column_info(PyObject *locations)
404 : : {
405 : 3417 : int offset = 0;
406 : 3417 : const uint8_t *data = (const uint8_t *)PyBytes_AS_STRING(locations);
407 : 3417 : PyObject *res = PyBytes_FromStringAndSize(NULL, 32);
408 [ - + ]: 3417 : if (res == NULL) {
409 : : PyErr_NoMemory();
410 : 0 : return NULL;
411 : : }
412 : 3417 : uint8_t *output = (uint8_t *)PyBytes_AS_STRING(res);
413 [ + + ]: 179522 : while (offset < PyBytes_GET_SIZE(locations)) {
414 : 176105 : Py_ssize_t write_offset = output - (uint8_t *)PyBytes_AS_STRING(res);
415 [ + + ]: 176105 : if (write_offset + 16 >= PyBytes_GET_SIZE(res)) {
416 [ - + ]: 5188 : if (_PyBytes_Resize(&res, PyBytes_GET_SIZE(res) * 2) < 0) {
417 : 0 : return NULL;
418 : : }
419 : 5188 : output = (uint8_t *)PyBytes_AS_STRING(res) + write_offset;
420 : : }
421 : 176105 : int code = (data[offset] >> 3) & 15;
422 [ + + ]: 176105 : if (code == PY_CODE_LOCATION_INFO_NONE) {
423 : 3448 : *output++ = data[offset];
424 : : }
425 : : else {
426 : 172657 : int blength = (data[offset] & 7)+1;
427 : 172657 : output += write_location_entry_start(
428 : : output, PY_CODE_LOCATION_INFO_NO_COLUMNS, blength);
429 : 172657 : int ldelta = get_line_delta(&data[offset]);
430 : 172657 : output += write_signed_varint(output, ldelta);
431 : : }
432 : 176105 : offset++;
433 [ + + ]: 538347 : while (offset < PyBytes_GET_SIZE(locations) &&
434 [ + + ]: 534930 : (data[offset] & 128) == 0) {
435 : 362242 : offset++;
436 : : }
437 : : }
438 : 3417 : Py_ssize_t write_offset = output - (uint8_t *)PyBytes_AS_STRING(res);
439 [ - + ]: 3417 : if (_PyBytes_Resize(&res, write_offset)) {
440 : 0 : return NULL;
441 : : }
442 : 3417 : return res;
443 : : }
444 : :
445 : : /* The caller is responsible for ensuring that the given data is valid. */
446 : :
447 : : PyCodeObject *
448 : 7507388 : _PyCode_New(struct _PyCodeConstructor *con)
449 : : {
450 : : /* Ensure that strings are ready Unicode string */
451 [ - + ]: 7507388 : if (PyUnicode_READY(con->name) < 0) {
452 : 0 : return NULL;
453 : : }
454 [ - + ]: 7507388 : if (PyUnicode_READY(con->qualname) < 0) {
455 : 0 : return NULL;
456 : : }
457 [ - + ]: 7507388 : if (PyUnicode_READY(con->filename) < 0) {
458 : 0 : return NULL;
459 : : }
460 : :
461 [ - + ]: 7507388 : if (intern_strings(con->names) < 0) {
462 : 0 : return NULL;
463 : : }
464 [ - + ]: 7507388 : if (intern_string_constants(con->consts, NULL) < 0) {
465 : 0 : return NULL;
466 : : }
467 [ - + ]: 7507388 : if (intern_strings(con->localsplusnames) < 0) {
468 : 0 : return NULL;
469 : : }
470 : :
471 : 7507388 : PyObject *replacement_locations = NULL;
472 : : // Compact the linetable if we are opted out of debug
473 : : // ranges.
474 [ + + ]: 7507388 : if (!_Py_GetConfig()->code_debug_ranges) {
475 : 3417 : replacement_locations = remove_column_info(con->linetable);
476 [ - + ]: 3417 : if (replacement_locations == NULL) {
477 : 0 : return NULL;
478 : : }
479 : 3417 : con->linetable = replacement_locations;
480 : : }
481 : :
482 : 7507388 : Py_ssize_t size = PyBytes_GET_SIZE(con->code) / sizeof(_Py_CODEUNIT);
483 : 7507388 : PyCodeObject *co = PyObject_NewVar(PyCodeObject, &PyCode_Type, size);
484 [ - + ]: 7507388 : if (co == NULL) {
485 : 0 : Py_XDECREF(replacement_locations);
486 : : PyErr_NoMemory();
487 : 0 : return NULL;
488 : : }
489 : 7507388 : init_code(co, con);
490 : 7507388 : Py_XDECREF(replacement_locations);
491 : 7507388 : return co;
492 : : }
493 : :
494 : :
495 : : /******************
496 : : * the legacy "constructors"
497 : : ******************/
498 : :
499 : : PyCodeObject *
500 : 859 : 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 : 859 : PyCodeObject *co = NULL;
510 : 859 : PyObject *localsplusnames = NULL;
511 : 859 : PyObject *localspluskinds = NULL;
512 : :
513 [ + - + - : 859 : if (varnames == NULL || !PyTuple_Check(varnames) ||
+ - ]
514 [ + - + - ]: 859 : cellvars == NULL || !PyTuple_Check(cellvars) ||
515 [ - + ]: 859 : freevars == NULL || !PyTuple_Check(freevars)
516 : : ) {
517 : 0 : PyErr_BadInternalCall();
518 : 0 : return NULL;
519 : : }
520 : :
521 : : // Set the "fast locals plus" info.
522 : 859 : int nvarnames = (int)PyTuple_GET_SIZE(varnames);
523 : 859 : int ncellvars = (int)PyTuple_GET_SIZE(cellvars);
524 : 859 : int nfreevars = (int)PyTuple_GET_SIZE(freevars);
525 : 859 : int nlocalsplus = nvarnames + ncellvars + nfreevars;
526 : 859 : localsplusnames = PyTuple_New(nlocalsplus);
527 [ - + ]: 859 : if (localsplusnames == NULL) {
528 : 0 : goto error;
529 : : }
530 : 859 : localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
531 [ - + ]: 859 : if (localspluskinds == NULL) {
532 : 0 : goto error;
533 : : }
534 : 859 : int offset = 0;
535 [ + + ]: 1306 : for (int i = 0; i < nvarnames; i++, offset++) {
536 : 447 : PyObject *name = PyTuple_GET_ITEM(varnames, i);
537 : 447 : _Py_set_localsplus_info(offset, name, CO_FAST_LOCAL,
538 : : localsplusnames, localspluskinds);
539 : : }
540 [ + + ]: 861 : 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 : : 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 [ + + ]: 866 : 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 [ + + ]: 859 : 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 : 859 : 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 [ - + ]: 859 : if (_PyCode_Validate(&con) < 0) {
602 : 0 : goto error;
603 : : }
604 : : assert(PyBytes_GET_SIZE(code) % sizeof(_Py_CODEUNIT) == 0);
605 : : assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(code), sizeof(_Py_CODEUNIT)));
606 [ + + ]: 859 : 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 : 855 : co = _PyCode_New(&con);
613 [ + - ]: 855 : if (co == NULL) {
614 : 0 : goto error;
615 : : }
616 : :
617 : 855 : error:
618 : 859 : Py_XDECREF(localsplusnames);
619 : 859 : Py_XDECREF(localspluskinds);
620 : 859 : 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 : 3068 : _PyCode_CreateLineArray(PyCodeObject *co)
709 : : {
710 : : assert(co->_co_linearray == NULL);
711 : : PyCodeAddressRange bounds;
712 : : int size;
713 : 3068 : int max_line = 0;
714 : 3068 : _PyCode_InitAddressRange(co, &bounds);
715 [ + + ]: 133987 : while(_PyLineTable_NextAddressRange(&bounds)) {
716 [ + + ]: 130919 : if (bounds.ar_line > max_line) {
717 : 24144 : max_line = bounds.ar_line;
718 : : }
719 : : }
720 [ + + ]: 3068 : if (max_line < (1 << 15)) {
721 : 3065 : size = 2;
722 : : }
723 : : else {
724 : 3 : size = 4;
725 : : }
726 : 3068 : co->_co_linearray = PyMem_Malloc(Py_SIZE(co)*size);
727 [ - + ]: 3068 : if (co->_co_linearray == NULL) {
728 : : PyErr_NoMemory();
729 : 0 : return -1;
730 : : }
731 : 3068 : co->_co_linearray_entry_size = size;
732 : 3068 : _PyCode_InitAddressRange(co, &bounds);
733 [ + + ]: 133987 : while(_PyLineTable_NextAddressRange(&bounds)) {
734 : 130919 : int start = bounds.ar_start / sizeof(_Py_CODEUNIT);
735 : 130919 : int end = bounds.ar_end / sizeof(_Py_CODEUNIT);
736 [ + + ]: 442758 : for (int index = start; index < end; index++) {
737 : : assert(index < (int)Py_SIZE(co));
738 [ + + ]: 311839 : if (size == 2) {
739 : : assert(((int16_t)bounds.ar_line) == bounds.ar_line);
740 : 311803 : ((int16_t *)co->_co_linearray)[index] = bounds.ar_line;
741 : : }
742 : : else {
743 : : assert(size == 4);
744 : 36 : ((int32_t *)co->_co_linearray)[index] = bounds.ar_line;
745 : : }
746 : : }
747 : : }
748 : 3068 : return 0;
749 : : }
750 : :
751 : : int
752 : 11008745 : PyCode_Addr2Line(PyCodeObject *co, int addrq)
753 : : {
754 [ - + ]: 11008745 : if (addrq < 0) {
755 : 0 : return co->co_firstlineno;
756 : : }
757 : : assert(addrq >= 0 && addrq < _PyCode_NBYTES(co));
758 [ + + ]: 11008745 : if (co->_co_linearray) {
759 : 33877 : return _PyCode_LineNumberFromArray(co, addrq / sizeof(_Py_CODEUNIT));
760 : : }
761 : : PyCodeAddressRange bounds;
762 : 10974868 : _PyCode_InitAddressRange(co, &bounds);
763 : 10974868 : return _PyCode_CheckLineNumber(addrq, &bounds);
764 : : }
765 : :
766 : : void
767 : 10995422 : _PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range)
768 : : {
769 : 10995422 : range->opaque.lo_next = (const uint8_t *)linetable;
770 : 10995422 : range->opaque.limit = range->opaque.lo_next + length;
771 : 10995422 : range->ar_start = -1;
772 : 10995422 : range->ar_end = 0;
773 : 10995422 : range->opaque.computed_line = firstlineno;
774 : 10995422 : range->ar_line = -1;
775 : 10995422 : }
776 : :
777 : : int
778 : 10995422 : _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds)
779 : : {
780 : : assert(co->co_linetable != NULL);
781 : 10995422 : const char *linetable = PyBytes_AS_STRING(co->co_linetable);
782 : 10995422 : Py_ssize_t length = PyBytes_GET_SIZE(co->co_linetable);
783 : 10995422 : _PyLineTable_InitAddressRange(linetable, length, co->co_firstlineno, bounds);
784 : 10995422 : 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 : 10975297 : _PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds)
791 : : {
792 [ + + ]: 412742677 : while (bounds->ar_end <= lasti) {
793 [ + + ]: 401767381 : if (!_PyLineTable_NextAddressRange(bounds)) {
794 : 1 : return -1;
795 : : }
796 : : }
797 [ - + ]: 10975296 : while (bounds->ar_start > lasti) {
798 [ # # ]: 0 : if (!_PyLineTable_PreviousAddressRange(bounds)) {
799 : 0 : return -1;
800 : : }
801 : : }
802 : 10975296 : return bounds->ar_line;
803 : : }
804 : :
805 : : static int
806 : 402251066 : is_no_line_marker(uint8_t b)
807 : : {
808 : 402251066 : 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 : 402250637 : next_code_delta(PyCodeAddressRange *bounds)
820 : : {
821 : : assert((*bounds->opaque.lo_next) & 128);
822 : 402250637 : return (((*bounds->opaque.lo_next) & 7) + 1) * sizeof(_Py_CODEUNIT);
823 : : }
824 : :
825 : : static int
826 : 429 : previous_code_delta(PyCodeAddressRange *bounds)
827 : : {
828 [ + + ]: 429 : 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 : 428 : const uint8_t *ptr = bounds->opaque.lo_next-1;
834 [ + + ]: 1074 : while (((*ptr) & 128) == 0) {
835 : 646 : ptr--;
836 : : }
837 : 428 : return (((*ptr) & 7) + 1) * sizeof(_Py_CODEUNIT);
838 : : }
839 : :
840 : : static int
841 : 1002831 : read_byte(PyCodeAddressRange *bounds)
842 : : {
843 : 1002831 : return *bounds->opaque.lo_next++;
844 : : }
845 : :
846 : : static int
847 : 189119 : read_varint(PyCodeAddressRange *bounds)
848 : : {
849 : 189119 : unsigned int read = read_byte(bounds);
850 : 189119 : unsigned int val = read & 63;
851 : 189119 : unsigned int shift = 0;
852 [ + + ]: 244426 : while (read & 64) {
853 : 55307 : read = read_byte(bounds);
854 : 55307 : shift += 6;
855 : 55307 : val |= (read & 63) << shift;
856 : : }
857 : 189119 : return val;
858 : : }
859 : :
860 : : static int
861 : 47543 : read_signed_varint(PyCodeAddressRange *bounds)
862 : : {
863 : 47543 : unsigned int uval = read_varint(bounds);
864 [ + + ]: 47543 : if (uval & 1) {
865 : 3512 : return -(int)(uval >> 1);
866 : : }
867 : : else {
868 : 44031 : return uval >> 1;
869 : : }
870 : : }
871 : :
872 : : static void
873 : 429 : retreat(PyCodeAddressRange *bounds)
874 : : {
875 : : ASSERT_VALID_BOUNDS(bounds);
876 : : assert(bounds->ar_start >= 0);
877 : : do {
878 : 1133 : bounds->opaque.lo_next--;
879 [ + + ]: 1133 : } while (((*bounds->opaque.lo_next) & 128) == 0);
880 : 429 : bounds->opaque.computed_line -= get_line_delta(bounds->opaque.lo_next);
881 : 429 : bounds->ar_end = bounds->ar_start;
882 : 429 : bounds->ar_start -= previous_code_delta(bounds);
883 [ - + ]: 429 : if (is_no_line_marker(bounds->opaque.lo_next[-1])) {
884 : 0 : bounds->ar_line = -1;
885 : : }
886 : : else {
887 : 429 : bounds->ar_line = bounds->opaque.computed_line;
888 : : }
889 : : ASSERT_VALID_BOUNDS(bounds);
890 : 429 : }
891 : :
892 : : static void
893 : 402250637 : advance(PyCodeAddressRange *bounds)
894 : : {
895 : : ASSERT_VALID_BOUNDS(bounds);
896 : 402250637 : bounds->opaque.computed_line += get_line_delta(bounds->opaque.lo_next);
897 [ + + ]: 402250637 : if (is_no_line_marker(*bounds->opaque.lo_next)) {
898 : 2269101 : bounds->ar_line = -1;
899 : : }
900 : : else {
901 : 399981536 : bounds->ar_line = bounds->opaque.computed_line;
902 : : }
903 : 402250637 : bounds->ar_start = bounds->ar_end;
904 : 402250637 : bounds->ar_end += next_code_delta(bounds);
905 : : do {
906 : 1168246199 : bounds->opaque.lo_next++;
907 [ + + ]: 1168246199 : } while (bounds->opaque.lo_next < bounds->opaque.limit &&
908 [ + + ]: 1168173262 : ((*bounds->opaque.lo_next) & 128) == 0);
909 : : ASSERT_VALID_BOUNDS(bounds);
910 : 402250637 : }
911 : :
912 : : static void
913 : 338218 : advance_with_locations(PyCodeAddressRange *bounds, int *endline, int *column, int *endcolumn)
914 : : {
915 : : ASSERT_VALID_BOUNDS(bounds);
916 : 338218 : int first_byte = read_byte(bounds);
917 : 338218 : int code = (first_byte >> 3) & 15;
918 : 338218 : bounds->ar_start = bounds->ar_end;
919 : 338218 : bounds->ar_end = bounds->ar_start + ((first_byte & 7) + 1) * sizeof(_Py_CODEUNIT);
920 [ + + + + : 338218 : switch(code) {
+ ]
921 : 5224 : case PY_CODE_LOCATION_INFO_NONE:
922 : 5224 : bounds->ar_line = *endline = -1;
923 : 5224 : *column = *endcolumn = -1;
924 : 5224 : break;
925 : 47192 : case PY_CODE_LOCATION_INFO_LONG:
926 : : {
927 : 47192 : bounds->opaque.computed_line += read_signed_varint(bounds);
928 : 47192 : bounds->ar_line = bounds->opaque.computed_line;
929 : 47192 : *endline = bounds->ar_line + read_varint(bounds);
930 : 47192 : *column = read_varint(bounds)-1;
931 : 47192 : *endcolumn = read_varint(bounds)-1;
932 : 47192 : break;
933 : : }
934 : 351 : case PY_CODE_LOCATION_INFO_NO_COLUMNS:
935 : : {
936 : : /* No column */
937 : 351 : bounds->opaque.computed_line += read_signed_varint(bounds);
938 : 351 : *endline = bounds->ar_line = bounds->opaque.computed_line;
939 : 351 : *column = *endcolumn = -1;
940 : 351 : break;
941 : : }
942 : 134736 : 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 : 134736 : int line_delta = code - 10;
948 : 134736 : bounds->opaque.computed_line += line_delta;
949 : 134736 : *endline = bounds->ar_line = bounds->opaque.computed_line;
950 : 134736 : *column = read_byte(bounds);
951 : 134736 : *endcolumn = read_byte(bounds);
952 : 134736 : break;
953 : : }
954 : 150715 : default:
955 : : {
956 : : /* Short forms */
957 : 150715 : int second_byte = read_byte(bounds);
958 : : assert((second_byte & 128) == 0);
959 : 150715 : *endline = bounds->ar_line = bounds->opaque.computed_line;
960 : 150715 : *column = code << 3 | (second_byte >> 4);
961 : 150715 : *endcolumn = *column + (second_byte & 15);
962 : : }
963 : : }
964 : : ASSERT_VALID_BOUNDS(bounds);
965 : 338218 : }
966 : : int
967 : 429 : PyCode_Addr2Location(PyCodeObject *co, int addrq,
968 : : int *start_line, int *start_column,
969 : : int *end_line, int *end_column)
970 : : {
971 [ - + ]: 429 : if (addrq < 0) {
972 : 0 : *start_line = *end_line = co->co_firstlineno;
973 : 0 : *start_column = *end_column = 0;
974 : : }
975 : : assert(addrq >= 0 && addrq < _PyCode_NBYTES(co));
976 : : PyCodeAddressRange bounds;
977 : 429 : _PyCode_InitAddressRange(co, &bounds);
978 : 429 : _PyCode_CheckLineNumber(addrq, &bounds);
979 : 429 : retreat(&bounds);
980 : 429 : advance_with_locations(&bounds, end_line, start_column, end_column);
981 : 429 : *start_line = bounds.ar_line;
982 : 429 : return 1;
983 : : }
984 : :
985 : :
986 : : static inline int
987 : 402600027 : at_end(PyCodeAddressRange *bounds) {
988 : 402600027 : 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 : : assert(range->ar_end > range->ar_start);
999 : 0 : return 1;
1000 : : }
1001 : :
1002 : : int
1003 : 402262209 : _PyLineTable_NextAddressRange(PyCodeAddressRange *range)
1004 : : {
1005 [ + + ]: 402262209 : if (at_end(range)) {
1006 : 11572 : return 0;
1007 : : }
1008 : 402250637 : advance(range);
1009 : : assert(range->ar_end > range->ar_start);
1010 : 402250637 : 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 : 5342 : lineiter_dealloc(lineiterator *li)
1121 : : {
1122 : 5342 : Py_DECREF(li->li_code);
1123 : 5342 : Py_TYPE(li)->tp_free(li);
1124 : 5342 : }
1125 : :
1126 : : static PyObject *
1127 : 222871 : lineiter_next(lineiterator *li)
1128 : : {
1129 : 222871 : PyCodeAddressRange *bounds = &li->li_line;
1130 [ + + ]: 222871 : if (!_PyLineTable_NextAddressRange(bounds)) {
1131 : 5342 : return NULL;
1132 : : }
1133 : 217529 : PyObject *start = NULL;
1134 : 217529 : PyObject *end = NULL;
1135 : 217529 : PyObject *line = NULL;
1136 : 217529 : PyObject *result = PyTuple_New(3);
1137 : 217529 : start = PyLong_FromLong(bounds->ar_start);
1138 : 217529 : end = PyLong_FromLong(bounds->ar_end);
1139 [ + + ]: 217529 : if (bounds->ar_line < 0) {
1140 : 3490 : Py_INCREF(Py_None);
1141 : 3490 : line = Py_None;
1142 : : }
1143 : : else {
1144 : 214039 : line = PyLong_FromLong(bounds->ar_line);
1145 : : }
1146 [ + - + - : 217529 : if (result == NULL || start == NULL || end == NULL || line == NULL) {
+ - - + ]
1147 : 0 : goto error;
1148 : : }
1149 : 217529 : PyTuple_SET_ITEM(result, 0, start);
1150 : 217529 : PyTuple_SET_ITEM(result, 1, end);
1151 : 217529 : PyTuple_SET_ITEM(result, 2, line);
1152 : 217529 : 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 : 5342 : new_linesiterator(PyCodeObject *code)
1206 : : {
1207 : 5342 : lineiterator *li = (lineiterator *)PyType_GenericAlloc(&_PyLineIterator, 0);
1208 [ - + ]: 5342 : if (li == NULL) {
1209 : 0 : return NULL;
1210 : : }
1211 : 5342 : Py_INCREF(code);
1212 : 5342 : li->li_code = code;
1213 : 5342 : _PyCode_InitAddressRange(code, &li->li_line);
1214 : 5342 : 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 : 8554 : positionsiter_dealloc(positionsiterator* pi)
1230 : : {
1231 : 8554 : Py_DECREF(pi->pi_code);
1232 : 8554 : Py_TYPE(pi)->tp_free(pi);
1233 : 8554 : }
1234 : :
1235 : : static PyObject*
1236 : 2614368 : _source_offset_converter(int* value) {
1237 [ + + ]: 2614368 : if (*value == -1) {
1238 : 21716 : Py_RETURN_NONE;
1239 : : }
1240 : 2592652 : return PyLong_FromLong(*value);
1241 : : }
1242 : :
1243 : : static PyObject*
1244 : 653621 : positionsiter_next(positionsiterator* pi)
1245 : : {
1246 [ + + ]: 653621 : if (pi->pi_offset >= pi->pi_range.ar_end) {
1247 : : assert(pi->pi_offset == pi->pi_range.ar_end);
1248 [ + + ]: 337818 : if (at_end(&pi->pi_range)) {
1249 : 29 : return NULL;
1250 : : }
1251 : 337789 : advance_with_locations(&pi->pi_range, &pi->pi_endline, &pi->pi_column, &pi->pi_endcolumn);
1252 : : }
1253 : 653592 : pi->pi_offset += 2;
1254 : 653592 : 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 : 8554 : code_positionsiterator(PyCodeObject* code, PyObject* Py_UNUSED(args))
1306 : : {
1307 : 8554 : positionsiterator* pi = (positionsiterator*)PyType_GenericAlloc(&_PyPositionsIterator, 0);
1308 [ - + ]: 8554 : if (pi == NULL) {
1309 : 0 : return NULL;
1310 : : }
1311 : 8554 : Py_INCREF(code);
1312 : 8554 : pi->pi_code = code;
1313 : 8554 : _PyCode_InitAddressRange(code, &pi->pi_range);
1314 : 8554 : pi->pi_offset = pi->pi_range.ar_end;
1315 : 8554 : 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 : 3603 : _PyCode_GetVarnames(PyCodeObject *co)
1399 : : {
1400 : 3603 : 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 : 2492280 : deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len)
1417 : : {
1418 [ + + ]: 99038504 : for (int i = 0; i < len; i++) {
1419 : 96546224 : _Py_CODEUNIT instruction = instructions[i];
1420 : 96546224 : int opcode = _PyOpcode_Original[_Py_OPCODE(instruction)];
1421 : 96546224 : int caches = _PyOpcode_Caches[opcode];
1422 : 96546224 : instructions[i] = _Py_MAKECODEUNIT(opcode, _Py_OPARG(instruction));
1423 [ + + ]: 227354266 : while (caches--) {
1424 : 130808042 : instructions[++i] = _Py_MAKECODEUNIT(CACHE, 0);
1425 : : }
1426 : : }
1427 : 2492280 : }
1428 : :
1429 : : PyObject *
1430 : 232521 : _PyCode_GetCode(PyCodeObject *co)
1431 : : {
1432 [ + + ]: 232521 : if (co->_co_code != NULL) {
1433 : 3126 : return Py_NewRef(co->_co_code);
1434 : : }
1435 : 229395 : PyObject *code = PyBytes_FromStringAndSize((const char *)_PyCode_CODE(co),
1436 : 229395 : _PyCode_NBYTES(co));
1437 [ - + ]: 229395 : if (code == NULL) {
1438 : 0 : return NULL;
1439 : : }
1440 : 229395 : deopt_code((_Py_CODEUNIT *)PyBytes_AS_STRING(code), Py_SIZE(co));
1441 : : assert(co->_co_code == NULL);
1442 : 229395 : co->_co_code = Py_NewRef(code);
1443 : 229395 : 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 : 7465010 : code_dealloc(PyCodeObject *co)
1576 : : {
1577 [ + + ]: 7465010 : 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 : 7465010 : Py_XDECREF(co->co_consts);
1593 : 7465010 : Py_XDECREF(co->co_names);
1594 : 7465010 : Py_XDECREF(co->co_localsplusnames);
1595 : 7465010 : Py_XDECREF(co->co_localspluskinds);
1596 : 7465010 : Py_XDECREF(co->co_filename);
1597 : 7465010 : Py_XDECREF(co->co_name);
1598 : 7465010 : Py_XDECREF(co->co_qualname);
1599 : 7465010 : Py_XDECREF(co->co_linetable);
1600 : 7465010 : Py_XDECREF(co->co_exceptiontable);
1601 : 7465010 : Py_XDECREF(co->_co_code);
1602 [ + + ]: 7465010 : if (co->co_weakreflist != NULL) {
1603 : 1 : PyObject_ClearWeakRefs((PyObject*)co);
1604 : : }
1605 [ + + ]: 7465010 : if (co->_co_linearray) {
1606 : 2314 : PyMem_Free(co->_co_linearray);
1607 : : }
1608 [ + + ]: 7465010 : if (co->co_warmup == 0) {
1609 : 346515 : _Py_QuickenedCount--;
1610 : : }
1611 : 7465010 : PyObject_Free(co);
1612 : 7465010 : }
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 : 55086 : 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 [ + + + - : 110172 : if ((op != Py_EQ && op != Py_NE) ||
+ - ]
1642 [ - + ]: 110172 : !PyCode_Check(self) ||
1643 : 55086 : !PyCode_Check(other)) {
1644 : 0 : Py_RETURN_NOTIMPLEMENTED;
1645 : : }
1646 : :
1647 : 55086 : co = (PyCodeObject *)self;
1648 : 55086 : cp = (PyCodeObject *)other;
1649 : :
1650 : 55086 : eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
1651 [ + + ]: 55086 : if (!eq) goto unequal;
1652 : 28232 : eq = co->co_argcount == cp->co_argcount;
1653 [ + + ]: 28232 : if (!eq) goto unequal;
1654 : 28218 : eq = co->co_posonlyargcount == cp->co_posonlyargcount;
1655 [ - + ]: 28218 : if (!eq) goto unequal;
1656 : 28218 : eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
1657 [ - + ]: 28218 : if (!eq) goto unequal;
1658 : 28218 : eq = co->co_flags == cp->co_flags;
1659 [ - + ]: 28218 : if (!eq) goto unequal;
1660 : 28218 : eq = co->co_firstlineno == cp->co_firstlineno;
1661 [ + + ]: 28218 : if (!eq) goto unequal;
1662 : 2324 : eq = Py_SIZE(co) == Py_SIZE(cp);
1663 [ - + ]: 2324 : if (!eq) {
1664 : 0 : goto unequal;
1665 : : }
1666 [ + + ]: 68670 : for (int i = 0; i < Py_SIZE(co); i++) {
1667 : 66349 : _Py_CODEUNIT co_instr = _PyCode_CODE(co)[i];
1668 : 66349 : _Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i];
1669 : 66349 : _Py_SET_OPCODE(co_instr, _PyOpcode_Deopt[_Py_OPCODE(co_instr)]);
1670 : 66349 : _Py_SET_OPCODE(cp_instr, _PyOpcode_Deopt[_Py_OPCODE(cp_instr)]);
1671 : 66349 : eq = co_instr == cp_instr;
1672 [ + + ]: 66349 : if (!eq) {
1673 : 3 : goto unequal;
1674 : : }
1675 : 66346 : i += _PyOpcode_Caches[_Py_OPCODE(co_instr)];
1676 : : }
1677 : :
1678 : : /* compare constants */
1679 : 2321 : consts1 = _PyCode_ConstantKey(co->co_consts);
1680 [ - + ]: 2321 : if (!consts1)
1681 : 0 : return NULL;
1682 : 2321 : consts2 = _PyCode_ConstantKey(cp->co_consts);
1683 [ - + ]: 2321 : if (!consts2) {
1684 : 0 : Py_DECREF(consts1);
1685 : 0 : return NULL;
1686 : : }
1687 : 2321 : eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
1688 : 2321 : Py_DECREF(consts1);
1689 : 2321 : Py_DECREF(consts2);
1690 [ + + ]: 2321 : if (eq <= 0) goto unequal;
1691 : :
1692 : 2279 : eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
1693 [ - + ]: 2279 : if (eq <= 0) goto unequal;
1694 : 2279 : eq = PyObject_RichCompareBool(co->co_localsplusnames,
1695 : : cp->co_localsplusnames, Py_EQ);
1696 [ - + ]: 2279 : if (eq <= 0) goto unequal;
1697 : :
1698 [ + + ]: 2279 : if (op == Py_EQ)
1699 : 2188 : res = Py_True;
1700 : : else
1701 : 91 : res = Py_False;
1702 : 2279 : goto done;
1703 : :
1704 : 52807 : unequal:
1705 [ - + ]: 52807 : if (eq < 0)
1706 : 0 : return NULL;
1707 [ + + ]: 52807 : if (op == Py_NE)
1708 : 7 : res = Py_True;
1709 : : else
1710 : 52800 : res = Py_False;
1711 : :
1712 : 55086 : done:
1713 : 55086 : Py_INCREF(res);
1714 : 55086 : return res;
1715 : : }
1716 : :
1717 : : static Py_hash_t
1718 : 3006948 : code_hash(PyCodeObject *co)
1719 : : {
1720 : : Py_hash_t h, h0, h1, h2, h3;
1721 : 3006948 : h0 = PyObject_Hash(co->co_name);
1722 [ - + ]: 3006948 : if (h0 == -1) return -1;
1723 : 3006948 : h1 = PyObject_Hash(co->co_consts);
1724 [ - + ]: 3006948 : if (h1 == -1) return -1;
1725 : 3006948 : h2 = PyObject_Hash(co->co_names);
1726 [ - + ]: 3006948 : if (h2 == -1) return -1;
1727 : 3006948 : h3 = PyObject_Hash(co->co_localsplusnames);
1728 [ - + ]: 3006948 : if (h3 == -1) return -1;
1729 : 3006948 : h = h0 ^ h1 ^ h2 ^ h3 ^
1730 : 3006948 : co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^
1731 : 3006948 : co->co_flags;
1732 [ - + ]: 3006948 : if (h == -1) h = -2;
1733 : 3006948 : 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 : 3580 : code_getvarnames(PyCodeObject *code, void *closure)
1766 : : {
1767 : 3580 : 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 : 4515 : code_getcode(PyCodeObject *code, void *closure)
1791 : : {
1792 : 4515 : 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 : 5342 : code_linesiterator(PyCodeObject *code, PyObject *Py_UNUSED(args))
1823 : : {
1824 : 5342 : 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 : 856 : 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 [ - + ]: 856 : CHECK_INT_ARG(co_argcount);
1874 [ - + ]: 856 : CHECK_INT_ARG(co_posonlyargcount);
1875 [ - + ]: 856 : CHECK_INT_ARG(co_kwonlyargcount);
1876 [ - + ]: 856 : CHECK_INT_ARG(co_nlocals);
1877 [ - + ]: 856 : CHECK_INT_ARG(co_stacksize);
1878 [ - + ]: 856 : CHECK_INT_ARG(co_flags);
1879 [ - + ]: 856 : CHECK_INT_ARG(co_firstlineno);
1880 : :
1881 : : #undef CHECK_INT_ARG
1882 : :
1883 : 856 : PyObject *code = NULL;
1884 [ + + ]: 856 : if (co_code == NULL) {
1885 : 854 : code = _PyCode_GetCode(self);
1886 [ - + ]: 854 : if (code == NULL) {
1887 : 0 : return NULL;
1888 : : }
1889 : 854 : co_code = (PyBytesObject *)code;
1890 : : }
1891 : :
1892 [ - + ]: 856 : 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 : 856 : PyCodeObject *co = NULL;
1900 : 856 : PyObject *varnames = NULL;
1901 : 856 : PyObject *cellvars = NULL;
1902 : 856 : PyObject *freevars = NULL;
1903 [ + + ]: 856 : if (co_varnames == NULL) {
1904 : 854 : varnames = get_localsplus_names(self, CO_FAST_LOCAL, self->co_nlocals);
1905 [ - + ]: 854 : if (varnames == NULL) {
1906 : 0 : goto error;
1907 : : }
1908 : 854 : co_varnames = varnames;
1909 : : }
1910 [ + + ]: 856 : if (co_cellvars == NULL) {
1911 : 855 : cellvars = get_localsplus_names(self, CO_FAST_CELL, self->co_ncellvars);
1912 [ - + ]: 855 : if (cellvars == NULL) {
1913 : 0 : goto error;
1914 : : }
1915 : 855 : co_cellvars = cellvars;
1916 : : }
1917 [ + + ]: 856 : if (co_freevars == NULL) {
1918 : 854 : freevars = get_localsplus_names(self, CO_FAST_FREE, self->co_nfreevars);
1919 [ - + ]: 854 : if (freevars == NULL) {
1920 : 0 : goto error;
1921 : : }
1922 : 854 : co_freevars = freevars;
1923 : : }
1924 : :
1925 : 856 : 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 : 856 : error:
1933 : 856 : Py_XDECREF(code);
1934 : 856 : Py_XDECREF(varnames);
1935 : 856 : Py_XDECREF(cellvars);
1936 : 856 : Py_XDECREF(freevars);
1937 : 856 : 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 : 8945 : code__varname_from_oparg_impl(PyCodeObject *self, int oparg)
1952 : : /*[clinic end generated code: output=1fd1130413184206 input=c5fa3ee9bac7d4ca]*/
1953 : : {
1954 : 8945 : PyObject *name = PyTuple_GetItem(self->co_localsplusnames, oparg);
1955 [ - + ]: 8945 : if (name == NULL) {
1956 : 0 : return NULL;
1957 : : }
1958 : 8945 : Py_INCREF(name);
1959 : 8945 : 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 : 15789746 : _PyCode_ConstantKey(PyObject *op)
2022 : : {
2023 : : PyObject *key;
2024 : :
2025 : : /* Py_None and Py_Ellipsis are singletons. */
2026 [ + + + + ]: 15789746 : if (op == Py_None || op == Py_Ellipsis
2027 [ + + ]: 15377461 : || PyLong_CheckExact(op)
2028 [ + + ]: 11355451 : || PyUnicode_CheckExact(op)
2029 : : /* code_richcompare() uses _PyCode_ConstantKey() internally */
2030 [ + + ]: 4341191 : || PyCode_Check(op))
2031 : : {
2032 : : /* Objects of these types are always different from object of other
2033 : : * type and from tuples. */
2034 : 12146464 : Py_INCREF(op);
2035 : 12146464 : key = op;
2036 : : }
2037 [ + + + + ]: 3643282 : 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 : 1602444 : key = PyTuple_Pack(2, Py_TYPE(op), op);
2041 : : }
2042 [ + + ]: 2040838 : else if (PyFloat_CheckExact(op)) {
2043 : 31400 : 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 [ + + + + ]: 31400 : if (d == 0.0 && copysign(1.0, d) < 0.0)
2048 : 372 : key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
2049 : : else
2050 : 31028 : key = PyTuple_Pack(2, Py_TYPE(op), op);
2051 : : }
2052 [ + + ]: 2009438 : 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 : 1840 : z = PyComplex_AsCComplex(op);
2060 [ + + + + ]: 1840 : real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
2061 [ + + + + ]: 1840 : 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 [ + + + + ]: 1840 : if (real_negzero && imag_negzero) {
2065 : 73 : key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True);
2066 : : }
2067 [ + + ]: 1767 : else if (imag_negzero) {
2068 : 2 : key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False);
2069 : : }
2070 [ + + ]: 1765 : else if (real_negzero) {
2071 : 61 : key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
2072 : : }
2073 : : else {
2074 : 1704 : key = PyTuple_Pack(2, Py_TYPE(op), op);
2075 : : }
2076 : : }
2077 [ + + ]: 2007598 : else if (PyTuple_CheckExact(op)) {
2078 : : Py_ssize_t i, len;
2079 : : PyObject *tuple;
2080 : :
2081 : 2005121 : len = PyTuple_GET_SIZE(op);
2082 : 2005121 : tuple = PyTuple_New(len);
2083 [ - + ]: 2005121 : if (tuple == NULL)
2084 : 0 : return NULL;
2085 : :
2086 [ + + ]: 10649358 : for (i=0; i < len; i++) {
2087 : : PyObject *item, *item_key;
2088 : :
2089 : 8644237 : item = PyTuple_GET_ITEM(op, i);
2090 : 8644237 : item_key = _PyCode_ConstantKey(item);
2091 [ - + ]: 8644237 : if (item_key == NULL) {
2092 : 0 : Py_DECREF(tuple);
2093 : 0 : return NULL;
2094 : : }
2095 : :
2096 : 8644237 : PyTuple_SET_ITEM(tuple, i, item_key);
2097 : : }
2098 : :
2099 : 2005121 : key = PyTuple_Pack(2, tuple, op);
2100 : 2005121 : Py_DECREF(tuple);
2101 : : }
2102 [ + - ]: 2477 : else if (PyFrozenSet_CheckExact(op)) {
2103 : 2477 : 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 : 2477 : len = PySet_GET_SIZE(op);
2110 : 2477 : tuple = PyTuple_New(len);
2111 [ - + ]: 2477 : if (tuple == NULL)
2112 : 0 : return NULL;
2113 : :
2114 : 2477 : i = 0;
2115 [ + + ]: 16240 : while (_PySet_NextEntry(op, &pos, &item, &hash)) {
2116 : : PyObject *item_key;
2117 : :
2118 : 13763 : item_key = _PyCode_ConstantKey(item);
2119 [ - + ]: 13763 : if (item_key == NULL) {
2120 : 0 : Py_DECREF(tuple);
2121 : 0 : return NULL;
2122 : : }
2123 : :
2124 : : assert(i < len);
2125 : 13763 : PyTuple_SET_ITEM(tuple, i, item_key);
2126 : 13763 : i++;
2127 : : }
2128 : 2477 : set = PyFrozenSet_New(tuple);
2129 : 2477 : Py_DECREF(tuple);
2130 [ - + ]: 2477 : if (set == NULL)
2131 : 0 : return NULL;
2132 : :
2133 : 2477 : key = PyTuple_Pack(2, set, op);
2134 : 2477 : Py_DECREF(set);
2135 : 2477 : 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 : 15787269 : return key;
2148 : : }
2149 : :
2150 : : void
2151 : 2262885 : _PyStaticCode_Dealloc(PyCodeObject *co)
2152 : : {
2153 [ + + ]: 2262885 : if (co->co_warmup == 0) {
2154 : 251027 : _Py_QuickenedCount--;
2155 : : }
2156 : 2262885 : deopt_code(_PyCode_CODE(co), Py_SIZE(co));
2157 : 2262885 : co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE;
2158 : 2262885 : PyMem_Free(co->co_extra);
2159 [ - + ]: 2262885 : Py_CLEAR(co->_co_code);
2160 : 2262885 : co->co_extra = NULL;
2161 [ - + ]: 2262885 : if (co->co_weakreflist != NULL) {
2162 : 0 : PyObject_ClearWeakRefs((PyObject *)co);
2163 : 0 : co->co_weakreflist = NULL;
2164 : : }
2165 [ + + ]: 2262885 : if (co->_co_linearray) {
2166 : 751 : PyMem_Free(co->_co_linearray);
2167 : 751 : co->_co_linearray = NULL;
2168 : : }
2169 : 2262885 : }
2170 : :
2171 : : int
2172 : 2400123 : _PyStaticCode_InternStrings(PyCodeObject *co)
2173 : : {
2174 : 2400123 : int res = intern_strings(co->co_names);
2175 [ - + ]: 2400123 : if (res < 0) {
2176 : 0 : return -1;
2177 : : }
2178 : 2400123 : res = intern_string_constants(co->co_consts, NULL);
2179 [ - + ]: 2400123 : if (res < 0) {
2180 : 0 : return -1;
2181 : : }
2182 : 2400123 : res = intern_strings(co->co_localsplusnames);
2183 [ - + ]: 2400123 : if (res < 0) {
2184 : 0 : return -1;
2185 : : }
2186 : 2400123 : return 0;
2187 : : }
|