Line data Source code
1 : #include "Python.h"
2 : #include "code.h"
3 : #include "structmember.h"
4 :
5 : #define NAME_CHARS \
6 : "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
7 :
8 : /* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
9 :
10 : static int
11 24303 : all_name_chars(PyObject *o)
12 : {
13 : static char ok_name_char[256];
14 : static const unsigned char *name_chars = (unsigned char *)NAME_CHARS;
15 : const unsigned char *s, *e;
16 :
17 24303 : if (ok_name_char[*name_chars] == 0) {
18 : const unsigned char *p;
19 192 : for (p = name_chars; *p; p++)
20 189 : ok_name_char[*p] = 1;
21 : }
22 24303 : s = (unsigned char *)PyString_AS_STRING(o);
23 24303 : e = s + PyString_GET_SIZE(o);
24 173445 : while (s != e) {
25 136968 : if (ok_name_char[*s++] == 0)
26 12129 : return 0;
27 : }
28 12174 : return 1;
29 : }
30 :
31 : static void
32 28188 : intern_strings(PyObject *tuple)
33 : {
34 : Py_ssize_t i;
35 :
36 127440 : for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
37 71064 : PyObject *v = PyTuple_GET_ITEM(tuple, i);
38 71064 : if (v == NULL || !PyString_CheckExact(v)) {
39 0 : Py_FatalError("non-string found in code slot");
40 : }
41 71064 : PyString_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
42 : }
43 28188 : }
44 :
45 : /* Intern selected string constants */
46 : static int
47 8526 : intern_string_constants(PyObject *tuple)
48 : {
49 8526 : int modified = 0;
50 : Py_ssize_t i;
51 :
52 61104 : for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
53 44052 : PyObject *v = PyTuple_GET_ITEM(tuple, i);
54 44052 : if (PyString_CheckExact(v)) {
55 24303 : if (all_name_chars(v)) {
56 12174 : PyObject *w = v;
57 12174 : PyString_InternInPlace(&v);
58 12174 : if (w != v) {
59 705 : PyTuple_SET_ITEM(tuple, i, v);
60 705 : modified = 1;
61 : }
62 : }
63 : }
64 19749 : else if (PyTuple_CheckExact(v)) {
65 1479 : intern_string_constants(v);
66 : }
67 18270 : else if (PyFrozenSet_CheckExact(v)) {
68 0 : PyObject *w = v;
69 0 : PyObject *tmp = PySequence_Tuple(v);
70 0 : if (tmp == NULL) {
71 0 : PyErr_Clear();
72 0 : continue;
73 : }
74 0 : if (intern_string_constants(tmp)) {
75 0 : v = PyFrozenSet_New(tmp);
76 0 : if (v == NULL) {
77 0 : PyErr_Clear();
78 : }
79 : else {
80 0 : PyTuple_SET_ITEM(tuple, i, v);
81 0 : Py_DECREF(w);
82 0 : modified = 1;
83 : }
84 : }
85 0 : Py_DECREF(tmp);
86 : }
87 : }
88 8526 : return modified;
89 : }
90 :
91 :
92 : PyCodeObject *
93 7047 : PyCode_New(int argcount, int nlocals, int stacksize, int flags,
94 : PyObject *code, PyObject *consts, PyObject *names,
95 : PyObject *varnames, PyObject *freevars, PyObject *cellvars,
96 : PyObject *filename, PyObject *name, int firstlineno,
97 : PyObject *lnotab)
98 : {
99 : PyCodeObject *co;
100 : /* Check argument types */
101 7047 : if (argcount < 0 || nlocals < 0 ||
102 7047 : code == NULL ||
103 7047 : consts == NULL || !PyTuple_Check(consts) ||
104 7047 : names == NULL || !PyTuple_Check(names) ||
105 7047 : varnames == NULL || !PyTuple_Check(varnames) ||
106 7047 : freevars == NULL || !PyTuple_Check(freevars) ||
107 7047 : cellvars == NULL || !PyTuple_Check(cellvars) ||
108 7047 : name == NULL || !PyString_Check(name) ||
109 7047 : filename == NULL || !PyString_Check(filename) ||
110 14094 : lnotab == NULL || !PyString_Check(lnotab) ||
111 7047 : !PyObject_CheckReadBuffer(code)) {
112 0 : PyErr_BadInternalCall();
113 0 : return NULL;
114 : }
115 7047 : intern_strings(names);
116 7047 : intern_strings(varnames);
117 7047 : intern_strings(freevars);
118 7047 : intern_strings(cellvars);
119 7047 : intern_string_constants(consts);
120 7047 : co = PyObject_NEW(PyCodeObject, &PyCode_Type);
121 7047 : if (co != NULL) {
122 7047 : co->co_argcount = argcount;
123 7047 : co->co_nlocals = nlocals;
124 7047 : co->co_stacksize = stacksize;
125 7047 : co->co_flags = flags;
126 7047 : Py_INCREF(code);
127 7047 : co->co_code = code;
128 7047 : Py_INCREF(consts);
129 7047 : co->co_consts = consts;
130 7047 : Py_INCREF(names);
131 7047 : co->co_names = names;
132 7047 : Py_INCREF(varnames);
133 7047 : co->co_varnames = varnames;
134 7047 : Py_INCREF(freevars);
135 7047 : co->co_freevars = freevars;
136 7047 : Py_INCREF(cellvars);
137 7047 : co->co_cellvars = cellvars;
138 7047 : Py_INCREF(filename);
139 7047 : co->co_filename = filename;
140 7047 : Py_INCREF(name);
141 7047 : co->co_name = name;
142 7047 : co->co_firstlineno = firstlineno;
143 7047 : Py_INCREF(lnotab);
144 7047 : co->co_lnotab = lnotab;
145 7047 : co->co_zombieframe = NULL;
146 7047 : co->co_weakreflist = NULL;
147 : }
148 7047 : return co;
149 : }
150 :
151 : PyCodeObject *
152 0 : PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
153 : {
154 : static PyObject *emptystring = NULL;
155 : static PyObject *nulltuple = NULL;
156 0 : PyObject *filename_ob = NULL;
157 0 : PyObject *funcname_ob = NULL;
158 0 : PyCodeObject *result = NULL;
159 0 : if (emptystring == NULL) {
160 0 : emptystring = PyString_FromString("");
161 0 : if (emptystring == NULL)
162 0 : goto failed;
163 : }
164 0 : if (nulltuple == NULL) {
165 0 : nulltuple = PyTuple_New(0);
166 0 : if (nulltuple == NULL)
167 0 : goto failed;
168 : }
169 0 : funcname_ob = PyString_FromString(funcname);
170 0 : if (funcname_ob == NULL)
171 0 : goto failed;
172 0 : filename_ob = PyString_FromString(filename);
173 0 : if (filename_ob == NULL)
174 0 : goto failed;
175 :
176 0 : result = PyCode_New(0, /* argcount */
177 : 0, /* nlocals */
178 : 0, /* stacksize */
179 : 0, /* flags */
180 : emptystring, /* code */
181 : nulltuple, /* consts */
182 : nulltuple, /* names */
183 : nulltuple, /* varnames */
184 : nulltuple, /* freevars */
185 : nulltuple, /* cellvars */
186 : filename_ob, /* filename */
187 : funcname_ob, /* name */
188 : firstlineno, /* firstlineno */
189 : emptystring /* lnotab */
190 : );
191 :
192 : failed:
193 0 : Py_XDECREF(funcname_ob);
194 0 : Py_XDECREF(filename_ob);
195 0 : return result;
196 : }
197 :
198 : #define OFF(x) offsetof(PyCodeObject, x)
199 :
200 : static PyMemberDef code_memberlist[] = {
201 : {"co_argcount", T_INT, OFF(co_argcount), READONLY},
202 : {"co_nlocals", T_INT, OFF(co_nlocals), READONLY},
203 : {"co_stacksize",T_INT, OFF(co_stacksize), READONLY},
204 : {"co_flags", T_INT, OFF(co_flags), READONLY},
205 : {"co_code", T_OBJECT, OFF(co_code), READONLY},
206 : {"co_consts", T_OBJECT, OFF(co_consts), READONLY},
207 : {"co_names", T_OBJECT, OFF(co_names), READONLY},
208 : {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY},
209 : {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY},
210 : {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY},
211 : {"co_filename", T_OBJECT, OFF(co_filename), READONLY},
212 : {"co_name", T_OBJECT, OFF(co_name), READONLY},
213 : {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY},
214 : {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY},
215 : {NULL} /* Sentinel */
216 : };
217 :
218 : /* Helper for code_new: return a shallow copy of a tuple that is
219 : guaranteed to contain exact strings, by converting string subclasses
220 : to exact strings and complaining if a non-string is found. */
221 : static PyObject*
222 0 : validate_and_copy_tuple(PyObject *tup)
223 : {
224 : PyObject *newtuple;
225 : PyObject *item;
226 : Py_ssize_t i, len;
227 :
228 0 : len = PyTuple_GET_SIZE(tup);
229 0 : newtuple = PyTuple_New(len);
230 0 : if (newtuple == NULL)
231 0 : return NULL;
232 :
233 0 : for (i = 0; i < len; i++) {
234 0 : item = PyTuple_GET_ITEM(tup, i);
235 0 : if (PyString_CheckExact(item)) {
236 0 : Py_INCREF(item);
237 : }
238 0 : else if (!PyString_Check(item)) {
239 0 : PyErr_Format(
240 : PyExc_TypeError,
241 : "name tuples must contain only "
242 : "strings, not '%.500s'",
243 0 : item->ob_type->tp_name);
244 0 : Py_DECREF(newtuple);
245 0 : return NULL;
246 : }
247 : else {
248 0 : item = PyString_FromStringAndSize(
249 0 : PyString_AS_STRING(item),
250 : PyString_GET_SIZE(item));
251 0 : if (item == NULL) {
252 0 : Py_DECREF(newtuple);
253 0 : return NULL;
254 : }
255 : }
256 0 : PyTuple_SET_ITEM(newtuple, i, item);
257 : }
258 :
259 0 : return newtuple;
260 : }
261 :
262 : PyDoc_STRVAR(code_doc,
263 : "code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n\
264 : varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\
265 : \n\
266 : Create a code object. Not for the faint of heart.");
267 :
268 : static PyObject *
269 0 : code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
270 : {
271 : int argcount;
272 : int nlocals;
273 : int stacksize;
274 : int flags;
275 0 : PyObject *co = NULL;
276 : PyObject *code;
277 : PyObject *consts;
278 0 : PyObject *names, *ournames = NULL;
279 0 : PyObject *varnames, *ourvarnames = NULL;
280 0 : PyObject *freevars = NULL, *ourfreevars = NULL;
281 0 : PyObject *cellvars = NULL, *ourcellvars = NULL;
282 : PyObject *filename;
283 : PyObject *name;
284 : int firstlineno;
285 : PyObject *lnotab;
286 :
287 0 : if (!PyArg_ParseTuple(args, "iiiiSO!O!O!SSiS|O!O!:code",
288 : &argcount, &nlocals, &stacksize, &flags,
289 : &code,
290 : &PyTuple_Type, &consts,
291 : &PyTuple_Type, &names,
292 : &PyTuple_Type, &varnames,
293 : &filename, &name,
294 : &firstlineno, &lnotab,
295 : &PyTuple_Type, &freevars,
296 : &PyTuple_Type, &cellvars))
297 0 : return NULL;
298 :
299 0 : if (argcount < 0) {
300 0 : PyErr_SetString(
301 : PyExc_ValueError,
302 : "code: argcount must not be negative");
303 0 : goto cleanup;
304 : }
305 :
306 0 : if (nlocals < 0) {
307 0 : PyErr_SetString(
308 : PyExc_ValueError,
309 : "code: nlocals must not be negative");
310 0 : goto cleanup;
311 : }
312 :
313 0 : ournames = validate_and_copy_tuple(names);
314 0 : if (ournames == NULL)
315 0 : goto cleanup;
316 0 : ourvarnames = validate_and_copy_tuple(varnames);
317 0 : if (ourvarnames == NULL)
318 0 : goto cleanup;
319 0 : if (freevars)
320 0 : ourfreevars = validate_and_copy_tuple(freevars);
321 : else
322 0 : ourfreevars = PyTuple_New(0);
323 0 : if (ourfreevars == NULL)
324 0 : goto cleanup;
325 0 : if (cellvars)
326 0 : ourcellvars = validate_and_copy_tuple(cellvars);
327 : else
328 0 : ourcellvars = PyTuple_New(0);
329 0 : if (ourcellvars == NULL)
330 0 : goto cleanup;
331 :
332 0 : co = (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags,
333 : code, consts, ournames, ourvarnames,
334 : ourfreevars, ourcellvars, filename,
335 : name, firstlineno, lnotab);
336 : cleanup:
337 0 : Py_XDECREF(ournames);
338 0 : Py_XDECREF(ourvarnames);
339 0 : Py_XDECREF(ourfreevars);
340 0 : Py_XDECREF(ourcellvars);
341 0 : return co;
342 : }
343 :
344 : static void
345 4857 : code_dealloc(PyCodeObject *co)
346 : {
347 4857 : Py_XDECREF(co->co_code);
348 4857 : Py_XDECREF(co->co_consts);
349 4857 : Py_XDECREF(co->co_names);
350 4857 : Py_XDECREF(co->co_varnames);
351 4857 : Py_XDECREF(co->co_freevars);
352 4857 : Py_XDECREF(co->co_cellvars);
353 4857 : Py_XDECREF(co->co_filename);
354 4857 : Py_XDECREF(co->co_name);
355 4857 : Py_XDECREF(co->co_lnotab);
356 4857 : if (co->co_zombieframe != NULL)
357 1644 : PyObject_GC_Del(co->co_zombieframe);
358 4857 : if (co->co_weakreflist != NULL)
359 0 : PyObject_ClearWeakRefs((PyObject*)co);
360 4857 : PyObject_DEL(co);
361 4857 : }
362 :
363 : static PyObject *
364 0 : code_repr(PyCodeObject *co)
365 : {
366 : char buf[500];
367 0 : int lineno = -1;
368 0 : char *filename = "???";
369 0 : char *name = "???";
370 :
371 0 : if (co->co_firstlineno != 0)
372 0 : lineno = co->co_firstlineno;
373 0 : if (co->co_filename && PyString_Check(co->co_filename))
374 0 : filename = PyString_AS_STRING(co->co_filename);
375 0 : if (co->co_name && PyString_Check(co->co_name))
376 0 : name = PyString_AS_STRING(co->co_name);
377 0 : PyOS_snprintf(buf, sizeof(buf),
378 : "<code object %.100s at %p, file \"%.300s\", line %d>",
379 : name, co, filename, lineno);
380 0 : return PyString_FromString(buf);
381 : }
382 :
383 : static int
384 0 : code_compare(PyCodeObject *co, PyCodeObject *cp)
385 : {
386 : int cmp;
387 0 : cmp = PyObject_Compare(co->co_name, cp->co_name);
388 0 : if (cmp) return cmp;
389 0 : cmp = co->co_argcount - cp->co_argcount;
390 0 : if (cmp) goto normalize;
391 0 : cmp = co->co_nlocals - cp->co_nlocals;
392 0 : if (cmp) goto normalize;
393 0 : cmp = co->co_flags - cp->co_flags;
394 0 : if (cmp) goto normalize;
395 0 : cmp = co->co_firstlineno - cp->co_firstlineno;
396 0 : if (cmp) goto normalize;
397 0 : cmp = PyObject_Compare(co->co_code, cp->co_code);
398 0 : if (cmp) return cmp;
399 0 : cmp = PyObject_Compare(co->co_consts, cp->co_consts);
400 0 : if (cmp) return cmp;
401 0 : cmp = PyObject_Compare(co->co_names, cp->co_names);
402 0 : if (cmp) return cmp;
403 0 : cmp = PyObject_Compare(co->co_varnames, cp->co_varnames);
404 0 : if (cmp) return cmp;
405 0 : cmp = PyObject_Compare(co->co_freevars, cp->co_freevars);
406 0 : if (cmp) return cmp;
407 0 : cmp = PyObject_Compare(co->co_cellvars, cp->co_cellvars);
408 0 : return cmp;
409 :
410 : normalize:
411 0 : if (cmp > 0)
412 0 : return 1;
413 0 : else if (cmp < 0)
414 0 : return -1;
415 : else
416 0 : return 0;
417 : }
418 :
419 : PyObject*
420 30147 : _PyCode_ConstantKey(PyObject *op)
421 : {
422 : PyObject *key;
423 :
424 : /* Py_None is a singleton */
425 30147 : if (op == Py_None
426 29216 : || PyInt_CheckExact(op)
427 28213 : || PyLong_CheckExact(op)
428 28213 : || PyBool_Check(op)
429 28213 : || PyBytes_CheckExact(op)
430 : #ifdef Py_USING_UNICODE
431 1157 : || PyUnicode_CheckExact(op)
432 : #endif
433 : /* code_richcompare() uses _PyCode_ConstantKey() internally */
434 1157 : || PyCode_Check(op)) {
435 29970 : key = PyTuple_Pack(2, Py_TYPE(op), op);
436 : }
437 177 : else if (PyFloat_CheckExact(op)) {
438 1 : double d = PyFloat_AS_DOUBLE(op);
439 : /* all we need is to make the tuple different in either the 0.0
440 : * or -0.0 case from all others, just to avoid the "coercion".
441 : */
442 1 : if (d == 0.0 && copysign(1.0, d) < 0.0)
443 0 : key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
444 : else
445 1 : key = PyTuple_Pack(2, Py_TYPE(op), op);
446 : }
447 : #ifndef WITHOUT_COMPLEX
448 176 : else if (PyComplex_CheckExact(op)) {
449 : Py_complex z;
450 : int real_negzero, imag_negzero;
451 : /* For the complex case we must make complex(x, 0.)
452 : different from complex(x, -0.) and complex(0., y)
453 : different from complex(-0., y), for any x and y.
454 : All four complex zeros must be distinguished.*/
455 0 : z = PyComplex_AsCComplex(op);
456 0 : real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
457 0 : imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
458 : /* use True, False and None singleton as tags for the real and imag
459 : * sign, to make tuples different */
460 0 : if (real_negzero && imag_negzero) {
461 0 : key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True);
462 : }
463 0 : else if (imag_negzero) {
464 0 : key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False);
465 : }
466 0 : else if (real_negzero) {
467 0 : key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
468 : }
469 : else {
470 0 : key = PyTuple_Pack(2, Py_TYPE(op), op);
471 : }
472 : }
473 : #endif
474 176 : else if (PyTuple_CheckExact(op)) {
475 : Py_ssize_t i, len;
476 : PyObject *tuple;
477 :
478 176 : len = PyTuple_GET_SIZE(op);
479 176 : tuple = PyTuple_New(len);
480 176 : if (tuple == NULL)
481 0 : return NULL;
482 :
483 386 : for (i=0; i < len; i++) {
484 : PyObject *item, *item_key;
485 :
486 210 : item = PyTuple_GET_ITEM(op, i);
487 210 : item_key = _PyCode_ConstantKey(item);
488 210 : if (item_key == NULL) {
489 0 : Py_DECREF(tuple);
490 0 : return NULL;
491 : }
492 :
493 210 : PyTuple_SET_ITEM(tuple, i, item_key);
494 : }
495 :
496 176 : key = PyTuple_Pack(3, Py_TYPE(op), op, tuple);
497 176 : Py_DECREF(tuple);
498 : }
499 0 : else if (PyFrozenSet_CheckExact(op)) {
500 0 : Py_ssize_t pos = 0;
501 : PyObject *item;
502 : long hash;
503 : Py_ssize_t i, len;
504 : PyObject *tuple, *set;
505 :
506 0 : len = PySet_GET_SIZE(op);
507 0 : tuple = PyTuple_New(len);
508 0 : if (tuple == NULL)
509 0 : return NULL;
510 :
511 0 : i = 0;
512 0 : while (_PySet_NextEntry(op, &pos, &item, &hash)) {
513 : PyObject *item_key;
514 :
515 0 : item_key = _PyCode_ConstantKey(item);
516 0 : if (item_key == NULL) {
517 0 : Py_DECREF(tuple);
518 0 : return NULL;
519 : }
520 :
521 : assert(i < len);
522 0 : PyTuple_SET_ITEM(tuple, i, item_key);
523 0 : i++;
524 : }
525 0 : set = PyFrozenSet_New(tuple);
526 0 : Py_DECREF(tuple);
527 0 : if (set == NULL)
528 0 : return NULL;
529 :
530 0 : key = PyTuple_Pack(3, Py_TYPE(op), op, set);
531 0 : Py_DECREF(set);
532 0 : return key;
533 : }
534 : else {
535 : /* for other types, use the object identifier as a unique identifier
536 : * to ensure that they are seen as unequal. */
537 0 : PyObject *obj_id = PyLong_FromVoidPtr(op);
538 0 : if (obj_id == NULL)
539 0 : return NULL;
540 :
541 0 : key = PyTuple_Pack(3, Py_TYPE(op), op, obj_id);
542 0 : Py_DECREF(obj_id);
543 : }
544 30147 : return key;
545 : }
546 :
547 : static PyObject *
548 4 : code_richcompare(PyObject *self, PyObject *other, int op)
549 : {
550 : PyCodeObject *co, *cp;
551 : int eq;
552 : PyObject *consts1, *consts2;
553 : PyObject *res;
554 :
555 8 : if ((op != Py_EQ && op != Py_NE) ||
556 8 : !PyCode_Check(self) ||
557 4 : !PyCode_Check(other)) {
558 :
559 : /* Py3K warning if types are not equal and comparison
560 : isn't == or != */
561 0 : if (PyErr_WarnPy3k("code inequality comparisons not supported "
562 0 : "in 3.x", 1) < 0) {
563 0 : return NULL;
564 : }
565 :
566 0 : Py_INCREF(Py_NotImplemented);
567 0 : return Py_NotImplemented;
568 : }
569 :
570 4 : co = (PyCodeObject *)self;
571 4 : cp = (PyCodeObject *)other;
572 :
573 4 : eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
574 4 : if (eq <= 0) goto unequal;
575 4 : eq = co->co_argcount == cp->co_argcount;
576 4 : if (!eq) goto unequal;
577 4 : eq = co->co_nlocals == cp->co_nlocals;
578 4 : if (!eq) goto unequal;
579 4 : eq = co->co_flags == cp->co_flags;
580 4 : if (!eq) goto unequal;
581 4 : eq = co->co_firstlineno == cp->co_firstlineno;
582 4 : if (!eq) goto unequal;
583 0 : eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
584 0 : if (eq <= 0) goto unequal;
585 :
586 : /* compare constants */
587 0 : consts1 = _PyCode_ConstantKey(co->co_consts);
588 0 : if (!consts1)
589 0 : return NULL;
590 0 : consts2 = _PyCode_ConstantKey(cp->co_consts);
591 0 : if (!consts2) {
592 0 : Py_DECREF(consts1);
593 0 : return NULL;
594 : }
595 0 : eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
596 0 : Py_DECREF(consts1);
597 0 : Py_DECREF(consts2);
598 0 : if (eq <= 0) goto unequal;
599 :
600 0 : eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
601 0 : if (eq <= 0) goto unequal;
602 0 : eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
603 0 : if (eq <= 0) goto unequal;
604 0 : eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
605 0 : if (eq <= 0) goto unequal;
606 0 : eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
607 0 : if (eq <= 0) goto unequal;
608 :
609 0 : if (op == Py_EQ)
610 0 : res = Py_True;
611 : else
612 0 : res = Py_False;
613 0 : goto done;
614 :
615 : unequal:
616 4 : if (eq < 0)
617 0 : return NULL;
618 4 : if (op == Py_NE)
619 0 : res = Py_True;
620 : else
621 4 : res = Py_False;
622 :
623 : done:
624 4 : Py_INCREF(res);
625 4 : return res;
626 : }
627 :
628 : static long
629 3380 : code_hash(PyCodeObject *co)
630 : {
631 : long h, h0, h1, h2, h3, h4, h5, h6;
632 3380 : h0 = PyObject_Hash(co->co_name);
633 3380 : if (h0 == -1) return -1;
634 3380 : h1 = PyObject_Hash(co->co_code);
635 3380 : if (h1 == -1) return -1;
636 3380 : h2 = PyObject_Hash(co->co_consts);
637 3380 : if (h2 == -1) return -1;
638 3380 : h3 = PyObject_Hash(co->co_names);
639 3380 : if (h3 == -1) return -1;
640 3380 : h4 = PyObject_Hash(co->co_varnames);
641 3380 : if (h4 == -1) return -1;
642 3380 : h5 = PyObject_Hash(co->co_freevars);
643 3380 : if (h5 == -1) return -1;
644 3380 : h6 = PyObject_Hash(co->co_cellvars);
645 3380 : if (h6 == -1) return -1;
646 10140 : h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
647 6760 : co->co_argcount ^ co->co_nlocals ^ co->co_flags;
648 3380 : if (h == -1) h = -2;
649 3380 : return h;
650 : }
651 :
652 : /* XXX code objects need to participate in GC? */
653 :
654 : PyTypeObject PyCode_Type = {
655 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
656 : "code",
657 : sizeof(PyCodeObject),
658 : 0,
659 : (destructor)code_dealloc, /* tp_dealloc */
660 : 0, /* tp_print */
661 : 0, /* tp_getattr */
662 : 0, /* tp_setattr */
663 : (cmpfunc)code_compare, /* tp_compare */
664 : (reprfunc)code_repr, /* tp_repr */
665 : 0, /* tp_as_number */
666 : 0, /* tp_as_sequence */
667 : 0, /* tp_as_mapping */
668 : (hashfunc)code_hash, /* tp_hash */
669 : 0, /* tp_call */
670 : 0, /* tp_str */
671 : PyObject_GenericGetAttr, /* tp_getattro */
672 : 0, /* tp_setattro */
673 : 0, /* tp_as_buffer */
674 : Py_TPFLAGS_DEFAULT, /* tp_flags */
675 : code_doc, /* tp_doc */
676 : 0, /* tp_traverse */
677 : 0, /* tp_clear */
678 : code_richcompare, /* tp_richcompare */
679 : offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */
680 : 0, /* tp_iter */
681 : 0, /* tp_iternext */
682 : 0, /* tp_methods */
683 : code_memberlist, /* tp_members */
684 : 0, /* tp_getset */
685 : 0, /* tp_base */
686 : 0, /* tp_dict */
687 : 0, /* tp_descr_get */
688 : 0, /* tp_descr_set */
689 : 0, /* tp_dictoffset */
690 : 0, /* tp_init */
691 : 0, /* tp_alloc */
692 : code_new, /* tp_new */
693 : };
694 :
695 : /* Use co_lnotab to compute the line number from a bytecode index, addrq. See
696 : lnotab_notes.txt for the details of the lnotab representation.
697 : */
698 :
699 : int
700 2154 : PyCode_Addr2Line(PyCodeObject *co, int addrq)
701 : {
702 2154 : int size = PyString_Size(co->co_lnotab) / 2;
703 2154 : unsigned char *p = (unsigned char*)PyString_AsString(co->co_lnotab);
704 2154 : int line = co->co_firstlineno;
705 2154 : int addr = 0;
706 13866 : while (--size >= 0) {
707 10551 : addr += *p++;
708 10551 : if (addr > addrq)
709 993 : break;
710 9558 : line += *p++;
711 : }
712 2154 : return line;
713 : }
714 :
715 : /* Update *bounds to describe the first and one-past-the-last instructions in
716 : the same line as lasti. Return the number of that line. */
717 : int
718 0 : _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
719 : {
720 : int size, addr, line;
721 : unsigned char* p;
722 :
723 0 : p = (unsigned char*)PyString_AS_STRING(co->co_lnotab);
724 0 : size = PyString_GET_SIZE(co->co_lnotab) / 2;
725 :
726 0 : addr = 0;
727 0 : line = co->co_firstlineno;
728 : assert(line > 0);
729 :
730 : /* possible optimization: if f->f_lasti == instr_ub
731 : (likely to be a common case) then we already know
732 : instr_lb -- if we stored the matching value of p
733 : somewhere we could skip the first while loop. */
734 :
735 : /* See lnotab_notes.txt for the description of
736 : co_lnotab. A point to remember: increments to p
737 : come in (addr, line) pairs. */
738 :
739 0 : bounds->ap_lower = 0;
740 0 : while (size > 0) {
741 0 : if (addr + *p > lasti)
742 0 : break;
743 0 : addr += *p++;
744 0 : if (*p)
745 0 : bounds->ap_lower = addr;
746 0 : line += *p++;
747 0 : --size;
748 : }
749 :
750 0 : if (size > 0) {
751 0 : while (--size >= 0) {
752 0 : addr += *p++;
753 0 : if (*p++)
754 0 : break;
755 : }
756 0 : bounds->ap_upper = addr;
757 : }
758 : else {
759 0 : bounds->ap_upper = INT_MAX;
760 : }
761 :
762 0 : return line;
763 : }
|