From: Peep P. <so...@us...> - 2004-07-21 12:06:13
|
Update of /cvsroot/agd/server/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9576 Modified Files: interpret.c Log Message: On a runtime: function names are displayed this_player() isn't disconnected anymore a stack trace is shown the value stack is correctly cleared Proper arrays! (F_ADD, F_ADD_EQ, F_SUB, F_SUB_EQ support) Control stack is correctly popped when this_object is destructed in apply, csp->this_ob, previous_ob, code and codelen are correctly set Index: interpret.c =================================================================== RCS file: /cvsroot/agd/server/src/interpret.c,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- interpret.c 20 Jun 2004 14:03:53 -0000 1.25 +++ interpret.c 21 Jul 2004 12:05:59 -0000 1.26 @@ -2,7 +2,6 @@ #include <setjmp.h> #include <stdarg.h> -/*#include "config.h"*/ #include "compile_options.h" #include "sys.h" #include "lpc.h" @@ -24,21 +23,18 @@ int dont_debug_interpreter; #endif -/* Let's try to hold sp, fp, cp, codelen and code in csp */ /* This is the stack containing all local variables, function arguments and function return values. */ variable_t value_stack[VALUE_STACK_SIZE]; variable_t *sp = value_stack, /* Stack pointer after the last element pushed. */ *fp = value_stack; /* Frame pointer - where locals begin on the stack */ -int *cp; /* Code pointer into code->data */ -int *code, codelen; +int *cp; /* Code pointer into code->data */ +int *code, codelen; control_stack_t control_stack[CONTROL_STACK_SIZE]; control_stack_t *csp = control_stack; -#define CHECK_CSP() if(csp >= control_stack + CONTROL_STACK_SIZE) \ - runtime("control stack overflow (too deep recursion)"); #define CHECK_SP() if(sp >= value_stack + VALUE_STACK_SIZE) \ runtime("value stack overflow"); @@ -49,22 +45,36 @@ void call_function(object_t *ob, int index); extern char *opc_name(int i); -#if 0 +unsigned get_line_number(control_stack_t *p) { + return 42; +} + +char *get_fun_name(int num, control_stack_t *csp) { + if(num < 0) + return "*DFUN"; + if(csp->this_ob) { + if(csp->this_ob->prog) + return csp->this_ob->prog->fun_table[num]; + else + return "nil"; + } else + return this_ob->prog->fun_table[num]; +} void stack_trace(void) { int i, len; len = csp - &control_stack[0]; printf("Stack trace:\n"); - for(i=len;i>1;i--) { + for(i=len;i>0;i--) { control_stack_t *p = &control_stack[i]; - printf(" %s: function %d on line %d\n", - p->this_ob?p->this_ob->name:"unknown", p->fun, p->line); + printf("%d %s: function %d (%s) on line %d\n", + i, p->this_ob?p->this_ob->name:"unknown", + p->fun, get_fun_name(p->fun, p), + get_line_number(p)); } } -#endif -/* 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) @@ -72,29 +82,34 @@ char *buf; if(!this_ob) { - printf("%s on line %d (function %d)\n", s, csp->line, csp->fun); + printf("%s on line %d (function %s)\n", s, + get_line_number(csp), + get_fun_name(csp->fun, csp)); goto out; } buf = xmalloc(strlen(this_ob->name) + strlen(s) + 64); - sprintf(buf, "%s: %s on line %d (function %d)\n", this_ob->name, s, csp->line, csp->fun); + sprintf(buf, "%s: %s on line %d function %d (%s)\n", this_ob->name, s, + get_line_number(csp-1), + csp->fun, get_fun_name(csp->fun, csp)); printf(buf); if(this_player) { do_write(buf); - net_disconnect(this_player); +/* net_disconnect(this_player);*/ } free(buf); if(free_str) free(s); -/* stack_trace();*/ + stack_trace(); out: - while(csp > &control_stack[0]) { - pop_locals(); - pop_control_stack(1); - } + fp = value_stack; + pop_locals(); + csp = &control_stack[2]; + pop_control_stack(0); + longjmp(error_context, 1); } @@ -151,14 +166,12 @@ CHECK_SP() } +/* Has this a point? */ void push_array(array_t *a, int type) { - printf("a.data[0]: "); print_var(a->data[0]); putchar('\n'); sp->type = T_ARRAY | type; sp->u.a = a; - printf("a: %p; sp->u.a: %p\n", a, sp->u.a); - printf("a.data[0]: "); print_var(sp->u.a->data[0]); putchar('\n'); - /*ref_array(sp->u.a);*/ + ref_array(sp->u.a); sp++; CHECK_SP() } @@ -168,7 +181,7 @@ lval->type = rval->type; if(rval->type & T_ARRAY) { lval->u.a = rval->u.a; - /*ref_array(lval->u.a);*/ + ref_array(lval->u.a); } else switch(rval->type & ~T_ARRAY) { case T_OBJECT: lval->u.ob = rval->u.ob; @@ -188,26 +201,46 @@ } } -void do_assign_free(variable_t *lval, variable_t *rval) +#ifdef DEBUG +void show_control_stack(void) { - free_var(lval); - do_assign(lval, rval); + control_stack_t *_csp; + int i; + + printf("Control stack:\n"); + printf("csp: %d\n", csp - &control_stack[0]); + for(i=1;i<=csp-&control_stack[0];i++) { + _csp = &control_stack[i]; + printf("%d | cp: %d; fp: %d; sp: %d fun:%d(%s); ob:%p(%s) |\n", i, + _csp->cp ? _csp->cp - (_csp->code ? _csp->code : 0) : 0, + _csp->fp ? _csp->fp - &value_stack[0] : 0, + _csp->sp ? _csp->sp - &value_stack[0] : 0, + _csp->fun, get_fun_name(_csp->fun, _csp), + _csp->this_ob, _csp->this_ob->name); + } } -#ifdef DEBUG void show_stack(void) { int i; int len; - len = max(sp-&value_stack[0], fp-&value_stack[0]); - printf("sp: %d; fp: %d; cp: %d; csp: %d\n", sp ? sp - &value_stack[0] : 0, - fp ? fp - &value_stack[0] : 0, cp ? cp - code : 0, - csp ? csp - &control_stack[0] : 0); + variable_t *_sp; + control_stack_t *_csp; + + _sp = &value_stack[0]; + _csp = &control_stack[0]; + + len = max(sp-_sp, fp-_sp); + printf("sp: %d; fp: %d; cp: %d; csp: %d\n", + sp ? sp - _sp : 0, + fp ? fp - _sp : 0, + cp ? cp - code : 0, + csp ? csp - _csp : 0); printf("Value stack: |"); for(i=0;i<=len;i++) { putchar(' '); - if(value_stack[i].type) + if(value_stack[i].type && sp != value_stack+i) print_var(&value_stack[i]); else putchar('0'); @@ -220,23 +253,21 @@ putchar('|'); } putchar('\n'); - printf("Control stack:\n"); - for(i=0;i<=csp-&control_stack[0];i++) { - printf("%d | cp: %d; fp: %d; sp: %d fun:%d line:%d |\n", i, - control_stack[i].cp ? control_stack[i].cp - - (control_stack[i].code ? control_stack[i].code : 0) : 0, - control_stack[i].fp ? control_stack[i].fp - &value_stack[0] : 0, - control_stack[i].sp ? control_stack[i].sp - &value_stack[0] : 0, - control_stack[i].fun, control_stack[i].line); - } +/* show_control_stack();*/ } #else -/* foo! */ #define show_stack() #endif +void check_csp() { + if(csp >= control_stack + CONTROL_STACK_SIZE) + runtime("control stack overflow (too deep recursion)"); +} + void push_control_stack(void) { + csp++; + check_csp(); csp->previous_ob = previous_ob; csp->this_ob = this_ob; if(this_ob) @@ -246,17 +277,10 @@ csp->cp = cp; csp->code = code; csp->codelen = codelen; - csp++; - CHECK_CSP() } void pop_control_stack(int pop_sp) { - csp--; - if(csp < control_stack) { - runtime("control stack underflow"); - } - fp = csp->fp; if(pop_sp) sp = csp->sp; @@ -268,6 +292,11 @@ this_ob = csp->this_ob; if(this_ob && this_ob->iaob) this_player = /*this_ob->iaob*/ csp->this_player; + + csp--; + if(csp < control_stack) { + runtime("control stack underflow"); + } } /* Used by F_JUMP and F_JUMP_IF_FALSE to check if they jumped too far. */ @@ -286,12 +315,21 @@ fp = sp - csp->num_arg; } -void index_check(int *arg, char *str) +void index_check(variable_t *var, int *arg) { - if(!str) - runtime("taking element of null string"); - if(arg[0] < 0 || arg[0] > strlen(str)) - runtime("index out of range"); + if(var->type & T_ARRAY) { + if(!var->u.a) { + runtime("taking element of null array"); + } + if(arg[0] < 0 || arg[0] >= var->u.a->length) { + runtime("index out of range"); + } + } else if(var->type == T_STRING) { + if(!var->u.s) + runtime("taking element of null string"); + if(arg[0] < 0 || arg[0] > strlen(var->u.s)) + runtime("index out of range"); + } } variable_t *take_slice(int *arg) @@ -317,12 +355,11 @@ int tmpi, arg[2]; char *tmps; - /* csp is never at &control_stack[0] when we get here, so this is safe. */ saved_csp = csp - 1; again: #ifdef DEBUG - if(!dont_debug_interpreter) - debug("interpret", "Executing %s at %d\n", opc_name(*cp), cp - code); + if(!dont_debug_interpreter && conf.debuglevel > 0) + printf("[interpret] executing %s at %d\n", opc_name(*cp), cp - code); #endif switch(*cp) { case F_PUSH_INT: @@ -345,25 +382,39 @@ break; case F_PUSH_ARRAY: { - array_t *a = xmalloc(sizeof(array_t)); + array_t *a; + arg[0] = *++cp; arg[1] = *++cp; + a = xmalloc(sizeof(array_t)); a->length = arg[1]; - a->data = calloc(arg[1], sizeof(variable_t*)); - for(tmpi=0;tmpi<arg[1];tmpi++) { - do_assign(a->data[tmpi], --sp); - /* Note that we're not freeing the arguments, - * as they go into the array. */ + a->ref = 1; + if(a->length) { + a->data = xmalloc(a->length * sizeof(variable_t)); + for(tmpi=a->length-1;tmpi>=0;tmpi--) { + do_assign(&a->data[tmpi], --sp); +#ifdef DEBUG + a->data[tmpi].name = NULL; +#endif + + } } - printf("a0: "); print_var(a->data[0]); putchar('\n'); - sp -= arg[1]; - printf("a.data[0]: "); print_var(a->data[0]); putchar('\n'); push_array(a, arg[0]); } break; case F_POP: pop_stack(); break; + case F_POP_N: + cp++; + for(tmpi=0;tmpi<*cp;tmpi++) + pop_stack(); + break; + case F_POP_PENUL: + sp--; + free_var(sp-1); + do_assign(sp-1, sp); + break; case F_PUSH_LVAR: cp++; push_var(&fp[*cp]); @@ -397,26 +448,43 @@ push_int(*tmpvp->u.s); } else { tmpv = *sp[-2].u.v; - tmpvp = add_vars(&tmpv, sp-1); - do_assign(sp[-2].u.v, tmpvp); - pop_stack(); pop_stack(); - push_var(tmpvp); + if(tmpv.type & T_ARRAY) { + tmpvp = add_vars(&tmpv, sp-1); + do_assign(sp[-2].u.v, tmpvp); + pop_stack(); pop_stack(); + push_var(tmpvp); + } else { + tmpvp = add_vars(&tmpv, sp-1); + do_assign(sp[-2].u.v, tmpvp); + pop_stack(); pop_stack(); + push_var(tmpvp); + } } break; case F_SUB: - GET_ARGS(); - push_int(arg[0] - arg[1]); + tmpvp = sub_vars(sp-2, sp-1); + pop_stack(); pop_stack(); + push_var(tmpvp); +/* GET_ARGS(); + push_int(arg[0] - arg[1]);*/ break; case F_SUB_EQ: if(sp[-2].type == T_CHAR_PTR) { tmpi = sp[-2].u.s[0] - sp[-1].u.i; } else { tmpv = *sp[-2].u.v; - tmpi = tmpv.u.i - sp[-1].u.i; - sp[-2].u.v->u.i = tmpi; + if(tmpv.type & T_ARRAY) { + tmpvp = sub_vars(&tmpv, sp-1); + do_assign(sp[-2].u.v, tmpvp); + pop_stack(); pop_stack(); + push_var(tmpvp); + } else { + tmpi = tmpv.u.i - sp[-1].u.i; + sp[-2].u.v->u.i = tmpi; + pop_stack(); pop_stack(); + push_int(tmpi); + } } - pop_stack(); pop_stack(); - push_int(tmpi); break; case F_MUL: GET_ARGS(); @@ -528,18 +596,12 @@ pop_stack(); tmpvp = sp[-1].u.v; pop_stack(); - + if(tmpvp->type & T_ARRAY) { - if(!tmpvp->u.a) { - runtime("taking element of null array"); - } - if(arg[0] < 0 || arg[0] >= tmpvp->u.a->length) { - runtime("index out of range"); - } - tmpvp = tmpvp->u.a->data[arg[0]]; - push_var(tmpvp); + index_check(tmpvp, arg); + push_var(&tmpvp->u.a->data[arg[0]]); } else { - index_check(arg, tmpvp->u.s); + index_check(tmpvp, arg); arg[1] = tmpvp->u.s[arg[0]]; push_int(arg[1]); } @@ -549,12 +611,18 @@ pop_stack(); tmpvp = sp[-1].u.v; pop_stack(); - index_check(arg, tmpvp->u.s); - sp->type = T_CHAR_PTR; - sp->u.s = tmpvp->u.s + arg[0]; - sp++; - CHECK_SP() + if(tmpvp->type & T_ARRAY) { + index_check(tmpvp, arg); + push_lvalue(&tmpvp->u.a->data[arg[0]]); + } else { + index_check(tmpvp, arg); + + sp->type = T_CHAR_PTR; + sp->u.s = tmpvp->u.s + arg[0]; + sp++; + CHECK_SP() + } break; case F_SLICE: tmpvp = take_slice(arg); @@ -644,6 +712,7 @@ tmpi = *++cp; cp++; setup_frame(); + csp->fun = -tmpi-1; dfptr[tmpi](); pop_control_stack(0); break; @@ -692,26 +761,24 @@ printf("Unknown instruction %d\n", *cp); /* runtime here? */ break; } + #ifdef DEBUG if(conf.debuglevel > 2 && !dont_debug_interpreter) show_stack(); #endif + /* We return to the control level where we entered - we have finished. */ - if(csp == saved_csp) { -#ifdef DEBUG - debug("interpret", "csp (%d) == saved_csp (%d); returning\n", csp - &control_stack[0], saved_csp - &control_stack[0]); -#endif + if(csp == saved_csp) return; - } + /* Abnormal termination - need to pop unnecessary stuff off the stack. */ if(this_ob->flags & O_DESTRUCTED) { -#ifdef DEBUG - debug("interpret", "this_ob destructed; returning\n"); -#endif - pop_control_stack(1); + while(csp->this_ob == this_ob) + pop_control_stack(1); pop_locals(); return; } + cp++; goto again; } @@ -726,7 +793,7 @@ runtime_dyn(buf); } - csp->line = f->lineno; +/* csp->line = f->lineno;*/ csp->fun = index; i = f->num_arg - csp->num_arg; @@ -759,17 +826,6 @@ codelen = f->codelen; } -#if 0 -void init_interpreter(void) -{ - fp = sp = &value_stack[0]; - csp = &control_stack[0]; - csp->fp = fp; - csp->sp = sp; - cp = 0; -} -#endif - int get_fun_index(object_t *ob, char *fun_name) { int i; @@ -808,6 +864,11 @@ #ifdef DEBUG gettimeofday(&tm, NULL); #endif + +#ifdef DEBUG + if(conf.debuglevel) + printf("[lpc] apply \"%s\" on \"%s\"\n", fun, ob->name); +#endif push_control_stack(); @@ -838,10 +899,6 @@ } va_end(va); - -#ifdef DEBUG - debug("lpc", "apply \"%s\" on \"%s\"\n", fun, ob->name); -#endif if(!have_error_context) { if(setjmp(error_context)) { @@ -854,11 +911,17 @@ } call_function(ob, index); + csp->this_ob = this_ob; + csp->previous_ob = previous_ob; + csp->code = csp->cp = cp; + csp->codelen = codelen; + eval_instruction(); #ifdef DEBUG gettimeofday(&tm2, NULL); - debug("lpc", "apply \"%s\" done in %d microseconds\n", fun, tm2.tv_usec - tm.tv_usec); + if(conf.debuglevel) + printf("[lpc] apply \"%s\" done in %d microseconds\n", fun, tm2.tv_usec - tm.tv_usec); #endif have_error_context = 0; |