From a01388ea7dc38a8d895488e63d0ec9d875159156 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Sat, 12 Jan 2013 15:06:19 +0100 Subject: [PATCH] Copying arg counter into the local --- ast.c | 24 +++++++++++++++++++++--- ast.h | 1 + parser.c | 12 ++++++------ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/ast.c b/ast.c index ebded6a..ddbffb9 100644 --- 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 6588422..2e9858f 100644 --- 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 */ diff --git a/parser.c b/parser.c index 84c3e09..32e9427 100644 --- 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); -- 2.39.2