[gamecode] Use the stack frame to find local defs

Of course, only in Ruamoko progs, but it works quite nicely.
global_string is now passed the absolute address of the referenced
operand. With a little groveling through the progs stack, it should be
possible to resolve pointers to locals in functions further up the
stack.
This commit is contained in:
Bill Currie 2022-01-27 14:16:05 +09:00
parent de974fdd3f
commit 5c22253095

View file

@ -989,7 +989,19 @@ PR_Get_Local_Def (progs_t *pr, pr_ptr_t *offset)
aux_func = res->auxfunction_map[func - pr->pr_functions]; aux_func = res->auxfunction_map[func - pr->pr_functions];
if (!aux_func) if (!aux_func)
return 0; return 0;
offs -= func->params_start;
pr_ptr_t locals_start;
if (pr->progs->version == PROG_VERSION) {
if (pr->pr_depth) {
prstack_t *frame = pr->pr_stack + pr->pr_depth - 1;
locals_start = frame->stack_ptr - func->params_start;
} else {
locals_start = 0; //FIXME ? when disassembling in qfprogs
}
} else {
locals_start = func->params_start;
}
offs -= locals_start;
if (offs >= func->locals) if (offs >= func->locals)
return 0; return 0;
if ((def = PR_SearchDefs (res->local_defs + aux_func->local_defs, if ((def = PR_SearchDefs (res->local_defs + aux_func->local_defs,
@ -1115,12 +1127,12 @@ pr_debug_find_def (progs_t *pr, pr_ptr_t *ofs)
prdeb_resources_t *res = pr->pr_debug_resources; prdeb_resources_t *res = pr->pr_debug_resources;
pr_def_t *def = 0; pr_def_t *def = 0;
if (*ofs >= pr->progs->globals.count) {
return 0;
}
if (pr_debug->int_val && res->debug) { if (pr_debug->int_val && res->debug) {
def = PR_Get_Local_Def (pr, ofs); def = PR_Get_Local_Def (pr, ofs);
} }
if (*ofs >= pr->progs->globals.count) {
return 0;
}
if (!def) { if (!def) {
def = PR_GlobalAtOfs (pr, *ofs); def = PR_GlobalAtOfs (pr, *ofs);
if (def) { if (def) {
@ -1630,6 +1642,7 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
char mode = fmt[1], opchar = fmt[2]; char mode = fmt[1], opchar = fmt[2];
unsigned param_ind = 0; unsigned param_ind = 0;
pr_uint_t shift = 0; pr_uint_t shift = 0;
pr_uint_t opreg;
pr_uint_t opval; pr_uint_t opval;
qfot_type_t *optype = &res->void_type; qfot_type_t *optype = &res->void_type;
pr_func_t func; pr_func_t func;
@ -1653,23 +1666,31 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
switch (opchar) { switch (opchar) {
case 'a': case 'a':
opreg = PR_BASE_IND (s->op, A);
opval = s->a; opval = s->a;
optype = res->type_encodings[op_type[0]]; optype = res->type_encodings[op_type[0]];
break; break;
case 'b': case 'b':
opreg = PR_BASE_IND (s->op, B);
opval = s->b; opval = s->b;
optype = res->type_encodings[op_type[1]]; optype = res->type_encodings[op_type[1]];
break; break;
case 'c': case 'c':
opreg = PR_BASE_IND (s->op, C);
opval = s->c; opval = s->c;
optype = res->type_encodings[op_type[2]]; optype = res->type_encodings[op_type[2]];
break; break;
case 'o':
opreg = 0;
opval = s->op;
break;
case 'x': case 'x':
if (mode == 'P') { if (mode == 'P') {
opval = pr->pr_real_params[param_ind] opval = pr->pr_real_params[param_ind]
- pr->pr_globals; - pr->pr_globals;
break; break;
} }
goto err;
default: default:
goto err; goto err;
} }
@ -1701,14 +1722,17 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
contents & 1); contents & 1);
break; break;
case 'V': case 'V':
opval += pr->pr_bases[opreg];
str = global_string (&data, opval, ev_void, str = global_string (&data, opval, ev_void,
contents & 1); contents & 1);
break; break;
case 'G': case 'G':
opval += pr->pr_bases[opreg];
str = global_string (&data, opval, optype, str = global_string (&data, opval, optype,
contents & 1); contents & 1);
break; break;
case 'g': case 'g':
opval += pr->pr_bases[opreg];
str = global_string (&data, opval, optype, 0); str = global_string (&data, opval, optype, 0);
break; break;
case 's': case 's':