Immidiate sharing now /works/ (shaved off two pr_globals from CustomTF, too:).

Detect assignments to initialized globals and give an error, unless the --cow
(copy on write) option is given, and then allocate a new global for the var,
clear its initialized flag.
Relocate all globals.
This commit is contained in:
Bill Currie 2001-06-08 06:32:15 +00:00
parent 5ffc8e5349
commit 7ef4c2776e
5 changed files with 112 additions and 21 deletions

View file

@ -452,6 +452,8 @@ void PR_NewLine (void);
def_t *PR_GetDef (type_t *type, const char *name, def_t *scope,
int *allocate);
def_t *PR_NewDef (type_t *type, const char *name, def_t *scope);
int PR_NewLocation (type_t *type);
void PR_FreeLocation (def_t *def);
def_t *PR_GetTempDef (type_t *type, def_t *scope);
void PR_FreeTempDefs ();
void PR_ResetTempDefs ();
@ -524,3 +526,9 @@ extern int numfiles;
int CopyString (const char *str);
int ReuseString (const char *str);
typedef struct {
int cow; // copy on write for constants
} options_t;
extern options_t options;

View file

@ -309,10 +309,22 @@ PR_Expression (int priority)
if (e->type->type == ev_pointer && e2->type->type != e->type->aux_type->type)
PR_ParseError ("type mismatch for %s", op->name);
if (op->right_associative)
if (op->right_associative) {
if (e->initialized) {
if (options.cow) {
int size = type_size [e->type->type];
int ofs = PR_NewLocation (e->type);
memcpy (pr_globals + ofs, pr_globals + e->ofs, size);
e->ofs = ofs;
e->initialized = 0;
} else {
PR_ParseError ("assignment to constant: %s", e->name);
}
}
e = PR_Statement (op, e2, e);
else
} else {
e = PR_Statement (op, e, e2);
}
if (var_c.type != &type_void) // field access gets type from field
e->type = e2->type->aux_type;

View file

@ -24,11 +24,17 @@
#include "qfcc.h"
typedef struct locref_s {
struct locref_s *next;
int ofs;
} locref_t;
def_t *pr_global_defs[MAX_REGS]; // to find def for a global variable
int pr_edict_size;
static def_t *free_temps[4]; // indexted by type size
static def_t temp_scope;
static locref_t *free_locs[4]; // indexted by type size
static locref_t *free_free_locs;
static hashtab_t *defs_by_name;
@ -77,6 +83,7 @@ PR_GetDef (type_t *type, const char *name, def_t *scope, int *allocate)
def = PR_NewDef (type, name, scope);
Hash_Add (defs_by_name, def);
//FIXME: need to sort out location re-use
def->ofs = *allocate;
pr_global_defs[*allocate] = def;
@ -145,6 +152,44 @@ PR_NewDef (type_t *type, const char *name, def_t *scope)
return def;
}
int
PR_NewLocation (type_t *type)
{
int size = type_size[type->type];
locref_t *loc;
if (free_locs[size]) {
loc = free_locs[size];
free_locs[size] = loc->next;
loc->next = free_free_locs;
free_free_locs = loc;
return loc->ofs;
}
numpr_globals += size;
return numpr_globals - size;
}
void
PR_FreeLocation (def_t *def)
{
int size = type_size[def->type->type];
locref_t *loc;
if (!free_free_locs) {
free_free_locs = malloc (256 * sizeof (locref_t));
for (loc = free_free_locs; loc - free_free_locs < 255; loc++)
loc->next = loc + 1;
loc->next = 0;
}
loc = free_free_locs;
free_free_locs = loc->next;
loc->ofs = def->ofs;
loc->next = free_locs[size];
free_locs[size] = loc;
}
def_t *
PR_GetTempDef (type_t *type, def_t *scope)
{

View file

@ -71,6 +71,9 @@ PR_ParseImmediate (def_t *def)
float_imm_defs = Hash_NewTable (16381, float_imm_get_key, 0, 0);
vector_imm_defs = Hash_NewTable (16381, vector_imm_get_key, 0, 0);
}
if (def && def->type != pr_immediate_type) {
PR_ParseError ("immediate type missmatch");
}
if (pr_immediate_type == &type_string) {
cn = (def_t*) Hash_Find (string_imm_defs, pr_immediate_string);
tab = string_imm_defs;
@ -92,8 +95,15 @@ PR_ParseImmediate (def_t *def)
PR_ParseError ("weird immediate type");
}
if (cn) {
if (cn->type != pr_immediate_type) printf("urk\n");
if (cn->type != pr_immediate_type)
printf("urk\n");
//printf("found\n");
if (def) {
PR_FreeLocation (def);
def->ofs = cn->ofs;
def->initialized = 1;
cn = def;
}
PR_Lex ();
return cn;
}
@ -104,9 +114,8 @@ PR_ParseImmediate (def_t *def)
cn = def;
} else {
cn = PR_NewDef (pr_immediate_type, "IMMEDIATE", 0);
cn->ofs = numpr_globals;
cn->ofs = PR_NewLocation (pr_immediate_type);
pr_global_defs[cn->ofs] = cn;
numpr_globals += type_size[pr_immediate_type->type];
}
cn->initialized = 1;
// copy the immediate to the global area

View file

@ -37,6 +37,7 @@
#include "qfcc.h"
options_t options;
char sourcedir[1024];
char destfile[1024];
@ -604,6 +605,27 @@ PR_BeginCompilation (void *memory, int memsize)
pr_error_count = 0;
}
void
PR_RelocateRefs (def_t *def)
{
statref_t *ref;
for (ref = def->refs; ref; ref = ref->next) {
switch (ref->field) {
case 0:
ref->statement->a = def->ofs;
break;
case 1:
ref->statement->b = def->ofs;
break;
case 2:
ref->statement->c = def->ofs;
break;
default:
abort();
}
}
}
/*
PR_FinishCompilation
@ -617,7 +639,6 @@ PR_FinishCompilation (void)
qboolean errors = false;
function_t *f;
def_t *def;
statref_t *ref;
// check to make sure all functions prototyped have code
for (d = pr.def_head.next; d; d = d->next) {
@ -634,6 +655,12 @@ PR_FinishCompilation (void)
if (errors)
return !errors;
for (def = pr.def_head.next; def; def = def->next) {
if (def->scope)
continue;
PR_RelocateRefs (def);
}
for (f = pr_functions; f; f = f->next) {
if (f->builtin)
continue;
@ -641,22 +668,8 @@ PR_FinishCompilation (void)
num_locals = f->def->num_locals;
f->dfunc->parm_start = numpr_globals;
for (def = f->def->scope_next; def; def = def->scope_next) {
for (ref = def->refs; ref; ref = ref->next) {
switch (ref->field) {
case 0:
ref->statement->a += numpr_globals;
break;
case 1:
ref->statement->b += numpr_globals;
break;
case 2:
ref->statement->c += numpr_globals;
break;
default:
abort();
}
}
def->ofs += numpr_globals;
PR_RelocateRefs (def);
}
}
numpr_globals += num_locals;
@ -856,6 +869,10 @@ Options: \n\
}
}
if (CheckParm ("--cow")) {
options.cow = 1;
}
if (strcmp (sourcedir, ".")) {
printf ("Source directory: %s\n", sourcedir);
}