From: Peep P. <so...@us...> - 2004-06-20 14:04:02
|
Update of /cvsroot/agd/server/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv587 Modified Files: interpret.c Log Message: Lots of fixes. Notably: runtime for dynamically allocated memory is now called runtime_dyn; F_INDEX_LVALUE works with any operator; changed some macros into functions; F_SLICE works quite okay now; F_CALL_OTHER doesn't fail if called with no arguments Index: interpret.c =================================================================== RCS file: /cvsroot/agd/server/src/interpret.c,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- interpret.c 14 Jun 2004 20:55:42 -0000 1.24 +++ interpret.c 20 Jun 2004 14:03:53 -0000 1.25 @@ -38,9 +38,9 @@ control_stack_t *csp = control_stack; #define CHECK_CSP() if(csp >= control_stack + CONTROL_STACK_SIZE) \ - runtime("control stack overflow (too deep recursion)", 0); + runtime("control stack overflow (too deep recursion)"); #define CHECK_SP() if(sp >= value_stack + VALUE_STACK_SIZE) \ - runtime("value stack overflow", 0); + runtime("value stack overflow"); extern void (**dfptr)(void); @@ -67,7 +67,7 @@ /* Need the F_NEWLINE operation for this. */ /* free_str: whether to free the string passed to it before * doing longjmp() or not - for dynamically allocated strings */ -void runtime(char *s, int free_str) +void _runtime(char *s, int free_str) { char *buf; @@ -91,7 +91,7 @@ /* stack_trace();*/ out: - if(csp > &control_stack[0]) { + while(csp > &control_stack[0]) { pop_locals(); pop_control_stack(1); } @@ -254,7 +254,7 @@ { csp--; if(csp < control_stack) { - runtime("control stack underflow", 0); + runtime("control stack underflow"); } fp = csp->fp; @@ -271,15 +271,44 @@ } /* Used by F_JUMP and F_JUMP_IF_FALSE to check if they jumped too far. */ -#define CHECK_OVERRUN() if(cp >= code + codelen) {\ - debug("interpret", "Ran over end of array: returning\n"); return; } +#define CHECK_OVERRUN() do { if(cp >= code + codelen) {\ + debug("interpret", "Ran over end of array: returning\n"); return; \ + } } while(0) -#define GET_ARGS() arg[0] = sp[-1].u.i; pop_stack(); arg[1] = sp[-1].u.i; pop_stack(); +#define GET_ARGS() \ + arg[1] = sp[-1].u.i; pop_stack(); \ + arg[0] = sp[-1].u.i; pop_stack() -#define TAKE_SLICE() GET_ARGS() if(!sp[-1].u.s) runtime("taking substring of null string", 0); \ - if(arg[1] >= strlen(sp[-1].u.s)+1 || arg[1] < 0 || arg[1] > arg[0]) runtime("substring out of range", 0); \ +void setup_frame(void) +{ + push_control_stack(); + csp->num_arg = *cp; + fp = sp - csp->num_arg; +} -#define SETUP_FRAME() push_control_stack(); csp->num_arg = *cp; fp = sp - csp->num_arg; +void index_check(int *arg, char *str) +{ + if(!str) + runtime("taking element of null string"); + if(arg[0] < 0 || arg[0] > strlen(str)) + runtime("index out of range"); +} + +variable_t *take_slice(int *arg) +{ + variable_t *v; + GET_ARGS(); + + v = sp[-1].u.v; + if(!v->u.s) + runtime("taking substring of null string"); + if(arg[0] > arg[1]) + runtime("first index is bigger than second index"); + if(arg[0] < 0 || arg[1] > strlen(v->u.s)) { + runtime("substring out of range"); + } + return v; +} void eval_instruction(void) { @@ -305,9 +334,7 @@ if(*cp == -1) tmps = NULL; else - tmps = this_ob->prog->str_tbl[*cp]; - if(tmps) - tmps = stringdup(tmps); + tmps = stringdup(this_ob->prog->str_tbl[*cp]); push_string(tmps, ST_MALLOC); break; case F_PUSH_VOID: @@ -377,8 +404,8 @@ } break; case F_SUB: - GET_ARGS() - push_int(arg[1] - arg[0]); + GET_ARGS(); + push_int(arg[0] - arg[1]); break; case F_SUB_EQ: if(sp[-2].type == T_CHAR_PTR) { @@ -392,8 +419,8 @@ push_int(tmpi); break; case F_MUL: - GET_ARGS() - push_int(arg[1] * arg[0]); + GET_ARGS(); + push_int(arg[0] * arg[1]); break; case F_MUL_EQ: if(sp[-2].type == T_CHAR_PTR) { @@ -407,14 +434,14 @@ push_int(tmpi); break; case F_DIV: - GET_ARGS() - if(!arg[0]) - runtime("division by zero", 0); - push_int(arg[1] / arg[0]); + GET_ARGS(); + if(!arg[1]) + runtime("division by zero"); + push_int(arg[0] / arg[1]); break; case F_DIV_EQ: if(!sp[-1].u.i) - runtime("division by zero", 0); + runtime("division by zero"); if(sp[-2].type == T_CHAR_PTR) { tmpi = sp[-2].u.s[0] / sp[-1].u.i; @@ -427,14 +454,14 @@ push_int(tmpi); break; case F_MOD: - GET_ARGS() - if(!arg[0]) - runtime("divison by zero", 0); - push_int(arg[1] % arg[0]); + GET_ARGS(); + if(!arg[1]) + runtime("divison by zero"); + push_int(arg[0] % arg[1]); break; case F_MOD_EQ: if(!sp[-1].u.i) - runtime("divison by zero", 0); + runtime("divison by zero"); if(sp[-2].type == T_CHAR_PTR) { tmpi = sp[-2].u.s[0] % sp[-1].u.i; } else { @@ -504,62 +531,43 @@ if(tmpvp->type & T_ARRAY) { if(!tmpvp->u.a) { - runtime("taking element of null array", 0); + runtime("taking element of null array"); } if(arg[0] < 0 || arg[0] >= tmpvp->u.a->length) { - runtime("index out of range", 0); + runtime("index out of range"); } tmpvp = tmpvp->u.a->data[arg[0]]; push_var(tmpvp); } else { - if(!tmpvp->u.s) { - runtime("taking element of null string", 0); - } - if(arg[0] < 0 || arg[0] > strlen(tmpvp->u.s)+1) { - runtime("index out of range", 0); - } + index_check(arg, tmpvp->u.s); arg[1] = tmpvp->u.s[arg[0]]; push_int(arg[1]); } break; case F_INDEX_LVALUE: - /* A bit hacky. */ arg[0] = sp[-1].u.i; pop_stack(); tmpvp = sp[-1].u.v; pop_stack(); - - tmps = tmpvp->u.s; - if(!tmps) { - runtime("taking element of null string", 0); - } - if(arg[0] < 0 || arg[0] > strlen(tmps)+1) { - runtime("index out of range", 0); - } + index_check(arg, tmpvp->u.s); sp->type = T_CHAR_PTR; - sp->u.s = tmps + arg[0]; + sp->u.s = tmpvp->u.s + arg[0]; sp++; CHECK_SP() -/* do_assign(sp, &sp[-1]); - sp->u.s += arg[0]; - pop_stack(); - push_var(sp+1); - push_lvalue(sp-1);*/ break; case F_SLICE: - TAKE_SLICE() - tmps = xmalloc(arg[0] - arg[1] + 1); - for(tmpi=0;tmpi<arg[0];tmpi++) - tmps[tmpi] = sp[-1].u.s[tmpi+arg[1]]; - tmps[tmpi] = '\0'; + tmpvp = take_slice(arg); + tmps = xmalloc(arg[1] - arg[0] + 2); + for(tmpi=arg[0];tmpi<=arg[1];tmpi++) + tmps[tmpi-arg[0]] = tmpvp->u.s[tmpi]; + tmps[arg[1] - arg[0] + 1] = '\0'; pop_stack(); push_string(tmps, ST_MALLOC); break; case F_SLICE_LVALUE: - TAKE_SLICE() - tmpvp = sp[-1].u.v; - tmps = tmpvp->u.s + arg[0]; /* begin */ + tmpvp = take_slice(arg); + tmps = tmpvp->u.s + arg[1]; /* begin */ tmpi = tmpvp->string_type; pop_stack(); push_string(tmps, tmpi); @@ -574,12 +582,12 @@ cp++; } free_var(sp); - CHECK_OVERRUN() + CHECK_OVERRUN(); break; case F_JUMP: tmpi = cp[1]; cp += tmpi; - CHECK_OVERRUN() + CHECK_OVERRUN(); break; case F_NEG: sp--; @@ -610,32 +618,32 @@ push_int(!tmpi); break; case F_GT: - GET_ARGS() - push_int(arg[1] > arg[0] ? 1 : 0); + GET_ARGS(); + push_int(arg[0] > arg[1] ? 1 : 0); break; case F_LT: - GET_ARGS() - push_int(arg[1] < arg[0] ? 1 : 0); + GET_ARGS(); + push_int(arg[0] < arg[1] ? 1 : 0); break; case F_GE: - GET_ARGS() - push_int(arg[1] >= arg[0] ? 1 : 0); + GET_ARGS(); + push_int(arg[0] >= arg[1] ? 1 : 0); break; case F_LE: - GET_ARGS() - push_int(arg[1] <= arg[0] ? 1 : 0); + GET_ARGS(); + push_int(arg[0] <= arg[1] ? 1 : 0); break; case F_CALL_LFUN: tmpi = *++cp; cp++; - SETUP_FRAME(); + setup_frame(); call_function(this_ob, tmpi); goto again; break; case F_CALL_DFUN: tmpi = *++cp; cp++; - SETUP_FRAME(); + setup_frame(); dfptr[tmpi](); pop_control_stack(0); break; @@ -643,7 +651,8 @@ cp++; tmps = this_ob->prog->str_tbl[*cp]; cp++; - sp -= *cp + 1; + arg[0] = *cp; /* num_arg */ + sp -= arg[0] + 1; if(sp->type == T_OBJECT) { tmpv.u.ob = sp->u.ob; /* A little hack so we don't need an object_t variable in this scope. @@ -656,15 +665,17 @@ } if(!tmpv.u.ob) { - runtime("call_other on null object", 0); + runtime("call_other on null object"); } tmpi = get_fun_index(tmpv.u.ob, tmps); if(tmpi == -1) - runtime("function doesn't exist", 0); - SETUP_FRAME(); + runtime("function doesn't exist"); + setup_frame(); fp = sp + 1; - sp = fp + 1; + sp = fp; + if(arg[0]) + sp++; call_function(tmpv.u.ob, tmpi); goto again; break; @@ -678,7 +689,7 @@ pop_control_stack(0); break; default: - printf("Unknown instruction %d\n", *cp); + printf("Unknown instruction %d\n", *cp); /* runtime here? */ break; } #ifdef DEBUG @@ -712,7 +723,7 @@ if(!f) { char *buf = xmalloc(512); sprintf(buf, "function %d doesn't exist in object \"%s\"", index, ob->name); - runtime(buf, 1); + runtime_dyn(buf); } csp->line = f->lineno; |