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:
Wolfgang Bumiller 2012-07-28 21:55:01 +02:00
parent a7957a9fdc
commit d05bee94d1
4 changed files with 93 additions and 20 deletions

13
code.c
View file

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

View file

@ -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
View file

@ -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
View file

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