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
#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

View file

@ -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;

View file

@ -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 ();

View file

@ -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)

View file

@ -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

View file

@ -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);

View file

@ -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 ();

View file

@ -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;

View file

@ -42,6 +42,7 @@ static const char rcsid[] =
#include <stdlib.h>
#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;