]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
IR generation: for functions: first generate all defs, then the code, so access to...
authorWolfgang (Blub) Bumiller <blub@speed.at>
Sun, 19 Aug 2012 16:00:53 +0000 (18:00 +0200)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Sun, 19 Aug 2012 16:00:53 +0000 (18:00 +0200)
ir.c
ir.h

diff --git a/ir.c b/ir.c
index 2adaa724a7007624234d7655a4f66a0a49a1294f..3132685eae51c6bfa1c7550f4ca0aa6eac63c29d 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -322,6 +322,8 @@ ir_function* ir_function_new(ir_builder* owner, int outtype)
     MEM_VECTOR_INIT(self, values);
     MEM_VECTOR_INIT(self, locals);
 
+    self->code_function_def = -1;
+
     self->run_id = 0;
     return self;
 }
@@ -2580,7 +2582,7 @@ static bool gen_global_function(ir_builder *ir, ir_value *global)
     local_var_end = fun.firstlocal;
     for (i = 0; i < irfun->locals_count; ++i) {
         if (!ir_builder_gen_global(ir, irfun->locals[i])) {
-            irerror(irfun->locals[i]->context, "Failed to generate local %s\n", irfun->locals[i]->name);
+            irerror(irfun->locals[i]->context, "Failed to generate local %s", irfun->locals[i]->name);
             return false;
         }
     }
@@ -2603,16 +2605,42 @@ static bool gen_global_function(ir_builder *ir, ir_value *global)
     if (irfun->builtin)
         fun.entry = irfun->builtin;
     else {
+        irfun->code_function_def = code_functions_elements;
         fun.entry = code_statements_elements;
+        /* done in second pass: gen_global_function_code!
         if (!gen_function_code(irfun)) {
-            irerror(irfun->context, "Failed to generate code for function %s\n", irfun->name);
+            irerror(irfun->context, "Failed to generate code for function %s", irfun->name);
             return false;
         }
+        */
     }
 
     return (code_functions_add(fun) >= 0);
 }
 
+static bool gen_global_function_code(ir_builder *ir, ir_value *global)
+{
+    prog_section_function *fundef;
+    ir_function           *irfun;
+
+    irfun = global->constval.vfunc;
+    if (irfun->builtin)
+        return true;
+
+    if (irfun->code_function_def < 0) {
+        irerror(irfun->context, "`%s`: IR global wasn't generated, failed to access function-def", irfun->name);
+        return false;
+    }
+    fundef = &code_functions_data[irfun->code_function_def];
+
+    fundef->entry = code_statements_elements;
+    if (!gen_function_code(irfun)) {
+        irerror(irfun->context, "Failed to generate code for function %s", irfun->name);
+        return false;
+    }
+    return true;
+}
+
 static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
 {
     size_t           i;
@@ -2793,6 +2821,16 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
         }
     }
 
+    /* generate function code */
+    for (i = 0; i < self->globals_count; ++i)
+    {
+        if (self->globals[i]->vtype == TYPE_FUNCTION) {
+            if (!gen_global_function_code(self, self->globals[i])) {
+                return false;
+            }
+        }
+    }
+
     printf("writing '%s'...\n", filename);
     return code_write(filename);
 }
diff --git a/ir.h b/ir.h
index 59b4488724d7be4b2ff242856110e00a25a1735d..dc29e79e297c109a4b203913fca87d91309d36dd 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -260,6 +260,14 @@ typedef struct ir_function_s
 
     lex_ctx       context;
 
+    /* for prototypes - first we generate all the
+     * globals, and we remember teh function-defs
+     * so we can later fill in the entry pos
+     *
+     * remember the ID:
+     */
+    qcint code_function_def;
+
     /* for temp allocation */
     size_t run_id;