[Python-checkins] python/dist/src/Python newcompile.c,1.1.2.46,1.1.2.47
nascheme@users.sourceforge.net
nascheme@users.sourceforge.net
2003年3月30日 13:13:42 -0800
Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1:/tmp/cvs-serv7163/Python
Modified Files:
Tag: ast-branch
newcompile.c
Log Message:
Generate (hopefully) correct code for try/finally nodes. I'm not sure
I got the block and fblock stuff right but it seems to work.
Add missing POP_TOP instructions for assert code.
Index: newcompile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v
retrieving revision 1.1.2.46
retrieving revision 1.1.2.47
diff -C2 -d -r1.1.2.46 -r1.1.2.47
*** newcompile.c 29 Mar 2003 15:47:55 -0000 1.1.2.46
--- newcompile.c 30 Mar 2003 21:13:38 -0000 1.1.2.47
***************
*** 932,935 ****
--- 932,996 ----
}
+ /* Code generated for "try: S finally: Sf" is as follows:
+
+ SETUP_FINALLY L
+ <code for body>
+ POP_BLOCK
+ LOAD_CONST <None>
+ L: <code for finalbody>
+ END_FINALLY
+
+ The special instructions use the block stack. Each block
+ stack entry contains the instruction that created it (here
+ SETUP_FINALLY), the level of the value stack at the time the
+ block stack entry was created, and a label (here L).
+
+ SETUP_FINALLY:
+ Pushes the current value stack level and the label
+ onto the block stack.
+ POP_BLOCK:
+ Pops en entry from the block stack, and pops the value
+ stack until its level is the same as indicated on the
+ block stack. (The label is ignored.)
+ END_FINALLY:
+ Pops a variable number of entries from the *value* stack
+ and re-raises the exception they specify. The number of
+ entries popped depends on the (pseudo) exception type.
+
+ The block stack is unwound when an exception is raised:
+ when a SETUP_FINALLY entry is found, the exception is pushed
+ onto the value stack (and the exception condition is cleared),
+ and the interpreter jumps to the label gotten from the block
+ stack.
+ */
+
+ static int
+ compiler_try_finally(struct compiler *c, stmt_ty s)
+ {
+ int body, end;
+ body = compiler_new_block(c);
+ end = compiler_new_block(c);
+ if (body < 0 || end < 0)
+ return 0;
+
+ ADDOP_JREL(c, SETUP_FINALLY, end);
+ compiler_use_next_block(c, body);
+ if (!compiler_push_fblock(c, FINALLY_TRY, body))
+ return 0;
+ VISIT_SEQ(c, stmt, s->v.TryFinally.body);
+ ADDOP(c, POP_BLOCK);
+ compiler_pop_fblock(c, FINALLY_TRY, body);
+
+ ADDOP_O(c, LOAD_CONST, Py_None, consts);
+ compiler_use_next_block(c, end);
+ if (!compiler_push_fblock(c, FINALLY_END, end))
+ return 0;
+ VISIT_SEQ(c, stmt, s->v.TryFinally.finalbody);
+ ADDOP(c, END_FINALLY);
+ compiler_pop_fblock(c, FINALLY_END, end);
+
+ return 1;
+ }
+
static int
compiler_import(struct compiler *c, stmt_ty s)
***************
*** 1014,1017 ****
--- 1075,1079 ----
return 0;
ADDOP_JREL(c, JUMP_IF_TRUE, end);
+ ADDOP(c, POP_TOP);
ADDOP_O(c, LOAD_GLOBAL, assertion_error, names);
if (s->v.Assert.msg) {
***************
*** 1023,1026 ****
--- 1085,1089 ----
}
compiler_use_block(c, end);
+ ADDOP(c, POP_TOP);
return 1;
}
***************
*** 1096,1102 ****
break;
case TryFinally_kind:
! VISIT_SEQ(c, stmt, s->v.TryFinally.body);
! VISIT_SEQ(c, stmt, s->v.TryFinally.finalbody);
! break;
case Assert_kind:
return compiler_assert(c, s);
--- 1159,1163 ----
break;
case TryFinally_kind:
! return compiler_try_finally(c, s);
case Assert_kind:
return compiler_assert(c, s);