mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
entity fields seem to work. I guess this means separate compilation is now
useful :)
This commit is contained in:
parent
c36b7e36d2
commit
678a45cfe2
7 changed files with 95 additions and 12 deletions
|
@ -36,7 +36,7 @@
|
|||
#include "QF/pr_debug.h"
|
||||
|
||||
#define QFO "QFO"
|
||||
#define QFO_VERSION 0x00001003 // MMmmmRRR 0.001.002 (hex)
|
||||
#define QFO_VERSION 0x00001004 // MMmmmRRR 0.001.004 (hex)
|
||||
|
||||
typedef struct qfo_header_s {
|
||||
char qfo[4];
|
||||
|
@ -50,6 +50,7 @@ typedef struct qfo_header_s {
|
|||
int num_funcs;
|
||||
int num_lines;
|
||||
int types_size;
|
||||
int entity_fields;
|
||||
} qfo_header_t;
|
||||
|
||||
typedef struct qfo_def_s {
|
||||
|
@ -122,6 +123,7 @@ typedef struct qfo_s {
|
|||
int num_lines;
|
||||
char *types;
|
||||
int types_size;
|
||||
int entity_fields;
|
||||
} qfo_t;
|
||||
|
||||
#define QFO_var(q, t, o) ((q)->data[o].t##_var)
|
||||
|
|
|
@ -44,6 +44,7 @@ typedef enum {
|
|||
rel_def_def,
|
||||
rel_def_func,
|
||||
rel_def_string,
|
||||
rel_def_field,
|
||||
} reloc_type;
|
||||
|
||||
typedef struct reloc_s {
|
||||
|
@ -59,5 +60,6 @@ void relocate_refs (reloc_t *refs, int ofs);
|
|||
void reloc_def_def (struct def_s *def, int ofs);
|
||||
void reloc_def_func (struct function_s *func, int ofs);
|
||||
void reloc_def_string (int ofs);
|
||||
void reloc_def_field (struct def_s *def, int ofs);
|
||||
|
||||
#endif//__reloc_h
|
||||
|
|
|
@ -37,6 +37,7 @@ static const char rcsid[] =
|
|||
#include "qfcc.h"
|
||||
#include "def.h"
|
||||
#include "expr.h"
|
||||
#include "reloc.h"
|
||||
#include "strpool.h"
|
||||
#include "struct.h"
|
||||
#include "type.h"
|
||||
|
@ -196,8 +197,10 @@ vector_component (int is_field, def_t *vec, int comp, scope_t *scope,
|
|||
d->parent = vec;
|
||||
d->ofs = vec->ofs + comp;
|
||||
set_storage_bits (d, storage);
|
||||
if (is_field && (storage == st_global || storage == st_static))
|
||||
if (is_field && (storage == st_global || storage == st_static)) {
|
||||
G_INT (d->ofs) = G_INT (vec->ofs) + comp;
|
||||
reloc_def_field (d, d->ofs);
|
||||
}
|
||||
Hash_Add (defs_by_name, d);
|
||||
}
|
||||
|
||||
|
@ -258,8 +261,10 @@ get_def (type_t *type, const char *name, scope_t *scope,
|
|||
}
|
||||
|
||||
if (type->type == ev_field) {
|
||||
if (storage == st_global || storage == st_static)
|
||||
if (storage == st_global || storage == st_static) {
|
||||
G_INT (def->ofs) = new_location (type->aux_type, pr.entity_data);
|
||||
reloc_def_field (def, def->ofs);
|
||||
}
|
||||
|
||||
if (type->aux_type->type == ev_vector) {
|
||||
vector_component (1, def, 0, scope, storage);
|
||||
|
|
|
@ -67,14 +67,16 @@ Xgroup(func) // funcgroup_t
|
|||
|
||||
static hashtab_t *extern_defs;
|
||||
static hashtab_t *defined_defs;
|
||||
static hashtab_t *field_defs;
|
||||
|
||||
static codespace_t *code;
|
||||
static defspace_t *data;
|
||||
static defspace_t *far_data;
|
||||
static defspace_t *entity;
|
||||
static strpool_t *strings;
|
||||
static strpool_t *type_strings;
|
||||
static relocgroup_t relocs, final_relocs;
|
||||
static defgroup_t global_defs, local_defs, defs;
|
||||
static defgroup_t global_defs, local_defs, fields, defs;
|
||||
static funcgroup_t funcs;
|
||||
static struct {
|
||||
pr_lineno_t *lines;
|
||||
|
@ -84,6 +86,7 @@ static struct {
|
|||
static int code_base;
|
||||
static int data_base;
|
||||
static int far_data_base;
|
||||
static int entity_base;
|
||||
static int reloc_base;
|
||||
static int func_base;
|
||||
static int line_base;
|
||||
|
@ -159,6 +162,10 @@ add_relocs (qfo_t *qfo)
|
|||
strpool_addstr (strings,
|
||||
qfo->strings + data->data[reloc->ofs].string_var);
|
||||
break;
|
||||
case rel_def_field:
|
||||
//FIXME more?
|
||||
reloc->ofs += data_base;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -205,6 +212,24 @@ process_def (qfo_def_t *def)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
process_field (qfo_def_t *def)
|
||||
{
|
||||
qfo_def_t *field_def;
|
||||
pr_type_t *var = data->data + def->ofs;
|
||||
|
||||
if ((field_def = Hash_Find (field_defs, strings->strings + def->name))) {
|
||||
pr.source_file = def->file;
|
||||
pr.source_line = def->line;
|
||||
error (0, "%s redefined", strings->strings + def->name);
|
||||
}
|
||||
defgroup_add_defs (&fields, def, 1);
|
||||
field_def = fields.defs + fields.num_defs - 1;
|
||||
field_def->ofs = var->integer_var + entity_base;
|
||||
Hash_Add (field_defs, field_def);
|
||||
printf ("%s %d\n", strings->strings + field_def->name, field_def->ofs);
|
||||
}
|
||||
|
||||
static void
|
||||
fixup_def (qfo_t *qfo, qfo_def_t *def, int def_num)
|
||||
{
|
||||
|
@ -226,9 +251,19 @@ fixup_def (qfo_t *qfo, qfo_def_t *def, int def_num)
|
|||
return;
|
||||
if (!(def->flags & QFOD_EXTERNAL)) {
|
||||
def->ofs += data_base;
|
||||
if (def->basic_type == ev_func && (def->flags & QFOD_INITIALIZED)) {
|
||||
func = funcs.funcs + data->data[def->ofs].func_var - 1 + func_base;
|
||||
func->def = def_num;
|
||||
if (def->flags & QFOD_INITIALIZED) {
|
||||
pr_type_t *var = data->data + def->ofs;
|
||||
switch (def->basic_type) {
|
||||
case ev_func:
|
||||
func = funcs.funcs + var->func_var - 1 + func_base;
|
||||
func->def = def_num;
|
||||
break;
|
||||
case ev_field:
|
||||
process_field (def);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
process_def (def);
|
||||
|
@ -307,7 +342,7 @@ static void
|
|||
fixup_relocs ()
|
||||
{
|
||||
qfo_reloc_t *reloc;
|
||||
qfo_def_t *def;
|
||||
qfo_def_t *def, *field_def;
|
||||
qfo_func_t *func;
|
||||
int i;
|
||||
|
||||
|
@ -322,6 +357,7 @@ fixup_relocs ()
|
|||
case rel_op_b_def:
|
||||
case rel_op_c_def:
|
||||
case rel_def_def:
|
||||
case rel_def_field:
|
||||
def = defs.defs + reloc->def;
|
||||
if (def->flags & (QFOD_EXTERNAL | QFOD_LOCAL | QFOD_ABSOLUTE))
|
||||
continue;
|
||||
|
@ -362,6 +398,11 @@ fixup_relocs ()
|
|||
break;
|
||||
case rel_def_string:
|
||||
break;
|
||||
case rel_def_field:
|
||||
field_def = Hash_Find (field_defs,
|
||||
strings->strings + def->name);
|
||||
data->data[reloc->ofs].integer_var = field_def->ofs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < defs.num_defs; i++) {
|
||||
|
@ -449,10 +490,12 @@ merge_defgroups (void)
|
|||
}
|
||||
|
||||
static void
|
||||
define_def (const char *name, etype_t basic_type, const char *full_type)
|
||||
define_def (const char *name, etype_t basic_type, const char *full_type, int v)
|
||||
{
|
||||
qfo_def_t d;
|
||||
pr_type_t val = {0};
|
||||
pr_type_t val;
|
||||
|
||||
val.integer_var = v;
|
||||
|
||||
memset (&d, 0, sizeof (d));
|
||||
d.basic_type = basic_type;
|
||||
|
@ -463,6 +506,13 @@ define_def (const char *name, etype_t basic_type, const char *full_type)
|
|||
defspace_adddata (data, &val, 1);
|
||||
defgroup_add_defs (&global_defs, &d, 1);
|
||||
process_def (global_defs.defs + global_defs.num_defs - 1);
|
||||
if (basic_type == ev_field) {
|
||||
int def_num = global_defs.num_defs - 1;
|
||||
qfo_def_t *def = global_defs.defs + def_num;
|
||||
qfo_reloc_t rel = {def->ofs, rel_def_field, def_num};
|
||||
relocgroup_add_relocs (&relocs, &rel, 1);
|
||||
process_field (def);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -470,9 +520,11 @@ linker_begin (void)
|
|||
{
|
||||
extern_defs = Hash_NewTable (16381, defs_get_key, 0, 0);
|
||||
defined_defs = Hash_NewTable (16381, defs_get_key, 0, 0);
|
||||
field_defs = Hash_NewTable (16381, defs_get_key, 0, 0);
|
||||
code = codespace_new ();
|
||||
data = new_defspace ();
|
||||
far_data = new_defspace ();
|
||||
entity = new_defspace ();
|
||||
strings = strpool_new ();
|
||||
type_strings = strpool_new ();
|
||||
|
||||
|
@ -496,10 +548,12 @@ linker_add_object_file (const char *filename)
|
|||
reloc_base = relocs.num_relocs;
|
||||
func_base = funcs.num_funcs;
|
||||
line_base = lines.num_lines;
|
||||
entity_base = entity->size;
|
||||
|
||||
codespace_addcode (code, qfo->code, qfo->code_size);
|
||||
defspace_adddata (data, qfo->data, qfo->data_size);
|
||||
defspace_adddata (far_data, qfo->far_data, qfo->far_data_size);
|
||||
defspace_adddata (entity, 0, qfo->entity_fields);
|
||||
add_strings (qfo);
|
||||
add_relocs (qfo);
|
||||
add_funcs (qfo);
|
||||
|
@ -523,10 +577,12 @@ linker_finish (void)
|
|||
const char *name = strings->strings + (*def)->name;
|
||||
|
||||
if (strcmp (name, ".self") == 0 && !did_self) {
|
||||
define_def (".self", ev_entity, "E");
|
||||
define_def (".self", ev_entity, "E", 0);
|
||||
did_self = 1;
|
||||
} else if (strcmp (name, ".this") == 0 && !did_this) {
|
||||
define_def (".this", ev_field, "F@");
|
||||
entity_base = 0;
|
||||
define_def (".this", ev_field, "F@", entity->size);
|
||||
defspace_adddata (entity, 0, 1);
|
||||
did_this = 1;
|
||||
}
|
||||
}
|
||||
|
@ -560,5 +616,6 @@ linker_finish (void)
|
|||
qfo_add_funcs (qfo, funcs.funcs, funcs.num_funcs);
|
||||
qfo_add_lines (qfo, lines.lines, lines.num_lines);
|
||||
qfo_add_types (qfo, type_strings->strings, type_strings->size);
|
||||
qfo->entity_fields = entity->size;
|
||||
return qfo;
|
||||
}
|
||||
|
|
|
@ -255,6 +255,7 @@ qfo_from_progs (pr_info_t *pr)
|
|||
qfo_add_funcs (qfo, funcs, num_funcs);
|
||||
qfo_add_lines (qfo, linenos, num_linenos);
|
||||
qfo_add_types (qfo, types->strings, types->size);
|
||||
qfo->entity_fields = pr->entity_data->size;
|
||||
|
||||
free (defs);
|
||||
free (relocs);
|
||||
|
@ -284,6 +285,7 @@ qfo_write (qfo_t *qfo, const char *filename)
|
|||
hdr.num_funcs = LittleLong (qfo->num_funcs);
|
||||
hdr.num_lines = LittleLong (qfo->num_lines);
|
||||
hdr.types_size = LittleLong (qfo->types_size);
|
||||
hdr.entity_fields = LittleLong (qfo->entity_fields);
|
||||
|
||||
Qwrite (file, &hdr, sizeof (hdr));
|
||||
if (qfo->code_size)
|
||||
|
@ -349,6 +351,7 @@ qfo_read (const char *filename)
|
|||
qfo->num_funcs = LittleLong (hdr.num_funcs);
|
||||
qfo->num_lines = LittleLong (hdr.num_lines);
|
||||
qfo->types_size = LittleLong (hdr.types_size);
|
||||
qfo->entity_fields = LittleLong (hdr.entity_fields);
|
||||
|
||||
if (hdr.version != QFO_VERSION) {
|
||||
fprintf (stderr, "can't read version %x.%03x.%03x\n",
|
||||
|
@ -531,6 +534,7 @@ qfo_to_progs (qfo_t *qfo, pr_info_t *pr)
|
|||
pf->refs[qf->num_relocs - 1].next = 0;
|
||||
}
|
||||
}
|
||||
pr->entity_data = init_space (qfo->entity_fields, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,6 +102,8 @@ dump_defs (qfo_t *qfo)
|
|||
func = qfo->funcs + qfo->data[def->ofs].func_var - 1;
|
||||
printf (" %4d %s\n", qfo->data[def->ofs].func_var,
|
||||
func ? qfo->strings + func->name : "BORKAGE");
|
||||
} else if (def->basic_type == ev_field) {
|
||||
printf (" %4d\n", qfo->data[def->ofs].integer_var);
|
||||
} else {
|
||||
// printf (" %4d\n", qfo->data[def->ofs].integer_var);
|
||||
}
|
||||
|
@ -137,6 +139,7 @@ const char *reloc_names[] = {
|
|||
"def_def",
|
||||
"def_func",
|
||||
"def_string",
|
||||
"def_field",
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -110,6 +110,8 @@ relocate_refs (reloc_t *refs, int ofs)
|
|||
break;
|
||||
case rel_def_string:
|
||||
break;
|
||||
case rel_def_field:
|
||||
break;
|
||||
}
|
||||
refs = refs->next;
|
||||
}
|
||||
|
@ -149,3 +151,11 @@ reloc_def_string (int ofs)
|
|||
ref->next = pr.relocs;
|
||||
pr.relocs = ref;
|
||||
}
|
||||
|
||||
void
|
||||
reloc_def_field (def_t *def, int ofs)
|
||||
{
|
||||
reloc_t *ref = new_reloc (ofs, rel_def_field);
|
||||
ref->next = def->refs;
|
||||
def->refs = ref;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue