pike.git
/
src
/
docode.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/docode.c:1:
/*\ ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License) ||| See the files COPYING and DISCLAIMER for more information. \*/ /**/ #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" #include "stralloc.h" #include "interpret.h" #include "constants.h" #include "array.h" #include "pike_macros.h" #include "pike_error.h" #include "pike_memory.h"
pike.git/src/docode.c:101:
) \ current_label->prev->cleanups = cleanup_frame__.prev; \ } \ } while (0) #define POP_AND_DO_CLEANUP \ do_pop(current_stack_depth - cleanup_frame__.stack_depth); \ 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; \ if (current_label->break_label != -2) { \ /* Only cover the current label if it's closed. */ \ new_label__.name = 0; \ new_label__.break_label = new_label__.continue_label = -1; \ new_label__.emit_break_label = 0; \ new_label__.cleanups = 0; \ new_label__.stack_depth = current_stack_depth; \
pike.git/src/docode.c:222:
#endif switch(x) { case 0: return; case 1: emit0(F_POP_VALUE); break; default: emit1(F_POP_N_ELEMS,x); break; } 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); } 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) { int i; int stack_depth_save = current_stack_depth; int save_current_line=lex.current_line; if(!n) return 0; lex.current_line=n->line_number; #ifdef PIKE_DEBUG if (current_stack_depth == -4711) fatal("do_docode() used outside docode().\n");
pike.git/src/docode.c:823:
emit0(F_DEC_AND_POP); return 0; }else{ emit0(n->token); return 1; } case F_FOR: { INT32 *prev_switch_jumptable = current_switch_jumptable;
+
BLOCK_BEGIN;
PUSH_STATEMENT_LABEL; current_switch_jumptable=0; current_label->break_label=alloc_label(); current_label->continue_label=alloc_label(); if(CDR(n)) { do_jump_when_zero(CAR(n),current_label->break_label); tmp2=ins_label(-1);
pike.git/src/docode.c:844:
ins_label(current_label->continue_label); DO_CODE_BLOCK(CDDR(n)); }else{ tmp2=ins_label(-1); } do_jump_when_non_zero(CAR(n), DO_NOT_WARN((INT32)tmp2)); ins_label(current_label->break_label); current_switch_jumptable = prev_switch_jumptable; POP_STATEMENT_LABEL;
+
BLOCK_END;
return 0; } case ' ': return do_docode(CAR(n),0)+do_docode(CDR(n),DO_LVALUE); case F_FOREACH: { node *arr; INT32 *prev_switch_jumptable = current_switch_jumptable;
-
+
BLOCK_BEGIN;
arr=CAR(n); if(arr->token==F_RANGE) { node **a1=my_get_arg(&_CDR(n),0); node **a2=my_get_arg(&_CDR(n),1); if(a1 && a2 && a2[0]->token==F_CONSTANT && a2[0]->u.sval.type==T_INT && 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; current_label->break_label=alloc_label(); current_label->continue_label=alloc_label(); tmp3=do_branch(-1); tmp1=ins_label(-1); DO_CODE_BLOCK(CDR(n)); ins_label(current_label->continue_label); low_insert_label( DO_NOT_WARN((INT32)tmp3)); do_jump(n->token, DO_NOT_WARN((INT32)tmp1)); ins_label(current_label->break_label); current_switch_jumptable = prev_switch_jumptable; POP_STATEMENT_LABEL; POP_AND_DO_CLEANUP;
-
+
BLOCK_END;
return 0; } case F_INC_NEQ_LOOP: case F_DEC_NEQ_LOOP: case F_INC_LOOP: 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; current_label->break_label=alloc_label(); current_label->continue_label=alloc_label(); tmp3=do_branch(-1); tmp1=ins_label(-1); DO_CODE_BLOCK(CDR(n)); ins_label(current_label->continue_label); low_insert_label( DO_NOT_WARN((INT32)tmp3)); do_jump(n->token, DO_NOT_WARN((INT32)tmp1)); ins_label(current_label->break_label); current_switch_jumptable = prev_switch_jumptable; POP_STATEMENT_LABEL; POP_AND_DO_CLEANUP;
-
+
BLOCK_END;
return 0; } case F_LOOP: { /* FIXME: No support for break or continue. */ PUSH_STATEMENT_LABEL; tmp1 = do_docode(CAR(n), 0); if (tmp1 > 0) { do_pop(tmp1-1);
pike.git/src/docode.c:962:
ins_label(tmp2); emit1(F_LOOP, tmp3); } POP_STATEMENT_LABEL; return 0; } case F_DO: { INT32 *prev_switch_jumptable = current_switch_jumptable;
+
BLOCK_BEGIN;
PUSH_STATEMENT_LABEL; current_switch_jumptable=0; current_label->break_label=alloc_label(); current_label->continue_label=alloc_label(); tmp2=ins_label(-1); DO_CODE_BLOCK(CAR(n)); ins_label(current_label->continue_label); do_jump_when_non_zero(CDR(n), DO_NOT_WARN((INT32)tmp2)); ins_label(current_label->break_label); 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; } case F_CAST: if(n->type==void_type_string) { DO_CODE_BLOCK(CAR(n)); return 0; } tmp1=store_prog_string(n->type);
pike.git/src/docode.c:1134:
INT32 e,cases,*order; INT32 *jumptable; INT32 prev_switch_values_on_stack = current_switch_values_on_stack; INT32 prev_switch_case = current_switch_case; INT32 prev_switch_default = current_switch_default; INT32 *prev_switch_jumptable = current_switch_jumptable; struct pike_string *prev_switch_type = current_switch_type; #ifdef PIKE_DEBUG struct svalue *save_sp=Pike_sp; #endif
+
BLOCK_BEGIN;
PUSH_STATEMENT_LABEL; if(do_docode(CAR(n),0)!=1) fatal("Internal compiler error, time to panic\n"); if (!(CAR(n) && (current_switch_type = CAR(n)->type))) { current_switch_type = mixed_type_string; } current_label->break_label=alloc_label();
pike.git/src/docode.c:1229:
current_switch_jumptable = prev_switch_jumptable; current_switch_default = prev_switch_default; current_switch_case = prev_switch_case; current_switch_values_on_stack = prev_switch_values_on_stack; current_switch_type = prev_switch_type; 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"); #endif return 0; } case F_CASE: { if(!current_switch_jumptable)
pike.git/src/docode.c:1395:
else do_branch(label->continue_label); return 0; } case F_NORMAL_STMT_LABEL: 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; for (label = current_label; label; label = label->prev) { struct statement_label_name *lbl_name; for (lbl_name = label->name; lbl_name; lbl_name = lbl_name->next) if (lbl_name->str == name.str) { INT32 save_line = lex.current_line; lex.current_line = name.line_number;
pike.git/src/docode.c:1429:
* the statement_label "open" so the statement will use it * instead of covering it. */ current_label->break_label = -2; else current_label->break_label = -1; } DO_CODE_BLOCK(CDR(n)); if (!name.next && current_label->emit_break_label) low_insert_label(current_label->break_label); POP_STATEMENT_LABEL;
+
BLOCK_END;
return 0; } case F_RETURN: do_docode(CAR(n),0); emit0(F_RETURN); return 0; case F_SSCANF: tmp1=do_docode(CAR(n),DO_NOT_COPY); tmp2=do_docode(CDR(n),DO_NOT_COPY | DO_LVALUE); emit1(F_SSCANF, DO_NOT_WARN((INT32)(tmp1+tmp2))); return 1; case F_CATCH: { INT32 *prev_switch_jumptable = current_switch_jumptable;
-
+
tmp1=do_jump(F_CATCH,-1); PUSH_CLEANUP_FRAME(do_escape_catch, 0); PUSH_STATEMENT_LABEL; 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++; POP_AND_DONT_CLEANUP; return 1; } case F_LVALUE_LIST: return do_docode(CAR(n),DO_LVALUE)+do_docode(CDR(n),DO_LVALUE);