From: Wolfgang Bumiller Date: Sat, 12 Jan 2013 12:29:47 +0000 (+0100) Subject: ast_call now has a va_count which causes a store to reserved:va_count before the... X-Git-Tag: before-library~294 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=commitdiff_plain;h=973122ed9bc0679d4f9bb0fde90f90d57c17c3d7 ast_call now has a va_count which causes a store to reserved:va_count before the call --- diff --git a/ast.c b/ast.c index 0f5b05c..ef24336 100644 --- a/ast.c +++ b/ast.c @@ -894,8 +894,9 @@ ast_call* ast_call_new(lex_ctx ctx, ast_side_effects(self) = true; - self->params = NULL; - self->func = funcexpr; + self->params = NULL; + self->func = funcexpr; + self->va_count = NULL; ast_type_adopt(self, funcexpr->expression.next); @@ -912,6 +913,9 @@ void ast_call_delete(ast_call *self) if (self->func) ast_unref(self->func); + if (self->va_count) + ast_unref(self->va_count); + ast_expression_delete((ast_expression*)self); mem_d(self); } @@ -3030,6 +3034,20 @@ bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value vec_push(params, param); } + /* varargs counter */ + if (self->va_count) { + ir_value *va_count; + ir_builder *builder = func->curblock->owner->owner; + cgen = self->va_count->expression.codegen; + if (!(*cgen)((ast_expression*)(self->va_count), func, false, &va_count)) + return false; + if (!ir_block_create_store_op(func->curblock, ast_ctx(self), INSTR_STORE_F, + ir_builder_get_va_count(builder), va_count)) + { + return false; + } + } + callinstr = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "call"), funval, !!(self->func->expression.flags & AST_FLAG_NORETURN)); diff --git a/ast.h b/ast.h index 463e6e4..6588422 100644 --- a/ast.h +++ b/ast.h @@ -151,7 +151,6 @@ typedef struct #define AST_FLAG_DEPRECATED (1<<4) #define AST_FLAG_INCLUDE_DEF (1<<5) #define AST_FLAG_IS_VARARG (1<<6) -#define AST_FLAG_VARARG_COUNT (1<<7) #define AST_FLAG_TYPE_MASK (AST_FLAG_VARIADIC | AST_FLAG_NORETURN) /* Value @@ -577,6 +576,7 @@ struct ast_call_s ast_expression_common expression; ast_expression *func; ast_expression* *params; + ast_expression *va_count; }; ast_call* ast_call_new(lex_ctx ctx, ast_expression *funcexpr); diff --git a/ir.c b/ir.c index 5461b44..f743d33 100644 --- a/ir.c +++ b/ir.c @@ -320,6 +320,8 @@ ir_builder* ir_builder_new(const char *modulename) self->nil = ir_value_var("nil", store_value, TYPE_NIL); self->nil->cvq = CV_CONST; + self->reserved_va_count = NULL; + return self; } @@ -418,6 +420,13 @@ ir_value* ir_builder_create_global(ir_builder *self, const char *name, int vtype return ve; } +ir_value* ir_builder_get_va_count(ir_builder *self) +{ + if (self->reserved_va_count) + return self->reserved_va_count; + return (self->reserved_va_count = ir_builder_create_global(self, "reserved:va_count", TYPE_FLOAT)); +} + ir_value* ir_builder_get_field(ir_builder *self, const char *name) { return (ir_value*)util_htget(self->htfields, name); diff --git a/ir.h b/ir.h index 9a953a6..b1b0ea7 100644 --- a/ir.h +++ b/ir.h @@ -328,6 +328,7 @@ typedef struct ir_builder_s qcint str_immediate; /* there should just be this one nil */ ir_value *nil; + ir_value *reserved_va_count; } ir_builder; ir_builder* ir_builder_new(const char *modulename); @@ -343,6 +344,8 @@ ir_value* ir_builder_create_global(ir_builder*, const char *name, int vtype); ir_value* ir_builder_get_field(ir_builder*, const char *fun); ir_value* ir_builder_create_field(ir_builder*, const char *name, int vtype); +ir_value* ir_builder_get_va_count(ir_builder*); + bool ir_builder_generate(ir_builder *self, const char *filename); void ir_builder_dump(ir_builder*, int (*oprintf)(const char*, ...));