diff --git a/src/docode.c b/src/docode.c index 744d8565d167a8dd5bda6b3726820c137901ba7b..83689e54174798b7efe47c74d25c99cad4766c11 100644 --- a/src/docode.c +++ b/src/docode.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: docode.c,v 1.101 2001/01/25 09:14:38 hubbe Exp $"); +RCSID("$Id: docode.c,v 1.102 2001/01/31 22:02:12 mast Exp $"); #include "las.h" #include "program.h" #include "pike_types.h" @@ -108,6 +108,29 @@ static int current_stack_depth = 0; cleanup_frame__.cleanup(cleanup_frame__.cleanup_arg); \ POP_AND_DONT_CLEANUP +/* A block in the following sense is a region of code where: + * o Execution always enters at the beginning. + * o All stack nesting is left intact on exit (both normally and + * through jumps, but not through exceptions). This includes the + * svalue and mark stacks, and the catch block nesting. + */ +#ifdef PIKE_DEBUG +#define BLOCK_BEGIN \ + PUSH_CLEANUP_FRAME(do_cleanup_synch_mark, 0); \ + if (d_flag > 2) emit0(F_SYNCH_MARK); +#define BLOCK_END \ + if (current_stack_depth != cleanup_frame__.stack_depth) { \ + print_tree(n); \ + fatal("Stack not in synch after block: is %d, should be %d.\n", \ + current_stack_depth, cleanup_frame__.stack_depth); \ + } \ + if (d_flag > 2) emit0(F_POP_SYNCH_MARK); \ + POP_AND_DONT_CLEANUP +#else +#define BLOCK_BEGIN +#define BLOCK_END +#endif + #define PUSH_STATEMENT_LABEL do { \ struct statement_label new_label__; \ new_label__.prev = current_label; \ @@ -229,15 +252,6 @@ void do_pop(int x) current_stack_depth -= x; } -void do_cleanup_pop(int x) -{ -#ifdef PIKE_DEBUG - if(d_flag) - emit0(F_POP_MARK); -#endif - do_pop(x); -} - void do_pop_mark() { emit0(F_POP_MARK); @@ -248,12 +262,18 @@ void do_pop_to_mark() emit0(F_POP_TO_MARK); } +void do_cleanup_synch_mark() +{ + if (d_flag > 2) + emit0(F_CLEANUP_SYNCH_MARK); +} + void do_escape_catch() { emit0(F_ESCAPE_CATCH); } -#define DO_CODE_BLOCK(X) do_pop(do_docode((X),DO_NOT_COPY | DO_POP | DO_DEFER_POP)) +#define DO_CODE_BLOCK(X) do_pop(do_docode((X),DO_NOT_COPY | DO_POP )) int do_docode(node *n, INT16 flags) { @@ -830,6 +850,7 @@ static int do_docode2(node *n, INT16 flags) case F_FOR: { INT32 *prev_switch_jumptable = current_switch_jumptable; + BLOCK_BEGIN; PUSH_STATEMENT_LABEL; current_switch_jumptable=0; @@ -851,6 +872,7 @@ static int do_docode2(node *n, INT16 flags) current_switch_jumptable = prev_switch_jumptable; POP_STATEMENT_LABEL; + BLOCK_END; return 0; } @@ -861,6 +883,7 @@ static int do_docode2(node *n, INT16 flags) { node *arr; INT32 *prev_switch_jumptable = current_switch_jumptable; + BLOCK_BEGIN; arr=CAR(n); @@ -873,25 +896,16 @@ static int do_docode2(node *n, INT16 flags) a2[0]->u.sval.type==0x7fffffff && a1[0]->type == int_type_string) { - tmp2=do_docode(CAR(arr),DO_NOT_COPY); + do_docode(CAR(arr),DO_NOT_COPY); do_docode(*a1,DO_NOT_COPY); goto foreach_arg_pushed; } } - tmp2=do_docode(CAR(n),DO_NOT_COPY); + do_docode(CAR(n),DO_NOT_COPY); emit0(F_CONST0); current_stack_depth++; - foreach_arg_pushed: -#ifdef PIKE_DEBUG - /* This is really ugly because there is always a chance that the bug - * will disappear when new instructions are added to the code, but - * think it is worth it. - */ - if(d_flag) - emit0(F_MARK); -#endif - PUSH_CLEANUP_FRAME(do_cleanup_pop, 4); + PUSH_CLEANUP_FRAME(do_pop, 4); PUSH_STATEMENT_LABEL; current_switch_jumptable=0; @@ -909,6 +923,7 @@ static int do_docode2(node *n, INT16 flags) current_switch_jumptable = prev_switch_jumptable; POP_STATEMENT_LABEL; POP_AND_DO_CLEANUP; + BLOCK_END; return 0; } @@ -918,17 +933,10 @@ static int do_docode2(node *n, INT16 flags) case F_DEC_LOOP: { INT32 *prev_switch_jumptable = current_switch_jumptable; + BLOCK_BEGIN; - tmp2=do_docode(CAR(n),0); -#ifdef PIKE_DEBUG - /* This is really ugly because there is always a chance that the bug - * will disappear when new instructions are added to the code, but - * think it is worth it. - */ - if(d_flag) - emit0(F_MARK); -#endif - PUSH_CLEANUP_FRAME(do_cleanup_pop, 3); + do_docode(CAR(n),0); + PUSH_CLEANUP_FRAME(do_pop, 3); PUSH_STATEMENT_LABEL; current_switch_jumptable=0; @@ -946,6 +954,7 @@ static int do_docode2(node *n, INT16 flags) current_switch_jumptable = prev_switch_jumptable; POP_STATEMENT_LABEL; POP_AND_DO_CLEANUP; + BLOCK_END; return 0; } @@ -969,6 +978,7 @@ static int do_docode2(node *n, INT16 flags) case F_DO: { INT32 *prev_switch_jumptable = current_switch_jumptable; + BLOCK_BEGIN; PUSH_STATEMENT_LABEL; current_switch_jumptable=0; @@ -983,12 +993,15 @@ static int do_docode2(node *n, INT16 flags) current_switch_jumptable = prev_switch_jumptable; POP_STATEMENT_LABEL; + BLOCK_END; return 0; } case F_POP_VALUE: { + BLOCK_BEGIN; DO_CODE_BLOCK(CAR(n)); + BLOCK_END; return 0; } @@ -1141,6 +1154,7 @@ static int do_docode2(node *n, INT16 flags) #ifdef PIKE_DEBUG struct svalue *save_sp=Pike_sp; #endif + BLOCK_BEGIN; PUSH_STATEMENT_LABEL; if(do_docode(CAR(n),0)!=1) @@ -1174,7 +1188,7 @@ static int do_docode2(node *n, INT16 flags) current_switch_jumptable[current_switch_case++]=-1; DO_CODE_BLOCK(CDR(n)); - + #ifdef PIKE_DEBUG if(Pike_sp-save_sp != cases) fatal("Count cases is wrong!\n"); @@ -1236,6 +1250,7 @@ static int do_docode2(node *n, INT16 flags) low_insert_label( current_label->break_label); POP_STATEMENT_LABEL; + BLOCK_END; #ifdef PIKE_DEBUG if(Pike_interpreter.recoveries && Pike_sp-Pike_interpreter.evaluator_stack < Pike_interpreter.recoveries->stack_pointer) fatal("Stack error after F_SWITCH (underflow)\n"); @@ -1402,6 +1417,7 @@ static int do_docode2(node *n, INT16 flags) case F_CUSTOM_STMT_LABEL: { struct statement_label *label; struct statement_label_name name; + BLOCK_BEGIN; PUSH_STATEMENT_LABEL; name.str = CAR(n)->u.sval.u.string; name.line_number = n->line_number; @@ -1436,6 +1452,7 @@ static int do_docode2(node *n, INT16 flags) if (!name.next && current_label->emit_break_label) low_insert_label(current_label->break_label); POP_STATEMENT_LABEL; + BLOCK_END; return 0; } @@ -1452,6 +1469,7 @@ static int do_docode2(node *n, INT16 flags) case F_CATCH: { INT32 *prev_switch_jumptable = current_switch_jumptable; + tmp1=do_jump(F_CATCH,-1); PUSH_CLEANUP_FRAME(do_escape_catch, 0); @@ -1459,16 +1477,14 @@ static int do_docode2(node *n, INT16 flags) current_switch_jumptable=0; current_label->break_label=alloc_label(); if (TEST_COMPAT(7,0)) - current_label->continue_label=alloc_label(); + current_label->continue_label = current_label->break_label; DO_CODE_BLOCK(CAR(n)); - if (TEST_COMPAT(7,0)) - ins_label(current_label->continue_label); ins_label(current_label->break_label); emit0(F_THROW_ZERO); - current_switch_jumptable = prev_switch_jumptable; POP_STATEMENT_LABEL; + current_switch_jumptable = prev_switch_jumptable; ins_label(DO_NOT_WARN((INT32)tmp1)); current_stack_depth++;