From 0616cd47bda80132df929a61929af8cd3da22704 Mon Sep 17 00:00:00 2001 From: divverent Date: Wed, 9 Jan 2013 12:19:15 +0000 Subject: [PATCH] Make watchpoints data type aware; now vector watchpoints work too. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11875 d7cf8633-e32d-0410-b094-e92efae38249 ::stable-branch::merge=0b4104966c3390067281b17983023676074ae734 --- progsvm.h | 7 +++++-- prvm_edict.c | 42 ++++++++++++++++++++++++++++---------- prvm_execprogram.h | 50 +++++++++++++++------------------------------- 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/progsvm.h b/progsvm.h index 569f1edb..c4e0f3d1 100644 --- a/progsvm.h +++ b/progsvm.h @@ -594,10 +594,12 @@ typedef struct prvm_prog_s int break_statement; int break_stack_index; int watch_global; - prvm_vec_t watch_global_value; + etype_t watch_global_type; + prvm_eval_t watch_global_value; int watch_edict; int watch_field; - prvm_vec_t watch_edictfield_value; + etype_t watch_field_type; + prvm_eval_t watch_edictfield_value; mfunction_t *xfunction; int xstatement; @@ -870,6 +872,7 @@ void PRVM_Prog_Reset(prvm_prog_t *prog); void PRVM_StackTrace(prvm_prog_t *prog); void PRVM_Breakpoint(prvm_prog_t *prog, int stack_index, const char *text); +void PRVM_Watchpoint(prvm_prog_t *prog, int stack_index, const char *text, etype_t type, prvm_eval_t *o, prvm_eval_t *n); void VM_Warning(prvm_prog_t *prog, const char *fmt, ...) DP_FUNC_PRINTF(2); diff --git a/prvm_edict.c b/prvm_edict.c index 41f8b2a1..2c60372b 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -1825,8 +1825,8 @@ void PRVM_Prog_Reset(prvm_prog_t *prog) } memset(prog,0,sizeof(prvm_prog_t)); prog->break_statement = -1; - prog->watch_global = -1; - prog->watch_edict = -1; + prog->watch_global_type = ev_void; + prog->watch_field_type = ev_void; } /* @@ -2657,6 +2657,22 @@ void PRVM_Breakpoint(prvm_prog_t *prog, int stack_index, const char *text) Host_Savegame_to(prog, va(vabuf, sizeof(vabuf), "breakpoint-%s.dmp", prog->name)); } +void PRVM_Watchpoint(prvm_prog_t *prog, int stack_index, const char *text, etype_t type, prvm_eval_t *o, prvm_eval_t *n) +{ + size_t sz = sizeof(prvm_vec_t) * ((type & ~DEF_SAVEGLOBAL) == ev_vector ? 3 : 1); + if (memcmp(o, n, sz)) + { + char buf[1024]; + char valuebuf_o[128]; + char valuebuf_n[128]; + PRVM_UglyValueString(prog, type, o, valuebuf_o, sizeof(valuebuf_o)); + PRVM_UglyValueString(prog, type, n, valuebuf_n, sizeof(valuebuf_n)); + dpsnprintf(buf, sizeof(buf), "%s: %s -> %s", text, valuebuf_o, valuebuf_n); + PRVM_Breakpoint(prog, stack_index, buf); + memcpy(o, n, sz); + } +} + static void PRVM_UpdateBreakpoints(prvm_prog_t *prog) { debug_data_t *debug = &debug_data[prog - prvm_prog_list]; @@ -2696,18 +2712,20 @@ static void PRVM_UpdateBreakpoints(prvm_prog_t *prog) if( !global ) { Con_Printf( "%s progs: no global named '%s' to watch!\n", prog->name, debug->watch_global ); - prog->watch_global = -1; + prog->watch_global_type = ev_void; } else { + size_t sz = sizeof(prvm_vec_t) * ((global->type & ~DEF_SAVEGLOBAL) == ev_vector ? 3 : 1); prog->watch_global = global->ofs; - prog->watch_global_value = PRVM_GLOBALFIELDFLOAT(prog->watch_global); + prog->watch_global_type = global->type; + memcpy(&prog->watch_global_value, PRVM_GLOBALFIELDVALUE(prog->watch_global), sz); } - if (prog->watch_global >= -1) + if (prog->watch_global_type != ev_void) Con_Printf("%s progs: global watchpoint is at global index %d\n", prog->name, prog->watch_global); } else - prog->watch_global = -1; + prog->watch_global_type = ev_void; if (debug->watch_field[0]) { @@ -2715,22 +2733,24 @@ static void PRVM_UpdateBreakpoints(prvm_prog_t *prog) if( !field ) { Con_Printf( "%s progs: no field named '%s' to watch!\n", prog->name, debug->watch_field ); - prog->watch_edict = -1; + prog->watch_field_type = ev_void; } else { + size_t sz = sizeof(prvm_vec_t) * ((field->type & ~DEF_SAVEGLOBAL) == ev_vector ? 3 : 1); prog->watch_edict = debug->watch_edict; prog->watch_field = field->ofs; + prog->watch_field_type = field->type; if (prog->watch_edict < prog->num_edicts) - prog->watch_edictfield_value = PRVM_EDICTFIELDFLOAT(PRVM_EDICT_NUM(prog->watch_edict), prog->watch_field); + memcpy(&prog->watch_edictfield_value, PRVM_EDICTFIELDVALUE(PRVM_EDICT_NUM(prog->watch_edict), prog->watch_field), sz); else - prog->watch_edictfield_value = 0; + memset(&prog->watch_edictfield_value, 0, sz); } - if (prog->watch_edict >= -1) + if (prog->watch_edict != ev_void) Con_Printf("%s progs: edict field watchpoint is at edict %d field index %d\n", prog->name, prog->watch_edict, prog->watch_field); } else - prog->watch_edict = -1; + prog->watch_field_type = ev_void; } static void PRVM_Breakpoint_f(void) diff --git a/prvm_execprogram.h b/prvm_execprogram.h index 314f0e9a..ca550df7 100644 --- a/prvm_execprogram.h +++ b/prvm_execprogram.h @@ -14,26 +14,17 @@ #if PRVMSLOWINTERPRETER { - char vabuf[1024]; - if (prog->watch_global >= 0) + if (prog->watch_global_type != ev_void) { - prvm_vec_t f = PRVM_GLOBALFIELDFLOAT(prog->watch_global); - if (memcmp(&f, &prog->watch_global_value, sizeof(f))) - { - prog->xstatement = st + 1 - prog->statements; - PRVM_Breakpoint(prog, 1, va(vabuf, sizeof(vabuf), "Global watchpoint hit by engine: " FLOAT_LOSSLESS_FORMAT " -> " FLOAT_LOSSLESS_FORMAT, prog->watch_global_value, f)); - prog->watch_global_value = f; - } + prvm_eval_t *f = PRVM_GLOBALFIELDVALUE(prog->watch_global); + prog->xstatement = st + 1 - prog->statements; + PRVM_Watchpoint(prog, 1, "Global watchpoint hit by engine", prog->watch_global_type, &prog->watch_global_value, f); } - if (prog->watch_edict >= 0 && prog->watch_edict < prog->max_edicts) + if (prog->watch_field_type != ev_void && prog->watch_edict < prog->max_edicts) { - prvm_vec_t f = PRVM_EDICTFIELDFLOAT(prog->edicts + prog->watch_edict, prog->watch_field); - if (memcmp(&f, &prog->watch_edictfield_value, sizeof(f))) - { - prog->xstatement = st + 1 - prog->statements; - PRVM_Breakpoint(prog, 1, va(vabuf, sizeof(vabuf), "Entityfield watchpoint hit by engine: " FLOAT_LOSSLESS_FORMAT " -> " FLOAT_LOSSLESS_FORMAT, prog->watch_edictfield_value, f)); - prog->watch_edictfield_value = f; - } + prvm_vec_t *f = PRVM_EDICTFIELDVALUE(prog->edicts + prog->watch_edict, prog->watch_field); + prog->xstatement = st + 1 - prog->statements; + PRVM_Watchpoint(prog, 1, "Entityfield watchpoint hit by engine", prog->watch_field_type, &prog->watch_edictfield_value, f); } } #endif @@ -713,26 +704,17 @@ } #if PRVMSLOWINTERPRETER { - char vabuf[1024]; - if (prog->watch_global >= 0) + if (prog->watch_global_type != ev_void) { - prvm_vec_t f = PRVM_GLOBALFIELDFLOAT(prog->watch_global); - if (memcmp(&f, &prog->watch_global_value, sizeof(f))) - { - prog->xstatement = st - prog->statements; - PRVM_Breakpoint(prog, 0, va(vabuf, sizeof(vabuf), "Global watchpoint hit: " FLOAT_LOSSLESS_FORMAT " -> " FLOAT_LOSSLESS_FORMAT, prog->watch_global_value, f)); - prog->watch_global_value = f; - } + prvm_eval_t *f = PRVM_GLOBALFIELDVALUE(prog->watch_global); + prog->xstatement = st - prog->statements; + PRVM_Watchpoint(prog, 0, "Global watchpoint hit", prog->watch_global_type, &prog->watch_global_value, f); } - if (prog->watch_edict >= 0 && prog->watch_edict < prog->max_edicts) + if (prog->watch_field_type != ev_void && prog->watch_edict < prog->max_edicts) { - prvm_vec_t f = PRVM_EDICTFIELDFLOAT(prog->edicts + prog->watch_edict, prog->watch_field); - if (memcmp(&f, &prog->watch_edictfield_value, sizeof(f))) - { - prog->xstatement = st - prog->statements; - PRVM_Breakpoint(prog, 0, va(vabuf, sizeof(vabuf), "Entityfield watchpoint hit: " FLOAT_LOSSLESS_FORMAT " -> " FLOAT_LOSSLESS_FORMAT, prog->watch_edictfield_value, f)); - prog->watch_edictfield_value = f; - } + prvm_vec_t *f = PRVM_EDICTFIELDVALUE(prog->edicts + prog->watch_edict, prog->watch_field); + prog->xstatement = st - prog->statements; + PRVM_Watchpoint(prog, 0, "Entityfield watchpoint hit", prog->watch_field_type, &prog->watch_edictfield_value, f); } } #endif -- 2.39.2