[Python-checkins] python/dist/src/Python newcompile.c,1.1.2.50,1.1.2.51
jhylton@users.sourceforge.net
jhylton@users.sourceforge.net
Thu, 03 Apr 2003 05:52:27 -0800
Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1:/tmp/cvs-serv5957
Modified Files:
Tag: ast-branch
newcompile.c
Log Message:
Add some infrastructure for creating lnotab.
Index: newcompile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v
retrieving revision 1.1.2.50
retrieving revision 1.1.2.51
diff -C2 -d -r1.1.2.50 -r1.1.2.51
*** newcompile.c 1 Apr 2003 22:17:00 -0000 1.1.2.50
--- newcompile.c 3 Apr 2003 13:52:24 -0000 1.1.2.51
***************
*** 44,48 ****
int u_curblock; /* index of current block in u_blocks */
int u_tmpname; /* temporary variables for list comps */
! identifier u_tmp; /* name for u_tmpname */
struct basicblock u_exit;
struct basicblock **u_blocks;
--- 44,48 ----
int u_curblock; /* index of current block in u_blocks */
int u_tmpname; /* temporary variables for list comps */
! identifier u_tmp; /* name for u_tmpname */
struct basicblock u_exit;
struct basicblock **u_blocks;
***************
*** 51,55 ****
struct fblockinfo u_fblock[CO_MAXBLOCKS];
! int u_lineno;
};
--- 51,57 ----
struct fblockinfo u_fblock[CO_MAXBLOCKS];
! int u_lineno; /* the lineno for the current stmt */
! bool u_lineno_set; /* boolean to indicate whether instr
! has been generated with current lineno */
};
***************
*** 68,71 ****
--- 70,74 ----
struct assembler {
PyObject *a_bytecode; /* string containing bytecode */
+ PyObject *a_lnotab; /* string containing lnotab */
int a_offset; /* offset into bytecode */
int a_nblocks; /* number of reachable blocks */
***************
*** 285,288 ****
--- 288,293 ----
u->u_tmpname = 0;
u->u_nfblocks = 0;
+ u->u_lineno = 0;
+ u->u_lineno_set = true;
memset(u->u_blocks, 0, sizeof(struct basicblock *) * DEFAULT_BLOCKS);
u->u_consts = PyDict_New();
***************
*** 483,486 ****
--- 488,502 ----
*/
+ static void
+ compiler_set_lineno(struct compiler *c, int off)
+ {
+ struct basicblock *b;
+ if (c->u->u_lineno_set)
+ return;
+ c->u->u_lineno_set = true;
+ b = c->u->u_blocks[c->u->u_curblock];
+ b->b_instr[off].i_lineno = c->u->u_lineno;
+ }
+
static int
compiler_addop(struct compiler *c, int opcode)
***************
*** 492,495 ****
--- 508,512 ----
if (off < 0)
return 0;
+ compiler_set_lineno(c, off);
b = c->u->u_blocks[c->u->u_curblock];
i = &b->b_instr[off];
***************
*** 537,540 ****
--- 554,558 ----
if (off < 0)
return 0;
+ compiler_set_lineno(c, off);
i = &c->u->u_blocks[c->u->u_curblock]->b_instr[off];
i->i_opcode = opcode;
***************
*** 549,555 ****
--- 567,576 ----
struct instr *i;
int off;
+
+ assert(block >= 0);
off = compiler_next_instr(c, c->u->u_curblock);
if (off < 0)
return 0;
+ compiler_set_lineno(c, off);
i = &c->u->u_blocks[c->u->u_curblock]->b_instr[off];
i->i_opcode = opcode;
***************
*** 1192,1196 ****
fprintf(stderr, "compile stmt %d lineno %d\n",
s->kind, s->lineno);
! c->u->u_lineno = s->lineno; /* XXX this isn't right */
switch (s->kind) {
case FunctionDef_kind:
--- 1213,1218 ----
fprintf(stderr, "compile stmt %d lineno %d\n",
s->kind, s->lineno);
! c->u->u_lineno = s->lineno;
! c->u->u_lineno_set = false;
switch (s->kind) {
case FunctionDef_kind:
***************
*** 1563,1567 ****
compiler_compare(struct compiler *c, expr_ty e)
{
! int i, n, cleanup;
VISIT(c, expr, e->v.Compare.left);
--- 1585,1589 ----
compiler_compare(struct compiler *c, expr_ty e)
{
! int i, n, cleanup = -1;
VISIT(c, expr, e->v.Compare.left);
***************
*** 2026,2029 ****
--- 2048,2101 ----
}
+ /* All about c_lnotab.
+
+ c_lnotab is an array of unsigned bytes disguised as a Python string. In -O
+ mode, SET_LINENO opcodes aren't generated, and bytecode offsets are mapped
+ to source code line #s (when needed for tracebacks) via c_lnotab instead.
+ The array is conceptually a list of
+ (bytecode offset increment, line number increment)
+ pairs. The details are important and delicate, best illustrated by example:
+
+ byte code offset source code line number
+ 0 1
+ 6 2
+ 50 7
+ 350 307
+ 361 308
+
+ The first trick is that these numbers aren't stored, only the increments
+ from one row to the next (this doesn't really work, but it's a start):
+
+ 0, 1, 6, 1, 44, 5, 300, 300, 11, 1
+
+ The second trick is that an unsigned byte can't hold negative values, or
+ values larger than 255, so (a) there's a deep assumption that byte code
+ offsets and their corresponding line #s both increase monotonically, and (b)
+ if at least one column jumps by more than 255 from one row to the next, more
+ than one pair is written to the table. In case #b, there's no way to know
+ from looking at the table later how many were written. That's the delicate
+ part. A user of c_lnotab desiring to find the source line number
+ corresponding to a bytecode address A should do something like this
+
+ lineno = addr = 0
+ for addr_incr, line_incr in c_lnotab:
+ addr += addr_incr
+ if addr > A:
+ return lineno
+ lineno += line_incr
+
+ In order for this to work, when the addr field increments by more than 255,
+ the line # increment in each pair generated must be 0 until the remaining addr
+ increment is < 256. So, in the example above, com_set_lineno should not (as
+ was actually done until 2.2) expand 300, 300 to 255, 255, 45, 45, but to
+ 255, 0, 45, 255, 0, 45.
+ */
+
+ static int
+ assemble_lnotab(struct assembler *a)
+ {
+ return 1;
+ }
+
/* Return the size of a basic block in bytes. */
***************
*** 2251,2254 ****
--- 2323,2328 ----
/* Can't modify the bytecode after computing jump offsets. */
if (!assemble_jump_offsets(&a, c))
+ goto error;
+ if (!assemble_lnotab(&a))
goto error;