]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
Copying arg counter into the local
authorWolfgang Bumiller <blub@speed.at>
Sat, 12 Jan 2013 14:06:19 +0000 (15:06 +0100)
committerWolfgang Bumiller <blub@speed.at>
Sat, 12 Jan 2013 14:06:19 +0000 (15:06 +0100)
ast.c
ast.h
parser.c

diff --git a/ast.c b/ast.c
index ebded6a143c40df45716ee29ed10fd10fd3f40a6..ddbffb961d20f31c8ddadfa6d44e0f12df4029a7 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -1079,6 +1079,7 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype)
     vtype->constval.vfunc = self;
 
     self->varargs = NULL;
+    self->argc    = NULL;
 
     return self;
 }
@@ -1104,6 +1105,8 @@ void ast_function_delete(ast_function *self)
     vec_free(self->continueblocks);
     if (self->varargs)
         ast_delete(self->varargs);
+    if (self->argc)
+        ast_delete(self->argc);
     mem_d(self);
 }
 
@@ -1554,7 +1557,8 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
 {
     ir_function *irf;
     ir_value    *dummy;
-    ast_expression_common *ec;
+    ast_expression_common  *ec;
+    ast_expression_codegen *cgen;
     size_t    i;
 
     (void)ir;
@@ -1601,9 +1605,23 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
         return false;
     }
 
+    if (self->argc) {
+        ir_value *va_count;
+        if (!ast_local_codegen(self->argc, self->ir_func, true))
+            return false;
+        cgen = self->argc->expression.codegen;
+        if (!(*cgen)((ast_expression*)(self->argc), self, false, &va_count))
+            return false;
+        if (!ir_block_create_store_op(self->curblock, ast_ctx(self), INSTR_STORE_F,
+                                      va_count, ir_builder_get_va_count(ir)))
+        {
+            return false;
+        }
+    }
+
     for (i = 0; i < vec_size(self->blocks); ++i) {
-        ast_expression_codegen *gen = self->blocks[i]->expression.codegen;
-        if (!(*gen)((ast_expression*)self->blocks[i], self, false, &dummy))
+        cgen = self->blocks[i]->expression.codegen;
+        if (!(*cgen)((ast_expression*)self->blocks[i], self, false, &dummy))
             return false;
     }
 
diff --git a/ast.h b/ast.h
index 658842291c15a158884c4d7fd2f67ecf4fb06e39..2e9858fc85054ed6c6ff81dd7ebbe295d7bd7e77 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -647,6 +647,7 @@ struct ast_function_s
     ast_block* *blocks;
 
     ast_value   *varargs;
+    ast_value   *argc;
 };
 ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype);
 /* This will NOT delete the underlying ast_value */
index 84c3e0907673fe5c9848bf5f5e1334713efb5a06..32e9427bc49be1bb6c14e261fa8fe30a7ca6cc74 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -3998,12 +3998,6 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
         }
     }
 
-    if (var->argcounter) {
-        ast_value *argc = ast_value_new(ast_ctx(var), var->argcounter, TYPE_FLOAT);
-        ast_block_collect(block, (ast_expression*)argc);
-        parser_addlocal(parser, argc->name, (ast_expression*)argc);
-    }
-
     func = ast_function_new(ast_ctx(var), var->name, var);
     if (!func) {
         parseerror(parser, "failed to allocate function for `%s`", var->name);
@@ -4012,6 +4006,12 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
     }
     vec_push(parser->functions, func);
 
+    if (var->argcounter) {
+        ast_value *argc = ast_value_new(ast_ctx(var), var->argcounter, TYPE_FLOAT);
+        parser_addlocal(parser, argc->name, (ast_expression*)argc);
+        func->argc = argc;
+    }
+
     if (var->expression.flags & AST_FLAG_VARIADIC) {
         char name[1024];
         ast_value *varargs = ast_value_new(ast_ctx(var), "reserved:va_args", TYPE_ARRAY);