mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
fix a silly segfault and make statement allocation saner
This commit is contained in:
parent
c1894db59f
commit
2cb6138f2b
9 changed files with 103 additions and 75 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue