2001-01-31
2001-01-31 22:02:12 by Martin Stjernholm <mast@lysator.liu.se>
-
1544fd8f5e030e9b46a24401b01b799d944ff31d
(93 lines)
(+55/-38)
[
Show
| Annotate
]
Branch: 7.9
Added more debug checks of stacks by introducing a block concept: when the
debug level is 3 or higher the SYNCH_MARK opcodes are inserted to isolate
stack errors more.
Rev: src/docode.c:1.102
5:
\*/
/**/
#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:
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:
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:
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:
case F_FOR:
{
INT32 *prev_switch_jumptable = current_switch_jumptable;
+ BLOCK_BEGIN;
PUSH_STATEMENT_LABEL;
current_switch_jumptable=0;
851:
current_switch_jumptable = prev_switch_jumptable;
POP_STATEMENT_LABEL;
+ BLOCK_END;
return 0;
}
861:
{
node *arr;
INT32 *prev_switch_jumptable = current_switch_jumptable;
+ BLOCK_BEGIN;
arr=CAR(n);
873:
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:
current_switch_jumptable = prev_switch_jumptable;
POP_STATEMENT_LABEL;
POP_AND_DO_CLEANUP;
+ BLOCK_END;
return 0;
}
918:
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:
current_switch_jumptable = prev_switch_jumptable;
POP_STATEMENT_LABEL;
POP_AND_DO_CLEANUP;
+ BLOCK_END;
return 0;
}
969:
case F_DO:
{
INT32 *prev_switch_jumptable = current_switch_jumptable;
+ BLOCK_BEGIN;
PUSH_STATEMENT_LABEL;
current_switch_jumptable=0;
983:
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: Inside #if defined(PIKE_DEBUG)
#ifdef PIKE_DEBUG
struct svalue *save_sp=Pike_sp;
#endif
+ BLOCK_BEGIN;
PUSH_STATEMENT_LABEL;
if(do_docode(CAR(n),0)!=1)
1236:
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:
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:
if (!name.next && current_label->emit_break_label)
low_insert_label(current_label->break_label);
POP_STATEMENT_LABEL;
+ BLOCK_END;
return 0;
}
1452:
case F_CATCH: {
INT32 *prev_switch_jumptable = current_switch_jumptable;
+
tmp1=do_jump(F_CATCH,-1);
PUSH_CLEANUP_FRAME(do_escape_catch, 0);
1459:
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++;