]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ir.c
code_alloc_field to allocate entityfield data, ir now has ir_builder_create_field...
[xonotic/gmqcc.git] / ir.c
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])) {