|
From: Peep P. <so...@us...> - 2004-06-12 16:46:42
|
Update of /cvsroot/agd/server/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4700 Modified Files: interpret.c interpret.h Log Message: Interpreter now works again; runtime can free its argument; added *_EQ operators Index: interpret.c =================================================================== RCS file: /cvsroot/agd/server/src/interpret.c,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- interpret.c 8 Jun 2004 20:40:54 -0000 1.20 +++ interpret.c 12 Jun 2004 16:46:33 -0000 1.21 @@ -1,7 +1,6 @@ #include <stdlib.h> #include <setjmp.h> #include <stdarg.h> -/*#include "vars.h"*/ /*#include "config.h"*/ #include "compile_options.h" @@ -12,6 +11,8 @@ #include "object.h" #include "net.h" #include "interpret.h" +#include "instr.h" +#include "vars.h" extern player_t *this_player; extern object_t *this_ob, *previous_ob; @@ -28,35 +29,28 @@ and function return values. */ variable_t value_stack[VALUE_STACK_SIZE]; variable_t *sp = value_stack, /* Stack pointer after the last element pushed. */ - *fp; /* Frame pointer - where locals begin on the stack */ + *fp = value_stack; /* Frame pointer - where locals begin on the stack */ int *cp; /* Code pointer into code->data */ -/*array_t *code;*/ +int *code, codelen; control_stack_t control_stack[CONTROL_STACK_SIZE]; control_stack_t *csp = control_stack; -void push_void() { } -void push_string(char *s, int x) { } -void push_object(object_t *ob) { } -void pop_control_stack(int x) { } -void push_int(int i) { } -void runtime(char *s) { } -void push_control_stack() { } - #define CHECK_CSP() if(csp >= control_stack + CONTROL_STACK_SIZE) \ - runtime("control stack overflow (too deep recursion)"); + runtime("control stack overflow (too deep recursion)", 0); #define CHECK_SP() if(sp >= value_stack + VALUE_STACK_SIZE) \ - runtime("value stack overflow"); + runtime("value stack overflow", 0); extern void (**dfptr)(void); -#if 0 -void call_function(object_t *ob, int index); void do_assign(variable_t *lval, variable_t *rval); void pop_control_stack(int pop_sp); +void call_function(object_t *ob, int index); extern char *opc_name(int i); +#if 0 + void stack_trace(void) { int i, len; @@ -68,9 +62,12 @@ p->this_ob?p->this_ob->name:"unknown", p->fun, p->line); } } +#endif /* Need the F_NEWLINE operation for this. */ -void runtime(char *s) +/* 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) { char *buf; @@ -88,6 +85,9 @@ } xfree(buf); + if(free_str) + xfree(s); + /* stack_trace();*/ out: @@ -201,7 +201,7 @@ 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 - (int *)code->data : 0, + fp ? fp - &value_stack[0] : 0, cp ? cp - code : 0, csp ? csp - &control_stack[0] : 0); printf("Value stack: |"); for(i=0;i<=len;i++) { @@ -224,7 +224,7 @@ 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 ? (int *) control_stack[i].code->data : 0) : 0, + (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); @@ -235,7 +235,6 @@ #define show_stack() #endif - void push_control_stack(void) { csp->previous_ob = previous_ob; @@ -254,7 +253,7 @@ { csp--; if(csp < control_stack) { - runtime("control stack underflow"); + runtime("control stack underflow", 0); } fp = csp->fp; @@ -269,15 +268,14 @@ this_player = /*this_ob->iaob*/ csp->this_player; } -#if 0 /* Used by F_JMP and F_JMPF to check if they jumped too far. */ -#define CHECK_OVERRUN() if((int *) cp >= (int *) code->data + code->length) {\ +#define CHECK_OVERRUN() if(cp >= code + codelen) {\ debug("interpret", "Ran over end of array: returning\n"); return; } #define GET_ARGS() arg[0] = sp[-1].u.i; pop_stack(); arg[1] = sp[-1].u.i; pop_stack(); -#define TAKE_SLICE() GET_ARGS() if(!sp[-1].u.s) runtime("taking substring of null string"); \ - if(arg[1] >= strlen(sp[-1].u.s) || arg[1] < 0 || arg[1] > arg[0]) runtime("substring out of range"); \ +#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) || arg[1] < 0 || arg[1] > arg[0]) runtime("substring out of range", 0); \ #define SETUP_FRAME() push_control_stack(); csp->num_arg = *cp; fp = sp - csp->num_arg; @@ -293,7 +291,7 @@ again: #ifdef DEBUG if(!dont_debug_interpreter) - debug("interpret", "Executing %s at %d\n", opc_name(*cp), cp - (int *)code->data); + debug("interpret", "Executing %s at %d\n", opc_name(*cp), cp - code); #endif switch(*cp) { case F_PUSH_INT: @@ -302,7 +300,7 @@ break; case F_PUSH_STRING: cp++; - tmps = this_prog->str_tbl[*cp]; + tmps = this_ob->prog->str_tbl[*cp]; push_string(tmps, ST_STATIC); break; case F_PUSH_VOID: @@ -313,13 +311,13 @@ break; case F_PUSH_ARRAY: { - array_t *a = type_xmalloc(array_t); + array_t *a = xmalloc(sizeof(array_t)); arg[0] = *++cp; arg[1] = *++cp; 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); + do_assign(a->data[tmpi], --sp); /* Note that we're not freeing the arguments, * as they go into the array. */ } @@ -346,33 +344,76 @@ break; case F_PUSH_GVAR: cp++; - push_var(this_ob->variables.data[*cp]); + push_var(&this_ob->globals[*cp]); break; case F_PUSH_GVAR_LVALUE: cp++; - push_lvalue(this_ob->variables.data[*cp]); + push_lvalue(&this_ob->globals[*cp]); break; case F_ADD: tmpvp = add_vars(sp-2, sp-1); pop_stack(); pop_stack(); push_var(tmpvp); break; + case F_ADD_EQ: + 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); + break; case F_SUB: GET_ARGS() push_int(arg[1] - arg[0]); break; + case F_SUB_EQ: + tmpv = *sp[-2].u.v; + tmpi = tmpv.u.i - sp[-1].u.i; + sp[-2].u.v->u.i = tmpi; + pop_stack(); pop_stack(); + push_int(tmpi); + break; case F_MUL: GET_ARGS() push_int(arg[1] * arg[0]); break; + case F_MUL_EQ: + tmpv = *sp[-2].u.v; + tmpi = tmpv.u.i * sp[-1].u.i; + sp[-2].u.v->u.i = tmpi; + pop_stack(); pop_stack(); + push_int(tmpi); + break; case F_DIV: GET_ARGS() + if(!arg[0]) + runtime("division by zero", 0); push_int(arg[1] / arg[0]); break; + case F_DIV_EQ: + tmpv = *sp[-2].u.v; + if(!sp[-1].u.i) + runtime("division by zero", 0); + tmpi = tmpv.u.i / sp[-1].u.i; + sp[-2].u.v->u.i = tmpi; + pop_stack(); pop_stack(); + push_int(tmpi); + break; case F_MOD: GET_ARGS() + if(!arg[0]) + runtime("divison by zero", 0); push_int(arg[1] % arg[0]); break; + case F_MOD_EQ: + tmpv = *sp[-2].u.v; + if(!sp[-1].u.i) + runtime("divison by zero", 0); + tmpi = tmpv.u.i % sp[-1].u.i; + sp[-2].u.v->u.i = tmpi; + pop_stack(); pop_stack(); + push_int(tmpi); + break; case F_ASSIGN: do_assign(sp[-2].u.v, sp-1); do_assign(&tmpv, sp-1); @@ -407,17 +448,17 @@ if(sp[-1].type & T_ARRAY) { if(!sp[-1].u.a) { - runtime("taking element of null array"); + runtime("taking element of null array", 0); } if(arg[0] >= sp[-1].u.a->length || arg[0] < 0) { - runtime("index out of range"); + runtime("index out of range", 0); } tmpvp = sp[-1].u.a->data[arg[0]]; pop_stack(); push_var(tmpvp); } else { if(!sp[-1].u.s) { - runtime("taking element of null string"); + runtime("taking element of null string", 0); } arg[1] = sp[-1].u.s[arg[0]]; pop_stack(); @@ -429,7 +470,7 @@ arg[0] = sp[-1].u.i; pop_stack(); if(!sp[-1].u.s) { - runtime("taking element of null string"); + runtime("taking element of null string", 0); } do_assign(sp, &sp[-1]); sp->u.s += arg[0]; @@ -455,7 +496,7 @@ push_string(tmps, tmpi); push_lvalue(sp-1); break; - case F_JMPF: + case F_JUMP_IF_FALSE: sp--; if(!test_var(sp)) { tmpi = cp[1]; @@ -466,7 +507,7 @@ free_var(sp); CHECK_OVERRUN() break; - case F_JMP: + case F_JUMP: tmpi = cp[1]; cp += tmpi; CHECK_OVERRUN() @@ -530,8 +571,9 @@ pop_control_stack(0); break; case F_CALL_OTHER: - tmps = (char *) *++cp; - ++cp; + cp++; + tmps = this_ob->prog->str_tbl[*cp]; + cp++; sp--; if(sp->type == T_OBJECT) { tmpv.u.ob = sp->u.ob; /* A little hack so we don't @@ -545,13 +587,13 @@ } if(!tmpv.u.ob) { - runtime("call_other on null object"); + runtime("call_other on null object", 0); } tmpi = get_fun_index(tmpv.u.ob, tmps); free_var(sp); if(tmpi == -1) - runtime("function doesn't exist"); + runtime("function doesn't exist", 0); SETUP_FRAME(); call_function(tmpv.u.ob, tmpi); goto again; @@ -596,22 +638,20 @@ void call_function(object_t *ob, int index) { int i, j; - function_t *f; - f = ob->prog->functions.data[index]; + function_t *f = ob->prog->functions[index]; if(!f) { - char buf[512]; /* Can't use dynamic memory - because of runtime()'s longjmp() */ + char *buf = xmalloc(512); sprintf(buf, "function %d doesn't exist in object \"%s\"", index, ob->name); - runtime(buf); + runtime(buf, 1); } csp->line = f->lineno; csp->fun = index; - i = f->args.length - csp->num_arg; + i = f->num_arg - csp->num_arg; if(i > 0) { for(j=0;j<i;j++) { - switch((*(variable_t*)f->args.data[j]).type) { + switch(f->args[j]) { case T_INT: push_int(0); break; @@ -633,10 +673,10 @@ if(this_ob->iaob) this_player = this_ob->iaob; - cp = (int *) &f->code.data[0]; - code = &f->code; + cp = f->code; + code = f->code; + codelen = f->codelen; } -#endif #if 0 void init_interpreter(void) @@ -649,7 +689,6 @@ } #endif -#endif int get_fun_index(object_t *ob, char *fun_name) { int i; @@ -689,7 +728,6 @@ gettimeofday(&tm, NULL); #endif -#if 0 push_control_stack(); va_start(va, argfmt); @@ -719,13 +757,11 @@ } va_end(va); -#endif #ifdef DEBUG debug("lpc", "apply \"%s\" on \"%s\"\n", fun, ob->name); #endif -#if 0 if(!have_error_context) { if(setjmp(error_context)) { /* setjmp() returned a value, @@ -738,7 +774,6 @@ call_function(ob, index); eval_instruction(); -#endif #ifdef DEBUG gettimeofday(&tm2, NULL); Index: interpret.h =================================================================== RCS file: /cvsroot/agd/server/src/interpret.h,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- interpret.h 7 Jun 2004 15:41:13 -0000 1.14 +++ interpret.h 12 Jun 2004 16:46:33 -0000 1.15 @@ -2,7 +2,7 @@ #define _INTERPRET_H variable_t *apply(object_t *ob, char *fun, char *argfmt, ...); -void runtime(char *s); +void runtime(char *s, int free_str); #define pop_stack() sp--; free_var(sp) #define pop_locals() while(sp > fp) { sp--; free_var(sp); } @@ -12,7 +12,7 @@ int num_arg; int *cp; - int **code; + int *code; int codelen; int fun, line; |