History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Objects/codeobject.c (1 of 3706 files). Show all

Unified · Split

sys/src/cmd/python/Objects/codeobject.c+590−0
@@ -0,0 +1,590 @@
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+ }
107+ return co;
108+}
109+
110+
111+#define OFF(x) offsetof(PyCodeObject, x)
112+
113+static PyMemberDef code_memberlist[] = {
114+ {"co_argcount", T_INT, OFF(co_argcount), READONLY},
115+ {"co_nlocals", T_INT, OFF(co_nlocals), READONLY},
116+ {"co_stacksize",T_INT, OFF(co_stacksize), READONLY},
117+ {"co_flags", T_INT, OFF(co_flags), READONLY},
118+ {"co_code", T_OBJECT, OFF(co_code), READONLY},
119+ {"co_consts", T_OBJECT, OFF(co_consts), READONLY},
120+ {"co_names", T_OBJECT, OFF(co_names), READONLY},
121+ {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY},
122+ {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY},
123+ {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY},
124+ {"co_filename", T_OBJECT, OFF(co_filename), READONLY},
125+ {"co_name", T_OBJECT, OFF(co_name), READONLY},
126+ {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY},
127+ {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY},
128+ {NULL} /* Sentinel */
129+};
130+
131+/* Helper for code_new: return a shallow copy of a tuple that is
132+ guaranteed to contain exact strings, by converting string subclasses
133+ to exact strings and complaining if a non-string is found. */
134+static PyObject*
135+validate_and_copy_tuple(PyObject *tup)
136+{
137+ PyObject *newtuple;
138+ PyObject *item;
139+ Py_ssize_t i, len;
140+
141+ len = PyTuple_GET_SIZE(tup);
142+ newtuple = PyTuple_New(len);
143+ if (newtuple == NULL)
144+ return NULL;
145+
146+ for (i = 0; i < len; i++) {
147+ item = PyTuple_GET_ITEM(tup, i);
148+ if (PyString_CheckExact(item)) {
149+ Py_INCREF(item);
150+ }
151+ else if (!PyString_Check(item)) {
152+ PyErr_Format(
153+ PyExc_TypeError,
154+ "name tuples must contain only "
155+ "strings, not '%.500s'",
156+ item->ob_type->tp_name);
157+ Py_DECREF(newtuple);
158+ return NULL;
159+ }
160+ else {
161+ item = PyString_FromStringAndSize(
162+ PyString_AS_STRING(item),
163+ PyString_GET_SIZE(item));
164+ if (item == NULL) {
165+ Py_DECREF(newtuple);
166+ return NULL;
167+ }
168+ }
169+ PyTuple_SET_ITEM(newtuple, i, item);
170+ }
171+
172+ return newtuple;
173+}
174+
175+PyDoc_STRVAR(code_doc,
176+"code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n\
177+ varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\
178+\n\
179+Create a code object. Not for the faint of heart.");
180+
181+static PyObject *
182+code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
183+{
184+ int argcount;
185+ int nlocals;
186+ int stacksize;
187+ int flags;
188+ PyObject *co = NULL;
189+ PyObject *code;
190+ PyObject *consts;
191+ PyObject *names, *ournames = NULL;
192+ PyObject *varnames, *ourvarnames = NULL;
193+ PyObject *freevars = NULL, *ourfreevars = NULL;
194+ PyObject *cellvars = NULL, *ourcellvars = NULL;
195+ PyObject *filename;
196+ PyObject *name;
197+ int firstlineno;
198+ PyObject *lnotab;
199+
200+ if (!PyArg_ParseTuple(args, "iiiiSO!O!O!SSiS|O!O!:code",
201+ &argcount, &nlocals, &stacksize, &flags,
202+ &code,
203+ &PyTuple_Type, &consts,
204+ &PyTuple_Type, &names,
205+ &PyTuple_Type, &varnames,
206+ &filename, &name,
207+ &firstlineno, &lnotab,
208+ &PyTuple_Type, &freevars,
209+ &PyTuple_Type, &cellvars))
210+ return NULL;
211+
212+ if (argcount < 0) {
213+ PyErr_SetString(
214+ PyExc_ValueError,
215+ "code: argcount must not be negative");
216+ goto cleanup;
217+ }
218+
219+ if (nlocals < 0) {
220+ PyErr_SetString(
221+ PyExc_ValueError,
222+ "code: nlocals must not be negative");
223+ goto cleanup;
224+ }
225+
226+ ournames = validate_and_copy_tuple(names);
227+ if (ournames == NULL)
228+ goto cleanup;
229+ ourvarnames = validate_and_copy_tuple(varnames);
230+ if (ourvarnames == NULL)
231+ goto cleanup;
232+ if (freevars)
233+ ourfreevars = validate_and_copy_tuple(freevars);
234+ else
235+ ourfreevars = PyTuple_New(0);
236+ if (ourfreevars == NULL)
237+ goto cleanup;
238+ if (cellvars)
239+ ourcellvars = validate_and_copy_tuple(cellvars);
240+ else
241+ ourcellvars = PyTuple_New(0);
242+ if (ourcellvars == NULL)
243+ goto cleanup;
244+
245+ co = (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags,
246+ code, consts, ournames, ourvarnames,
247+ ourfreevars, ourcellvars, filename,
248+ name, firstlineno, lnotab);
249+ cleanup:
250+ Py_XDECREF(ournames);
251+ Py_XDECREF(ourvarnames);
252+ Py_XDECREF(ourfreevars);
253+ Py_XDECREF(ourcellvars);
254+ return co;
255+}
256+
257+static void
258+code_dealloc(PyCodeObject *co)
259+{
260+ Py_XDECREF(co->co_code);
261+ Py_XDECREF(co->co_consts);
262+ Py_XDECREF(co->co_names);
263+ Py_XDECREF(co->co_varnames);
264+ Py_XDECREF(co->co_freevars);
265+ Py_XDECREF(co->co_cellvars);
266+ Py_XDECREF(co->co_filename);
267+ Py_XDECREF(co->co_name);
268+ Py_XDECREF(co->co_lnotab);
269+ if (co->co_zombieframe != NULL)
270+ PyObject_GC_Del(co->co_zombieframe);
271+ PyObject_DEL(co);
272+}
273+
274+static PyObject *
275+code_repr(PyCodeObject *co)
276+{
277+ char buf[500];
278+ int lineno = -1;
279+ char *filename = "???";
280+ char *name = "???";
281+
282+ if (co->co_firstlineno != 0)
283+ lineno = co->co_firstlineno;
284+ if (co->co_filename && PyString_Check(co->co_filename))
285+ filename = PyString_AS_STRING(co->co_filename);
286+ if (co->co_name && PyString_Check(co->co_name))
287+ name = PyString_AS_STRING(co->co_name);
288+ PyOS_snprintf(buf, sizeof(buf),
289+ "<code object %.100s at %p, file \"%.300s\", line %d>",
290+ name, co, filename, lineno);
291+ return PyString_FromString(buf);
292+}
293+
294+static int
295+code_compare(PyCodeObject *co, PyCodeObject *cp)
296+{
297+ int cmp;
298+ cmp = PyObject_Compare(co->co_name, cp->co_name);
299+ if (cmp) return cmp;
300+ cmp = co->co_argcount - cp->co_argcount;
301+ if (cmp) goto normalize;
302+ cmp = co->co_nlocals - cp->co_nlocals;
303+ if (cmp) goto normalize;
304+ cmp = co->co_flags - cp->co_flags;
305+ if (cmp) goto normalize;
306+ cmp = co->co_firstlineno - cp->co_firstlineno;
307+ if (cmp) goto normalize;
308+ cmp = PyObject_Compare(co->co_code, cp->co_code);
309+ if (cmp) return cmp;
310+ cmp = PyObject_Compare(co->co_consts, cp->co_consts);
311+ if (cmp) return cmp;
312+ cmp = PyObject_Compare(co->co_names, cp->co_names);
313+ if (cmp) return cmp;
314+ cmp = PyObject_Compare(co->co_varnames, cp->co_varnames);
315+ if (cmp) return cmp;
316+ cmp = PyObject_Compare(co->co_freevars, cp->co_freevars);
317+ if (cmp) return cmp;
318+ cmp = PyObject_Compare(co->co_cellvars, cp->co_cellvars);
319+ return cmp;
320+
321+ normalize:
322+ if (cmp > 0)
323+ return 1;
324+ else if (cmp < 0)
325+ return -1;
326+ else
327+ return 0;
328+}
329+
330+static long
331+code_hash(PyCodeObject *co)
332+{
333+ long h, h0, h1, h2, h3, h4, h5, h6;
334+ h0 = PyObject_Hash(co->co_name);
335+ if (h0 == -1) return -1;
336+ h1 = PyObject_Hash(co->co_code);
337+ if (h1 == -1) return -1;
338+ h2 = PyObject_Hash(co->co_consts);
339+ if (h2 == -1) return -1;
340+ h3 = PyObject_Hash(co->co_names);
341+ if (h3 == -1) return -1;
342+ h4 = PyObject_Hash(co->co_varnames);
343+ if (h4 == -1) return -1;
344+ h5 = PyObject_Hash(co->co_freevars);
345+ if (h5 == -1) return -1;
346+ h6 = PyObject_Hash(co->co_cellvars);
347+ if (h6 == -1) return -1;
348+ h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
349+ co->co_argcount ^ co->co_nlocals ^ co->co_flags;
350+ if (h == -1) h = -2;
351+ return h;
352+}
353+
354+/* XXX code objects need to participate in GC? */
355+
356+PyTypeObject PyCode_Type = {
357+ PyObject_HEAD_INIT(&PyType_Type)
358+ 0,
359+ "code",
360+ sizeof(PyCodeObject),
361+ 0,
362+ (destructor)code_dealloc, /* tp_dealloc */
363+ 0, /* tp_print */
364+ 0, /* tp_getattr */
365+ 0, /* tp_setattr */
366+ (cmpfunc)code_compare, /* tp_compare */
367+ (reprfunc)code_repr, /* tp_repr */
368+ 0, /* tp_as_number */
369+ 0, /* tp_as_sequence */
370+ 0, /* tp_as_mapping */
371+ (hashfunc)code_hash, /* tp_hash */
372+ 0, /* tp_call */
373+ 0, /* tp_str */
374+ PyObject_GenericGetAttr, /* tp_getattro */
375+ 0, /* tp_setattro */
376+ 0, /* tp_as_buffer */
377+ Py_TPFLAGS_DEFAULT, /* tp_flags */
378+ code_doc, /* tp_doc */
379+ 0, /* tp_traverse */
380+ 0, /* tp_clear */
381+ 0, /* tp_richcompare */
382+ 0, /* tp_weaklistoffset */
383+ 0, /* tp_iter */
384+ 0, /* tp_iternext */
385+ 0, /* tp_methods */
386+ code_memberlist, /* tp_members */
387+ 0, /* tp_getset */
388+ 0, /* tp_base */
389+ 0, /* tp_dict */
390+ 0, /* tp_descr_get */
391+ 0, /* tp_descr_set */
392+ 0, /* tp_dictoffset */
393+ 0, /* tp_init */
394+ 0, /* tp_alloc */
395+ code_new, /* tp_new */
396+};
397+
398+/* All about c_lnotab.
399+
400+c_lnotab is an array of unsigned bytes disguised as a Python string. In -O
401+mode, SET_LINENO opcodes aren't generated, and bytecode offsets are mapped
402+to source code line #s (when needed for tracebacks) via c_lnotab instead.
403+The array is conceptually a list of
404+ (bytecode offset increment, line number increment)
405+pairs. The details are important and delicate, best illustrated by example:
406+
407+ byte code offset source code line number
408+ 0 1
409+ 6 2
410+ 50 7
411+ 350 307
412+ 361 308
413+
414+The first trick is that these numbers aren't stored, only the increments
415+from one row to the next (this doesn't really work, but it's a start):
416+
417+ 0, 1, 6, 1, 44, 5, 300, 300, 11, 1
418+
419+The second trick is that an unsigned byte can't hold negative values, or
420+values larger than 255, so (a) there's a deep assumption that byte code
421+offsets and their corresponding line #s both increase monotonically, and (b)
422+if at least one column jumps by more than 255 from one row to the next, more
423+than one pair is written to the table. In case #b, there's no way to know
424+from looking at the table later how many were written. That's the delicate
425+part. A user of c_lnotab desiring to find the source line number
426+corresponding to a bytecode address A should do something like this
427+
428+ lineno = addr = 0
429+ for addr_incr, line_incr in c_lnotab:
430+ addr += addr_incr
431+ if addr > A:
432+ return lineno
433+ lineno += line_incr
434+
435+In order for this to work, when the addr field increments by more than 255,
436+the line # increment in each pair generated must be 0 until the remaining addr
437+increment is < 256. So, in the example above, com_set_lineno should not (as
438+was actually done until 2.2) expand 300, 300 to 255, 255, 45, 45, but to
439+255, 0, 45, 255, 0, 45.
440+*/
441+
442+int
443+PyCode_Addr2Line(PyCodeObject *co, int addrq)
444+{
445+ int size = PyString_Size(co->co_lnotab) / 2;
446+ unsigned char *p = (unsigned char*)PyString_AsString(co->co_lnotab);
447+ int line = co->co_firstlineno;
448+ int addr = 0;
449+ while (--size >= 0) {
450+ addr += *p++;
451+ if (addr > addrq)
452+ break;
453+ line += *p++;
454+ }
455+ return line;
456+}
457+
458+/*
459+ Check whether the current instruction is at the start of a line.
460+
461+ */
462+
463+ /* The theory of SET_LINENO-less tracing.
464+
465+ In a nutshell, we use the co_lnotab field of the code object
466+ to tell when execution has moved onto a different line.
467+
468+ As mentioned above, the basic idea is so set things up so
469+ that
470+
471+ *instr_lb <= frame->f_lasti < *instr_ub
472+
473+ is true so long as execution does not change lines.
474+
475+ This is all fairly simple. Digging the information out of
476+ co_lnotab takes some work, but is conceptually clear.
477+
478+ Somewhat harder to explain is why we don't *always* call the
479+ line trace function when the above test fails.
480+
481+ Consider this code:
482+
483+ 1: def f(a):
484+ 2: if a:
485+ 3: print 1
486+ 4: else:
487+ 5: print 2
488+
489+ which compiles to this:
490+
491+ 2 0 LOAD_FAST 0 (a)
492+ 3 JUMP_IF_FALSE 9 (to 15)
493+ 6 POP_TOP
494+
495+ 3 7 LOAD_CONST 1 (1)
496+ 10 PRINT_ITEM
497+ 11 PRINT_NEWLINE
498+ 12 JUMP_FORWARD 6 (to 21)
499+ >> 15 POP_TOP
500+
501+ 5 16 LOAD_CONST 2 (2)
502+ 19 PRINT_ITEM
503+ 20 PRINT_NEWLINE
504+ >> 21 LOAD_CONST 0 (None)
505+ 24 RETURN_VALUE
506+
507+ If 'a' is false, execution will jump to instruction at offset
508+ 15 and the co_lnotab will claim that execution has moved to
509+ line 3. This is at best misleading. In this case we could
510+ associate the POP_TOP with line 4, but that doesn't make
511+ sense in all cases (I think).
512+
513+ What we do is only call the line trace function if the co_lnotab
514+ indicates we have jumped to the *start* of a line, i.e. if the
515+ current instruction offset matches the offset given for the
516+ start of a line by the co_lnotab.
517+
518+ This also takes care of the situation where 'a' is true.
519+ Execution will jump from instruction offset 12 to offset 21.
520+ Then the co_lnotab would imply that execution has moved to line
521+ 5, which is again misleading.
522+
523+ Why do we set f_lineno when tracing? Well, consider the code
524+ above when 'a' is true. If stepping through this with 'n' in
525+ pdb, you would stop at line 1 with a "call" type event, then
526+ line events on lines 2 and 3, then a "return" type event -- but
527+ you would be shown line 5 during this event. This is a change
528+ from the behaviour in 2.2 and before, and I've found it
529+ confusing in practice. By setting and using f_lineno when
530+ tracing, one can report a line number different from that
531+ suggested by f_lasti on this one occasion where it's desirable.
532+ */
533+
534+
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 comments in compile.c for the description of
554+ co_lnotab. A point to remember: increments to p
555+ should come in pairs -- although we don't care about
556+ the line increments here, treating them as byte
557+ increments gets confusing, to say the least. */
558+
559+ bounds->ap_lower = 0;
560+ while (size > 0) {
561+ if (addr + *p > lasti)
562+ break;
563+ addr += *p++;
564+ if (*p)
565+ bounds->ap_lower = addr;
566+ line += *p++;
567+ --size;
568+ }
569+
570+ /* If lasti and addr don't match exactly, we don't want to
571+ change the lineno slot on the frame or execute a trace
572+ function. Return -1 instead.
573+ */
574+ if (addr != lasti)
575+ line = -1;
576+
577+ if (size > 0) {
578+ while (--size >= 0) {
579+ addr += *p++;
580+ if (*p++)
581+ break;
582+ }
583+ bounds->ap_upper = addr;
584+ }
585+ else {
586+ bounds->ap_upper = INT_MAX;
587+ }
588+
589+ return line;
590+}