mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-27 06:02:22 +00:00
ast_call now has a va_count which causes a store to reserved:va_count before the call
This commit is contained in:
parent
6dfdf69a8e
commit
973122ed9b
4 changed files with 33 additions and 3 deletions
22
ast.c
22
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));
|
||||
|
|
2
ast.h
2
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);
|
||||
|
|
9
ir.c
9
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);
|
||||
|
|
3
ir.h
3
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*, ...));
|
||||
|
|
Loading…
Reference in a new issue