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);
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);
}
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));
#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
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);
self->nil = ir_value_var("nil", store_value, TYPE_NIL);
self->nil->cvq = CV_CONST;
+ self->reserved_va_count = NULL;
+
return self;
}
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);
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);
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*, ...));