From 2cb6138f2b9c89f5655096ba239d458253a077ba Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 8 Jul 2002 20:31:59 +0000 Subject: [PATCH] fix a silly segfault and make statement allocation saner --- tools/qfcc/include/emit.h | 13 ++++++++ tools/qfcc/include/qfcc.h | 4 +-- tools/qfcc/source/class.c | 3 +- tools/qfcc/source/emit.c | 57 +++++++++++++++++++++++++++--------- tools/qfcc/source/linker.c | 40 ++++++++----------------- tools/qfcc/source/obj_file.c | 15 +++++----- tools/qfcc/source/qc-parse.y | 3 +- tools/qfcc/source/qfcc.c | 28 +++++++++--------- tools/qfcc/source/reloc.c | 15 +++++----- 9 files changed, 103 insertions(+), 75 deletions(-) diff --git a/tools/qfcc/include/emit.h b/tools/qfcc/include/emit.h index 1419d323d..daee60c61 100644 --- a/tools/qfcc/include/emit.h +++ b/tools/qfcc/include/emit.h @@ -32,8 +32,21 @@ #ifndef __emit_h #define __emit_h +typedef struct codespace_s { + struct statement_s *code; + int size; + int max_size; +} codespace_t; + +codespace_t *codespace_new (void); +void codespace_delete (codespace_t *codespace); +void codespace_addcode (codespace_t *codespace, struct statement_s *code, + int size); +struct statement_s *codespace_newstatement (codespace_t *codespace); + struct expr_s; struct def_s *emit_statement (struct expr_s *e, opcode_t *op, struct def_s *var_a, struct def_s *var_b, struct def_s *var_c); +struct def_s *emit_sub_expr (struct expr_s*e, struct def_s *dest); void emit_expr (struct expr_s *e); #endif//__emit_h diff --git a/tools/qfcc/include/qfcc.h b/tools/qfcc/include/qfcc.h index 507298c99..229f789c4 100644 --- a/tools/qfcc/include/qfcc.h +++ b/tools/qfcc/include/qfcc.h @@ -50,9 +50,7 @@ typedef struct pr_info_s { struct strpool_s *strings; - dstatement_t *statements; - int num_statements; - int statements_size; + struct codespace_s *code; struct function_s *func_head; struct function_s **func_tail; diff --git a/tools/qfcc/source/class.c b/tools/qfcc/source/class.c index f3eded796..3fd42684e 100644 --- a/tools/qfcc/source/class.c +++ b/tools/qfcc/source/class.c @@ -50,6 +50,7 @@ static const char rcsid[] = #include "class.h" #include "def.h" +#include "emit.h" #include "expr.h" #include "immediate.h" #include "method.h" @@ -494,7 +495,7 @@ class_finish_module (void) init_func = new_function (".ctor"); init_func->def = init_def; init_func->refs = new_reloc (init_def->ofs, rel_def_func); - init_func->code = pr.num_statements; + init_func->code = pr.code->size; build_scope (init_func, init_def, 0); build_function (init_func); init_expr = new_block_expr (); diff --git a/tools/qfcc/source/emit.c b/tools/qfcc/source/emit.c index ebe477fd5..968af7985 100644 --- a/tools/qfcc/source/emit.c +++ b/tools/qfcc/source/emit.c @@ -56,15 +56,50 @@ static const char rcsid[] = #include "type.h" #include "qc-parse.h" -def_t *emit_sub_expr (expr_t *e, def_t *dest); - static expr_t zero; +codespace_t * +codespace_new (void) +{ + return calloc (1, sizeof (codespace_t)); +} + +void +codespace_delete (codespace_t *codespace) +{ + free (codespace->code); + free (codespace); +} + +void +codespace_addcode (codespace_t *codespace, dstatement_t *code, int size) +{ + if (codespace->size + size > codespace->max_size) { + codespace->max_size = (codespace->size + size + 16383) & ~16383; + codespace->code = realloc (codespace->code, + codespace->max_size * sizeof (dstatement_t)); + } + memcpy (codespace->code + codespace->size, code, + size * sizeof (dstatement_t)); + codespace->size += size; +} + +dstatement_t * +codespace_newstatement (codespace_t *codespace) +{ + if (codespace->size >= codespace->max_size) { + codespace->max_size += 16384; + codespace->code = realloc (codespace->code, + codespace->max_size * sizeof (dstatement_t)); + } + return codespace->code + codespace->size++; +} + void add_statement_ref (def_t *def, dstatement_t *st, reloc_type type) { if (def) { - reloc_t *ref = new_reloc (st - pr.statements, type); + reloc_t *ref = new_reloc (st - pr.code->code, type); ref->next = def->refs; def->refs = ref; @@ -86,22 +121,16 @@ emit_statement (expr_t *e, opcode_t *op, def_t *var_a, def_t *var_b, abort (); } if (options.code.debug) { - int line = e->line - lineno_base; + int line = (e ? e->line : pr.source_line) - lineno_base; if (line != linenos[num_linenos - 1].line) { pr_lineno_t *lineno = new_lineno (); lineno->line = line; - lineno->fa.addr = pr.num_statements; + lineno->fa.addr = pr.code->size; } } - if (pr.num_statements >= pr.statements_size) { - pr.statements_size += 16384; - pr.statements = realloc (pr.statements, - pr.statements_size * sizeof (dstatement_t)); - } - statement = &pr.statements[pr.num_statements]; - pr.num_statements++; + statement = codespace_newstatement (pr.code); statement->op = op->opcode; statement->a = var_a ? var_a->ofs : 0; statement->b = var_b ? var_b->ofs : 0; @@ -148,7 +177,7 @@ emit_branch (expr_t *_e, opcode_t *op, expr_t *e, expr_t *l) if (e) def = emit_sub_expr (e, 0); - st = &pr.statements[ofs = pr.num_statements]; + st = &pr.code->code[ofs = pr.code->size]; emit_statement (_e, op, def, 0, 0); if (l->e.label.ofs) { if (op == op_goto) @@ -512,7 +541,7 @@ emit_expr (expr_t *e) break; case ex_label: label = &e->e.label; - label->ofs = pr.num_statements; + label->ofs = pr.code->size; break; case ex_block: for (e = e->e.block.head; e; e = e->next) diff --git a/tools/qfcc/source/linker.c b/tools/qfcc/source/linker.c index fa1a3789c..8719e4903 100644 --- a/tools/qfcc/source/linker.c +++ b/tools/qfcc/source/linker.c @@ -44,6 +44,7 @@ static const char rcsid[] = #include "QF/hash.h" #include "def.h" +#include "emit.h" #include "expr.h" #include "immediate.h" #include "obj_file.h" @@ -52,6 +53,8 @@ static const char rcsid[] = static hashtab_t *extern_defs; static hashtab_t *defined_defs; +static strpool_t *strings; +static strpool_t *type_strings; static const char * defs_get_key (void *_def, void *unused) @@ -64,16 +67,6 @@ defs_get_key (void *_def, void *unused) void add_code (qfo_t *qfo) { - int num_statements = pr.num_statements; - - pr.num_statements += qfo->code_size; - if (pr.num_statements >= pr.statements_size) { - pr.statements_size = (pr.num_statements + 16383) & ~16383; - pr.statements = realloc (pr.statements, - pr.statements_size * sizeof (dstatement_t)); - } - memcpy (pr.statements + num_statements, qfo->code, - qfo->code_size * sizeof (dstatement_t)); } void @@ -83,9 +76,10 @@ add_defs (qfo_t *qfo) qfo_def_t *d; for (def = qfo->defs; def - qfo->defs < qfo->num_defs; def++) { - def->full_type = ReuseString (qfo->strings + def->full_type); - def->name = ReuseString (qfo->strings + def->name); - def->file = ReuseString (qfo->strings + def->file); + def->full_type = strpool_addstr (type_strings, + qfo->strings + def->full_type); + def->name = strpool_addstr (strings, qfo->strings + def->name); + def->file = strpool_addstr (strings, qfo->strings + def->file); if (def->flags & QFOD_EXTERNAL) { Hash_Add (extern_defs, def); } else { @@ -99,7 +93,7 @@ add_defs (qfo_t *qfo) if (def->basic_type == ev_string && def->ofs && QFO_var (qfo, string, def->ofs)) { string_t s; - s = ReuseString (QFO_STRING (qfo, def->ofs)); + s = strpool_addstr (strings, QFO_STRING (qfo, def->ofs)); QFO_var (qfo, string, def->ofs) = s; } if (def->ofs) @@ -128,10 +122,10 @@ add_functions (qfo_t *qfo) for (func = qfo->functions; func - qfo->functions < qfo->num_functions; func++) { - func->name = ReuseString (qfo->strings + func->name); - func->file = ReuseString (qfo->strings + func->file); + func->name = strpool_addstr (strings, qfo->strings + func->name); + func->file = strpool_addstr (strings, qfo->strings + func->file); if (func->code) - func->code += pr.num_statements; + func->code += pr.code->size; } } @@ -140,16 +134,8 @@ linker_begin (void) { extern_defs = Hash_NewTable (16381, defs_get_key, 0, 0); defined_defs = Hash_NewTable (16381, defs_get_key, 0, 0); - if (pr.statements) - free (pr.statements); - memset (&pr, 0, sizeof (pr)); - pr.num_statements = 1; - pr.statements_size = 16384; - pr.statements = calloc (pr.statements_size, sizeof (dstatement_t)); - pr.strings = strpool_new (); - pr.num_functions = 1; - pr.near_data = new_defspace (); - pr.near_data->data = calloc (65536, sizeof (pr_type_t)); + strings = strpool_new (); + type_strings = strpool_new (); } void diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index b9545b585..a01839676 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -47,6 +47,7 @@ static const char rcsid[] = #include "debug.h" #include "def.h" +#include "emit.h" #include "function.h" #include "immediate.h" #include "obj_file.h" @@ -199,7 +200,7 @@ setup_data (void) for (d = f->scope->head; d; d = d->def_next) write_def (d, def++, &reloc); } - for (st = pr.statements; st - pr.statements < pr.num_statements; st++) { + for (st = pr.code->code; st - pr.code->code < pr.code->size; st++) { st->op = LittleLong (st->op); st->a = LittleLong (st->a); st->b = LittleLong (st->b); @@ -237,7 +238,7 @@ write_obj_file (const char *filename) memcpy (hdr.qfo, QFO, sizeof (hdr.qfo)); hdr.version = LittleLong (QFO_VERSION); - hdr.code_size = LittleLong (pr.num_statements); + hdr.code_size = LittleLong (pr.code->size); hdr.data_size = LittleLong (pr.near_data->size); if (pr.far_data) { hdr.far_data_size = LittleLong (pr.far_data->size); @@ -250,8 +251,8 @@ write_obj_file (const char *filename) hdr.types_size = LittleLong (types->size); Qwrite (file, &hdr, sizeof (hdr)); - if (pr.num_statements) - Qwrite (file, pr.statements, pr.num_statements * sizeof (dstatement_t)); + if (pr.code->size) + Qwrite (file, pr.code->code, pr.code->size * sizeof (dstatement_t)); if (pr.near_data->size) Qwrite (file, pr.near_data->data, pr.near_data->size * sizeof (pr_type_t)); @@ -439,10 +440,8 @@ qfo_to_progs (qfo_t *qfo, pr_info_t *pr) pr->strings = strpool_build (qfo->strings, qfo->strings_size); - pr->num_statements = pr->statements_size = qfo->code_size; - pr->statements = malloc (pr->statements_size * sizeof (dstatement_t)); - memcpy (pr->statements, qfo->code, - pr->statements_size * sizeof (dstatement_t)); + pr->code = codespace_new (); + codespace_addcode (pr->code, qfo->code, qfo->code_size); pr->near_data = init_space (qfo->data_size, qfo->data); pr->far_data = init_space (qfo->far_data_size, qfo->far_data); diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 031ae8e17..b1686f82c 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -48,6 +48,7 @@ static const char rcsid[] = #include "class.h" #include "debug.h" #include "def.h" +#include "emit.h" #include "expr.h" #include "function.h" #include "immediate.h" @@ -486,7 +487,7 @@ begin_function $$ = current_func = new_function (current_def->name); $$->def = current_def; $$->refs = new_reloc ($$->def->ofs, rel_def_func); - $$->code = pr.num_statements; + $$->code = pr.code->size; if (options.code.debug) { pr_lineno_t *lineno = new_lineno (); $$->aux = new_auxfunction (); diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index f01e2e5de..841d42def 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -67,6 +67,7 @@ static const char rcsid[] = #include "cpp.h" #include "debug.h" #include "def.h" +#include "emit.h" #include "expr.h" #include "function.h" #include "idstuff.h" @@ -126,17 +127,16 @@ InitData (void) { int i; - if (pr.statements) { - free (pr.statements); + if (pr.code) { + codespace_delete (pr.code); strpool_delete (pr.strings); - memset (&pr, 0, sizeof (pr)); } + memset (&pr, 0, sizeof (pr)); chain_initial_types (); pr.source_line = 1; pr.error_count = 0; - pr.num_statements = 1; - pr.statements_size = 16384; - pr.statements = calloc (pr.statements_size, sizeof (dstatement_t)); + pr.code = codespace_new (); + memset (codespace_newstatement (pr.code), 0, sizeof (dstatement_t)); pr.strings = strpool_new (); pr.num_functions = 1; @@ -197,7 +197,7 @@ WriteData (int crc) if (options.verbosity >= 0) { printf ("%6i strofs\n", pr.strings->size); - printf ("%6i statements\n", pr.num_statements); + printf ("%6i statements\n", pr.code->size); printf ("%6i functions\n", pr.num_functions); printf ("%6i global defs\n", numglobaldefs); printf ("%6i locals size (%s)\n", num_localdefs, big_function); @@ -214,14 +214,14 @@ WriteData (int crc) SafeWrite (h, pr.strings->strings, pr.strings->size); progs.ofs_statements = ftell (h); - progs.numstatements = pr.num_statements; - for (i = 0; i < pr.num_statements; i++) { - pr.statements[i].op = LittleShort (pr.statements[i].op); - pr.statements[i].a = LittleShort (pr.statements[i].a); - pr.statements[i].b = LittleShort (pr.statements[i].b); - pr.statements[i].c = LittleShort (pr.statements[i].c); + progs.numstatements = pr.code->size; + for (i = 0; i < pr.code->size; i++) { + pr.code->code[i].op = LittleShort (pr.code->code[i].op); + pr.code->code[i].a = LittleShort (pr.code->code[i].a); + pr.code->code[i].b = LittleShort (pr.code->code[i].b); + pr.code->code[i].c = LittleShort (pr.code->code[i].c); } - SafeWrite (h, pr.statements, pr.num_statements * sizeof (dstatement_t)); + SafeWrite (h, pr.code->code, pr.code->size * sizeof (dstatement_t)); { dfunction_t *df; diff --git a/tools/qfcc/source/reloc.c b/tools/qfcc/source/reloc.c index 069f32cf8..9e72fa9ba 100644 --- a/tools/qfcc/source/reloc.c +++ b/tools/qfcc/source/reloc.c @@ -42,6 +42,7 @@ static const char rcsid[] = #include #include "def.h" +#include "emit.h" #include "expr.h" #include "qfcc.h" #include "reloc.h" @@ -61,43 +62,43 @@ relocate_refs (reloc_t *refs, int ofs) if (ofs > 65535) error (0, "def offset too large"); else - pr.statements[refs->ofs].a = ofs; + pr.code->code[refs->ofs].a = ofs; break; case rel_op_b_def: if (ofs > 65535) error (0, "def offset too large"); else - pr.statements[refs->ofs].b = ofs; + pr.code->code[refs->ofs].b = ofs; break; case rel_op_c_def: if (ofs > 65535) error (0, "def offset too large"); else - pr.statements[refs->ofs].c = ofs; + pr.code->code[refs->ofs].c = ofs; break; case rel_op_a_op: o = ofs - refs->ofs; if (o < -32768 || o > 32767) error (0, "relative offset too large"); else - pr.statements[refs->ofs].a = o; + pr.code->code[refs->ofs].a = o; break; case rel_op_b_op: o = ofs - refs->ofs; if (o < -32768 || o > 32767) error (0, "relative offset too large"); else - pr.statements[refs->ofs].b = o; + pr.code->code[refs->ofs].b = o; break; case rel_op_c_op: o = ofs - refs->ofs; if (o < -32768 || o > 32767) error (0, "relative offset too large"); else - pr.statements[refs->ofs].c = o; + pr.code->code[refs->ofs].c = o; break; case rel_def_op: - if (ofs >= pr.num_statements) + if (ofs >= pr.code->size) error (0, "invalid statement offset"); else G_INT (refs->ofs) = ofs;