mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Do lazy computation of def sizes from type encodings
The size is calculated when needed and cached.
This commit is contained in:
parent
5374798ef9
commit
dda045bf96
4 changed files with 67 additions and 8 deletions
|
@ -434,7 +434,8 @@ typedef struct pr_xdefs_s {
|
|||
} pr_xdefs_t;
|
||||
|
||||
typedef struct pr_def_s {
|
||||
pr_uint_t type;
|
||||
pr_ushort_t type;
|
||||
pr_ushort_t size; ///< may not be correct
|
||||
pointer_t ofs;
|
||||
string_t name;
|
||||
pointer_t type_encoding;
|
||||
|
|
|
@ -195,6 +195,57 @@ pr_debug_expression_error (script_t *script, const char *msg)
|
|||
Sys_Printf ("%s\n", msg);
|
||||
}
|
||||
|
||||
#define RUP(x,a) (((x) + ((a) - 1)) & ~((a) - 1))
|
||||
static pr_short_t
|
||||
pr_debug_type_size (progs_t *pr, qfot_type_t *type)
|
||||
{
|
||||
pr_short_t size;
|
||||
qfot_type_t *aux_type;
|
||||
switch (type->meta) {
|
||||
case ty_basic:
|
||||
return pr_type_size[type->t.type];
|
||||
case ty_struct:
|
||||
case ty_union:
|
||||
size = 0;
|
||||
for (pr_int_t i = 0; i < type->t.strct.num_fields; i++) {
|
||||
qfot_var_t *field = &type->t.strct.fields[i];
|
||||
aux_type = &G_STRUCT (pr, qfot_type_t, field->type);
|
||||
size = max (size,
|
||||
field->offset + pr_debug_type_size (pr, aux_type));
|
||||
}
|
||||
return size;
|
||||
case ty_enum:
|
||||
return pr_type_size[ev_integer];
|
||||
case ty_array:
|
||||
aux_type = &G_STRUCT (pr, qfot_type_t, type->t.array.type);
|
||||
size = pr_debug_type_size (pr, aux_type);
|
||||
return type->t.array.size * size;
|
||||
case ty_class:
|
||||
return 1; //FIXME or should it return sizeof class struct?
|
||||
case ty_alias:
|
||||
aux_type = &G_STRUCT (pr, qfot_type_t, type->t.alias.aux_type);
|
||||
return pr_debug_type_size (pr, aux_type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qfot_type_t *
|
||||
get_def_type (progs_t *pr, pr_def_t *def, qfot_type_t *type)
|
||||
{
|
||||
if (!def->type_encoding) {
|
||||
// no type encoding, so use basic type data to fill in and return
|
||||
// the dummy encoding
|
||||
memset (type, 0, sizeof (*type));
|
||||
type->t.type = def->type;
|
||||
} else {
|
||||
type = &G_STRUCT (pr, qfot_type_t, def->type_encoding);
|
||||
if (!def->size) {
|
||||
def->size = pr_debug_type_size (pr, type);
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static pr_def_t
|
||||
parse_expression (progs_t *pr, const char *expr, int conditional)
|
||||
{
|
||||
|
@ -1379,7 +1430,7 @@ VISIBLE void
|
|||
ED_Print (progs_t *pr, edict_t *ed)
|
||||
{
|
||||
int l;
|
||||
pr_uint_t i;
|
||||
pr_uint_t i, j;
|
||||
const char *name;
|
||||
pr_def_t *d;
|
||||
pr_type_t *v;
|
||||
|
@ -1398,17 +1449,21 @@ ED_Print (progs_t *pr, edict_t *ed)
|
|||
d = &pr->pr_fielddefs[i];
|
||||
if (!d->name) // null field def (probably 1st)
|
||||
continue;
|
||||
if (!d->type_encoding) {
|
||||
dummy_type.t.type = d->type;
|
||||
type = &dummy_type;
|
||||
} else {
|
||||
type = &G_STRUCT (pr, qfot_type_t, d->type_encoding);
|
||||
}
|
||||
type = get_def_type (pr, d, &dummy_type);
|
||||
name = PR_GetString (pr, d->name);
|
||||
if (name[strlen (name) - 2] == '_'
|
||||
&& strchr ("xyz", name[strlen (name) -1]))
|
||||
continue; // skip _x, _y, _z vars
|
||||
|
||||
for (j = 0; j < d->size; j++) {
|
||||
if (E_INT (ed, d->ofs + j)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == d->size) {
|
||||
continue;
|
||||
}
|
||||
|
||||
v = ed->v + d->ofs;
|
||||
|
||||
l = 15 - strlen (name);
|
||||
|
|
|
@ -281,11 +281,13 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
|
|||
pr->pr_globaldefs = calloc (pr->progs->numglobaldefs, sizeof (pr_def_t));
|
||||
|
||||
for (i = 0; i < pr->progs->numglobaldefs; i++) {
|
||||
pr_ushort_t safe_type = global_ddefs[i].type & ~DEF_SAVEGLOBAL;
|
||||
global_ddefs[i].type = LittleShort (global_ddefs[i].type);
|
||||
global_ddefs[i].ofs = LittleShort (global_ddefs[i].ofs);
|
||||
global_ddefs[i].s_name = LittleLong (global_ddefs[i].s_name);
|
||||
|
||||
pr->pr_globaldefs[i].type = global_ddefs[i].type;
|
||||
pr->pr_globaldefs[i].size = pr_type_size[safe_type];
|
||||
pr->pr_globaldefs[i].ofs = global_ddefs[i].ofs;
|
||||
pr->pr_globaldefs[i].name = global_ddefs[i].s_name;
|
||||
Hash_Add (pr->global_hash, &pr->pr_globaldefs[i]);
|
||||
|
|
|
@ -62,6 +62,7 @@ VISIBLE pr_ushort_t pr_type_size[ev_type_count] = {
|
|||
1, // ev_uinteger
|
||||
0, // ev_short value in opcode
|
||||
2, // ev_double
|
||||
0, // ev_invalid not a valid/simple type
|
||||
};
|
||||
|
||||
VISIBLE const char *pr_type_name[ev_type_count] = {
|
||||
|
|
Loading…
Reference in a new issue