blob: e50f7306efb3b9610c18dfa8c1ba297154c428b6 [file] [log] [blame]
Jeremy Hylton3e0055f2005-10-20 19:59:25 +00001#include "Python.h"
2#include "code.h"
3#include "structmember.h"
4
5#define NAME_CHARS \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00006 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
Jeremy Hylton3e0055f2005-10-20 19:59:25 +00007
8/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
9
10static int
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020011all_name_chars(PyObject *o)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000012{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000013 static char ok_name_char[256];
14 static unsigned char *name_chars = (unsigned char *)NAME_CHARS;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020015 PyUnicodeObject *u = (PyUnicodeObject *)o;
16 const unsigned char *s;
17
18 if (!PyUnicode_Check(o) || PyUnicode_READY(u) == -1 ||
19 PyUnicode_MAX_CHAR_VALUE(u) >= 128)
20 return 0;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000021
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000022 if (ok_name_char[*name_chars] == 0) {
23 unsigned char *p;
24 for (p = name_chars; *p; p++)
25 ok_name_char[*p] = 1;
26 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020027 s = PyUnicode_1BYTE_DATA(u);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000028 while (*s) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000029 if (ok_name_char[*s++] == 0)
30 return 0;
31 }
32 return 1;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000033}
34
35static void
36intern_strings(PyObject *tuple)
37{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000038 Py_ssize_t i;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040 for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
41 PyObject *v = PyTuple_GET_ITEM(tuple, i);
42 if (v == NULL || !PyUnicode_CheckExact(v)) {
43 Py_FatalError("non-string found in code slot");
44 }
45 PyUnicode_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
46 }
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000047}
48
Serhiy Storchaka00a0fc12016-09-30 10:07:26 +030049/* Intern selected string constants */
50static int
51intern_string_constants(PyObject *tuple)
52{
53 int modified = 0;
54 Py_ssize_t i;
55
56 for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
57 PyObject *v = PyTuple_GET_ITEM(tuple, i);
58 if (PyUnicode_CheckExact(v)) {
59 if (all_name_chars(v)) {
60 PyObject *w = v;
61 PyUnicode_InternInPlace(&v);
62 if (w != v) {
63 PyTuple_SET_ITEM(tuple, i, v);
64 modified = 1;
65 }
66 }
67 }
68 else if (PyTuple_CheckExact(v)) {
69 intern_string_constants(v);
70 }
71 else if (PyFrozenSet_CheckExact(v)) {
72 PyObject *tmp = PySequence_Tuple(v);
73 if (tmp == NULL) {
74 PyErr_Clear();
75 continue;
76 }
77 if (intern_string_constants(tmp)) {
78 v = PyFrozenSet_New(tmp);
79 if (v == NULL) {
80 PyErr_Clear();
81 }
82 else {
83 PyTuple_SET_ITEM(tuple, i, v);
84 modified = 1;
85 }
86 }
87 Py_DECREF(tmp);
88 }
89 }
90 return modified;
91}
92
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000093
94PyCodeObject *
Guido van Rossum4f72a782006-10-27 23:31:49 +000095PyCode_New(int argcount, int kwonlyargcount,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096 int nlocals, int stacksize, int flags,
97 PyObject *code, PyObject *consts, PyObject *names,
98 PyObject *varnames, PyObject *freevars, PyObject *cellvars,
99 PyObject *filename, PyObject *name, int firstlineno,
100 PyObject *lnotab)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000102 PyCodeObject *co;
Benjamin Peterson90037602011-06-25 22:54:45 -0500103 unsigned char *cell2arg = NULL;
104 Py_ssize_t i, n_cellvars;
Guido van Rossum00bc0e02007-10-15 02:52:41 +0000105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 /* Check argument types */
107 if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 ||
108 code == NULL ||
109 consts == NULL || !PyTuple_Check(consts) ||
110 names == NULL || !PyTuple_Check(names) ||
111 varnames == NULL || !PyTuple_Check(varnames) ||
112 freevars == NULL || !PyTuple_Check(freevars) ||
113 cellvars == NULL || !PyTuple_Check(cellvars) ||
114 name == NULL || !PyUnicode_Check(name) ||
115 filename == NULL || !PyUnicode_Check(filename) ||
116 lnotab == NULL || !PyBytes_Check(lnotab) ||
117 !PyObject_CheckReadBuffer(code)) {
118 PyErr_BadInternalCall();
119 return NULL;
120 }
Victor Stinner7c74de42013-10-10 15:55:14 +0200121
122 /* Ensure that the filename is a ready Unicode string */
123 if (PyUnicode_READY(filename) < 0)
124 return NULL;
125
Benjamin Peterson90037602011-06-25 22:54:45 -0500126 n_cellvars = PyTuple_GET_SIZE(cellvars);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 intern_strings(names);
128 intern_strings(varnames);
129 intern_strings(freevars);
130 intern_strings(cellvars);
Serhiy Storchaka00a0fc12016-09-30 10:07:26 +0300131 intern_string_constants(consts);
Benjamin Peterson90037602011-06-25 22:54:45 -0500132 /* Create mapping between cells and arguments if needed. */
133 if (n_cellvars) {
134 Py_ssize_t total_args = argcount + kwonlyargcount +
135 ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0);
136 Py_ssize_t alloc_size = sizeof(unsigned char) * n_cellvars;
137 int used_cell2arg = 0;
138 cell2arg = PyMem_MALLOC(alloc_size);
139 if (cell2arg == NULL)
140 return NULL;
141 memset(cell2arg, CO_CELL_NOT_AN_ARG, alloc_size);
142 /* Find cells which are also arguments. */
143 for (i = 0; i < n_cellvars; i++) {
144 Py_ssize_t j;
145 PyObject *cell = PyTuple_GET_ITEM(cellvars, i);
146 for (j = 0; j < total_args; j++) {
147 PyObject *arg = PyTuple_GET_ITEM(varnames, j);
148 if (!PyUnicode_Compare(cell, arg)) {
149 cell2arg[i] = j;
150 used_cell2arg = 1;
151 break;
152 }
153 }
154 }
155 if (!used_cell2arg) {
156 PyMem_FREE(cell2arg);
157 cell2arg = NULL;
158 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 }
Benjamin Peterson90037602011-06-25 22:54:45 -0500160 co = PyObject_NEW(PyCodeObject, &PyCode_Type);
161 if (co == NULL) {
162 if (cell2arg)
163 PyMem_FREE(cell2arg);
164 return NULL;
165 }
166 co->co_argcount = argcount;
167 co->co_kwonlyargcount = kwonlyargcount;
168 co->co_nlocals = nlocals;
169 co->co_stacksize = stacksize;
170 co->co_flags = flags;
171 Py_INCREF(code);
172 co->co_code = code;
173 Py_INCREF(consts);
174 co->co_consts = consts;
175 Py_INCREF(names);
176 co->co_names = names;
177 Py_INCREF(varnames);
178 co->co_varnames = varnames;
179 Py_INCREF(freevars);
180 co->co_freevars = freevars;
181 Py_INCREF(cellvars);
182 co->co_cellvars = cellvars;
183 co->co_cell2arg = cell2arg;
184 Py_INCREF(filename);
185 co->co_filename = filename;
186 Py_INCREF(name);
187 co->co_name = name;
188 co->co_firstlineno = firstlineno;
189 Py_INCREF(lnotab);
190 co->co_lnotab = lnotab;
191 co->co_zombieframe = NULL;
192 co->co_weakreflist = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 return co;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000194}
195
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000196PyCodeObject *
197PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
198{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 static PyObject *emptystring = NULL;
200 static PyObject *nulltuple = NULL;
201 PyObject *filename_ob = NULL;
202 PyObject *funcname_ob = NULL;
203 PyCodeObject *result = NULL;
204 if (emptystring == NULL) {
205 emptystring = PyBytes_FromString("");
206 if (emptystring == NULL)
207 goto failed;
208 }
209 if (nulltuple == NULL) {
210 nulltuple = PyTuple_New(0);
211 if (nulltuple == NULL)
212 goto failed;
213 }
214 funcname_ob = PyUnicode_FromString(funcname);
215 if (funcname_ob == NULL)
216 goto failed;
217 filename_ob = PyUnicode_DecodeFSDefault(filename);
218 if (filename_ob == NULL)
219 goto failed;
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000221 result = PyCode_New(0, /* argcount */
222 0, /* kwonlyargcount */
223 0, /* nlocals */
224 0, /* stacksize */
225 0, /* flags */
226 emptystring, /* code */
227 nulltuple, /* consts */
228 nulltuple, /* names */
229 nulltuple, /* varnames */
230 nulltuple, /* freevars */
231 nulltuple, /* cellvars */
232 filename_ob, /* filename */
233 funcname_ob, /* name */
234 firstlineno, /* firstlineno */
235 emptystring /* lnotab */
236 );
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000237
238failed:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 Py_XDECREF(funcname_ob);
240 Py_XDECREF(filename_ob);
241 return result;
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000242}
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000243
244#define OFF(x) offsetof(PyCodeObject, x)
245
246static PyMemberDef code_memberlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 {"co_argcount", T_INT, OFF(co_argcount), READONLY},
248 {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY},
249 {"co_nlocals", T_INT, OFF(co_nlocals), READONLY},
250 {"co_stacksize",T_INT, OFF(co_stacksize), READONLY},
251 {"co_flags", T_INT, OFF(co_flags), READONLY},
252 {"co_code", T_OBJECT, OFF(co_code), READONLY},
253 {"co_consts", T_OBJECT, OFF(co_consts), READONLY},
254 {"co_names", T_OBJECT, OFF(co_names), READONLY},
255 {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY},
256 {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY},
257 {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY},
258 {"co_filename", T_OBJECT, OFF(co_filename), READONLY},
259 {"co_name", T_OBJECT, OFF(co_name), READONLY},
260 {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY},
261 {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY},
262 {NULL} /* Sentinel */
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000263};
264
265/* Helper for code_new: return a shallow copy of a tuple that is
266 guaranteed to contain exact strings, by converting string subclasses
267 to exact strings and complaining if a non-string is found. */
268static PyObject*
269validate_and_copy_tuple(PyObject *tup)
270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 PyObject *newtuple;
272 PyObject *item;
273 Py_ssize_t i, len;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 len = PyTuple_GET_SIZE(tup);
276 newtuple = PyTuple_New(len);
277 if (newtuple == NULL)
278 return NULL;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 for (i = 0; i < len; i++) {
281 item = PyTuple_GET_ITEM(tup, i);
282 if (PyUnicode_CheckExact(item)) {
283 Py_INCREF(item);
284 }
285 else if (!PyUnicode_Check(item)) {
286 PyErr_Format(
287 PyExc_TypeError,
288 "name tuples must contain only "
289 "strings, not '%.500s'",
290 item->ob_type->tp_name);
291 Py_DECREF(newtuple);
292 return NULL;
293 }
294 else {
Victor Stinnerbf6e5602011-12-12 01:53:47 +0100295 item = _PyUnicode_Copy(item);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 if (item == NULL) {
297 Py_DECREF(newtuple);
298 return NULL;
299 }
300 }
301 PyTuple_SET_ITEM(newtuple, i, item);
302 }
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 return newtuple;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000305}
306
307PyDoc_STRVAR(code_doc,
Georg Brandl8c1a50a2009-07-18 09:07:48 +0000308"code(argcount, kwonlyargcount, nlocals, stacksize, flags, codestring,\n\
Georg Brandla1e7e132008-01-26 09:39:23 +0000309 constants, names, varnames, filename, name, firstlineno,\n\
310 lnotab[, freevars[, cellvars]])\n\
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000311\n\
312Create a code object. Not for the faint of heart.");
313
314static PyObject *
315code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
316{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 int argcount;
318 int kwonlyargcount;
319 int nlocals;
320 int stacksize;
321 int flags;
322 PyObject *co = NULL;
323 PyObject *code;
324 PyObject *consts;
325 PyObject *names, *ournames = NULL;
326 PyObject *varnames, *ourvarnames = NULL;
327 PyObject *freevars = NULL, *ourfreevars = NULL;
328 PyObject *cellvars = NULL, *ourcellvars = NULL;
329 PyObject *filename;
330 PyObject *name;
331 int firstlineno;
332 PyObject *lnotab;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 if (!PyArg_ParseTuple(args, "iiiiiSO!O!O!UUiS|O!O!:code",
335 &argcount, &kwonlyargcount,
336 &nlocals, &stacksize, &flags,
337 &code,
338 &PyTuple_Type, &consts,
339 &PyTuple_Type, &names,
340 &PyTuple_Type, &varnames,
341 &filename, &name,
342 &firstlineno, &lnotab,
343 &PyTuple_Type, &freevars,
344 &PyTuple_Type, &cellvars))
345 return NULL;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 if (argcount < 0) {
348 PyErr_SetString(
349 PyExc_ValueError,
350 "code: argcount must not be negative");
351 goto cleanup;
352 }
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 if (kwonlyargcount < 0) {
355 PyErr_SetString(
356 PyExc_ValueError,
357 "code: kwonlyargcount must not be negative");
358 goto cleanup;
359 }
360 if (nlocals < 0) {
361 PyErr_SetString(
362 PyExc_ValueError,
363 "code: nlocals must not be negative");
364 goto cleanup;
365 }
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 ournames = validate_and_copy_tuple(names);
368 if (ournames == NULL)
369 goto cleanup;
370 ourvarnames = validate_and_copy_tuple(varnames);
371 if (ourvarnames == NULL)
372 goto cleanup;
373 if (freevars)
374 ourfreevars = validate_and_copy_tuple(freevars);
375 else
376 ourfreevars = PyTuple_New(0);
377 if (ourfreevars == NULL)
378 goto cleanup;
379 if (cellvars)
380 ourcellvars = validate_and_copy_tuple(cellvars);
381 else
382 ourcellvars = PyTuple_New(0);
383 if (ourcellvars == NULL)
384 goto cleanup;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 co = (PyObject *)PyCode_New(argcount, kwonlyargcount,
387 nlocals, stacksize, flags,
388 code, consts, ournames, ourvarnames,
389 ourfreevars, ourcellvars, filename,
390 name, firstlineno, lnotab);
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000391 cleanup:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 Py_XDECREF(ournames);
393 Py_XDECREF(ourvarnames);
394 Py_XDECREF(ourfreevars);
395 Py_XDECREF(ourcellvars);
396 return co;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000397}
398
399static void
400code_dealloc(PyCodeObject *co)
401{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 Py_XDECREF(co->co_code);
403 Py_XDECREF(co->co_consts);
404 Py_XDECREF(co->co_names);
405 Py_XDECREF(co->co_varnames);
406 Py_XDECREF(co->co_freevars);
407 Py_XDECREF(co->co_cellvars);
408 Py_XDECREF(co->co_filename);
409 Py_XDECREF(co->co_name);
410 Py_XDECREF(co->co_lnotab);
Benjamin Peterson90037602011-06-25 22:54:45 -0500411 if (co->co_cell2arg != NULL)
412 PyMem_FREE(co->co_cell2arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 if (co->co_zombieframe != NULL)
414 PyObject_GC_Del(co->co_zombieframe);
415 if (co->co_weakreflist != NULL)
416 PyObject_ClearWeakRefs((PyObject*)co);
417 PyObject_DEL(co);
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000418}
419
420static PyObject *
Martin v. Löwis3bbd2fa2012-07-26 22:23:23 +0200421code_sizeof(PyCodeObject *co, void *unused)
422{
423 Py_ssize_t res;
424
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200425 res = _PyObject_SIZE(Py_TYPE(co));
Martin v. Löwis3bbd2fa2012-07-26 22:23:23 +0200426 if (co->co_cell2arg != NULL && co->co_cellvars != NULL)
427 res += PyTuple_GET_SIZE(co->co_cellvars) * sizeof(unsigned char);
428 return PyLong_FromSsize_t(res);
429}
430
431static PyObject *
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000432code_repr(PyCodeObject *co)
433{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 int lineno;
435 if (co->co_firstlineno != 0)
436 lineno = co->co_firstlineno;
437 else
438 lineno = -1;
439 if (co->co_filename && PyUnicode_Check(co->co_filename)) {
440 return PyUnicode_FromFormat(
Victor Stinneraaa4e9a2011-01-05 03:33:26 +0000441 "<code object %U at %p, file \"%U\", line %d>",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 co->co_name, co, co->co_filename, lineno);
443 } else {
444 return PyUnicode_FromFormat(
Victor Stinneraaa4e9a2011-01-05 03:33:26 +0000445 "<code object %U at %p, file ???, line %d>",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 co->co_name, co, lineno);
447 }
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000448}
449
Victor Stinner3cdd5fb2016-01-22 12:33:12 +0100450PyObject*
451_PyCode_ConstantKey(PyObject *op)
452{
453 PyObject *key;
454
455 /* Py_None and Py_Ellipsis are singleton */
456 if (op == Py_None || op == Py_Ellipsis
457 || PyLong_CheckExact(op)
458 || PyBool_Check(op)
459 || PyBytes_CheckExact(op)
460 || PyUnicode_CheckExact(op)
461 /* code_richcompare() uses _PyCode_ConstantKey() internally */
462 || PyCode_Check(op)) {
463 key = PyTuple_Pack(2, Py_TYPE(op), op);
464 }
465 else if (PyFloat_CheckExact(op)) {
466 double d = PyFloat_AS_DOUBLE(op);
467 /* all we need is to make the tuple different in either the 0.0
468 * or -0.0 case from all others, just to avoid the "coercion".
469 */
470 if (d == 0.0 && copysign(1.0, d) < 0.0)
471 key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
472 else
473 key = PyTuple_Pack(2, Py_TYPE(op), op);
474 }
475 else if (PyComplex_CheckExact(op)) {
476 Py_complex z;
477 int real_negzero, imag_negzero;
478 /* For the complex case we must make complex(x, 0.)
479 different from complex(x, -0.) and complex(0., y)
480 different from complex(-0., y), for any x and y.
481 All four complex zeros must be distinguished.*/
482 z = PyComplex_AsCComplex(op);
483 real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
484 imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
485 /* use True, False and None singleton as tags for the real and imag
486 * sign, to make tuples different */
487 if (real_negzero && imag_negzero) {
488 key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True);
489 }
490 else if (imag_negzero) {
491 key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False);
492 }
493 else if (real_negzero) {
494 key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
495 }
496 else {
497 key = PyTuple_Pack(2, Py_TYPE(op), op);
498 }
499 }
500 else if (PyTuple_CheckExact(op)) {
501 Py_ssize_t i, len;
502 PyObject *tuple;
503
504 len = PyTuple_GET_SIZE(op);
505 tuple = PyTuple_New(len);
506 if (tuple == NULL)
507 return NULL;
508
509 for (i=0; i < len; i++) {
510 PyObject *item, *item_key;
511
512 item = PyTuple_GET_ITEM(op, i);
513 item_key = _PyCode_ConstantKey(item);
514 if (item_key == NULL) {
515 Py_DECREF(tuple);
516 return NULL;
517 }
518
519 PyTuple_SET_ITEM(tuple, i, item_key);
520 }
521
522 key = PyTuple_Pack(3, Py_TYPE(op), op, tuple);
523 Py_DECREF(tuple);
524 }
525 else if (PyFrozenSet_CheckExact(op)) {
526 Py_ssize_t pos = 0;
527 PyObject *item;
528 Py_hash_t hash;
529 Py_ssize_t i, len;
530 PyObject *tuple, *set;
531
532 len = PySet_GET_SIZE(op);
533 tuple = PyTuple_New(len);
534 if (tuple == NULL)
535 return NULL;
536
537 i = 0;
538 while (_PySet_NextEntry(op, &pos, &item, &hash)) {
539 PyObject *item_key;
540
541 item_key = _PyCode_ConstantKey(item);
542 if (item_key == NULL) {
543 Py_DECREF(tuple);
544 return NULL;
545 }
546
547 assert(i < len);
548 PyTuple_SET_ITEM(tuple, i, item_key);
549 i++;
550 }
551 set = PyFrozenSet_New(tuple);
552 Py_DECREF(tuple);
553 if (set == NULL)
554 return NULL;
555
556 key = PyTuple_Pack(3, Py_TYPE(op), op, set);
557 Py_DECREF(set);
558 return key;
559 }
560 else {
Martin Panter6245cb32016-04-15 02:14:19 +0000561 /* for other types, use the object identifier as a unique identifier
Victor Stinner3cdd5fb2016-01-22 12:33:12 +0100562 * to ensure that they are seen as unequal. */
563 PyObject *obj_id = PyLong_FromVoidPtr(op);
564 if (obj_id == NULL)
565 return NULL;
566
567 key = PyTuple_Pack(3, Py_TYPE(op), op, obj_id);
568 Py_DECREF(obj_id);
569 }
570 return key;
571}
572
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000573static PyObject *
574code_richcompare(PyObject *self, PyObject *other, int op)
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000575{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 PyCodeObject *co, *cp;
577 int eq;
Victor Stinner3cdd5fb2016-01-22 12:33:12 +0100578 PyObject *consts1, *consts2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 PyObject *res;
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 if ((op != Py_EQ && op != Py_NE) ||
582 !PyCode_Check(self) ||
583 !PyCode_Check(other)) {
Brian Curtindfc80e32011-08-10 20:28:54 -0500584 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 }
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000586
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 co = (PyCodeObject *)self;
588 cp = (PyCodeObject *)other;
Guido van Rossumb6bb0c72006-08-24 04:12:18 +0000589
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
591 if (eq <= 0) goto unequal;
592 eq = co->co_argcount == cp->co_argcount;
593 if (!eq) goto unequal;
594 eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
595 if (!eq) goto unequal;
596 eq = co->co_nlocals == cp->co_nlocals;
597 if (!eq) goto unequal;
598 eq = co->co_flags == cp->co_flags;
599 if (!eq) goto unequal;
600 eq = co->co_firstlineno == cp->co_firstlineno;
601 if (!eq) goto unequal;
602 eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
603 if (eq <= 0) goto unequal;
Victor Stinner3cdd5fb2016-01-22 12:33:12 +0100604
605 /* compare constants */
606 consts1 = _PyCode_ConstantKey(co->co_consts);
607 if (!consts1)
608 return NULL;
609 consts2 = _PyCode_ConstantKey(cp->co_consts);
610 if (!consts2) {
611 Py_DECREF(consts1);
612 return NULL;
613 }
614 eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
615 Py_DECREF(consts1);
616 Py_DECREF(consts2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 if (eq <= 0) goto unequal;
Victor Stinner3cdd5fb2016-01-22 12:33:12 +0100618
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
620 if (eq <= 0) goto unequal;
621 eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
622 if (eq <= 0) goto unequal;
623 eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
624 if (eq <= 0) goto unequal;
625 eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
626 if (eq <= 0) goto unequal;
Guido van Rossumb6bb0c72006-08-24 04:12:18 +0000627
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 if (op == Py_EQ)
629 res = Py_True;
630 else
631 res = Py_False;
632 goto done;
Guido van Rossumb6bb0c72006-08-24 04:12:18 +0000633
634 unequal:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 if (eq < 0)
636 return NULL;
637 if (op == Py_NE)
638 res = Py_True;
639 else
640 res = Py_False;
Guido van Rossumb6bb0c72006-08-24 04:12:18 +0000641
642 done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 Py_INCREF(res);
644 return res;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000645}
646
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000647static Py_hash_t
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000648code_hash(PyCodeObject *co)
649{
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000650 Py_hash_t h, h0, h1, h2, h3, h4, h5, h6;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 h0 = PyObject_Hash(co->co_name);
652 if (h0 == -1) return -1;
653 h1 = PyObject_Hash(co->co_code);
654 if (h1 == -1) return -1;
655 h2 = PyObject_Hash(co->co_consts);
656 if (h2 == -1) return -1;
657 h3 = PyObject_Hash(co->co_names);
658 if (h3 == -1) return -1;
659 h4 = PyObject_Hash(co->co_varnames);
660 if (h4 == -1) return -1;
661 h5 = PyObject_Hash(co->co_freevars);
662 if (h5 == -1) return -1;
663 h6 = PyObject_Hash(co->co_cellvars);
664 if (h6 == -1) return -1;
665 h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
666 co->co_argcount ^ co->co_kwonlyargcount ^
667 co->co_nlocals ^ co->co_flags;
668 if (h == -1) h = -2;
669 return h;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000670}
671
672/* XXX code objects need to participate in GC? */
673
Martin v. Löwis3bbd2fa2012-07-26 22:23:23 +0200674static struct PyMethodDef code_methods[] = {
675 {"__sizeof__", (PyCFunction)code_sizeof, METH_NOARGS},
676 {NULL, NULL} /* sentinel */
677};
678
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000679PyTypeObject PyCode_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 PyVarObject_HEAD_INIT(&PyType_Type, 0)
681 "code",
682 sizeof(PyCodeObject),
683 0,
684 (destructor)code_dealloc, /* tp_dealloc */
685 0, /* tp_print */
686 0, /* tp_getattr */
687 0, /* tp_setattr */
688 0, /* tp_reserved */
689 (reprfunc)code_repr, /* tp_repr */
690 0, /* tp_as_number */
691 0, /* tp_as_sequence */
692 0, /* tp_as_mapping */
693 (hashfunc)code_hash, /* tp_hash */
694 0, /* tp_call */
695 0, /* tp_str */
696 PyObject_GenericGetAttr, /* tp_getattro */
697 0, /* tp_setattro */
698 0, /* tp_as_buffer */
699 Py_TPFLAGS_DEFAULT, /* tp_flags */
700 code_doc, /* tp_doc */
701 0, /* tp_traverse */
702 0, /* tp_clear */
703 code_richcompare, /* tp_richcompare */
704 offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */
705 0, /* tp_iter */
706 0, /* tp_iternext */
Martin v. Löwis3bbd2fa2012-07-26 22:23:23 +0200707 code_methods, /* tp_methods */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 code_memberlist, /* tp_members */
709 0, /* tp_getset */
710 0, /* tp_base */
711 0, /* tp_dict */
712 0, /* tp_descr_get */
713 0, /* tp_descr_set */
714 0, /* tp_dictoffset */
715 0, /* tp_init */
716 0, /* tp_alloc */
717 code_new, /* tp_new */
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000718};
719
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000720/* Use co_lnotab to compute the line number from a bytecode index, addrq. See
721 lnotab_notes.txt for the details of the lnotab representation.
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000722*/
723
724int
725PyCode_Addr2Line(PyCodeObject *co, int addrq)
726{
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000727 Py_ssize_t size = PyBytes_Size(co->co_lnotab) / 2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 unsigned char *p = (unsigned char*)PyBytes_AsString(co->co_lnotab);
729 int line = co->co_firstlineno;
730 int addr = 0;
731 while (--size >= 0) {
732 addr += *p++;
733 if (addr > addrq)
734 break;
735 line += *p++;
736 }
737 return line;
Jeremy Hylton3e0055f2005-10-20 19:59:25 +0000738}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000739
Alexandre Vassalotti7b82b402009-07-21 04:30:03 +0000740/* Update *bounds to describe the first and one-past-the-last instructions in
741 the same line as lasti. Return the number of that line. */
742int
743_PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000744{
Victor Stinner0fcab4a2011-01-04 12:59:15 +0000745 Py_ssize_t size;
746 int addr, line;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 unsigned char* p;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab);
750 size = PyBytes_GET_SIZE(co->co_lnotab) / 2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000751
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 addr = 0;
753 line = co->co_firstlineno;
754 assert(line > 0);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000756 /* possible optimization: if f->f_lasti == instr_ub
757 (likely to be a common case) then we already know
758 instr_lb -- if we stored the matching value of p
Martin Panter0be894b2016-09-07 12:03:06 +0000759 somewhere we could skip the first while loop. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 /* See lnotab_notes.txt for the description of
762 co_lnotab. A point to remember: increments to p
763 come in (addr, line) pairs. */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000764
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 bounds->ap_lower = 0;
766 while (size > 0) {
767 if (addr + *p > lasti)
768 break;
769 addr += *p++;
770 if (*p)
771 bounds->ap_lower = addr;
772 line += *p++;
773 --size;
774 }
775
776 if (size > 0) {
777 while (--size >= 0) {
778 addr += *p++;
779 if (*p++)
780 break;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000781 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000782 bounds->ap_upper = addr;
783 }
784 else {
785 bounds->ap_upper = INT_MAX;
786 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000788 return line;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000789}