X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=src%2Fsymbols.c;h=dc4eb53dbd5acbf615c7fa54e17b755be1d36e9f;hb=56a5292888e1d46fe3033cd1d5c636051692453f;hp=91d5f2ed7c0dd92099d3c6df4b50726f27223e6e;hpb=46cb3ffad9e3ed318a9109ff96421882f6642b2b;p=inform.git diff --git a/src/symbols.c b/src/symbols.c index 91d5f2e..dc4eb53 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -1,9 +1,8 @@ /* ------------------------------------------------------------------------- */ /* "symbols" : The symbols table; creating stock of reserved words */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2020 */ -/* */ -/* This file is part of Inform. */ +/* Part of Inform 6.42 */ +/* copyright (c) Graham Nelson 1993 - 2024 */ /* */ /* Inform is free software: you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ @@ -31,24 +30,32 @@ int no_symbols; /* Total number of symbols defined */ int no_named_constants; /* Copied into story file */ /* ------------------------------------------------------------------------- */ -/* Plus six arrays. Each symbol has its own index n (an int32) and */ +/* Plus an array of symbolinfo. Each symbol has its own index n (an */ +/* int32) in the array. The struct there contains: */ /* */ -/* svals[n] is its value (must be 32 bits wide, i.e. an int32, tho' */ -/* it is used to hold an unsigned 16 bit Z-machine value) */ -/* sflags[n] holds flags (see "header.h" for a list) */ -/* stypes[n] is the "type", distinguishing between the data type of */ +/* value is its value. In Z-code, this holds both the 16-bit value */ +/* and the 16-bit backpatch marker, so it is an int32. */ +/* marker is the backpatch marker in Glulx. */ +/* flags holds flags (see "header.h" for a list of ?_SFLAGS) */ +/* type is the "type", distinguishing between the data type of */ /* different kinds of constants/variables. */ -/* (See the "typename()" below.) */ -/* symbs[n] (needs to be cast to (char *) to be used) is the name */ -/* of the symbol, in the same case form as when created. */ -/* slines[n] is the source line on which the symbol value was first */ +/* (A ?_T constant; see the "typename()" below.) */ +/* name is the name of the symbol, in the same case form as */ +/* when created. */ +/* line is the source line on which the symbol value was first */ /* assigned */ -/* symbol_debug_backpatch_positions[n] */ +/* next_entry is the forward link in the symbol hash table. (See */ +/* start_of_list, below.) */ +/* */ +/* When generating a debug file (-k switch), we also allocate an array */ +/* of symboldebuginfo, which contains: */ +/* */ +/* backpatch_pos */ /* is a file position in the debug information file where */ /* the symbol's value should be written after backpatching, */ /* or else the null position if the value was known and */ /* written beforehand */ -/* replacement_debug_backpatch_positions[n] */ +/* replacement_backpatch_pos */ /* is a file position in the debug information file where */ /* the symbol's name can be erased if it is replaced, or */ /* else null if the name will never need to be replaced */ @@ -56,39 +63,33 @@ int no_named_constants; /* Copied into story file */ /* Comparison is case insensitive. */ /* Note that local variable names are not entered into the symbols table, */ /* as their numbers and scope are too limited for this to be efficient. */ -/* ------------------------------------------------------------------------- */ -/* Caveat editor: some array types are set up to work even on machines */ -/* where sizeof(int32 *) differs from, e.g., sizeof(char *): so do not */ -/* alter the types unless you understand what is going on! */ /* ------------------------------------------------------------------------- */ - int32 **symbs; - int32 *svals; - int *smarks; /* Glulx-only */ - brief_location *slines; - int *sflags; -#ifdef VAX - char *stypes; /* In VAX C, insanely, "signed char" is illegal */ -#else - signed char *stypes; -#endif - maybe_file_position *symbol_debug_backpatch_positions; - maybe_file_position *replacement_debug_backpatch_positions; +symbolinfo *symbols; /* Allocated up to no_symbols */ +static memory_list symbols_memlist; +symboldebuginfo *symbol_debug_info; /* Allocated up to no_symbols */ +static memory_list symbol_debug_info_memlist; +static char *temp_symbol_buf; /* used in write_the_identifier_names() */ +static memory_list temp_symbol_buf_memlist; /* ------------------------------------------------------------------------- */ /* Memory to hold the text of symbol names: note that this memory is */ -/* allocated as needed in chunks of size SYMBOLS_CHUNK_SIZE. */ +/* allocated as needed in chunks of size SYMBOLS_CHUNK_SIZE. (Or */ +/* larger, if needed for a particularly enormous symbol.) */ /* ------------------------------------------------------------------------- */ -#define MAX_SYMBOL_CHUNKS (100) +#define SYMBOLS_CHUNK_SIZE (4096) -static uchar *symbols_free_space, /* Next byte free to hold new names */ +static char *symbols_free_space, /* Next byte free to hold new names */ *symbols_ceiling; /* Pointer to the end of the current allocation of memory for names */ static char** symbol_name_space_chunks; /* For chunks of memory used to hold the name strings of symbols */ static int no_symbol_name_space_chunks; +static memory_list symbol_name_space_chunks_memlist; + +/* Symbol replacements (used by the "Replace X Y" directive). */ typedef struct value_pair_struct { int original_symbol; @@ -98,6 +99,18 @@ static value_pair_t *symbol_replacements; static int symbol_replacements_count; static int symbol_replacements_size; /* calloced size */ +/* Symbol definitions requested at compile time. (There may not be any.) + These are set up at command-line parse time, not in init_symbols_vars(). + Similarly, they are not cleaned up by symbols_free_arrays(). */ + +typedef struct keyvalue_pair_struct { + char *symbol; + int32 value; +} keyvalue_pair_t; +static keyvalue_pair_t *symbol_definitions = NULL; +static int symbol_definitions_count = 0; +static int symbol_definitions_size = 0; /* calloced size */ + /* ------------------------------------------------------------------------- */ /* The symbols table is "hash-coded" into a disjoint union of linked */ /* lists, so that for any symbol i, next_entry[i] is either -1 (meaning */ @@ -118,8 +131,8 @@ static int symbol_replacements_size; /* calloced size */ /* idea to choose HASH_TAB_SIZE as large as conveniently possible. */ /* ------------------------------------------------------------------------- */ -static int *next_entry; -static int32 *start_of_list; +static int32 *start_of_list; /* Allocated array of size HASH_TAB_SIZE */ +/* The next_entry field is part of the symbolinfo struct. */ /* ------------------------------------------------------------------------- */ /* Initialisation. */ @@ -171,21 +184,81 @@ extern int strcmpcis(char *p, char *q) return -qc; } +/* ------------------------------------------------------------------------- */ + +extern void add_config_symbol_definition(char *symbol, int32 value) +{ char *str; + + if (symbol_definitions_count == symbol_definitions_size) { + int oldsize = symbol_definitions_size; + if (symbol_definitions_size == 0) + symbol_definitions_size = 4; + else + symbol_definitions_size *= 2; + my_recalloc(&symbol_definitions, sizeof(keyvalue_pair_t), oldsize, + symbol_definitions_size, "symbol definition table"); + } + + str = my_malloc(strlen(symbol)+1, "symbol name"); + strcpy(str, symbol); + + symbol_definitions[symbol_definitions_count].symbol = str; + symbol_definitions[symbol_definitions_count].value = value; + symbol_definitions_count++; +} + /* ------------------------------------------------------------------------- */ /* Symbol finding, creating, and removing. */ /* ------------------------------------------------------------------------- */ -extern int symbol_index(char *p, int hashcode) +extern int get_symbol_index(char *p) { - /* Return the index in the symbs/svals/sflags/stypes/... arrays of symbol - "p", creating a new symbol with that name if it isn't already there. + /* Return the index in the symbols array of symbol "p", or -1 + if it isn't there. Does not create a new symbol or mark the + symbol as used. */ + + int32 new_entry, this; + char *r; + int hashcode = hash_code_from_string(p); + + this = start_of_list[hashcode]; + + do + { if (this == -1) break; + + r = symbols[this].name; + new_entry = strcmpcis(r, p); + if (new_entry == 0) + { + return this; + } + if (new_entry > 0) break; + + this = symbols[this].next_entry; + } while (this != -1); + + return -1; +} + +extern int symbol_index(char *p, int hashcode, int *created) +{ + /* Return the index in the symbols array of symbol "p", creating a + new symbol with that name if it isn't already there. This + always returns a valid symbol index. + + The optional created argument receives TRUE if the symbol + was newly created. + + Pass in the hashcode of p if you know it, or -1 if you don't. New symbols are created with flag UNKNOWN_SFLAG, value 0x100 (a 2-byte quantity in Z-machine terms) and type CONSTANT_T. The string "p" is undamaged. */ - int32 new_entry, this, last; char *r; + int32 new_entry, this, last; + char *r; + int len; if (hashcode == -1) hashcode = hash_code_from_string(p); @@ -194,90 +267,108 @@ extern int symbol_index(char *p, int hashcode) do { if (this == -1) break; - r = (char *)symbs[this]; + r = symbols[this].name; new_entry = strcmpcis(r, p); if (new_entry == 0) { if (track_unused_routines) df_note_function_symbol(this); + if (created) *created = FALSE; return this; } if (new_entry > 0) break; last = this; - this = next_entry[this]; + this = symbols[this].next_entry; } while (this != -1); - if (no_symbols >= MAX_SYMBOLS) - memoryerror("MAX_SYMBOLS", MAX_SYMBOLS); + if (symdef_trace_setting) + printf("%s: Encountered symbol %d '%s'\n", current_location_text(), no_symbols, p); + + ensure_memory_list_available(&symbols_memlist, no_symbols+1); + if (debugfile_switch) + ensure_memory_list_available(&symbol_debug_info_memlist, no_symbols+1); if (last == -1) - { next_entry[no_symbols]=start_of_list[hashcode]; + { symbols[no_symbols].next_entry=start_of_list[hashcode]; start_of_list[hashcode]=no_symbols; } else - { next_entry[no_symbols]=this; - next_entry[last]=no_symbols; + { symbols[no_symbols].next_entry=this; + symbols[last].next_entry=no_symbols; } - if (symbols_free_space+strlen(p)+1 >= symbols_ceiling) - { symbols_free_space - = my_malloc(SYMBOLS_CHUNK_SIZE, "symbol names chunk"); - symbols_ceiling = symbols_free_space + SYMBOLS_CHUNK_SIZE; - /* If we've passed MAX_SYMBOL_CHUNKS chunks, we print an error - message telling the user to increase SYMBOLS_CHUNK_SIZE. - That is the correct cure, even though the error comes out - worded inaccurately. */ - if (no_symbol_name_space_chunks >= MAX_SYMBOL_CHUNKS) - memoryerror("SYMBOLS_CHUNK_SIZE", SYMBOLS_CHUNK_SIZE); + len = strlen(p); + if (!symbols_free_space || symbols_free_space+len+1 >= symbols_ceiling) + { + /* Allocate a new chunk whose size is big enough for the current + symbol, or SYMBOLS_CHUNK_SIZE, whichever is greater. */ + int chunklen = SYMBOLS_CHUNK_SIZE; + if (chunklen < len+1) + chunklen = len+1; + symbols_free_space + = my_malloc(chunklen, "symbol names chunk"); + symbols_ceiling = symbols_free_space + chunklen; + ensure_memory_list_available(&symbol_name_space_chunks_memlist, no_symbol_name_space_chunks+1); symbol_name_space_chunks[no_symbol_name_space_chunks++] - = (char *) symbols_free_space; - if (symbols_free_space+strlen(p)+1 >= symbols_ceiling) - memoryerror("SYMBOLS_CHUNK_SIZE", SYMBOLS_CHUNK_SIZE); + = symbols_free_space; } - strcpy((char *) symbols_free_space, p); - symbs[no_symbols] = (int32 *) symbols_free_space; - symbols_free_space += strlen((char *)symbols_free_space) + 1; + strcpy(symbols_free_space, p); + symbols[no_symbols].name = symbols_free_space; + symbols_free_space += (len+1); - svals[no_symbols] = 0x100; /* ###-wrong? Would this fix the + symbols[no_symbols].value = 0x100; /* ###-wrong? Would this fix the unbound-symbol-causes-asm-error? */ - sflags[no_symbols] = UNKNOWN_SFLAG; - stypes[no_symbols] = CONSTANT_T; - slines[no_symbols] = get_brief_location(&ErrorReport); + symbols[no_symbols].flags = UNKNOWN_SFLAG; + symbols[no_symbols].marker = 0; + symbols[no_symbols].type = CONSTANT_T; + symbols[no_symbols].line = get_brief_location(&ErrorReport); if (debugfile_switch) { nullify_debug_file_position - (&symbol_debug_backpatch_positions[no_symbols]); + (&symbol_debug_info[no_symbols].backpatch_pos); nullify_debug_file_position - (&replacement_debug_backpatch_positions[no_symbols]); + (&symbol_debug_info[no_symbols].replacement_backpatch_pos); } if (track_unused_routines) df_note_function_symbol(no_symbols); + if (created) *created = TRUE; return(no_symbols++); } -extern void end_symbol_scope(int k) +extern void end_symbol_scope(int k, int neveruse) { /* Remove the given symbol from the hash table, making it - invisible to symbol_index. This is used by the Undef directive. - If the symbol is not found, this silently does nothing. + invisible to symbol_index. This is used by the Undef directive + and put_token_back(). + + If you know the symbol has never been used, set neveruse and + it will be flagged as an error if it *is* used. + + If the symbol is not found in the hash table, this silently does + nothing. */ int j; - j = hash_code_from_string((char *) symbs[k]); + + symbols[k].flags |= UNHASHED_SFLAG; + if (neveruse) + symbols[k].flags |= DISCARDED_SFLAG; + + j = hash_code_from_string(symbols[k].name); if (start_of_list[j] == k) - { start_of_list[j] = next_entry[k]; + { start_of_list[j] = symbols[k].next_entry; return; } j = start_of_list[j]; while (j != -1) { - if (next_entry[j] == k) - { next_entry[j] = next_entry[k]; + if (symbols[j].next_entry == k) + { symbols[j].next_entry = symbols[k].next_entry; return; } - j = next_entry[j]; + j = symbols[j].next_entry; } } @@ -305,6 +396,10 @@ extern char *typename(int type) case OBJECT_T: return("Object"); case CLASS_T: return("Class"); case FAKE_ACTION_T: return("Fake action"); + + /* These are not symbol types, but they get printed in errors. */ + case STRING_REQ_T: return("String"); + case DICT_WORD_REQ_T: return("Dictionary word"); default: return("(Unknown type)"); } @@ -312,66 +407,182 @@ extern char *typename(int type) static void describe_flags(int flags) { if (flags & UNKNOWN_SFLAG) printf("(?) "); - if (flags & USED_SFLAG) printf("(used) "); if (flags & REPLACE_SFLAG) printf("(Replaced) "); + if (flags & USED_SFLAG) printf("(used) "); if (flags & DEFCON_SFLAG) printf("(Defaulted) "); if (flags & STUB_SFLAG) printf("(Stubbed) "); + if (flags & UNHASHED_SFLAG) printf("(not in hash chain) "); + if (flags & DISCARDED_SFLAG) printf("(removed, do not use) "); + if (flags & ALIASED_SFLAG) printf("(aliased) "); if (flags & CHANGE_SFLAG) printf("(value will change) "); - if (flags & IMPORT_SFLAG) printf("(Imported) "); - if (flags & EXPORT_SFLAG) printf("(Exported) "); if (flags & SYSTEM_SFLAG) printf("(System) "); if (flags & INSF_SFLAG) printf("(created in sys file) "); if (flags & UERROR_SFLAG) printf("('Unknown' error issued) "); - if (flags & ALIASED_SFLAG) printf("(aliased) "); if (flags & ACTION_SFLAG) printf("(Action name) "); if (flags & REDEFINABLE_SFLAG) printf("(Redefinable) "); + if (flags & STAR_SFLAG) printf("(*) "); } extern void describe_symbol(int k) { printf("%4d %-16s %2d:%04d %04x %s ", - k, (char *) (symbs[k]), - (int)(slines[k].file_index), - (int)(slines[k].line_number), - svals[k], typename(stypes[k])); - describe_flags(sflags[k]); + k, (symbols[k].name), + (int)(symbols[k].line.file_index), + (int)(symbols[k].line.line_number), + symbols[k].value, typename(symbols[k].type)); + describe_flags(symbols[k].flags); } extern void list_symbols(int level) { int k; for (k=0; k=2) || + ((symbols[k].flags & (SYSTEM_SFLAG + UNKNOWN_SFLAG + INSF_SFLAG)) == 0)) { describe_symbol(k); printf("\n"); } } } +/* Check that the operand is of the given symbol type (XXX_T). If wanttype2 is nonzero, that's a second allowable type. + Generate a warning if no match. */ +extern void check_warn_symbol_type(const assembly_operand *AO, int wanttype, int wanttype2, char *context) +{ + symbolinfo *sym; + int symtype; + + if (AO->symindex < 0) + { + /* This argument is not a symbol; it's a local variable, a literal, or a computed expression. */ + /* We can recognize and type-check some literals. */ + if (AO->marker == DWORD_MV) { + if (wanttype != DICT_WORD_REQ_T && wanttype2 != DICT_WORD_REQ_T) + symtype_warning(context, NULL, typename(DICT_WORD_REQ_T), typename(wanttype)); + } + if (AO->marker == STRING_MV) { + if (wanttype != STRING_REQ_T && wanttype2 != STRING_REQ_T) + symtype_warning(context, NULL, typename(STRING_REQ_T), typename(wanttype)); + } + return; + } + + sym = &symbols[AO->symindex]; + symtype = sym->type; + + if (symtype == GLOBAL_VARIABLE_T) + { + /* A global variable could have any value. No way to generate a warning. */ + return; + } + if (symtype == CONSTANT_T) + { + /* A constant could also have any value. This case also includes forward-declared constants (UNKNOWN_SFLAG). */ + /* We try inferring its type by looking at the backpatch marker. Sadly, this only works for objects. (And not in Z-code, where object values are not backpatched.) */ + if (sym->marker == OBJECT_MV) { + /* Continue with inferred type. */ + symtype = OBJECT_T; + } + else { + /* Give up. */ + return; + } + } + + if (!( (symtype == wanttype) + || (wanttype2 != 0 && symtype == wanttype2))) + { + symtype_warning(context, sym->name, typename(symtype), typename(wanttype)); + } +} + +/* Similar, but we allow any type that has a metaclass: Object, Class, String, or Routine. + Generate a warning if no match. */ +extern void check_warn_symbol_has_metaclass(const assembly_operand *AO, char *context) +{ + symbolinfo *sym; + int symtype; + + if (AO->symindex < 0) + { + /* This argument is not a symbol; it's a local variable, a literal, or a computed expression. */ + /* We can recognize and type-check some literals. */ + if (AO->marker == DWORD_MV) { + symtype_warning(context, NULL, typename(DICT_WORD_REQ_T), "Object/Class/Routine/String"); + } + if (AO->marker == STRING_MV) { + /* Strings are good here. */ + } + return; + } + + sym = &symbols[AO->symindex]; + symtype = sym->type; + + if (symtype == GLOBAL_VARIABLE_T) + { + /* A global variable could have any value. No way to generate a warning. */ + return; + } + if (symtype == CONSTANT_T) + { + /* A constant could also have any value. This case also includes forward-declared constants (UNKNOWN_SFLAG). */ + /* We try inferring its type by looking at the backpatch marker. Sadly, this only works for objects. (And not in Z-code, where object values are not backpatched.) */ + if (sym->marker == OBJECT_MV) { + /* Continue with inferred type. */ + symtype = OBJECT_T; + } + else { + /* Give up. */ + return; + } + } + + if (!(symtype == ROUTINE_T || symtype == CLASS_T || symtype == OBJECT_T)) + { + symtype_warning(context, sym->name, typename(symtype), "Object/Class/Routine/String"); + } +} + extern void issue_unused_warnings(void) { int32 i; - if (module_switch) return; - /* Update any ad-hoc variables that might help the library */ if (glulx_mode) { global_initial_value[10]=statusline_flag; } /* Now back to mark anything necessary as used */ - i = symbol_index("Main", -1); - if (!(sflags[i] & UNKNOWN_SFLAG)) sflags[i] |= USED_SFLAG; + i = get_symbol_index("Main"); + if (i >= 0 && !(symbols[i].flags & UNKNOWN_SFLAG)) { + symbols[i].flags |= USED_SFLAG; + } for (i=0;i= 0 && (symbols[value].flags & USED_SFLAG) && !(symbols[value].flags & UNKNOWN_SFLAG)) { + value = get_symbol_index("debug_flag"); + if (value >= 0 && (symbols[value].flags & USED_SFLAG) && (symbols[value].flags & UNKNOWN_SFLAG)) { + warning("DEBUG mode is on, but this story or library does not appear to support it"); + } } } /* ------------------------------------------------------------------------- */ -/* These are arrays used only during story file (never module) creation, */ -/* and not allocated until then. */ +/* These are arrays used only during story file creation, and not */ +/* allocated until just before write_the_identifier_names() time. */ int32 *individual_name_strings; /* Packed addresses of Z-encoded strings of the names of the @@ -382,132 +593,149 @@ extern void issue_unused_warnings(void) int32 *array_name_strings; /* Ditto for arrays */ extern void write_the_identifier_names(void) -{ int i, j, k, t, null_value; char idname_string[256]; +{ int i, j, k, t, null_value; static char unknown_attribute[20] = ""; for (i=0; i"); debug_file_printf - ("##%s", idname_string); - debug_file_printf("%d", svals[i]); + ("##%s", temp_symbol_buf); + debug_file_printf("%d", symbols[i].value); debug_file_printf(""); } - action_name_strings[svals[i]] - = compile_string(idname_string, FALSE, FALSE); + action_name_strings[symbols[i].value] + = compile_string(temp_symbol_buf, STRCTX_SYMBOL); } } for (i=0; i= 0 && symbols[ix].type == ROUTINE_T) { + uint32 addr = symbols[ix].value * (glulx_mode ? 1 : scale_factor); tofunc = df_function_for_address(addr); if (tofunc) tofunc->usage |= DF_USAGE_MAIN; } - ix = symbol_index("Main", -1); - if (stypes[ix] == ROUTINE_T) { - uint32 addr = svals[ix] * (glulx_mode ? 1 : scale_factor); + ix = get_symbol_index("Main"); + if (ix >= 0 && symbols[ix].type == ROUTINE_T) { + uint32 addr = symbols[ix].value * (glulx_mode ? 1 : scale_factor); tofunc = df_function_for_address(addr); if (tofunc) tofunc->usage |= DF_USAGE_MAIN; @@ -1053,18 +1307,20 @@ extern void locate_dead_functions(void) mark them as used. */ func = df_functions_head; - if (!func || func->address != DF_NOT_IN_FUNCTION) + if (!func || func->address != DF_NOT_IN_FUNCTION) { compiler_error("DF: Global namespace entry is not at the head of the chain."); + return; + } for (ent = func->refs; ent; ent=ent->refsnext) { uint32 addr; int symbol = ent->symbol; - if (stypes[symbol] != ROUTINE_T) + if (symbols[symbol].type != ROUTINE_T) continue; - addr = svals[symbol] * (glulx_mode ? 1 : scale_factor); + addr = symbols[symbol].value * (glulx_mode ? 1 : scale_factor); tofunc = df_function_for_address(addr); if (!tofunc) { - error_named("Internal error in stripping: global ROUTINE_T symbol is not found in df_function map:", (char *)symbs[symbol]); + error_named("Internal error in stripping: global ROUTINE_T symbol is not found in df_function map:", symbols[symbol].name); continue; } /* A function may be marked here more than once. That's fine. */ @@ -1116,12 +1372,12 @@ extern void locate_dead_functions(void) for (ent = func->refs; ent; ent=ent->refsnext) { uint32 addr; int symbol = ent->symbol; - if (stypes[symbol] != ROUTINE_T) + if (symbols[symbol].type != ROUTINE_T) continue; - addr = svals[symbol] * (glulx_mode ? 1 : scale_factor); + addr = symbols[symbol].value * (glulx_mode ? 1 : scale_factor); tofunc = df_function_for_address(addr); if (!tofunc) { - error_named("Internal error in stripping: function ROUTINE_T symbol is not found in df_function map:", (char *)symbs[symbol]); + error_named("Internal error in stripping: function ROUTINE_T symbol is not found in df_function map:", symbols[symbol].name); continue; } if (tofunc->usage) @@ -1224,6 +1480,8 @@ uint32 df_stripped_offset_for_code_offset(uint32 offset, int *stripped) { df_function_t *func; int count; + int beg; + int end; if (!track_unused_routines) compiler_error("DF: df_stripped_offset_for_code_offset called, but function references have not been mapped"); @@ -1251,13 +1509,14 @@ uint32 df_stripped_offset_for_code_offset(uint32 offset, int *stripped) /* Do a binary search. Maintain beg <= res < end, where res is the function containing the desired address. */ - int beg = 0; - int end = df_functions_sorted_count; + beg = 0; + end = df_functions_sorted_count; /* Set stripped flag until we decide on a non-stripped function. */ *stripped = TRUE; while (1) { + int new; if (beg >= end) { error("DF: offset_for_code_offset: Could not locate address."); return 0; @@ -1269,7 +1528,7 @@ uint32 df_stripped_offset_for_code_offset(uint32 offset, int *stripped) *stripped = FALSE; return func->newaddress + (offset - func->address); } - int new = (beg + end) / 2; + new = (beg + end) / 2; if (new <= beg || new >= end) compiler_error("DF: binary search went off the rails"); @@ -1327,18 +1586,15 @@ extern uint32 df_next_function_iterate(int *funcused) extern void init_symbols_vars(void) { - symbs = NULL; - svals = NULL; - smarks = NULL; - stypes = NULL; - sflags = NULL; - next_entry = NULL; + symbols = NULL; start_of_list = NULL; + symbol_debug_info = NULL; + temp_symbol_buf = NULL; symbol_name_space_chunks = NULL; no_symbol_name_space_chunks = 0; - symbols_free_space=NULL; - symbols_ceiling=symbols_free_space; + symbols_free_space = NULL; + symbols_ceiling = NULL; no_symbols = 0; @@ -1369,28 +1625,26 @@ extern void symbols_begin_pass(void) extern void symbols_allocate_arrays(void) { - symbs = my_calloc(sizeof(char *), MAX_SYMBOLS, "symbols"); - svals = my_calloc(sizeof(int32), MAX_SYMBOLS, "symbol values"); - if (glulx_mode) - smarks = my_calloc(sizeof(int), MAX_SYMBOLS, "symbol markers"); - slines = my_calloc(sizeof(brief_location), MAX_SYMBOLS, "symbol lines"); - stypes = my_calloc(sizeof(char), MAX_SYMBOLS, "symbol types"); - sflags = my_calloc(sizeof(int), MAX_SYMBOLS, "symbol flags"); + initialise_memory_list(&symbols_memlist, + sizeof(symbolinfo), 6400, (void**)&symbols, + "symbols"); if (debugfile_switch) - { symbol_debug_backpatch_positions = - my_calloc(sizeof(maybe_file_position), MAX_SYMBOLS, - "symbol debug information backpatch positions"); - replacement_debug_backpatch_positions = - my_calloc(sizeof(maybe_file_position), MAX_SYMBOLS, - "replacement debug information backpatch positions"); + { + initialise_memory_list(&symbol_debug_info_memlist, + sizeof(symboldebuginfo), 6400, (void**)&symbol_debug_info, + "symbol debug backpatch info"); } - next_entry = my_calloc(sizeof(int), MAX_SYMBOLS, - "symbol linked-list forward links"); + + initialise_memory_list(&temp_symbol_buf_memlist, + sizeof(char), 64, (void**)&temp_symbol_buf, + "temporary symbol name"); + start_of_list = my_calloc(sizeof(int32), HASH_TAB_SIZE, "hash code list beginnings"); - symbol_name_space_chunks - = my_calloc(sizeof(char *), MAX_SYMBOL_CHUNKS, "symbol names chunk addresses"); + initialise_memory_list(&symbol_name_space_chunks_memlist, + sizeof(char *), 32, (void**)&symbol_name_space_chunks, + "symbol names chunk addresses"); if (track_unused_routines) { df_tables_closed = FALSE; @@ -1431,23 +1685,15 @@ extern void symbols_free_arrays(void) my_free(&(symbol_name_space_chunks[i]), "symbol names chunk"); - my_free(&symbol_name_space_chunks, "symbol names chunk addresses"); + deallocate_memory_list(&symbol_name_space_chunks_memlist); - my_free(&symbs, "symbols"); - my_free(&svals, "symbol values"); - my_free(&smarks, "symbol markers"); - my_free(&slines, "symbol lines"); - my_free(&stypes, "symbol types"); - my_free(&sflags, "symbol flags"); + deallocate_memory_list(&symbols_memlist); if (debugfile_switch) - { my_free - (&symbol_debug_backpatch_positions, - "symbol debug information backpatch positions"); - my_free - (&replacement_debug_backpatch_positions, - "replacement debug information backpatch positions"); + { + deallocate_memory_list(&symbol_debug_info_memlist); } - my_free(&next_entry, "symbol linked-list forward links"); + deallocate_memory_list(&temp_symbol_buf_memlist); + my_free(&start_of_list, "hash code list beginnings"); if (symbol_replacements)