[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);

AltStyle によって変換されたページ (->オリジナル) /