mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
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:
parent
5ffc8e5349
commit
7ef4c2776e
5 changed files with 112 additions and 21 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue