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:
Bill Currie 2001-12-14 08:15:04 +00:00
parent 2185e0a92e
commit 3dafbebf10
5 changed files with 51 additions and 77 deletions

View file

@ -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;

View file

@ -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... */

View file

@ -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);
}
}

View file

@ -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:

View file

@ -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++) {