fix a silly segfault and make statement allocation saner

This commit is contained in:
Bill Currie 2002-07-08 20:31:59 +00:00
parent c1894db59f
commit 2cb6138f2b
9 changed files with 103 additions and 75 deletions

View file

@ -32,8 +32,21 @@
#ifndef __emit_h #ifndef __emit_h
#define __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 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_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); void emit_expr (struct expr_s *e);
#endif//__emit_h #endif//__emit_h

View file

@ -50,9 +50,7 @@ typedef struct pr_info_s {
struct strpool_s *strings; struct strpool_s *strings;
dstatement_t *statements; struct codespace_s *code;
int num_statements;
int statements_size;
struct function_s *func_head; struct function_s *func_head;
struct function_s **func_tail; struct function_s **func_tail;

View file

@ -50,6 +50,7 @@ static const char rcsid[] =
#include "class.h" #include "class.h"
#include "def.h" #include "def.h"
#include "emit.h"
#include "expr.h" #include "expr.h"
#include "immediate.h" #include "immediate.h"
#include "method.h" #include "method.h"
@ -494,7 +495,7 @@ class_finish_module (void)
init_func = new_function (".ctor"); init_func = new_function (".ctor");
init_func->def = init_def; init_func->def = init_def;
init_func->refs = new_reloc (init_def->ofs, rel_def_func); 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_scope (init_func, init_def, 0);
build_function (init_func); build_function (init_func);
init_expr = new_block_expr (); init_expr = new_block_expr ();

View file

@ -56,15 +56,50 @@ static const char rcsid[] =
#include "type.h" #include "type.h"
#include "qc-parse.h" #include "qc-parse.h"
def_t *emit_sub_expr (expr_t *e, def_t *dest);
static expr_t zero; 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 void
add_statement_ref (def_t *def, dstatement_t *st, reloc_type type) add_statement_ref (def_t *def, dstatement_t *st, reloc_type type)
{ {
if (def) { 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; ref->next = def->refs;
def->refs = ref; def->refs = ref;
@ -86,22 +121,16 @@ emit_statement (expr_t *e, opcode_t *op, def_t *var_a, def_t *var_b,
abort (); abort ();
} }
if (options.code.debug) { 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) { if (line != linenos[num_linenos - 1].line) {
pr_lineno_t *lineno = new_lineno (); pr_lineno_t *lineno = new_lineno ();
lineno->line = line; lineno->line = line;
lineno->fa.addr = pr.num_statements; lineno->fa.addr = pr.code->size;
} }
} }
if (pr.num_statements >= pr.statements_size) { statement = codespace_newstatement (pr.code);
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->op = op->opcode; statement->op = op->opcode;
statement->a = var_a ? var_a->ofs : 0; statement->a = var_a ? var_a->ofs : 0;
statement->b = var_b ? var_b->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) if (e)
def = emit_sub_expr (e, 0); 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); emit_statement (_e, op, def, 0, 0);
if (l->e.label.ofs) { if (l->e.label.ofs) {
if (op == op_goto) if (op == op_goto)
@ -512,7 +541,7 @@ emit_expr (expr_t *e)
break; break;
case ex_label: case ex_label:
label = &e->e.label; label = &e->e.label;
label->ofs = pr.num_statements; label->ofs = pr.code->size;
break; break;
case ex_block: case ex_block:
for (e = e->e.block.head; e; e = e->next) for (e = e->e.block.head; e; e = e->next)

View file

@ -44,6 +44,7 @@ static const char rcsid[] =
#include "QF/hash.h" #include "QF/hash.h"
#include "def.h" #include "def.h"
#include "emit.h"
#include "expr.h" #include "expr.h"
#include "immediate.h" #include "immediate.h"
#include "obj_file.h" #include "obj_file.h"
@ -52,6 +53,8 @@ static const char rcsid[] =
static hashtab_t *extern_defs; static hashtab_t *extern_defs;
static hashtab_t *defined_defs; static hashtab_t *defined_defs;
static strpool_t *strings;
static strpool_t *type_strings;
static const char * static const char *
defs_get_key (void *_def, void *unused) defs_get_key (void *_def, void *unused)
@ -64,16 +67,6 @@ defs_get_key (void *_def, void *unused)
void void
add_code (qfo_t *qfo) 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 void
@ -83,9 +76,10 @@ add_defs (qfo_t *qfo)
qfo_def_t *d; qfo_def_t *d;
for (def = qfo->defs; def - qfo->defs < qfo->num_defs; def++) { for (def = qfo->defs; def - qfo->defs < qfo->num_defs; def++) {
def->full_type = ReuseString (qfo->strings + def->full_type); def->full_type = strpool_addstr (type_strings,
def->name = ReuseString (qfo->strings + def->name); qfo->strings + def->full_type);
def->file = ReuseString (qfo->strings + def->file); def->name = strpool_addstr (strings, qfo->strings + def->name);
def->file = strpool_addstr (strings, qfo->strings + def->file);
if (def->flags & QFOD_EXTERNAL) { if (def->flags & QFOD_EXTERNAL) {
Hash_Add (extern_defs, def); Hash_Add (extern_defs, def);
} else { } else {
@ -99,7 +93,7 @@ add_defs (qfo_t *qfo)
if (def->basic_type == ev_string && def->ofs if (def->basic_type == ev_string && def->ofs
&& QFO_var (qfo, string, def->ofs)) { && QFO_var (qfo, string, def->ofs)) {
string_t s; 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; QFO_var (qfo, string, def->ofs) = s;
} }
if (def->ofs) if (def->ofs)
@ -128,10 +122,10 @@ add_functions (qfo_t *qfo)
for (func = qfo->functions; func - qfo->functions < qfo->num_functions; for (func = qfo->functions; func - qfo->functions < qfo->num_functions;
func++) { func++) {
func->name = ReuseString (qfo->strings + func->name); func->name = strpool_addstr (strings, qfo->strings + func->name);
func->file = ReuseString (qfo->strings + func->file); func->file = strpool_addstr (strings, qfo->strings + func->file);
if (func->code) 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); extern_defs = Hash_NewTable (16381, defs_get_key, 0, 0);
defined_defs = Hash_NewTable (16381, defs_get_key, 0, 0); defined_defs = Hash_NewTable (16381, defs_get_key, 0, 0);
if (pr.statements) strings = strpool_new ();
free (pr.statements); type_strings = strpool_new ();
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));
} }
void void

View file

@ -47,6 +47,7 @@ static const char rcsid[] =
#include "debug.h" #include "debug.h"
#include "def.h" #include "def.h"
#include "emit.h"
#include "function.h" #include "function.h"
#include "immediate.h" #include "immediate.h"
#include "obj_file.h" #include "obj_file.h"
@ -199,7 +200,7 @@ setup_data (void)
for (d = f->scope->head; d; d = d->def_next) for (d = f->scope->head; d; d = d->def_next)
write_def (d, def++, &reloc); 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->op = LittleLong (st->op);
st->a = LittleLong (st->a); st->a = LittleLong (st->a);
st->b = LittleLong (st->b); st->b = LittleLong (st->b);
@ -237,7 +238,7 @@ write_obj_file (const char *filename)
memcpy (hdr.qfo, QFO, sizeof (hdr.qfo)); memcpy (hdr.qfo, QFO, sizeof (hdr.qfo));
hdr.version = LittleLong (QFO_VERSION); 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); hdr.data_size = LittleLong (pr.near_data->size);
if (pr.far_data) { if (pr.far_data) {
hdr.far_data_size = LittleLong (pr.far_data->size); 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); hdr.types_size = LittleLong (types->size);
Qwrite (file, &hdr, sizeof (hdr)); Qwrite (file, &hdr, sizeof (hdr));
if (pr.num_statements) if (pr.code->size)
Qwrite (file, pr.statements, pr.num_statements * sizeof (dstatement_t)); Qwrite (file, pr.code->code, pr.code->size * sizeof (dstatement_t));
if (pr.near_data->size) if (pr.near_data->size)
Qwrite (file, pr.near_data->data, Qwrite (file, pr.near_data->data,
pr.near_data->size * sizeof (pr_type_t)); 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->strings = strpool_build (qfo->strings, qfo->strings_size);
pr->num_statements = pr->statements_size = qfo->code_size; pr->code = codespace_new ();
pr->statements = malloc (pr->statements_size * sizeof (dstatement_t)); codespace_addcode (pr->code, qfo->code, qfo->code_size);
memcpy (pr->statements, qfo->code,
pr->statements_size * sizeof (dstatement_t));
pr->near_data = init_space (qfo->data_size, qfo->data); pr->near_data = init_space (qfo->data_size, qfo->data);
pr->far_data = init_space (qfo->far_data_size, qfo->far_data); pr->far_data = init_space (qfo->far_data_size, qfo->far_data);

View file

@ -48,6 +48,7 @@ static const char rcsid[] =
#include "class.h" #include "class.h"
#include "debug.h" #include "debug.h"
#include "def.h" #include "def.h"
#include "emit.h"
#include "expr.h" #include "expr.h"
#include "function.h" #include "function.h"
#include "immediate.h" #include "immediate.h"
@ -486,7 +487,7 @@ begin_function
$$ = current_func = new_function (current_def->name); $$ = current_func = new_function (current_def->name);
$$->def = current_def; $$->def = current_def;
$$->refs = new_reloc ($$->def->ofs, rel_def_func); $$->refs = new_reloc ($$->def->ofs, rel_def_func);
$$->code = pr.num_statements; $$->code = pr.code->size;
if (options.code.debug) { if (options.code.debug) {
pr_lineno_t *lineno = new_lineno (); pr_lineno_t *lineno = new_lineno ();
$$->aux = new_auxfunction (); $$->aux = new_auxfunction ();

View file

@ -67,6 +67,7 @@ static const char rcsid[] =
#include "cpp.h" #include "cpp.h"
#include "debug.h" #include "debug.h"
#include "def.h" #include "def.h"
#include "emit.h"
#include "expr.h" #include "expr.h"
#include "function.h" #include "function.h"
#include "idstuff.h" #include "idstuff.h"
@ -126,17 +127,16 @@ InitData (void)
{ {
int i; int i;
if (pr.statements) { if (pr.code) {
free (pr.statements); codespace_delete (pr.code);
strpool_delete (pr.strings); strpool_delete (pr.strings);
memset (&pr, 0, sizeof (pr));
} }
memset (&pr, 0, sizeof (pr));
chain_initial_types (); chain_initial_types ();
pr.source_line = 1; pr.source_line = 1;
pr.error_count = 0; pr.error_count = 0;
pr.num_statements = 1; pr.code = codespace_new ();
pr.statements_size = 16384; memset (codespace_newstatement (pr.code), 0, sizeof (dstatement_t));
pr.statements = calloc (pr.statements_size, sizeof (dstatement_t));
pr.strings = strpool_new (); pr.strings = strpool_new ();
pr.num_functions = 1; pr.num_functions = 1;
@ -197,7 +197,7 @@ WriteData (int crc)
if (options.verbosity >= 0) { if (options.verbosity >= 0) {
printf ("%6i strofs\n", pr.strings->size); 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 functions\n", pr.num_functions);
printf ("%6i global defs\n", numglobaldefs); printf ("%6i global defs\n", numglobaldefs);
printf ("%6i locals size (%s)\n", num_localdefs, big_function); 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); SafeWrite (h, pr.strings->strings, pr.strings->size);
progs.ofs_statements = ftell (h); progs.ofs_statements = ftell (h);
progs.numstatements = pr.num_statements; progs.numstatements = pr.code->size;
for (i = 0; i < pr.num_statements; i++) { for (i = 0; i < pr.code->size; i++) {
pr.statements[i].op = LittleShort (pr.statements[i].op); pr.code->code[i].op = LittleShort (pr.code->code[i].op);
pr.statements[i].a = LittleShort (pr.statements[i].a); pr.code->code[i].a = LittleShort (pr.code->code[i].a);
pr.statements[i].b = LittleShort (pr.statements[i].b); pr.code->code[i].b = LittleShort (pr.code->code[i].b);
pr.statements[i].c = LittleShort (pr.statements[i].c); 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; dfunction_t *df;

View file

@ -42,6 +42,7 @@ static const char rcsid[] =
#include <stdlib.h> #include <stdlib.h>
#include "def.h" #include "def.h"
#include "emit.h"
#include "expr.h" #include "expr.h"
#include "qfcc.h" #include "qfcc.h"
#include "reloc.h" #include "reloc.h"
@ -61,43 +62,43 @@ relocate_refs (reloc_t *refs, int ofs)
if (ofs > 65535) if (ofs > 65535)
error (0, "def offset too large"); error (0, "def offset too large");
else else
pr.statements[refs->ofs].a = ofs; pr.code->code[refs->ofs].a = ofs;
break; break;
case rel_op_b_def: case rel_op_b_def:
if (ofs > 65535) if (ofs > 65535)
error (0, "def offset too large"); error (0, "def offset too large");
else else
pr.statements[refs->ofs].b = ofs; pr.code->code[refs->ofs].b = ofs;
break; break;
case rel_op_c_def: case rel_op_c_def:
if (ofs > 65535) if (ofs > 65535)
error (0, "def offset too large"); error (0, "def offset too large");
else else
pr.statements[refs->ofs].c = ofs; pr.code->code[refs->ofs].c = ofs;
break; break;
case rel_op_a_op: case rel_op_a_op:
o = ofs - refs->ofs; o = ofs - refs->ofs;
if (o < -32768 || o > 32767) if (o < -32768 || o > 32767)
error (0, "relative offset too large"); error (0, "relative offset too large");
else else
pr.statements[refs->ofs].a = o; pr.code->code[refs->ofs].a = o;
break; break;
case rel_op_b_op: case rel_op_b_op:
o = ofs - refs->ofs; o = ofs - refs->ofs;
if (o < -32768 || o > 32767) if (o < -32768 || o > 32767)
error (0, "relative offset too large"); error (0, "relative offset too large");
else else
pr.statements[refs->ofs].b = o; pr.code->code[refs->ofs].b = o;
break; break;
case rel_op_c_op: case rel_op_c_op:
o = ofs - refs->ofs; o = ofs - refs->ofs;
if (o < -32768 || o > 32767) if (o < -32768 || o > 32767)
error (0, "relative offset too large"); error (0, "relative offset too large");
else else
pr.statements[refs->ofs].c = o; pr.code->code[refs->ofs].c = o;
break; break;
case rel_def_op: case rel_def_op:
if (ofs >= pr.num_statements) if (ofs >= pr.code->size)
error (0, "invalid statement offset"); error (0, "invalid statement offset");
else else
G_INT (refs->ofs) = ofs; G_INT (refs->ofs) = ofs;