From 1410840ef60e16fd3ed989dd79c79ba2df8ee773 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Thu, 17 Jan 2013 10:30:32 +0100 Subject: [PATCH] Make the varargs counter more stable, it'll now work with a function pointer with a different number of fixed params --- ast.c | 21 +++++++++++++++++---- ast.h | 1 + parser.c | 9 +++------ 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/ast.c b/ast.c index 5a553cf..108489f 100644 --- a/ast.c +++ b/ast.c @@ -348,7 +348,7 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t) self->getter = NULL; self->desc = NULL; - self->argcounter = NULL; + self->argcounter = NULL; return self; } @@ -1083,8 +1083,9 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype) vtype->hasvalue = true; vtype->constval.vfunc = self; - self->varargs = NULL; - self->argc = NULL; + self->varargs = NULL; + self->argc = NULL; + self->fixedparams = NULL; return self; } @@ -1112,6 +1113,8 @@ void ast_function_delete(ast_function *self) ast_delete(self->varargs); if (self->argc) ast_delete(self->argc); + if (self->fixedparams) + ast_unref(self->fixedparams); mem_d(self); } @@ -1612,13 +1615,23 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) if (self->argc) { ir_value *va_count; + ir_value *fixed; + ir_value *sub; 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; + cgen = self->fixedparams->expression.codegen; + if (!(*cgen)((ast_expression*)(self->fixedparams), self, false, &fixed)) + return false; + sub = ir_block_create_binop(self->curblock, ast_ctx(self), + ast_function_label(self, "va_count"), INSTR_SUB_F, + ir_builder_get_va_count(ir), fixed); + if (!sub) + return false; if (!ir_block_create_store_op(self->curblock, ast_ctx(self), INSTR_STORE_F, - va_count, ir_builder_get_va_count(ir))) + va_count, sub)) { return false; } diff --git a/ast.h b/ast.h index 2e9858f..94f388e 100644 --- a/ast.h +++ b/ast.h @@ -648,6 +648,7 @@ struct ast_function_s ast_value *varargs; ast_value *argc; + ast_value *fixedparams; }; 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 2616081..f5891e7 100644 --- a/parser.c +++ b/parser.c @@ -1450,12 +1450,7 @@ static bool parser_close_call(parser_t *parser, shunt *sy) if ((fun->expression.flags & AST_FLAG_VARIADIC) && !(/*funval->cvq == CV_CONST && */ funval->hasvalue && funval->constval.vfunc->builtin)) { - size_t va_count; - if (paramcount < vec_size(fun->expression.params)) - va_count = 0; - else - va_count = paramcount - vec_size(fun->expression.params); - call->va_count = (ast_expression*)parser_const_float(parser, (double)va_count); + call->va_count = (ast_expression*)parser_const_float(parser, (double)paramcount); } } @@ -4065,6 +4060,8 @@ static bool parse_function_body(parser_t *parser, ast_value *var) goto enderrfn; } func->varargs = varargs; + + func->fixedparams = parser_const_float(parser, vec_size(var->expression.params)); } parser->function = func; -- 2.39.2