mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
fix up #0 builtin functions at runtime. not done automaticly (need to call
PR_RelocateBuiltins) and fix a bug with profiling and unlimited execution counts
This commit is contained in:
parent
2185e0a92e
commit
3dafbebf10
5 changed files with 51 additions and 77 deletions
|
@ -166,7 +166,8 @@ char *PR_GlobalStringNoContents (progs_t *pr, int ofs, etype_t type);
|
|||
pr_type_t *GetEdictFieldValue(progs_t *pr, edict_t *ed, const char *field);
|
||||
|
||||
void PR_AddBuiltin (progs_t *pr, const char *name, builtin_proc builtin, int num);
|
||||
int PR_FindBuiltin (progs_t *pr, const char *name);
|
||||
builtin_t *PR_FindBuiltin (progs_t *pr, const char *name);
|
||||
void PR_RelocateBuiltins (progs_t *pr);
|
||||
|
||||
//
|
||||
// PR Strings stuff
|
||||
|
@ -223,6 +224,7 @@ struct progs_s {
|
|||
dprograms_t *progs;
|
||||
int progs_size;
|
||||
|
||||
struct hashtab_s *builtin_hash;
|
||||
struct hashtab_s *function_hash;
|
||||
struct hashtab_s *global_hash;
|
||||
struct hashtab_s *field_hash;
|
||||
|
|
|
@ -593,25 +593,6 @@ PF_charcount (progs_t *pr)
|
|||
G_FLOAT (pr, OFS_RETURN) = count;
|
||||
}
|
||||
|
||||
void
|
||||
PF_checkbuiltin (progs_t *pr)
|
||||
{
|
||||
G_FUNCTION (pr, OFS_RETURN) = -PR_FindBuiltin (pr, G_STRING (pr, OFS_PARM0));
|
||||
}
|
||||
|
||||
void
|
||||
PF_getbuiltin (progs_t *pr)
|
||||
{
|
||||
const char *name;
|
||||
int i;
|
||||
|
||||
name = G_STRING (pr, OFS_PARM0);
|
||||
i = PR_FindBuiltin (pr, name);
|
||||
if (!i)
|
||||
PR_RunError (pr, "PF_getfunction: function '%s' not found!\n", name);
|
||||
G_FUNCTION (pr, OFS_RETURN) = -i;
|
||||
}
|
||||
|
||||
#if (INT_MAX == 2147483647) && (INT_MIN == -2147483648)
|
||||
# define INT_WIDTH 11
|
||||
#else /* I hope... */
|
||||
|
|
|
@ -92,16 +92,6 @@ const char *pr_type_name[ev_type_count] = {
|
|||
ddef_t *ED_FieldAtOfs (progs_t * pr, int ofs);
|
||||
qboolean ED_ParseEpair (progs_t * pr, pr_type_t *base, ddef_t *key, const char *s);
|
||||
|
||||
#define MAX_FIELD_LEN 64
|
||||
#define GEFV_CACHESIZE 2
|
||||
|
||||
typedef struct {
|
||||
ddef_t *pcache;
|
||||
char field[MAX_FIELD_LEN];
|
||||
} gefv_cache;
|
||||
|
||||
static gefv_cache gefvCache[GEFV_CACHESIZE] = { {NULL, ""}, {NULL, ""} };
|
||||
|
||||
/*
|
||||
ED_ClearEdict
|
||||
|
||||
|
@ -323,26 +313,10 @@ ED_FindFunction (progs_t * pr, const char *name)
|
|||
pr_type_t *
|
||||
GetEdictFieldValue (progs_t * pr, edict_t *ed, const char *field)
|
||||
{
|
||||
ddef_t *def = NULL;
|
||||
int i;
|
||||
static int rep = 0;
|
||||
|
||||
for (i = 0; i < GEFV_CACHESIZE; i++) {
|
||||
if (!strcmp (field, gefvCache[i].field)) {
|
||||
def = gefvCache[i].pcache;
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
ddef_t *def;
|
||||
|
||||
def = ED_FindField (pr, field);
|
||||
|
||||
if (strlen (field) < MAX_FIELD_LEN) {
|
||||
gefvCache[rep].pcache = def;
|
||||
strcpy (gefvCache[rep].field, field);
|
||||
rep ^= 1;
|
||||
}
|
||||
|
||||
Done:
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
|
@ -1070,6 +1044,13 @@ ED_LoadFromFile (progs_t * pr, const char *data)
|
|||
Sys_DPrintf ("%i entities inhibited\n", inhibit);
|
||||
}
|
||||
|
||||
static const char *
|
||||
builtin_get_key (void *_bi, void *unused)
|
||||
{
|
||||
builtin_t *bi = (builtin_t *)_bi;
|
||||
return bi->name;
|
||||
}
|
||||
|
||||
static const char *
|
||||
function_get_key (void *f, void *_pr)
|
||||
{
|
||||
|
@ -1218,8 +1199,6 @@ PR_LoadProgsFile (progs_t * pr, const char *progsname)
|
|||
void
|
||||
PR_LoadProgs (progs_t * pr, const char *progsname)
|
||||
{
|
||||
int i;
|
||||
|
||||
PR_LoadProgsFile (pr, progsname);
|
||||
if (!pr->progs)
|
||||
return;
|
||||
|
@ -1227,10 +1206,6 @@ PR_LoadProgs (progs_t * pr, const char *progsname)
|
|||
if (!progsname)
|
||||
progsname = "(preloaded)";
|
||||
|
||||
// flush the non-C variable lookup cache
|
||||
for (i = 0; i < GEFV_CACHESIZE; i++)
|
||||
gefvCache[i].field[0] = 0;
|
||||
|
||||
if (!(pr->globals.time = (float*)PR_GetGlobalPointer (pr, "time")))
|
||||
PR_Error (pr, "%s: undefined symbol: time", progsname);
|
||||
if (!(pr->globals.self = (int*)PR_GetGlobalPointer (pr, "self")))
|
||||
|
@ -1297,48 +1272,43 @@ PR_Init (void)
|
|||
void
|
||||
PR_AddBuiltin (progs_t *pr, const char *name, builtin_proc builtin, int num)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
if (pr->numbuiltins == 0) {
|
||||
pr->builtins = malloc (PR_AUTOBUILTIN * sizeof (builtin_t));
|
||||
pr->builtins = calloc (PR_AUTOBUILTIN, sizeof (builtin_t));
|
||||
pr->numbuiltins = PR_AUTOBUILTIN;
|
||||
if (!pr->builtins)
|
||||
PR_Error (pr, "PR_AddBuiltin: memory allocation error!\n");
|
||||
for (i = 0; i < pr->numbuiltins; i++) {
|
||||
pr->builtins[i].proc = 0;
|
||||
pr->builtins[i].name = 0;
|
||||
}
|
||||
pr->builtin_hash = Hash_NewTable (1021, builtin_get_key, 0, pr);
|
||||
}
|
||||
|
||||
if (num < 0) {
|
||||
for (i = PR_AUTOBUILTIN; i < pr->numbuiltins && pr->builtins[i].proc; i++)
|
||||
for (i = PR_AUTOBUILTIN;
|
||||
i < pr->numbuiltins && pr->builtins[i].proc; i++)
|
||||
;
|
||||
if (i >= pr->numbuiltins) {
|
||||
pr->numbuiltins++;
|
||||
pr->builtins = realloc (pr->builtins, pr->numbuiltins * sizeof (builtin_t));
|
||||
pr->builtins = realloc (pr->builtins,
|
||||
pr->numbuiltins * sizeof (builtin_t));
|
||||
if (!pr->builtins)
|
||||
PR_Error (pr, "PR_AddBuiltin: memory allocation error!\n");
|
||||
}
|
||||
j = i;
|
||||
} else {
|
||||
if (num >= PR_AUTOBUILTIN || num == 0)
|
||||
PR_Error (pr, "PR_AddBuiltin: invalid builtin number.\n");
|
||||
if (pr->builtins[num].proc)
|
||||
PR_Error (pr, "PR_AddBuiltin: builtin number already exists.\n");
|
||||
j = num;
|
||||
i = num;
|
||||
}
|
||||
pr->builtins[j].proc = builtin;
|
||||
pr->builtins[j].name = name;
|
||||
pr->builtins[i].proc = builtin;
|
||||
pr->builtins[i].name = name;
|
||||
Hash_Add (pr->builtin_hash, &pr->builtins[i]);
|
||||
}
|
||||
|
||||
int
|
||||
builtin_t *
|
||||
PR_FindBuiltin (progs_t *pr, const char *name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < pr->numbuiltins; i++)
|
||||
if (pr->builtins[i].name && strequal (pr->builtins[i].name, name))
|
||||
return i;
|
||||
return 0;
|
||||
return (builtin_t *) Hash_Find (pr->builtin_hash, name);
|
||||
}
|
||||
|
||||
edict_t *
|
||||
|
@ -1385,7 +1355,7 @@ PR_Error (progs_t *pr, const char *error, ...)
|
|||
vsnprintf (string, sizeof (string), error, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
Sys_Error ("%s", string);
|
||||
Sys_Error ("%s: %s", pr->progs_name, string);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1402,3 +1372,23 @@ PR_AccessField (progs_t *pr, const char *name, etype_t type,
|
|||
file, line);
|
||||
return def->ofs;
|
||||
}
|
||||
|
||||
void
|
||||
PR_RelocateBuiltins (progs_t *pr)
|
||||
{
|
||||
int i;
|
||||
dfunction_t *func;
|
||||
builtin_t *bi;
|
||||
const char *bi_name;
|
||||
|
||||
for (i = 1; i < pr->progs->numfunctions; i++) {
|
||||
func = pr->pr_functions + i;
|
||||
if (func->first_statement)
|
||||
continue;
|
||||
bi_name = PR_GetString (pr, func->s_name);
|
||||
bi = PR_FindBuiltin (pr, bi_name);
|
||||
if (!bi)
|
||||
PR_Error (pr, "undefined builtin %s", bi_name);
|
||||
func->first_statement = -(bi - pr->builtins);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -291,8 +291,7 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
|
||||
while (1) {
|
||||
st++;
|
||||
if (!pr->no_exec_limit
|
||||
&& ++profile > 1000000) {
|
||||
if (++profile > 1000000 && !pr->no_exec_limit) {
|
||||
pr->pr_xstatement = st - pr->pr_statements;
|
||||
PR_RunError (pr, "runaway loop error");
|
||||
}
|
||||
|
@ -379,7 +378,7 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
case OP_AND: // OPA and OPB have to be float for -0.0
|
||||
OPC.integer_var = FNZ (OPA) && FNZ (OPB);
|
||||
break;
|
||||
case OP_OR: // OPA and OPB have to be float for -0.0
|
||||
case OP_OR: // OPA and OPB have to be float for -0.0
|
||||
OPC.integer_var = FNZ (OPA) || FNZ (OPB);
|
||||
break;
|
||||
case OP_NOT_F:
|
||||
|
|
|
@ -88,8 +88,9 @@ main ()
|
|||
progs.num_edicts = &num_edicts;
|
||||
progs.reserved_edicts = &reserved_edicts;
|
||||
progs.no_exec_limit = 1;
|
||||
progs.progs_name = "qwaq.dat";
|
||||
|
||||
f = fopen ("qwaq.dat", "rb");
|
||||
f = fopen (progs.progs_name, "rb");
|
||||
if (f) {
|
||||
fseek (f, 0, SEEK_END);
|
||||
len = ftell (f);
|
||||
|
@ -99,10 +100,11 @@ main ()
|
|||
fclose (f);
|
||||
com_filesize = len;
|
||||
if (progs.progs)
|
||||
PR_LoadProgs (&progs, 0);
|
||||
PR_LoadProgs (&progs, progs.progs_name);
|
||||
}
|
||||
if (!progs.progs)
|
||||
Sys_Error ("couldn't load %s\n", "qwaq.dat");
|
||||
PR_RelocateBuiltins (&progs);
|
||||
|
||||
*progs.edicts = PR_InitEdicts (&progs, MAX_EDICTS);
|
||||
for (i = 0; i < progs.progs->numstatements; i++) {
|
||||
|
|
Loading…
Reference in a new issue