diff --git a/tools/qfcc/include/defspace.h b/tools/qfcc/include/defspace.h index 1152bf5a5..c48bd6552 100644 --- a/tools/qfcc/include/defspace.h +++ b/tools/qfcc/include/defspace.h @@ -222,6 +222,8 @@ int defspace_alloc_aligned_highwater (defspace_t *space, int size, */ void defspace_reset (defspace_t *space); +void defspace_sort_defs (defspace_t *space); + ///@} #endif//__defspace_h diff --git a/tools/qfcc/source/defspace.c b/tools/qfcc/source/defspace.c index 97333dae6..356c481a4 100644 --- a/tools/qfcc/source/defspace.c +++ b/tools/qfcc/source/defspace.c @@ -317,3 +317,33 @@ defspace_reset (defspace_t *space) memset (space->data, 0, space->max_size * sizeof (pr_type_t)); } } + +void +defspace_sort_defs (defspace_t *space) +{ + int num_defs = 0; + for (auto d = space->defs; d; d = d->next) { + num_defs++; + } + if (!num_defs) { + return; + } + def_t *defs[num_defs]; + num_defs = 0; + for (auto d = space->defs; d; d = d->next) { + defs[num_defs++] = d; + } + for (int i = 1; i < num_defs; i++) { + auto d = defs[i]; + for (int j = i; j-- > 0 && d->offset < defs[j]->offset; ) { + defs[j + 1] = defs[j]; + defs[j] = d; + } + } + space->def_tail = &space->defs; + for (int i = 0; i < num_defs; i++) { + *space->def_tail = defs[i]; + space->def_tail = &defs[i]->next; + } + *space->def_tail = 0; +} diff --git a/tools/qfcc/source/function.c b/tools/qfcc/source/function.c index 57de54a16..5f0e00cff 100644 --- a/tools/qfcc/source/function.c +++ b/tools/qfcc/source/function.c @@ -790,6 +790,8 @@ build_code_function (symbol_t *fsym, expr_t *state_expr, expr_t *statements) } } emit_function (func, statements); + defspace_sort_defs (func->parameters->space); + defspace_sort_defs (func->locals->space); if (options.code.progsversion < PROG_VERSION) { // stitch parameter and locals data together with parameters coming // first diff --git a/tools/qfcc/source/linker.c b/tools/qfcc/source/linker.c index 8d04f4ef5..405c826b3 100644 --- a/tools/qfcc/source/linker.c +++ b/tools/qfcc/source/linker.c @@ -502,7 +502,7 @@ add_defs (qfo_t *qfo, qfo_mspace_t *space, qfo_mspace_t *dest_space, odef->file = linker_add_string (QFOSTR (qfo, idef->file)); idef->file = -1; // mark def as copied idef->line = num_work_defrefs; // so def can be found - // In the first passs, process_type_def sets the type meta to -1 and + // In the first pass, process_type_def sets the type meta to -1 and // class to the offset of the copied type, but the null type encodiing // is not modified. Other defs are processed in the second pass. type = QFOTYPE(idef->type); @@ -1293,6 +1293,19 @@ check_defs (void) free (undef_defs); } +static void +sort_defs (qfo_mspace_t *space) +{ + qfo_def_t *defs = space->defs; + for (pr_uint_t i = 1; i < space->num_defs; i++) { + qfo_def_t d = defs[i]; + for (pr_uint_t j = i; j-- > 0 && d.offset < defs[j].offset; ) { + defs[j + 1] = defs[j]; + defs[j] = d; + } + } +} + static qfo_t * build_qfo (void) { @@ -1305,6 +1318,9 @@ build_qfo (void) qfo = qfo_new (); qfo->spaces = calloc (work->num_spaces, sizeof (qfo_mspace_t)); qfo->num_spaces = work->num_spaces; + for (i = qfo_near_data_space; i <= qfo_entity_space; i++) { + sort_defs (&qfo->spaces[i]); + } for (i = 0; i < work->num_spaces; i++) { qfo->spaces[i].type = work->spaces[i].type; qfo->spaces[i].id = work->spaces[i].id; diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index 20db53372..01486c751 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -326,6 +326,10 @@ qfo_from_progs (pr_info_t *pr) qfo_reloc_t *reloc; reloc_t *r; + defspace_sort_defs (pr->near_data); + defspace_sort_defs (pr->far_data); + defspace_sort_defs (pr->entity_data); + qfo = calloc (1, sizeof (qfo_t)); qfo->num_spaces = qfo_num_spaces; // certain spaces are always present qfo_count_stuff (qfo, pr); diff --git a/tools/qfcc/source/stub.c b/tools/qfcc/source/stub.c index 97cc063c2..b5ba751c3 100644 --- a/tools/qfcc/source/stub.c +++ b/tools/qfcc/source/stub.c @@ -63,6 +63,7 @@ __attribute__((const)) symbol_t *new_symbol_type (const char *name, type_t *type __attribute__((const)) def_t *qfo_encode_type (type_t *type, defspace_t *space) {return 0;} __attribute__((const)) int obj_types_assignable (const type_t *dst, const type_t *src) {return 0;} void print_protocollist (struct dstring_s *dstr, protocollist_t *protocollist) {} +void defspace_sort_defs (defspace_t *space) {} int is_id (const type_t *type){return type->type;} int is_SEL (const type_t *type){return 0;} int is_Class (const type_t *type){return 0;}