mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-31 03:50:36 +00:00
code_alloc_field to allocate entityfield data, ir now has ir_builder_create_field - so that globals and fields can be created separately - properly
This commit is contained in:
parent
a7957a9fdc
commit
d05bee94d1
4 changed files with 93 additions and 20 deletions
13
code.c
13
code.c
|
@ -63,6 +63,8 @@ VECTOR_MAKE(prog_section_function, code_functions );
|
|||
VECTOR_MAKE(int, code_globals );
|
||||
VECTOR_MAKE(char, code_chars );
|
||||
|
||||
uint32_t code_entfields;
|
||||
|
||||
void code_init() {
|
||||
prog_section_function empty_function = {0,0,0,0,0,0,0,{0}};
|
||||
prog_section_statement empty_statement = {0,{0},{0},{0}};
|
||||
|
@ -82,6 +84,8 @@ void code_init() {
|
|||
code_chars_add ('\0');
|
||||
code_functions_add (empty_function);
|
||||
code_statements_add(empty_statement);
|
||||
|
||||
code_entfields = 0;
|
||||
}
|
||||
|
||||
uint32_t code_genstring(const char *str)
|
||||
|
@ -152,6 +156,13 @@ void code_test() {
|
|||
code_statements_add(s3);
|
||||
}
|
||||
|
||||
qcint code_alloc_field (size_t qcsize)
|
||||
{
|
||||
qcint pos = (qcint)code_entfields;
|
||||
code_entfields += qcsize;
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool code_write(const char *filename) {
|
||||
prog_header code_header;
|
||||
FILE *fp = NULL;
|
||||
|
@ -173,7 +184,7 @@ bool code_write(const char *filename) {
|
|||
code_header.strings.length = code_chars_elements;
|
||||
code_header.version = 6;
|
||||
code_header.crc16 = 0; /* TODO: */
|
||||
code_header.entfield = 0; /* TODO: */
|
||||
code_header.entfield = code_entfields;
|
||||
|
||||
if (OPTS_FLAG(DARKPLACES_STRING_TABLE_BUG)) {
|
||||
util_debug("GEN", "Patching stringtable for -fdarkplaces-stringtablebug\n");
|
||||
|
|
7
gmqcc.h
7
gmqcc.h
|
@ -584,6 +584,9 @@ VECTOR_PROT(prog_section_function, code_functions );
|
|||
VECTOR_PROT(int, code_globals );
|
||||
VECTOR_PROT(char, code_chars );
|
||||
|
||||
typedef float qcfloat;
|
||||
typedef int32_t qcint;
|
||||
|
||||
/*
|
||||
* code_write -- writes out the compiled file
|
||||
* code_init -- prepares the code file
|
||||
|
@ -592,6 +595,7 @@ bool code_write (const char *filename);
|
|||
void code_init ();
|
||||
uint32_t code_genstring (const char *string);
|
||||
uint32_t code_cachedstring(const char *string);
|
||||
qcint code_alloc_field (size_t qcsize);
|
||||
|
||||
/*===================================================================*/
|
||||
/*========================= assembler.c =============================*/
|
||||
|
@ -866,9 +870,6 @@ typedef struct {
|
|||
* Since we may want to support that as well, let's redefine
|
||||
* float and int here.
|
||||
*/
|
||||
typedef float qcfloat;
|
||||
typedef int32_t qcint;
|
||||
|
||||
typedef union {
|
||||
qcint _int;
|
||||
qcint string;
|
||||
|
|
89
ir.c
89
ir.c
|
@ -90,6 +90,7 @@ ir_builder* ir_builder_new(const char *modulename)
|
|||
|
||||
MEM_VECTOR_INIT(self, functions);
|
||||
MEM_VECTOR_INIT(self, globals);
|
||||
MEM_VECTOR_INIT(self, fields);
|
||||
self->name = NULL;
|
||||
if (!ir_builder_set_name(self, modulename)) {
|
||||
mem_d(self);
|
||||
|
@ -105,6 +106,7 @@ ir_builder* ir_builder_new(const char *modulename)
|
|||
}
|
||||
|
||||
MEM_VEC_FUNCTIONS(ir_builder, ir_value*, globals)
|
||||
MEM_VEC_FUNCTIONS(ir_builder, ir_value*, fields)
|
||||
MEM_VEC_FUNCTIONS(ir_builder, ir_function*, functions)
|
||||
|
||||
void ir_builder_delete(ir_builder* self)
|
||||
|
@ -118,7 +120,11 @@ void ir_builder_delete(ir_builder* self)
|
|||
for (i = 0; i != self->globals_count; ++i) {
|
||||
ir_value_delete(self->globals[i]);
|
||||
}
|
||||
MEM_VECTOR_CLEAR(self, globals);
|
||||
MEM_VECTOR_CLEAR(self, fields);
|
||||
for (i = 0; i != self->fields_count; ++i) {
|
||||
ir_value_delete(self->fields[i]);
|
||||
}
|
||||
MEM_VECTOR_CLEAR(self, fields);
|
||||
mem_d(self);
|
||||
}
|
||||
|
||||
|
@ -194,6 +200,33 @@ ir_value* ir_builder_create_global(ir_builder *self, const char *name, int vtype
|
|||
return ve;
|
||||
}
|
||||
|
||||
ir_value* ir_builder_get_field(ir_builder *self, const char *name)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < self->fields_count; ++i) {
|
||||
if (!strcmp(self->fields[i]->name, name))
|
||||
return self->fields[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ir_value* ir_builder_create_field(ir_builder *self, const char *name, int vtype)
|
||||
{
|
||||
ir_value *ve = ir_builder_get_field(self, name);
|
||||
if (ve) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ve = ir_value_var(name, store_global, TYPE_FIELD);
|
||||
ve->fieldtype = vtype;
|
||||
if (!ir_builder_fields_add(self, ve)) {
|
||||
ir_value_delete(ve);
|
||||
return NULL;
|
||||
}
|
||||
return ve;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*IR Function
|
||||
*/
|
||||
|
@ -2046,21 +2079,7 @@ static bool gen_global_field(ir_value *global)
|
|||
}
|
||||
else
|
||||
{
|
||||
prog_section_field fld;
|
||||
|
||||
fld.name = global->code.name;
|
||||
fld.offset = code_fields_elements;
|
||||
fld.type = global->fieldtype;
|
||||
|
||||
if (fld.type == TYPE_VOID) {
|
||||
printf("Field is missing a type: %s\n", global->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (code_fields_add(fld) < 0)
|
||||
return false;
|
||||
|
||||
global->code.globaladdr = code_globals_add(fld.offset);
|
||||
global->code.globaladdr = code_globals_add(0);
|
||||
}
|
||||
if (global->code.globaladdr < 0)
|
||||
return false;
|
||||
|
@ -2492,12 +2511,50 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
|
|||
}
|
||||
}
|
||||
|
||||
static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
|
||||
{
|
||||
prog_section_def def;
|
||||
prog_section_field fld;
|
||||
|
||||
def.type = field->vtype;
|
||||
def.offset = code_globals_elements;
|
||||
def.name = field->code.name = code_genstring(field->name);
|
||||
|
||||
if (code_defs_add(def) < 0)
|
||||
return false;
|
||||
|
||||
fld.name = def.name;
|
||||
fld.offset = code_fields_elements;
|
||||
fld.type = field->fieldtype;
|
||||
|
||||
if (fld.type == TYPE_VOID) {
|
||||
printf("field is missing a type: %s - don't know its size\n", field->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (code_fields_add(fld) < 0)
|
||||
return false;
|
||||
|
||||
if (!code_globals_add(code_alloc_field(type_sizeof[field->fieldtype])))
|
||||
return false;
|
||||
|
||||
field->code.globaladdr = code_globals_add(fld.offset);
|
||||
return field->code.globaladdr >= 0;
|
||||
}
|
||||
|
||||
bool ir_builder_generate(ir_builder *self, const char *filename)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
code_init();
|
||||
|
||||
for (i = 0; i < self->fields_count; ++i)
|
||||
{
|
||||
if (!ir_builder_gen_field(self, self->fields[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < self->globals_count; ++i)
|
||||
{
|
||||
if (!ir_builder_gen_global(self, self->globals[i])) {
|
||||
|
|
4
ir.h
4
ir.h
|
@ -286,6 +286,7 @@ typedef struct ir_builder_s
|
|||
char *name;
|
||||
MEM_VECTOR_MAKE(ir_function*, functions);
|
||||
MEM_VECTOR_MAKE(ir_value*, globals);
|
||||
MEM_VECTOR_MAKE(ir_value*, fields);
|
||||
} ir_builder;
|
||||
|
||||
ir_builder* ir_builder_new(const char *modulename);
|
||||
|
@ -295,12 +296,15 @@ bool ir_builder_set_name(ir_builder *self, const char *name);
|
|||
|
||||
MEM_VECTOR_PROTO(ir_builder, ir_function*, functions);
|
||||
MEM_VECTOR_PROTO(ir_builder, ir_value*, globals);
|
||||
MEM_VECTOR_PROTO(ir_builder, ir_value*, fields);
|
||||
|
||||
ir_function* ir_builder_get_function(ir_builder*, const char *fun);
|
||||
ir_function* ir_builder_create_function(ir_builder*, const char *name, int outtype);
|
||||
|
||||
ir_value* ir_builder_get_global(ir_builder*, const char *fun);
|
||||
ir_value* ir_builder_create_global(ir_builder*, const char *name, int vtype);
|
||||
ir_value* ir_builder_get_field(ir_builder*, const char *fun);
|
||||
ir_value* ir_builder_create_field(ir_builder*, const char *name, int vtype);
|
||||
|
||||
bool ir_builder_generate(ir_builder *self, const char *filename);
|
||||
|
||||
|
|
Loading…
Reference in a new issue