From e606913187a6601a7183784c91322344d6a4206d Mon Sep 17 00:00:00 2001 From: "Wolfgang (Blub) Bumiller" Date: Sun, 19 Aug 2012 18:00:53 +0200 Subject: [PATCH] IR generation: for functions: first generate all defs, then the code, so access to prototyped functions doesn't result in NULL code --- ir.c | 42 ++++++++++++++++++++++++++++++++++++++++-- ir.h | 8 ++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/ir.c b/ir.c index 2adaa72..3132685 100644 --- a/ir.c +++ b/ir.c @@ -322,6 +322,8 @@ ir_function* ir_function_new(ir_builder* owner, int outtype) MEM_VECTOR_INIT(self, values); MEM_VECTOR_INIT(self, locals); + self->code_function_def = -1; + self->run_id = 0; return self; } @@ -2580,7 +2582,7 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) local_var_end = fun.firstlocal; for (i = 0; i < irfun->locals_count; ++i) { if (!ir_builder_gen_global(ir, irfun->locals[i])) { - irerror(irfun->locals[i]->context, "Failed to generate local %s\n", irfun->locals[i]->name); + irerror(irfun->locals[i]->context, "Failed to generate local %s", irfun->locals[i]->name); return false; } } @@ -2603,16 +2605,42 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) if (irfun->builtin) fun.entry = irfun->builtin; else { + irfun->code_function_def = code_functions_elements; fun.entry = code_statements_elements; + /* done in second pass: gen_global_function_code! if (!gen_function_code(irfun)) { - irerror(irfun->context, "Failed to generate code for function %s\n", irfun->name); + irerror(irfun->context, "Failed to generate code for function %s", irfun->name); return false; } + */ } return (code_functions_add(fun) >= 0); } +static bool gen_global_function_code(ir_builder *ir, ir_value *global) +{ + prog_section_function *fundef; + ir_function *irfun; + + irfun = global->constval.vfunc; + if (irfun->builtin) + return true; + + if (irfun->code_function_def < 0) { + irerror(irfun->context, "`%s`: IR global wasn't generated, failed to access function-def", irfun->name); + return false; + } + fundef = &code_functions_data[irfun->code_function_def]; + + fundef->entry = code_statements_elements; + if (!gen_function_code(irfun)) { + irerror(irfun->context, "Failed to generate code for function %s", irfun->name); + return false; + } + return true; +} + static bool ir_builder_gen_global(ir_builder *self, ir_value *global) { size_t i; @@ -2793,6 +2821,16 @@ bool ir_builder_generate(ir_builder *self, const char *filename) } } + /* generate function code */ + for (i = 0; i < self->globals_count; ++i) + { + if (self->globals[i]->vtype == TYPE_FUNCTION) { + if (!gen_global_function_code(self, self->globals[i])) { + return false; + } + } + } + printf("writing '%s'...\n", filename); return code_write(filename); } diff --git a/ir.h b/ir.h index 59b4488..dc29e79 100644 --- a/ir.h +++ b/ir.h @@ -260,6 +260,14 @@ typedef struct ir_function_s lex_ctx context; + /* for prototypes - first we generate all the + * globals, and we remember teh function-defs + * so we can later fill in the entry pos + * + * remember the ID: + */ + qcint code_function_def; + /* for temp allocation */ size_t run_id; -- 2.39.2