X-Git-Url: https://jxself.org/git/?p=inform.git;a=blobdiff_plain;f=src%2Fmemory.c;fp=src%2Fmemory.c;h=bf2eec057c8caa16901d6ff45ab248ff82149eb7;hp=a160788d9b51b3195374afa3d7e5c17e6ed2a0a0;hb=8e63120c630c94c598d4e2d6ba823dac59bce8fa;hpb=d11f2f726ed7feea617476d99cf7505ddd9a27ce diff --git a/src/memory.c b/src/memory.c index a160788..bf2eec0 100644 --- a/src/memory.c +++ b/src/memory.c @@ -1,9 +1,8 @@ /* ------------------------------------------------------------------------- */ /* "memory" : Memory management and ICL memory setting commands */ -/* (For "memoryerror", see "errors.c") */ /* */ -/* Part of Inform 6.35 */ -/* copyright (c) Graham Nelson 1993 - 2021 */ +/* Part of Inform 6.40 */ +/* copyright (c) Graham Nelson 1993 - 2022 */ /* */ /* Inform is free software: you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ @@ -16,70 +15,81 @@ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ -/* along with Inform. If not, see https://gnu.org/licenses/ * +/* along with Inform. If not, see https://gnu.org/licenses/ */ /* */ /* ------------------------------------------------------------------------- */ #include "header.h" -int32 malloced_bytes=0; /* Total amount of memory allocated */ +size_t malloced_bytes=0; /* Total amount of memory allocated */ + +/* Wrappers for malloc(), realloc(), etc. + + Note that all of these functions call memory_out_error() on failure. + This is a fatal error and does not return. However, we check my_malloc() + return values anyway as a matter of good habit. + */ #ifdef PC_QUICKC -extern void *my_malloc(int32 size, char *whatfor) +extern void *my_malloc(size_t size, char *whatfor) { char _huge *c; if (memout_switch) printf("Allocating %ld bytes for %s\n",size,whatfor); if (size==0) return(NULL); - c=(char _huge *)halloc(size,1); malloced_bytes+=size; + c=(char _huge *)halloc(size,1); + malloced_bytes+=size; if (c==0) memory_out_error(size, 1, whatfor); return(c); } -extern void my_realloc(void *pointer, int32 oldsize, int32 size, +extern void my_realloc(void *pointer, size_t oldsize, size_t size, char *whatfor) { char _huge *c; if (size==0) { my_free(pointer, whatfor); return; } - c=halloc(size,1); malloced_bytes+=size; + c=halloc(size,1); + malloced_bytes+=(size-oldsize); if (c==0) memory_out_error(size, 1, whatfor); if (memout_switch) - printf("Increasing allocation to %ld bytes for %s was (%08lx) \ -now (%08lx)\n", - (long int) size,whatfor,(long int) (*(int **)pointer), + printf("Increasing allocation from %ld to %ld bytes for %s was (%08lx) now (%08lx)\n", + (long int) oldsize, (long int) size, whatfor, + (long int) (*(int **)pointer), (long int) c); memcpy(c, *(int **)pointer, MIN(oldsize, size)); hfree(*(int **)pointer); *(int **)pointer = c; } -extern void *my_calloc(int32 size, int32 howmany, char *whatfor) +extern void *my_calloc(size_t size, size_t howmany, char *whatfor) { void _huge *c; if (memout_switch) printf("Allocating %d bytes: array (%ld entries size %ld) for %s\n", size*howmany,howmany,size,whatfor); if ((size*howmany) == 0) return(NULL); - c=(void _huge *)halloc(howmany*size,1); malloced_bytes+=size*howmany; + c=(void _huge *)halloc(howmany*size,1); + malloced_bytes+=size*howmany; if (c==0) memory_out_error(size, howmany, whatfor); return(c); } -extern void my_recalloc(void *pointer, int32 size, int32 oldhowmany, +extern void my_recalloc(void *pointer, size_t size, size_t oldhowmany, int32 howmany, char *whatfor) { void _huge *c; if (size*howmany==0) { my_free(pointer, whatfor); return; } - c=(void _huge *)halloc(size*howmany,1); malloced_bytes+=size*howmany; + c=(void _huge *)halloc(size*howmany,1); + malloced_bytes+=size*(howmany-oldhowmany); if (c==0) memory_out_error(size, howmany, whatfor); if (memout_switch) - printf("Increasing allocation to %ld bytes: array (%ld entries size %ld) \ -for %s was (%08lx) now (%08lx)\n", + printf("Increasing allocation from %ld to %ld bytes: array (%ld entries size %ld) for %s was (%08lx) now (%08lx)\n", + ((long int)size) * ((long int)oldhowmany), ((long int)size) * ((long int)howmany), - (long int)howmany,(long int)size,whatfor, + (long int)howmany, (long int)size, whatfor, (long int) *(int **)pointer, (long int) c); memcpy(c, *(int **)pointer, MIN(size*oldhowmany, size*howmany)); hfree(*(int **)pointer); @@ -88,10 +98,11 @@ for %s was (%08lx) now (%08lx)\n", #else -extern void *my_malloc(int32 size, char *whatfor) +extern void *my_malloc(size_t size, char *whatfor) { char *c; if (size==0) return(NULL); - c=malloc((size_t) size); malloced_bytes+=size; + c=malloc(size); + malloced_bytes+=size; if (c==0) memory_out_error(size, 1, whatfor); if (memout_switch) printf("Allocating %ld bytes for %s at (%08lx)\n", @@ -99,27 +110,29 @@ extern void *my_malloc(int32 size, char *whatfor) return(c); } -extern void my_realloc(void *pointer, int32 oldsize, int32 size, +extern void my_realloc(void *pointer, size_t oldsize, size_t size, char *whatfor) { void *c; if (size==0) { my_free(pointer, whatfor); return; } - c=realloc(*(int **)pointer, (size_t) size); malloced_bytes+=size; + c=realloc(*(int **)pointer, size); + malloced_bytes+=(size-oldsize); if (c==0) memory_out_error(size, 1, whatfor); if (memout_switch) - printf("Increasing allocation to %ld bytes for %s was (%08lx) \ -now (%08lx)\n", - (long int) size,whatfor,(long int) (*(int **)pointer), + printf("Increasing allocation from %ld to %ld bytes for %s was (%08lx) now (%08lx)\n", + (long int) oldsize, (long int) size, whatfor, + (long int) (*(int **)pointer), (long int) c); *(int **)pointer = c; } -extern void *my_calloc(int32 size, int32 howmany, char *whatfor) +extern void *my_calloc(size_t size, size_t howmany, char *whatfor) { void *c; if (size*howmany==0) return(NULL); - c=calloc(howmany,(size_t) size); malloced_bytes+=size*howmany; + c=calloc(howmany, size); + malloced_bytes+=size*howmany; if (c==0) memory_out_error(size, howmany, whatfor); if (memout_switch) printf("Allocating %ld bytes: array (%ld entries size %ld) \ @@ -130,21 +143,21 @@ for %s at (%08lx)\n", return(c); } -extern void my_recalloc(void *pointer, int32 size, int32 oldhowmany, - int32 howmany, char *whatfor) +extern void my_recalloc(void *pointer, size_t size, size_t oldhowmany, + size_t howmany, char *whatfor) { void *c; if (size*howmany==0) { my_free(pointer, whatfor); return; } - c=realloc(*(int **)pointer, (size_t)size*(size_t)howmany); - malloced_bytes+=size*howmany; + c=realloc(*(int **)pointer, size*howmany); + malloced_bytes+=size*(howmany-oldhowmany); if (c==0) memory_out_error(size, howmany, whatfor); if (memout_switch) - printf("Increasing allocation to %ld bytes: array (%ld entries size %ld) \ -for %s was (%08lx) now (%08lx)\n", + printf("Increasing allocation from %ld to %ld bytes: array (%ld entries size %ld) for %s was (%08lx) now (%08lx)\n", + ((long int)size) * ((long int)oldhowmany), ((long int)size) * ((long int)howmany), - (long int)howmany,(long int)size,whatfor, + (long int)howmany, (long int)size, whatfor, (long int) *(int **)pointer, (long int) c); *(int **)pointer = c; } @@ -167,140 +180,118 @@ extern void my_free(void *pointer, char *whatitwas) } /* ------------------------------------------------------------------------- */ -/* Extensible blocks of memory, providing a kind of RAM disc as an */ -/* alternative to the temporary files option */ +/* A dynamic memory array. This grows as needed (but never shrinks). */ +/* Call ensure_memory_list_available(N) before accessing array item N-1. */ +/* */ +/* whatfor must be a static string describing the list. initalloc is */ +/* (optionally) the number of items to allocate right away. */ /* */ -/* The allocation is slightly confusing. A block can store up to 72 */ -/* chunks, which are allocated as needed when data is written. (Data does */ -/* not have to be written in order, but you should not try to read a byte */ -/* before writing it.) The size of a chunk is defined by ALLOC_CHUNK_SIZE. */ -/* So any block can store any amount of data, but you increase the limit */ -/* (for all blocks) by increasing ALLOC_CHUNK_SIZE, not the number of */ -/* chunks. */ +/* You typically initialise this with extpointer referring to an array of */ +/* structs or whatever type you need. Whenever the memory list grows, the */ +/* external array will be updated to refer to the new data. */ +/* */ +/* Add "#define DEBUG_MEMLISTS" to allocate exactly the number of items */ +/* needed, rather than increasing allocations exponentially. This is very */ +/* slow but it lets us track down array overruns. */ /* ------------------------------------------------------------------------- */ -static char chunk_name_buffer[60]; -static char *chunk_name(memory_block *MB, int no) -{ char *p = "(unknown)"; - if (MB == &static_strings_area) p = "static strings area"; - if (MB == &zcode_area) p = "Z-code area"; - if (MB == &link_data_area) p = "link data area"; - if (MB == &zcode_backpatch_table) p = "Z-code backpatch table"; - if (MB == &staticarray_backpatch_table) p = "Static array backpatch table"; - if (MB == &zmachine_backpatch_table) p = "Z-machine backpatch table"; - sprintf(chunk_name_buffer, "%s chunk %d", p, no); - return(chunk_name_buffer); -} +void initialise_memory_list(memory_list *ML, size_t itemsize, size_t initalloc, void **extpointer, char *whatfor) +{ + #ifdef DEBUG_MEMLISTS + initalloc = 0; /* No initial allocation */ + #endif + + ML->whatfor = whatfor; + ML->itemsize = itemsize; + ML->count = 0; + ML->data = NULL; + ML->extpointer = extpointer; -extern void initialise_memory_block(memory_block *MB) -{ int i; - MB->chunks = 0; - for (i=0; i<72; i++) MB->chunk[i] = NULL; - MB->extent_of_last = 0; - MB->write_pos = 0; -} + if (initalloc) { + ML->count = initalloc; + ML->data = my_calloc(ML->itemsize, ML->count, ML->whatfor); + if (ML->data == NULL) return; + } -extern void deallocate_memory_block(memory_block *MB) -{ int i; - for (i=0; i<72; i++) - if (MB->chunk[i] != NULL) - my_free(&(MB->chunk[i]), chunk_name(MB, i)); - MB->chunks = 0; - MB->extent_of_last = 0; + if (ML->extpointer) + *(ML->extpointer) = ML->data; } -extern int read_byte_from_memory_block(memory_block *MB, int32 index) -{ uchar *p; - p = MB->chunk[index/ALLOC_CHUNK_SIZE]; - if (p == NULL) - { compiler_error_named("memory: read from unwritten byte in", - chunk_name(MB, index/ALLOC_CHUNK_SIZE)); - return 0; - } - return p[index % ALLOC_CHUNK_SIZE]; +void deallocate_memory_list(memory_list *ML) +{ + ML->itemsize = 0; + ML->count = 0; + + if (ML->data) + my_free(&(ML->data), ML->whatfor); + + if (ML->extpointer) + *(ML->extpointer) = NULL; + ML->extpointer = NULL; } -extern void write_byte_to_memory_block(memory_block *MB, int32 index, int value) -{ uchar *p; int ch = index/ALLOC_CHUNK_SIZE; - if (ch < 0) - { compiler_error_named("memory: negative index to", chunk_name(MB, 0)); +/* After this is called, at least count items will be available in the list. + That is, you can freely access array[0] through array[count-1]. */ +void ensure_memory_list_available(memory_list *ML, size_t count) +{ + size_t oldcount; + + if (ML->itemsize == 0) { + /* whatfor is also null! */ + compiler_error("memory: attempt to access uninitialized memory_list"); return; } - if (ch >= 72) memoryerror("ALLOC_CHUNK_SIZE", ALLOC_CHUNK_SIZE); - if (MB->chunk[ch] == NULL) - { int i; - MB->chunk[ch] = my_malloc(ALLOC_CHUNK_SIZE, chunk_name(MB, ch)); - p = MB->chunk[ch]; - for (i=0; icount >= count) { + return; } - p = MB->chunk[ch]; - p[index % ALLOC_CHUNK_SIZE] = value; + oldcount = ML->count; + ML->count = 2*count+8; /* Allow headroom for future growth */ + + #ifdef DEBUG_MEMLISTS + ML->count = count; /* No headroom */ + #endif + + if (ML->data == NULL) + ML->data = my_calloc(ML->itemsize, ML->count, ML->whatfor); + else + my_recalloc(&(ML->data), ML->itemsize, oldcount, ML->count, ML->whatfor); + if (ML->data == NULL) return; + + if (ML->extpointer) + *(ML->extpointer) = ML->data; } /* ------------------------------------------------------------------------- */ /* Where the memory settings are declared as variables */ /* ------------------------------------------------------------------------- */ -int MAX_QTEXT_SIZE; -int MAX_SYMBOLS; -int SYMBOLS_CHUNK_SIZE; int HASH_TAB_SIZE; -int MAX_OBJECTS; -int MAX_ARRAYS; -int MAX_ACTIONS; -int MAX_ADJECTIVES; -int MAX_DICT_ENTRIES; -int MAX_STATIC_DATA; -int MAX_PROP_TABLE_SIZE; int MAX_ABBREVS; int MAX_DYNAMIC_STRINGS; -int MAX_EXPRESSION_NODES; -int MAX_VERBS; -int MAX_VERBSPACE; -int MAX_LABELS; -int MAX_LINESPACE; -int32 MAX_STATIC_STRINGS; -int32 MAX_ZCODE_SIZE; -int MAX_LOW_STRINGS; -int32 MAX_TRANSCRIPT_SIZE; -int MAX_CLASSES; -int32 MAX_LINK_DATA_SIZE; -int MAX_INCLUSION_DEPTH; -int MAX_SOURCE_FILES; -int32 MAX_INDIV_PROP_TABLE_SIZE; -int32 MAX_OBJ_PROP_TABLE_SIZE; -int MAX_OBJ_PROP_COUNT; int MAX_LOCAL_VARIABLES; -int MAX_GLOBAL_VARIABLES; int DICT_WORD_SIZE; /* number of characters in a dict word */ int DICT_CHAR_SIZE; /* (glulx) 1 for one-byte chars, 4 for Unicode chars */ int DICT_WORD_BYTES; /* DICT_WORD_SIZE*DICT_CHAR_SIZE */ int ZCODE_HEADER_EXT_WORDS; /* (zcode 1.0) requested header extension size */ int ZCODE_HEADER_FLAGS_3; /* (zcode 1.1) value to place in Flags 3 word */ +int ZCODE_LESS_DICT_DATA; /* (zcode) use 2 data bytes per dict word instead of 3 */ int NUM_ATTR_BYTES; int GLULX_OBJECT_EXT_BYTES; /* (glulx) extra bytes for each object record */ -int32 MAX_NUM_STATIC_STRINGS; -int32 MAX_UNICODE_CHARS; int32 MAX_STACK_SIZE; int32 MEMORY_MAP_EXTENSION; -int ALLOC_CHUNK_SIZE; int WARN_UNUSED_ROUTINES; /* 0: no, 1: yes except in system files, 2: yes always */ int OMIT_UNUSED_ROUTINES; /* 0: no, 1: yes */ +int STRIP_UNREACHABLE_LABELS; /* 0: no, 1: yes (default) */ int TRANSCRIPT_FORMAT; /* 0: classic, 1: prefixed */ /* The way memory sizes are set causes great nuisance for those parameters which have different defaults under Z-code and Glulx. We have to get the defaults right whether the user sets "-G $HUGE" or "$HUGE -G". And an explicit value set by the user should override both defaults. */ -static int32 MAX_ZCODE_SIZE_z, MAX_ZCODE_SIZE_g; -static int MAX_PROP_TABLE_SIZE_z, MAX_PROP_TABLE_SIZE_g; -static int MAX_GLOBAL_VARIABLES_z, MAX_GLOBAL_VARIABLES_g; -static int MAX_LOCAL_VARIABLES_z, MAX_LOCAL_VARIABLES_g; static int DICT_WORD_SIZE_z, DICT_WORD_SIZE_g; static int NUM_ATTR_BYTES_z, NUM_ATTR_BYTES_g; -static int ALLOC_CHUNK_SIZE_z, ALLOC_CHUNK_SIZE_g; static int MAX_DYNAMIC_STRINGS_z, MAX_DYNAMIC_STRINGS_g; /* ------------------------------------------------------------------------- */ @@ -312,227 +303,38 @@ static void list_memory_sizes(void) printf("| %25s = %-7s |\n","Memory setting","Value"); printf("+--------------------------------------+\n"); printf("| %25s = %-7d |\n","MAX_ABBREVS",MAX_ABBREVS); - printf("| %25s = %-7d |\n","MAX_ACTIONS",MAX_ACTIONS); - printf("| %25s = %-7d |\n","MAX_ADJECTIVES",MAX_ADJECTIVES); - printf("| %25s = %-7d |\n","ALLOC_CHUNK_SIZE",ALLOC_CHUNK_SIZE); - printf("| %25s = %-7d |\n","MAX_ARRAYS",MAX_ARRAYS); printf("| %25s = %-7d |\n","NUM_ATTR_BYTES",NUM_ATTR_BYTES); - printf("| %25s = %-7d |\n","MAX_CLASSES",MAX_CLASSES); - printf("| %25s = %-7d |\n","MAX_DICT_ENTRIES",MAX_DICT_ENTRIES); printf("| %25s = %-7d |\n","DICT_WORD_SIZE",DICT_WORD_SIZE); if (glulx_mode) printf("| %25s = %-7d |\n","DICT_CHAR_SIZE",DICT_CHAR_SIZE); printf("| %25s = %-7d |\n","MAX_DYNAMIC_STRINGS",MAX_DYNAMIC_STRINGS); - printf("| %25s = %-7d |\n","MAX_EXPRESSION_NODES",MAX_EXPRESSION_NODES); - printf("| %25s = %-7d |\n","MAX_GLOBAL_VARIABLES",MAX_GLOBAL_VARIABLES); printf("| %25s = %-7d |\n","HASH_TAB_SIZE",HASH_TAB_SIZE); if (!glulx_mode) printf("| %25s = %-7d |\n","ZCODE_HEADER_EXT_WORDS",ZCODE_HEADER_EXT_WORDS); if (!glulx_mode) printf("| %25s = %-7d |\n","ZCODE_HEADER_FLAGS_3",ZCODE_HEADER_FLAGS_3); - printf("| %25s = %-7d |\n","MAX_INCLUSION_DEPTH",MAX_INCLUSION_DEPTH); - printf("| %25s = %-7d |\n","MAX_INDIV_PROP_TABLE_SIZE", MAX_INDIV_PROP_TABLE_SIZE); + if (!glulx_mode) + printf("| %25s = %-7d |\n","ZCODE_LESS_DICT_DATA",ZCODE_LESS_DICT_DATA); printf("| %25s = %-7d |\n","INDIV_PROP_START", INDIV_PROP_START); - printf("| %25s = %-7d |\n","MAX_LABELS",MAX_LABELS); - printf("| %25s = %-7d |\n","MAX_LINESPACE",MAX_LINESPACE); - printf("| %25s = %-7d |\n","MAX_LINK_DATA_SIZE",MAX_LINK_DATA_SIZE); - if (glulx_mode) - printf("| %25s = %-7d |\n","MAX_LOCAL_VARIABLES",MAX_LOCAL_VARIABLES); - printf("| %25s = %-7d |\n","MAX_LOW_STRINGS",MAX_LOW_STRINGS); if (glulx_mode) printf("| %25s = %-7d |\n","MEMORY_MAP_EXTENSION", MEMORY_MAP_EXTENSION); - if (glulx_mode) - printf("| %25s = %-7d |\n","MAX_NUM_STATIC_STRINGS", - MAX_NUM_STATIC_STRINGS); - printf("| %25s = %-7d |\n","MAX_OBJECTS",MAX_OBJECTS); if (glulx_mode) printf("| %25s = %-7d |\n","GLULX_OBJECT_EXT_BYTES", GLULX_OBJECT_EXT_BYTES); - if (glulx_mode) - printf("| %25s = %-7d |\n","MAX_OBJ_PROP_COUNT", - MAX_OBJ_PROP_COUNT); - if (glulx_mode) - printf("| %25s = %-7d |\n","MAX_OBJ_PROP_TABLE_SIZE", - MAX_OBJ_PROP_TABLE_SIZE); - printf("| %25s = %-7d |\n","MAX_PROP_TABLE_SIZE",MAX_PROP_TABLE_SIZE); - printf("| %25s = %-7d |\n","MAX_QTEXT_SIZE",MAX_QTEXT_SIZE); - printf("| %25s = %-7d |\n","MAX_SOURCE_FILES",MAX_SOURCE_FILES); if (glulx_mode) printf("| %25s = %-7ld |\n","MAX_STACK_SIZE", (long int) MAX_STACK_SIZE); - printf("| %25s = %-7d |\n","MAX_STATIC_DATA",MAX_STATIC_DATA); - printf("| %25s = %-7ld |\n","MAX_STATIC_STRINGS", - (long int) MAX_STATIC_STRINGS); - printf("| %25s = %-7d |\n","MAX_SYMBOLS",MAX_SYMBOLS); - printf("| %25s = %-7d |\n","SYMBOLS_CHUNK_SIZE",SYMBOLS_CHUNK_SIZE); printf("| %25s = %-7d |\n","TRANSCRIPT_FORMAT",TRANSCRIPT_FORMAT); - printf("| %25s = %-7ld |\n","MAX_TRANSCRIPT_SIZE", - (long int) MAX_TRANSCRIPT_SIZE); - if (glulx_mode) - printf("| %25s = %-7ld |\n","MAX_UNICODE_CHARS", - (long int) MAX_UNICODE_CHARS); printf("| %25s = %-7d |\n","WARN_UNUSED_ROUTINES",WARN_UNUSED_ROUTINES); printf("| %25s = %-7d |\n","OMIT_UNUSED_ROUTINES",OMIT_UNUSED_ROUTINES); - printf("| %25s = %-7d |\n","MAX_VERBS",MAX_VERBS); - printf("| %25s = %-7d |\n","MAX_VERBSPACE",MAX_VERBSPACE); - printf("| %25s = %-7ld |\n","MAX_ZCODE_SIZE", - (long int) MAX_ZCODE_SIZE); + printf("| %25s = %-7d |\n","STRIP_UNREACHABLE_LABELS",STRIP_UNREACHABLE_LABELS); printf("+--------------------------------------+\n"); } -extern void set_memory_sizes(int size_flag) +extern void set_memory_sizes(void) { - if (size_flag == HUGE_SIZE) - { - MAX_QTEXT_SIZE = 4000; - MAX_SYMBOLS = 10000; - - SYMBOLS_CHUNK_SIZE = 5000; - HASH_TAB_SIZE = 512; - - MAX_OBJECTS = 640; - - MAX_ACTIONS = 200; - MAX_ADJECTIVES = 50; - MAX_DICT_ENTRIES = 2000; - MAX_STATIC_DATA = 10000; - - MAX_PROP_TABLE_SIZE_z = 30000; - MAX_PROP_TABLE_SIZE_g = 60000; - - MAX_EXPRESSION_NODES = 100; - MAX_VERBS = 200; - MAX_VERBSPACE = 4096; - MAX_LABELS = 1000; - MAX_LINESPACE = 16000; - - MAX_STATIC_STRINGS = 8000; - MAX_ZCODE_SIZE_z = 20000; - MAX_ZCODE_SIZE_g = 40000; - MAX_LINK_DATA_SIZE = 2000; - - MAX_LOW_STRINGS = 2048; - - MAX_TRANSCRIPT_SIZE = 200000; - MAX_NUM_STATIC_STRINGS = 20000; - - MAX_CLASSES = 64; - - MAX_OBJ_PROP_COUNT = 128; - MAX_OBJ_PROP_TABLE_SIZE = 4096; - - MAX_INDIV_PROP_TABLE_SIZE = 15000; - MAX_ARRAYS = 128; - - MAX_GLOBAL_VARIABLES_z = 240; - MAX_GLOBAL_VARIABLES_g = 512; - - ALLOC_CHUNK_SIZE_z = 8192; - ALLOC_CHUNK_SIZE_g = 32768; - } - if (size_flag == LARGE_SIZE) - { - MAX_QTEXT_SIZE = 4000; - MAX_SYMBOLS = 6400; - - SYMBOLS_CHUNK_SIZE = 5000; - HASH_TAB_SIZE = 512; - - MAX_OBJECTS = 512; - - MAX_ACTIONS = 200; - MAX_ADJECTIVES = 50; - MAX_DICT_ENTRIES = 1300; - MAX_STATIC_DATA = 10000; - - MAX_PROP_TABLE_SIZE_z = 15000; - MAX_PROP_TABLE_SIZE_g = 30000; - - MAX_EXPRESSION_NODES = 100; - MAX_VERBS = 140; - MAX_VERBSPACE = 4096; - MAX_LINESPACE = 10000; - - MAX_LABELS = 1000; - MAX_STATIC_STRINGS = 8000; - MAX_ZCODE_SIZE_z = 20000; - MAX_ZCODE_SIZE_g = 40000; - MAX_LINK_DATA_SIZE = 2000; - - MAX_LOW_STRINGS = 2048; - - MAX_TRANSCRIPT_SIZE = 200000; - MAX_NUM_STATIC_STRINGS = 20000; - - MAX_CLASSES = 64; - - MAX_OBJ_PROP_COUNT = 64; - MAX_OBJ_PROP_TABLE_SIZE = 2048; - - MAX_INDIV_PROP_TABLE_SIZE = 10000; - MAX_ARRAYS = 128; - - MAX_GLOBAL_VARIABLES_z = 240; - MAX_GLOBAL_VARIABLES_g = 512; - - ALLOC_CHUNK_SIZE_z = 8192; - ALLOC_CHUNK_SIZE_g = 16384; - } - if (size_flag == SMALL_SIZE) - { - MAX_QTEXT_SIZE = 4000; - MAX_SYMBOLS = 3000; - - SYMBOLS_CHUNK_SIZE = 2500; - HASH_TAB_SIZE = 512; - - MAX_OBJECTS = 300; - - MAX_ACTIONS = 200; - MAX_ADJECTIVES = 50; - MAX_DICT_ENTRIES = 700; - MAX_STATIC_DATA = 10000; - - MAX_PROP_TABLE_SIZE_z = 8000; - MAX_PROP_TABLE_SIZE_g = 16000; - - MAX_EXPRESSION_NODES = 40; - MAX_VERBS = 110; - MAX_VERBSPACE = 2048; - MAX_LINESPACE = 10000; - MAX_LABELS = 1000; - - MAX_STATIC_STRINGS = 8000; - MAX_ZCODE_SIZE_z = 10000; - MAX_ZCODE_SIZE_g = 20000; - MAX_LINK_DATA_SIZE = 1000; - - MAX_LOW_STRINGS = 1024; - - MAX_TRANSCRIPT_SIZE = 100000; - MAX_NUM_STATIC_STRINGS = 10000; - - MAX_CLASSES = 32; - - MAX_OBJ_PROP_COUNT = 64; - MAX_OBJ_PROP_TABLE_SIZE = 1024; - - MAX_INDIV_PROP_TABLE_SIZE = 5000; - MAX_ARRAYS = 64; - - MAX_GLOBAL_VARIABLES_z = 240; - MAX_GLOBAL_VARIABLES_g = 256; - - ALLOC_CHUNK_SIZE_z = 8192; - ALLOC_CHUNK_SIZE_g = 8192; - } - - /* Regardless of size_flag... */ - MAX_SOURCE_FILES = 256; - MAX_INCLUSION_DEPTH = 5; - MAX_LOCAL_VARIABLES_z = 16; - MAX_LOCAL_VARIABLES_g = 32; + HASH_TAB_SIZE = 512; DICT_CHAR_SIZE = 1; DICT_WORD_SIZE_z = 6; DICT_WORD_SIZE_g = 9; @@ -540,14 +342,14 @@ extern void set_memory_sizes(int size_flag) NUM_ATTR_BYTES_g = 7; MAX_ABBREVS = 64; MAX_DYNAMIC_STRINGS_z = 32; - MAX_DYNAMIC_STRINGS_g = 64; + MAX_DYNAMIC_STRINGS_g = 100; /* Backwards-compatible behavior: allow for a unicode table whether we need one or not. The user can set this to zero if there's no unicode table. */ ZCODE_HEADER_EXT_WORDS = 3; ZCODE_HEADER_FLAGS_3 = 0; + ZCODE_LESS_DICT_DATA = 0; GLULX_OBJECT_EXT_BYTES = 0; - MAX_UNICODE_CHARS = 64; MEMORY_MAP_EXTENSION = 0; /* We estimate the default Glulx stack size at 4096. That's about enough for 90 nested function calls with 8 locals each -- the @@ -557,6 +359,7 @@ extern void set_memory_sizes(int size_flag) MAX_STACK_SIZE = 4096; OMIT_UNUSED_ROUTINES = 0; WARN_UNUSED_ROUTINES = 0; + STRIP_UNREACHABLE_LABELS = 1; TRANSCRIPT_FORMAT = 0; adjust_memory_sizes(); @@ -565,24 +368,14 @@ extern void set_memory_sizes(int size_flag) extern void adjust_memory_sizes() { if (!glulx_mode) { - MAX_ZCODE_SIZE = MAX_ZCODE_SIZE_z; - MAX_PROP_TABLE_SIZE = MAX_PROP_TABLE_SIZE_z; - MAX_GLOBAL_VARIABLES = MAX_GLOBAL_VARIABLES_z; - MAX_LOCAL_VARIABLES = MAX_LOCAL_VARIABLES_z; DICT_WORD_SIZE = DICT_WORD_SIZE_z; NUM_ATTR_BYTES = NUM_ATTR_BYTES_z; - ALLOC_CHUNK_SIZE = ALLOC_CHUNK_SIZE_z; MAX_DYNAMIC_STRINGS = MAX_DYNAMIC_STRINGS_z; INDIV_PROP_START = 64; } else { - MAX_ZCODE_SIZE = MAX_ZCODE_SIZE_g; - MAX_PROP_TABLE_SIZE = MAX_PROP_TABLE_SIZE_g; - MAX_GLOBAL_VARIABLES = MAX_GLOBAL_VARIABLES_g; - MAX_LOCAL_VARIABLES = MAX_LOCAL_VARIABLES_g; DICT_WORD_SIZE = DICT_WORD_SIZE_g; NUM_ATTR_BYTES = NUM_ATTR_BYTES_g; - ALLOC_CHUNK_SIZE = ALLOC_CHUNK_SIZE_g; MAX_DYNAMIC_STRINGS = MAX_DYNAMIC_STRINGS_g; INDIV_PROP_START = 256; } @@ -590,56 +383,12 @@ extern void adjust_memory_sizes() static void explain_parameter(char *command) { printf("\n"); - if (strcmp(command,"MAX_QTEXT_SIZE")==0) - { printf( -" MAX_QTEXT_SIZE is the maximum length of a quoted string. Increasing\n\ - by 1 costs 5 bytes (for lexical analysis memory). Inform automatically\n\ - ensures that MAX_STATIC_STRINGS is at least twice the size of this."); - return; - } - if (strcmp(command,"MAX_SYMBOLS")==0) - { printf( -" MAX_SYMBOLS is the maximum number of symbols - names of variables, \n\ - objects, routines, the many internal Inform-generated names and so on.\n"); - return; - } - if (strcmp(command,"SYMBOLS_CHUNK_SIZE")==0) - { printf( -" The symbols names are stored in memory which is allocated in chunks \n\ - of size SYMBOLS_CHUNK_SIZE.\n"); - return; - } if (strcmp(command,"HASH_TAB_SIZE")==0) { printf( " HASH_TAB_SIZE is the size of the hash tables used for the heaviest \n\ symbols banks.\n"); return; } - if (strcmp(command,"MAX_OBJECTS")==0) - { printf( -" MAX_OBJECTS is the maximum number of objects. (If compiling a version-3 \n\ - game, 255 is an absolute maximum in any event.)\n"); - return; - } - if (strcmp(command,"MAX_ACTIONS")==0) - { printf( -" MAX_ACTIONS is the maximum number of actions - that is, routines such as \n\ - TakeSub which are referenced in the grammar table.\n"); - return; - } - if (strcmp(command,"MAX_ADJECTIVES")==0) - { printf( -" MAX_ADJECTIVES is the maximum number of different \"adjectives\" in the \n\ - grammar table. Adjectives are misleadingly named: they are words such as \n\ - \"in\", \"under\" and the like.\n"); - return; - } - if (strcmp(command,"MAX_DICT_ENTRIES")==0) - { printf( -" MAX_DICT_ENTRIES is the maximum number of words which can be entered \n\ - into the game's dictionary. It costs 29 bytes to increase this by one.\n"); - return; - } if (strcmp(command,"DICT_WORD_SIZE")==0) { printf( " DICT_WORD_SIZE is the number of characters in a dictionary word. In \n\ @@ -677,6 +426,12 @@ static void explain_parameter(char *command) header extension table (Z-Spec 1.1).\n"); return; } + if (strcmp(command,"ZCODE_LESS_DICT_DATA")==0) + { printf( +" ZCODE_LESS_DICT_DATA, if set, provides each dict word with two data bytes\n\ + rather than three. (Z-code only.)\n"); + return; + } if (strcmp(command,"GLULX_OBJECT_EXT_BYTES")==0) { printf( " GLULX_OBJECT_EXT_BYTES is an amount of additional space to add to each \n\ @@ -685,134 +440,17 @@ static void explain_parameter(char *command) specifies the object structure.)\n"); return; } - if (strcmp(command,"MAX_STATIC_DATA")==0) - { printf( -" MAX_STATIC_DATA is the size of an array of integers holding initial \n\ - values for arrays and strings stored as ASCII inside the Z-machine. It \n\ - should be at least 1024 but seldom needs much more.\n"); - return; - } - if (strcmp(command,"MAX_PROP_TABLE_SIZE")==0) - { printf( -" MAX_PROP_TABLE_SIZE is the number of bytes allocated to hold the \n\ - properties table.\n"); - return; - } if (strcmp(command,"MAX_ABBREVS")==0) { printf( " MAX_ABBREVS is the maximum number of declared abbreviations. It is not \n\ - allowed to exceed 96 in Z-code.\n"); + allowed to exceed 96 in Z-code. (This is not meaningful in Glulx, where \n\ + there is no limit on abbreviations.)\n"); return; } if (strcmp(command,"MAX_DYNAMIC_STRINGS")==0) { printf( " MAX_DYNAMIC_STRINGS is the maximum number of string substitution variables\n\ - (\"@00\"). It is not allowed to exceed 96 in Z-code or 100 in Glulx.\n"); - return; - } - if (strcmp(command,"MAX_ARRAYS")==0) - { printf( -" MAX_ARRAYS is the maximum number of declared arrays.\n"); - return; - } - if (strcmp(command,"MAX_EXPRESSION_NODES")==0) - { printf( -" MAX_EXPRESSION_NODES is the maximum number of nodes in the expression \n\ - evaluator's storage for parse trees. In effect, it measures how \n\ - complicated algebraic expressions are allowed to be. Increasing it by \n\ - one costs about 80 bytes.\n"); - return; - } - if (strcmp(command,"MAX_VERBS")==0) - { printf( -" MAX_VERBS is the maximum number of verbs (such as \"take\") which can be \n\ - defined, each with its own grammar. To increase it by one costs about\n\ - 128 bytes. A full game will contain at least 100.\n"); - return; - } - if (strcmp(command,"MAX_VERBSPACE")==0) - { printf( -" MAX_VERBSPACE is the size of workspace used to store verb words, so may\n\ - need increasing in games with many synonyms: unlikely to exceed 4K.\n"); - return; - } - if (strcmp(command,"MAX_LABELS")==0) - { printf( -" MAX_LABELS is the maximum number of label points in any one routine.\n\ - (If the -k debugging information switch is set, MAX_LABELS is raised to\n\ - a minimum level of 2000, as about twice the normal number of label points\n\ - are needed to generate tables of how source code corresponds to positions\n\ - in compiled code.)"); - return; - } - if (strcmp(command,"MAX_LINESPACE")==0) - { printf( -" MAX_LINESPACE is the size of workspace used to store grammar lines, so \n\ - may need increasing in games with complex or extensive grammars.\n"); - return; - } - if (strcmp(command,"MAX_STATIC_STRINGS")==0) - { - printf( -" MAX_STATIC_STRINGS is the size in bytes of a buffer to hold compiled\n\ - strings before they're written into longer-term storage. 2000 bytes is \n\ - plenty, allowing string constants of up to about 3000 characters long.\n\ - Inform automatically ensures that this is at least twice the size of\n\ - MAX_QTEXT_SIZE, to be on the safe side."); - return; - } - if (strcmp(command,"MAX_ZCODE_SIZE")==0) - { - printf( -" MAX_ZCODE_SIZE is the size in bytes of a buffer to hold compiled \n\ - code for a single routine. (It applies to both Z-code and Glulx, \n\ - despite the name.) As a guide, the longest library routine is \n\ - about 6500 bytes long in Z-code; about twice that in Glulx."); - return; - } - if (strcmp(command,"MAX_LINK_DATA_SIZE")==0) - { - printf( -" MAX_LINK_DATA_SIZE is the size in bytes of a buffer to hold module \n\ - link data before it's written into longer-term storage. 2000 bytes \n\ - is plenty."); - return; - } - if (strcmp(command,"MAX_LOW_STRINGS")==0) - { printf( -" MAX_LOW_STRINGS is the size in bytes of a buffer to hold all the \n\ - compiled \"low strings\" which are to be written above the synonyms table \n\ - in the Z-machine. 1024 is plenty.\n"); - return; - } - if (strcmp(command,"MAX_TRANSCRIPT_SIZE")==0) - { printf( -" MAX_TRANSCRIPT_SIZE is only allocated for the abbreviations optimisation \n\ - switch, and has the size in bytes of a buffer to hold the entire text of\n\ - the game being compiled: it has to be enormous, say 100000 to 200000.\n"); - return; - } - if (strcmp(command,"MAX_CLASSES")==0) - { printf( -" MAX_CLASSES maximum number of object classes which can be defined. This\n\ - is cheap to increase.\n"); - return; - } - if (strcmp(command,"MAX_INCLUSION_DEPTH")==0) - { printf( -" MAX_INCLUSION_DEPTH is the number of nested includes permitted.\n"); - return; - } - if (strcmp(command,"MAX_SOURCE_FILES")==0) - { printf( -" MAX_SOURCE_FILES is the number of source files that can be read in the \n\ - compilation.\n"); - return; - } - if (strcmp(command,"MAX_INDIV_PROP_TABLE_SIZE")==0) - { printf( -" MAX_INDIV_PROP_TABLE_SIZE is the number of bytes allocated to hold the \n\ - table of ..variable values.\n"); + (\"@00\" or \"@(0)\"). It is not allowed to exceed 96 in Z-code.\n"); return; } if (strcmp(command,"INDIV_PROP_START")==0) @@ -821,52 +459,6 @@ static void explain_parameter(char *command) properties are numbered INDIV_PROP_START and up.\n"); return; } - if (strcmp(command,"MAX_OBJ_PROP_COUNT")==0) - { printf( -" MAX_OBJ_PROP_COUNT is the maximum number of properties a single object \n\ - can have. (Glulx only)\n"); - return; - } - if (strcmp(command,"MAX_OBJ_PROP_TABLE_SIZE")==0) - { printf( -" MAX_OBJ_PROP_TABLE_SIZE is the number of words allocated to hold a \n\ - single object's properties. (Glulx only)\n"); - return; - } - if (strcmp(command,"MAX_LOCAL_VARIABLES")==0) - { printf( -" MAX_LOCAL_VARIABLES is the number of local variables (including \n\ - arguments) allowed in a procedure. (Glulx only)\n"); - return; - } - if (strcmp(command,"MAX_GLOBAL_VARIABLES")==0) - { printf( -" MAX_GLOBAL_VARIABLES is the number of global variables allowed in the \n\ - program. (Glulx only)\n"); - return; - } - if (strcmp(command,"MAX_NUM_STATIC_STRINGS")==0) - { - printf( -" MAX_NUM_STATIC_STRINGS is the maximum number of compiled strings \n\ - allowed in the program. (Glulx only)\n"); - return; - } - if (strcmp(command,"MAX_UNICODE_CHARS")==0) - { - printf( -" MAX_UNICODE_CHARS is the maximum number of different Unicode characters \n\ - (beyond the Latin-1 range, $00..$FF) which the game text can use. \n\ - (Glulx only)\n"); - return; - } - if (strcmp(command,"ALLOC_CHUNK_SIZE")==0) - { - printf( -" ALLOC_CHUNK_SIZE is a base unit of Inform's internal memory allocation \n\ - for various structures.\n"); - return; - } if (strcmp(command,"MAX_STACK_SIZE")==0) { printf( @@ -904,6 +496,14 @@ static void explain_parameter(char *command) into the game file.\n"); return; } + if (strcmp(command,"STRIP_UNREACHABLE_LABELS")==0) + { + printf( +" STRIP_UNREACHABLE_LABELS, if set to 1, will skip labels in unreachable \n\ + statements. Jumping to a skipped label is an error. If 0, all labels \n\ + will be compiled, at the cost of less optimized code. The default is 1.\n"); + return; + } if (strcmp(command,"SERIAL")==0) { printf( @@ -1002,6 +602,136 @@ static void add_predefined_symbol(char *command) add_config_symbol_definition(command, value); } +static void set_trace_option(char *command) +{ + char *cx; + int value; + + /* Parse options of the form STRING or STRING=NUM. (The $! has already been eaten.) If the string is null or empty, show help. */ + + if (!command || *command == '\0') { + printf("The full list of trace options:\n\n"); + printf(" ACTIONS: show actions defined\n"); + printf(" ASM: trace assembly (same as -a)\n"); + printf(" ASM=2: also show hex dumps\n"); + printf(" ASM=3: also show branch optimization info\n"); + printf(" ASM=4: more verbose branch info\n"); + printf(" BPATCH: show backpatch results\n"); + printf(" BPATCH=2: also show markers added\n"); + printf(" DICT: display the dictionary table\n"); + printf(" DICT=2: also the byte encoding of entries\n"); + printf(" EXPR: show expression trees\n"); + printf(" EXPR=2: more verbose\n"); + printf(" EXPR=3: even more verbose\n"); + printf(" FILES: show files opened\n"); + printf(" FINDABBREVS: show selection decisions during abbreviation optimization\n (only meaningful with -u)\n"); + printf(" FINDABBREVS=2: also show three-letter-block decisions\n"); + printf(" FREQ: show how efficient abbreviations were (same as -f)\n (only meaningful with -e)\n"); + printf(" LINKER: show module linking info\n"); + printf(" LINKER=2: more verbose (or 3, 4 for even more)\n"); + printf(" MAP: print memory map of the virtual machine (same as -z)\n"); + printf(" MAP=2: also show percentage of VM that each segment occupies\n"); + printf(" MEM: show internal memory allocations\n"); + printf(" OBJECTS: display the object table\n"); + printf(" PROPS: show attributes and properties defined\n"); + printf(" RUNTIME: show game function calls at runtime (same as -g)\n"); + printf(" RUNTIME=2: also show library calls (not supported in Glulx)\n"); + printf(" RUNTIME=3: also show veneer calls (not supported in Glulx)\n"); + printf(" STATS: give compilation statistics (same as -s)\n"); + printf(" SYMBOLS: display the symbol table\n"); + printf(" SYMBOLS=2: also show compiler-defined symbols\n"); + printf(" SYMDEF: show when symbols are noticed and defined\n"); + printf(" TOKENS: show token lexing\n"); + printf(" TOKENS=2: also show token types\n"); + printf(" TOKENS=3: also show lexical context\n"); + printf(" VERBS: display the verb grammar table\n"); + return; + } + + for (cx=command; *cx && *cx != '='; cx++) { + if (!(*cx >= 'A' && *cx <= 'Z')) { + printf("Invalid $! trace command \"%s\"\n", command); + return; + } + } + + value = 1; + if (*cx == '=') { + char *ex; + value = strtol(cx+1, &ex, 10); + + if (ex == cx+1 || *ex != '\0' || value < 0) { + printf("Bad numerical setting in $! trace command \"%s\"\n", command); + return; + } + + *cx = '\0'; + } + + /* We accept some reasonable synonyms, including plausible singular/plural confusion. */ + + if (strcmp(command, "ASSEMBLY")==0 || strcmp(command, "ASM")==0) { + asm_trace_setting = value; + } + else if (strcmp(command, "ACTION")==0 || strcmp(command, "ACTIONS")==0) { + printactions_switch = value; + } + else if (strcmp(command, "BPATCH")==0 || strcmp(command, "BACKPATCH")==0) { + bpatch_trace_setting = value; + } + else if (strcmp(command, "DICTIONARY")==0 || strcmp(command, "DICT")==0) { + list_dict_setting = value; + } + else if (strcmp(command, "EXPR")==0 || strcmp(command, "EXPRESSION")==0 || strcmp(command, "EXPRESSIONS")==0) { + expr_trace_setting = value; + } + else if (strcmp(command, "FILE")==0 || strcmp(command, "FILES")==0) { + files_trace_setting = value; + } + else if (strcmp(command, "FINDABBREV")==0 || strcmp(command, "FINDABBREVS")==0) { + optabbrevs_trace_setting = value; + } + else if (strcmp(command, "FREQUENCY")==0 || strcmp(command, "FREQUENCIES")==0 || strcmp(command, "FREQ")==0) { + frequencies_setting = value; + } + else if (strcmp(command, "LINK")==0 || strcmp(command, "LINKER")==0) { + linker_trace_setting = value; + } + else if (strcmp(command, "MAP")==0) { + memory_map_setting = value; + } + else if (strcmp(command, "MEM")==0 || strcmp(command, "MEMORY")==0) { + memout_switch = value; + } + else if (strcmp(command, "OBJECTS")==0 || strcmp(command, "OBJECT")==0 || strcmp(command, "OBJS")==0 || strcmp(command, "OBJ")==0) { + list_objects_setting = value; + } + else if (strcmp(command, "PROP")==0 || strcmp(command, "PROPERTY")==0 || strcmp(command, "PROPS")==0 || strcmp(command, "PROPERTIES")==0) { + printprops_switch = value; + } + else if (strcmp(command, "RUNTIME")==0) { + trace_fns_setting = value; + } + else if (strcmp(command, "STATISTICS")==0 || strcmp(command, "STATS")==0 || strcmp(command, "STAT")==0) { + statistics_switch = value; + } + else if (strcmp(command, "SYMBOLS")==0 || strcmp(command, "SYMBOL")==0) { + list_symbols_setting = value; + } + else if (strcmp(command, "SYMDEF")==0 || strcmp(command, "SYMBOLDEF")==0) { + symdef_trace_setting = value; + } + else if (strcmp(command, "TOKEN")==0 || strcmp(command, "TOKENS")==0) { + tokens_trace_setting = value; + } + else if (strcmp(command, "VERBS")==0 || strcmp(command, "VERB")==0) { + list_verbs_setting = value; + } + else { + printf("Unrecognized $! trace command \"%s\"\n", command); + } +} + /* Handle a dollar-sign command option: $LIST, $FOO=VAL, and so on. The option may come from the command line, an ICL file, or a header comment. @@ -1020,11 +750,18 @@ extern void memory_command(char *command) if (command[0]=='?') { explain_parameter(command+1); return; } if (command[0]=='#') { add_predefined_symbol(command+1); return; } + if (command[0]=='!') { set_trace_option(command+1); return; } - if (strcmp(command, "HUGE")==0) { set_memory_sizes(HUGE_SIZE); return; } - if (strcmp(command, "LARGE")==0) { set_memory_sizes(LARGE_SIZE); return; } - if (strcmp(command, "SMALL")==0) { set_memory_sizes(SMALL_SIZE); return; } + if (strcmp(command, "HUGE")==0 + || strcmp(command, "LARGE")==0 + || strcmp(command, "SMALL")==0) { + if (!nowarnings_switch) + printf("The Inform 6 memory size commands (\"SMALL, LARGE, HUGE\") are no longer needed and has been withdrawn.\n"); + return; + } + if (strcmp(command, "LIST")==0) { list_memory_sizes(); return; } + for (i=0; command[i]!=0; i++) { if (command[i]=='=') { command[i]=0; @@ -1034,28 +771,25 @@ extern void memory_command(char *command) if (strcmp(command,"BUFFER_LENGTH")==0) flag=2; if (strcmp(command,"MAX_QTEXT_SIZE")==0) - { MAX_QTEXT_SIZE=j, flag=1; - if (2*MAX_QTEXT_SIZE > MAX_STATIC_STRINGS) - MAX_STATIC_STRINGS = 2*MAX_QTEXT_SIZE; - } + flag=3; if (strcmp(command,"MAX_SYMBOLS")==0) - MAX_SYMBOLS=j, flag=1; + flag=3; if (strcmp(command,"MAX_BANK_SIZE")==0) flag=2; if (strcmp(command,"SYMBOLS_CHUNK_SIZE")==0) - SYMBOLS_CHUNK_SIZE=j, flag=1; + flag=3; if (strcmp(command,"BANK_CHUNK_SIZE")==0) flag=2; if (strcmp(command,"HASH_TAB_SIZE")==0) HASH_TAB_SIZE=j, flag=1; if (strcmp(command,"MAX_OBJECTS")==0) - MAX_OBJECTS=j, flag=1; + flag=3; if (strcmp(command,"MAX_ACTIONS")==0) - MAX_ACTIONS=j, flag=1; + flag=3; if (strcmp(command,"MAX_ADJECTIVES")==0) - MAX_ADJECTIVES=j, flag=1; + flag=3; if (strcmp(command,"MAX_DICT_ENTRIES")==0) - MAX_DICT_ENTRIES=j, flag=1; + flag=3; if (strcmp(command,"DICT_WORD_SIZE")==0) { DICT_WORD_SIZE=j, flag=1; DICT_WORD_SIZE_g=DICT_WORD_SIZE_z=j; @@ -1070,10 +804,12 @@ extern void memory_command(char *command) ZCODE_HEADER_EXT_WORDS=j, flag=1; if (strcmp(command,"ZCODE_HEADER_FLAGS_3")==0) ZCODE_HEADER_FLAGS_3=j, flag=1; + if (strcmp(command,"ZCODE_LESS_DICT_DATA")==0) + ZCODE_LESS_DICT_DATA=j, flag=1; if (strcmp(command,"GLULX_OBJECT_EXT_BYTES")==0) GLULX_OBJECT_EXT_BYTES=j, flag=1; if (strcmp(command,"MAX_STATIC_DATA")==0) - MAX_STATIC_DATA=j, flag=1; + flag=3; if (strcmp(command,"MAX_OLDEPTH")==0) flag=2; if (strcmp(command,"MAX_ROUTINES")==0) @@ -1081,9 +817,7 @@ extern void memory_command(char *command) if (strcmp(command,"MAX_GCONSTANTS")==0) flag=2; if (strcmp(command,"MAX_PROP_TABLE_SIZE")==0) - { MAX_PROP_TABLE_SIZE=j, flag=1; - MAX_PROP_TABLE_SIZE_g=MAX_PROP_TABLE_SIZE_z=j; - } + flag=3; if (strcmp(command,"MAX_FORWARD_REFS")==0) flag=2; if (strcmp(command,"STACK_SIZE")==0) @@ -1099,62 +833,51 @@ extern void memory_command(char *command) MAX_DYNAMIC_STRINGS_g=MAX_DYNAMIC_STRINGS_z=j; } if (strcmp(command,"MAX_ARRAYS")==0) - MAX_ARRAYS=j, flag=1; + flag=3; if (strcmp(command,"MAX_EXPRESSION_NODES")==0) - MAX_EXPRESSION_NODES=j, flag=1; + flag=3; if (strcmp(command,"MAX_VERBS")==0) - MAX_VERBS=j, flag=1; + flag=3; if (strcmp(command,"MAX_VERBSPACE")==0) - MAX_VERBSPACE=j, flag=1; + flag=3; if (strcmp(command,"MAX_LABELS")==0) - MAX_LABELS=j, flag=1; + flag=3; if (strcmp(command,"MAX_LINESPACE")==0) - MAX_LINESPACE=j, flag=1; + flag=3; if (strcmp(command,"MAX_NUM_STATIC_STRINGS")==0) - MAX_NUM_STATIC_STRINGS=j, flag=1; + flag=3; if (strcmp(command,"MAX_STATIC_STRINGS")==0) - { MAX_STATIC_STRINGS=j, flag=1; - if (2*MAX_QTEXT_SIZE > MAX_STATIC_STRINGS) - MAX_STATIC_STRINGS = 2*MAX_QTEXT_SIZE; - } + flag=3; if (strcmp(command,"MAX_ZCODE_SIZE")==0) - { MAX_ZCODE_SIZE=j, flag=1; - MAX_ZCODE_SIZE_g=MAX_ZCODE_SIZE_z=j; - } + flag=3; if (strcmp(command,"MAX_LINK_DATA_SIZE")==0) - MAX_LINK_DATA_SIZE=j, flag=1; + flag=3; if (strcmp(command,"MAX_LOW_STRINGS")==0) - MAX_LOW_STRINGS=j, flag=1; + flag=3; if (strcmp(command,"MAX_TRANSCRIPT_SIZE")==0) - MAX_TRANSCRIPT_SIZE=j, flag=1; + flag=3; if (strcmp(command,"MAX_CLASSES")==0) - MAX_CLASSES=j, flag=1; + flag=3; if (strcmp(command,"MAX_INCLUSION_DEPTH")==0) - MAX_INCLUSION_DEPTH=j, flag=1; + flag=3; if (strcmp(command,"MAX_SOURCE_FILES")==0) - MAX_SOURCE_FILES=j, flag=1; + flag=3; if (strcmp(command,"MAX_INDIV_PROP_TABLE_SIZE")==0) - MAX_INDIV_PROP_TABLE_SIZE=j, flag=1; + flag=3; if (strcmp(command,"INDIV_PROP_START")==0) INDIV_PROP_START=j, flag=1; if (strcmp(command,"MAX_OBJ_PROP_TABLE_SIZE")==0) - MAX_OBJ_PROP_TABLE_SIZE=j, flag=1; + flag=3; if (strcmp(command,"MAX_OBJ_PROP_COUNT")==0) - MAX_OBJ_PROP_COUNT=j, flag=1; + flag=3; if (strcmp(command,"MAX_LOCAL_VARIABLES")==0) - { MAX_LOCAL_VARIABLES=j, flag=1; - MAX_LOCAL_VARIABLES_g=MAX_LOCAL_VARIABLES_z=j; - } + flag=3; if (strcmp(command,"MAX_GLOBAL_VARIABLES")==0) - { MAX_GLOBAL_VARIABLES=j, flag=1; - MAX_GLOBAL_VARIABLES_g=MAX_GLOBAL_VARIABLES_z=j; - } + flag=3; if (strcmp(command,"ALLOC_CHUNK_SIZE")==0) - { ALLOC_CHUNK_SIZE=j, flag=1; - ALLOC_CHUNK_SIZE_g=ALLOC_CHUNK_SIZE_z=j; - } + flag=3; if (strcmp(command,"MAX_UNICODE_CHARS")==0) - MAX_UNICODE_CHARS=j, flag=1; + flag=3; if (strcmp(command,"MAX_STACK_SIZE")==0) { MAX_STACK_SIZE=j, flag=1; @@ -1185,6 +908,12 @@ extern void memory_command(char *command) if (OMIT_UNUSED_ROUTINES > 1 || OMIT_UNUSED_ROUTINES < 0) OMIT_UNUSED_ROUTINES = 1; } + if (strcmp(command,"STRIP_UNREACHABLE_LABELS")==0) + { + STRIP_UNREACHABLE_LABELS=j, flag=1; + if (STRIP_UNREACHABLE_LABELS > 1 || STRIP_UNREACHABLE_LABELS < 0) + STRIP_UNREACHABLE_LABELS = 1; + } if (strcmp(command,"SERIAL")==0) { if (j >= 0 && j <= 999999) @@ -1197,9 +926,10 @@ extern void memory_command(char *command) if (flag==0) printf("No such memory setting as \"%s\"\n", command); - if (flag==2) - printf("The Inform 5 memory setting \"%s\" has been withdrawn.\n\ -It should be safe to omit it (putting nothing in its place).\n", command); + if (flag==2 && !nowarnings_switch) + printf("The Inform 5 memory setting \"%s\" has been withdrawn.\n", command); + if (flag==3 && !nowarnings_switch) + printf("The Inform 6 memory setting \"%s\" is no longer needed and has been withdrawn.\n", command); return; } }