]> de.git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
code_alloc_field to allocate entityfield data, ir now has ir_builder_create_field...
authorWolfgang Bumiller <wolfgang.linux@bumiller.com>
Sat, 28 Jul 2012 19:55:01 +0000 (21:55 +0200)
committerWolfgang Bumiller <wolfgang.linux@bumiller.com>
Sat, 28 Jul 2012 19:55:01 +0000 (21:55 +0200)
code.c
gmqcc.h
ir.c
ir.h

diff --git a/code.c b/code.c
index 0cb373b96bc07a9eea6c232209bc4e4e0d9dad41..9149fbca6a717f7206984c10dcfd20dde71fb0e1 100644 (file)
--- a/code.c
+++ b/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");
diff --git a/gmqcc.h b/gmqcc.h
index bfc22d96a5c28504a6dbb7fb42597cb849223ec2..8ebe3afd60e0dae8f3a7e38ad6a07f843ab163fe 100644 (file)
--- a/gmqcc.h
+++ b/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;
diff --git a/ir.c b/ir.c
index f32f9d49492c2ae3efa4b58ec3d3df44e78a42f0..b3d49ec2849607a2e7d8c7dfaa913c2af61f2851 100644 (file)
--- a/ir.c
+++ b/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])) {
diff --git a/ir.h b/ir.h
index 9eab51f73f5d9282e4597986badb38ff85fb6268..47ff96b88b30fc279e2be9c91486c0a7133e16ac 100644 (file)
--- a/ir.h
+++ b/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);