No issues found
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 all_name_chars(unsigned char *s)
12 {
13 static char ok_name_char[256];
14 static unsigned char *name_chars = (unsigned char *)NAME_CHARS;
15
16 if (ok_name_char[*name_chars] == 0) {
17 unsigned char *p;
18 for (p = name_chars; *p; p++)
19 ok_name_char[*p] = 1;
20 }
21 while (*s) {
22 if (ok_name_char[*s++] == 0)
23 return 0;
24 }
25 return 1;
26 }
27
28 static void
29 intern_strings(PyObject *tuple)
30 {
31 Py_ssize_t i;
32
33 for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
34 PyObject *v = PyTuple_GET_ITEM(tuple, i);
35 if (v == NULL || !PyString_CheckExact(v)) {
36 Py_FatalError("non-string found in code slot");
37 }
38 PyString_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
39 }
40 }
41
42
43 PyCodeObject *
44 PyCode_New(int argcount, int nlocals, int stacksize, int flags,
45 PyObject *code, PyObject *consts, PyObject *names,
46 PyObject *varnames, PyObject *freevars, PyObject *cellvars,
47 PyObject *filename, PyObject *name, int firstlineno,
48 PyObject *lnotab)
49 {
50 PyCodeObject *co;
51 Py_ssize_t i;
52 /* Check argument types */
53 if (argcount < 0 || nlocals < 0 ||
54 code == NULL ||
55 consts == NULL || !PyTuple_Check(consts) ||
56 names == NULL || !PyTuple_Check(names) ||
57 varnames == NULL || !PyTuple_Check(varnames) ||
58 freevars == NULL || !PyTuple_Check(freevars) ||
59 cellvars == NULL || !PyTuple_Check(cellvars) ||
60 name == NULL || !PyString_Check(name) ||
61 filename == NULL || !PyString_Check(filename) ||
62 lnotab == NULL || !PyString_Check(lnotab) ||
63 !PyObject_CheckReadBuffer(code)) {
64 PyErr_BadInternalCall();
65 return NULL;
66 }
67 intern_strings(names);
68 intern_strings(varnames);
69 intern_strings(freevars);
70 intern_strings(cellvars);
71 /* Intern selected string constants */
72 for (i = PyTuple_Size(consts); --i >= 0; ) {
73 PyObject *v = PyTuple_GetItem(consts, i);
74 if (!PyString_Check(v))
75 continue;
76 if (!all_name_chars((unsigned char *)PyString_AS_STRING(v)))
77 continue;
78 PyString_InternInPlace(&PyTuple_GET_ITEM(consts, i));
79 }
80 co = PyObject_NEW(PyCodeObject, &PyCode_Type);
81 if (co != NULL) {
82 co->co_argcount = argcount;
83 co->co_nlocals = nlocals;
84 co->co_stacksize = stacksize;
85 co->co_flags = flags;
86 Py_INCREF(code);
87 co->co_code = code;
88 Py_INCREF(consts);
89 co->co_consts = consts;
90 Py_INCREF(names);
91 co->co_names = names;
92 Py_INCREF(varnames);
93 co->co_varnames = varnames;
94 Py_INCREF(freevars);
95 co->co_freevars = freevars;
96 Py_INCREF(cellvars);
97 co->co_cellvars = cellvars;
98 Py_INCREF(filename);
99 co->co_filename = filename;
100 Py_INCREF(name);
101 co->co_name = name;
102 co->co_firstlineno = firstlineno;
103 Py_INCREF(lnotab);
104 co->co_lnotab = lnotab;
105 co->co_zombieframe = NULL;
106 co->co_weakreflist = NULL;
107 }
108 return co;
109 }
110
111 PyCodeObject *
112 PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
113 {
114 static PyObject *emptystring = NULL;
115 static PyObject *nulltuple = NULL;
116 PyObject *filename_ob = NULL;
117 PyObject *funcname_ob = NULL;
118 PyCodeObject *result = NULL;
119 if (emptystring == NULL) {
120 emptystring = PyString_FromString("");
121 if (emptystring == NULL)
122 goto failed;
123 }
124 if (nulltuple == NULL) {
125 nulltuple = PyTuple_New(0);
126 if (nulltuple == NULL)
127 goto failed;
128 }
129 funcname_ob = PyString_FromString(funcname);
130 if (funcname_ob == NULL)
131 goto failed;
132 filename_ob = PyString_FromString(filename);
133 if (filename_ob == NULL)
134 goto failed;
135
136 result = PyCode_New(0, /* argcount */
137 0, /* nlocals */
138 0, /* stacksize */
139 0, /* flags */
140 emptystring, /* code */
141 nulltuple, /* consts */
142 nulltuple, /* names */
143 nulltuple, /* varnames */
144 nulltuple, /* freevars */
145 nulltuple, /* cellvars */
146 filename_ob, /* filename */
147 funcname_ob, /* name */
148 firstlineno, /* firstlineno */
149 emptystring /* lnotab */
150 );
151
152 failed:
153 Py_XDECREF(funcname_ob);
154 Py_XDECREF(filename_ob);
155 return result;
156 }
157
158 #define OFF(x) offsetof(PyCodeObject, x)
159
160 static PyMemberDef code_memberlist[] = {
161 {"co_argcount", T_INT, OFF(co_argcount), READONLY},
162 {"co_nlocals", T_INT, OFF(co_nlocals), READONLY},
163 {"co_stacksize",T_INT, OFF(co_stacksize), READONLY},
164 {"co_flags", T_INT, OFF(co_flags), READONLY},
165 {"co_code", T_OBJECT, OFF(co_code), READONLY},
166 {"co_consts", T_OBJECT, OFF(co_consts), READONLY},
167 {"co_names", T_OBJECT, OFF(co_names), READONLY},
168 {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY},
169 {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY},
170 {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY},
171 {"co_filename", T_OBJECT, OFF(co_filename), READONLY},
172 {"co_name", T_OBJECT, OFF(co_name), READONLY},
173 {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY},
174 {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY},
175 {NULL} /* Sentinel */
176 };
177
178 /* Helper for code_new: return a shallow copy of a tuple that is
179 guaranteed to contain exact strings, by converting string subclasses
180 to exact strings and complaining if a non-string is found. */
181 static PyObject*
182 validate_and_copy_tuple(PyObject *tup)
183 {
184 PyObject *newtuple;
185 PyObject *item;
186 Py_ssize_t i, len;
187
188 len = PyTuple_GET_SIZE(tup);
189 newtuple = PyTuple_New(len);
190 if (newtuple == NULL)
191 return NULL;
192
193 for (i = 0; i < len; i++) {
194 item = PyTuple_GET_ITEM(tup, i);
195 if (PyString_CheckExact(item)) {
196 Py_INCREF(item);
197 }
198 else if (!PyString_Check(item)) {
199 PyErr_Format(
200 PyExc_TypeError,
201 "name tuples must contain only "
202 "strings, not '%.500s'",
203 item->ob_type->tp_name);
204 Py_DECREF(newtuple);
205 return NULL;
206 }
207 else {
208 item = PyString_FromStringAndSize(
209 PyString_AS_STRING(item),
210 PyString_GET_SIZE(item));
211 if (item == NULL) {
212 Py_DECREF(newtuple);
213 return NULL;
214 }
215 }
216 PyTuple_SET_ITEM(newtuple, i, item);
217 }
218
219 return newtuple;
220 }
221
222 PyDoc_STRVAR(code_doc,
223 "code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n\
224 varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\
225 \n\
226 Create a code object. Not for the faint of heart.");
227
228 static PyObject *
229 code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
230 {
231 int argcount;
232 int nlocals;
233 int stacksize;
234 int flags;
235 PyObject *co = NULL;
236 PyObject *code;
237 PyObject *consts;
238 PyObject *names, *ournames = NULL;
239 PyObject *varnames, *ourvarnames = NULL;
240 PyObject *freevars = NULL, *ourfreevars = NULL;
241 PyObject *cellvars = NULL, *ourcellvars = NULL;
242 PyObject *filename;
243 PyObject *name;
244 int firstlineno;
245 PyObject *lnotab;
246
247 if (!PyArg_ParseTuple(args, "iiiiSO!O!O!SSiS|O!O!:code",
248 &argcount, &nlocals, &stacksize, &flags,
249 &code,
250 &PyTuple_Type, &consts,
251 &PyTuple_Type, &names,
252 &PyTuple_Type, &varnames,
253 &filename, &name,
254 &firstlineno, &lnotab,
255 &PyTuple_Type, &freevars,
256 &PyTuple_Type, &cellvars))
257 return NULL;
258
259 if (argcount < 0) {
260 PyErr_SetString(
261 PyExc_ValueError,
262 "code: argcount must not be negative");
263 goto cleanup;
264 }
265
266 if (nlocals < 0) {
267 PyErr_SetString(
268 PyExc_ValueError,
269 "code: nlocals must not be negative");
270 goto cleanup;
271 }
272
273 ournames = validate_and_copy_tuple(names);
274 if (ournames == NULL)
275 goto cleanup;
276 ourvarnames = validate_and_copy_tuple(varnames);
277 if (ourvarnames == NULL)
278 goto cleanup;
279 if (freevars)
280 ourfreevars = validate_and_copy_tuple(freevars);
281 else
282 ourfreevars = PyTuple_New(0);
283 if (ourfreevars == NULL)
284 goto cleanup;
285 if (cellvars)
286 ourcellvars = validate_and_copy_tuple(cellvars);
287 else
288 ourcellvars = PyTuple_New(0);
289 if (ourcellvars == NULL)
290 goto cleanup;
291
292 co = (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags,
293 code, consts, ournames, ourvarnames,
294 ourfreevars, ourcellvars, filename,
295 name, firstlineno, lnotab);
296 cleanup:
297 Py_XDECREF(ournames);
298 Py_XDECREF(ourvarnames);
299 Py_XDECREF(ourfreevars);
300 Py_XDECREF(ourcellvars);
301 return co;
302 }
303
304 static void
305 code_dealloc(PyCodeObject *co)
306 {
307 Py_XDECREF(co->co_code);
308 Py_XDECREF(co->co_consts);
309 Py_XDECREF(co->co_names);
310 Py_XDECREF(co->co_varnames);
311 Py_XDECREF(co->co_freevars);
312 Py_XDECREF(co->co_cellvars);
313 Py_XDECREF(co->co_filename);
314 Py_XDECREF(co->co_name);
315 Py_XDECREF(co->co_lnotab);
316 if (co->co_zombieframe != NULL)
317 PyObject_GC_Del(co->co_zombieframe);
318 if (co->co_weakreflist != NULL)
319 PyObject_ClearWeakRefs((PyObject*)co);
320 PyObject_DEL(co);
321 }
322
323 static PyObject *
324 code_repr(PyCodeObject *co)
325 {
326 char buf[500];
327 int lineno = -1;
328 char *filename = "???";
329 char *name = "???";
330
331 if (co->co_firstlineno != 0)
332 lineno = co->co_firstlineno;
333 if (co->co_filename && PyString_Check(co->co_filename))
334 filename = PyString_AS_STRING(co->co_filename);
335 if (co->co_name && PyString_Check(co->co_name))
336 name = PyString_AS_STRING(co->co_name);
337 PyOS_snprintf(buf, sizeof(buf),
338 "<code object %.100s at %p, file \"%.300s\", line %d>",
339 name, co, filename, lineno);
340 return PyString_FromString(buf);
341 }
342
343 static int
344 code_compare(PyCodeObject *co, PyCodeObject *cp)
345 {
346 int cmp;
347 cmp = PyObject_Compare(co->co_name, cp->co_name);
348 if (cmp) return cmp;
349 cmp = co->co_argcount - cp->co_argcount;
350 if (cmp) goto normalize;
351 cmp = co->co_nlocals - cp->co_nlocals;
352 if (cmp) goto normalize;
353 cmp = co->co_flags - cp->co_flags;
354 if (cmp) goto normalize;
355 cmp = co->co_firstlineno - cp->co_firstlineno;
356 if (cmp) goto normalize;
357 cmp = PyObject_Compare(co->co_code, cp->co_code);
358 if (cmp) return cmp;
359 cmp = PyObject_Compare(co->co_consts, cp->co_consts);
360 if (cmp) return cmp;
361 cmp = PyObject_Compare(co->co_names, cp->co_names);
362 if (cmp) return cmp;
363 cmp = PyObject_Compare(co->co_varnames, cp->co_varnames);
364 if (cmp) return cmp;
365 cmp = PyObject_Compare(co->co_freevars, cp->co_freevars);
366 if (cmp) return cmp;
367 cmp = PyObject_Compare(co->co_cellvars, cp->co_cellvars);
368 return cmp;
369
370 normalize:
371 if (cmp > 0)
372 return 1;
373 else if (cmp < 0)
374 return -1;
375 else
376 return 0;
377 }
378
379 static PyObject *
380 code_richcompare(PyObject *self, PyObject *other, int op)
381 {
382 PyCodeObject *co, *cp;
383 int eq;
384 PyObject *res;
385
386 if ((op != Py_EQ && op != Py_NE) ||
387 !PyCode_Check(self) ||
388 !PyCode_Check(other)) {
389
390 /* Py3K warning if types are not equal and comparison
391 isn't == or != */
392 if (PyErr_WarnPy3k("code inequality comparisons not supported "
393 "in 3.x", 1) < 0) {
394 return NULL;
395 }
396
397 Py_INCREF(Py_NotImplemented);
398 return Py_NotImplemented;
399 }
400
401 co = (PyCodeObject *)self;
402 cp = (PyCodeObject *)other;
403
404 eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
405 if (eq <= 0) goto unequal;
406 eq = co->co_argcount == cp->co_argcount;
407 if (!eq) goto unequal;
408 eq = co->co_nlocals == cp->co_nlocals;
409 if (!eq) goto unequal;
410 eq = co->co_flags == cp->co_flags;
411 if (!eq) goto unequal;
412 eq = co->co_firstlineno == cp->co_firstlineno;
413 if (!eq) goto unequal;
414 eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
415 if (eq <= 0) goto unequal;
416 eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ);
417 if (eq <= 0) goto unequal;
418 eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
419 if (eq <= 0) goto unequal;
420 eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
421 if (eq <= 0) goto unequal;
422 eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
423 if (eq <= 0) goto unequal;
424 eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
425 if (eq <= 0) goto unequal;
426
427 if (op == Py_EQ)
428 res = Py_True;
429 else
430 res = Py_False;
431 goto done;
432
433 unequal:
434 if (eq < 0)
435 return NULL;
436 if (op == Py_NE)
437 res = Py_True;
438 else
439 res = Py_False;
440
441 done:
442 Py_INCREF(res);
443 return res;
444 }
445
446 static long
447 code_hash(PyCodeObject *co)
448 {
449 long h, h0, h1, h2, h3, h4, h5, h6;
450 h0 = PyObject_Hash(co->co_name);
451 if (h0 == -1) return -1;
452 h1 = PyObject_Hash(co->co_code);
453 if (h1 == -1) return -1;
454 h2 = PyObject_Hash(co->co_consts);
455 if (h2 == -1) return -1;
456 h3 = PyObject_Hash(co->co_names);
457 if (h3 == -1) return -1;
458 h4 = PyObject_Hash(co->co_varnames);
459 if (h4 == -1) return -1;
460 h5 = PyObject_Hash(co->co_freevars);
461 if (h5 == -1) return -1;
462 h6 = PyObject_Hash(co->co_cellvars);
463 if (h6 == -1) return -1;
464 h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
465 co->co_argcount ^ co->co_nlocals ^ co->co_flags;
466 if (h == -1) h = -2;
467 return h;
468 }
469
470 /* XXX code objects need to participate in GC? */
471
472 PyTypeObject PyCode_Type = {
473 PyVarObject_HEAD_INIT(&PyType_Type, 0)
474 "code",
475 sizeof(PyCodeObject),
476 0,
477 (destructor)code_dealloc, /* tp_dealloc */
478 0, /* tp_print */
479 0, /* tp_getattr */
480 0, /* tp_setattr */
481 (cmpfunc)code_compare, /* tp_compare */
482 (reprfunc)code_repr, /* tp_repr */
483 0, /* tp_as_number */
484 0, /* tp_as_sequence */
485 0, /* tp_as_mapping */
486 (hashfunc)code_hash, /* tp_hash */
487 0, /* tp_call */
488 0, /* tp_str */
489 PyObject_GenericGetAttr, /* tp_getattro */
490 0, /* tp_setattro */
491 0, /* tp_as_buffer */
492 Py_TPFLAGS_DEFAULT, /* tp_flags */
493 code_doc, /* tp_doc */
494 0, /* tp_traverse */
495 0, /* tp_clear */
496 code_richcompare, /* tp_richcompare */
497 offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */
498 0, /* tp_iter */
499 0, /* tp_iternext */
500 0, /* tp_methods */
501 code_memberlist, /* tp_members */
502 0, /* tp_getset */
503 0, /* tp_base */
504 0, /* tp_dict */
505 0, /* tp_descr_get */
506 0, /* tp_descr_set */
507 0, /* tp_dictoffset */
508 0, /* tp_init */
509 0, /* tp_alloc */
510 code_new, /* tp_new */
511 };
512
513 /* Use co_lnotab to compute the line number from a bytecode index, addrq. See
514 lnotab_notes.txt for the details of the lnotab representation.
515 */
516
517 int
518 PyCode_Addr2Line(PyCodeObject *co, int addrq)
519 {
520 int size = PyString_Size(co->co_lnotab) / 2;
521 unsigned char *p = (unsigned char*)PyString_AsString(co->co_lnotab);
522 int line = co->co_firstlineno;
523 int addr = 0;
524 while (--size >= 0) {
525 addr += *p++;
526 if (addr > addrq)
527 break;
528 line += *p++;
529 }
530 return line;
531 }
532
533 /* Update *bounds to describe the first and one-past-the-last instructions in
534 the same line as lasti. Return the number of that line. */
535 int
536 _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
537 {
538 int size, addr, line;
539 unsigned char* p;
540
541 p = (unsigned char*)PyString_AS_STRING(co->co_lnotab);
542 size = PyString_GET_SIZE(co->co_lnotab) / 2;
543
544 addr = 0;
545 line = co->co_firstlineno;
546 assert(line > 0);
547
548 /* possible optimization: if f->f_lasti == instr_ub
549 (likely to be a common case) then we already know
550 instr_lb -- if we stored the matching value of p
551 somwhere we could skip the first while loop. */
552
553 /* See lnotab_notes.txt for the description of
554 co_lnotab. A point to remember: increments to p
555 come in (addr, line) pairs. */
556
557 bounds->ap_lower = 0;
558 while (size > 0) {
559 if (addr + *p > lasti)
560 break;
561 addr += *p++;
562 if (*p)
563 bounds->ap_lower = addr;
564 line += *p++;
565 --size;
566 }
567
568 if (size > 0) {
569 while (--size >= 0) {
570 addr += *p++;
571 if (*p++)
572 break;
573 }
574 bounds->ap_upper = addr;
575 }
576 else {
577 bounds->ap_upper = INT_MAX;
578 }
579
580 return line;
581 }