ast_call now has a va_count which causes a store to reserved:va_count before the call

This commit is contained in:
Wolfgang Bumiller 2013-01-12 13:29:47 +01:00
parent 6dfdf69a8e
commit 973122ed9b
4 changed files with 33 additions and 3 deletions

22
ast.c
View file

@ -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));

2
ast.h
View file

@ -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);

9
ir.c
View file

@ -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);

3
ir.h
View file

@ -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*, ...));