3 source/interpret.c | 136 ++++++++++++++++++++++++++++++++++++++---------------
5 2 files changed, 100 insertions(+), 37 deletions(-)
7 diff --quilt old/source/interpret.c new/source/interpret.c
8 --- old/source/interpret.c
9 +++ new/source/interpret.c
10 @@ -145,11 +145,17 @@ static int namedArg1(void);
11 static int namedArgN(void);
12 static int namedArg1orN(Boolean isFirst);
13 static int swapTop2(void);
14 static int arrayIndex(void);
15 static int makeArrayKeyFromArgs(int nArgs, char **keyString, int leaveParams);
16 -static void freeSymbolTable(Symbol *symTab);
17 +static void freeSymbolList(Symbol *symList);
18 +static void addToSymTab(Symbol **symTab, unsigned int symTabSize,
20 +static Symbol *lookUpInSymTab(Symbol **symTab, unsigned int symTabSize,
22 +static unsigned int hashNameWith(unsigned int hash, const char *name);
23 +static unsigned int hashName(const char *name);
24 static int errCheck(const char *s);
25 static int execError(const char *s1, const char *s2);
26 static rbTreeNode *arrayEmptyAllocator(void);
27 static rbTreeNode *arrayAllocateNode(rbTreeNode *src);
28 static int arrayEntryCopyToNode(rbTreeNode *dst, rbTreeNode *src);
29 @@ -191,12 +197,13 @@ static void stackdumpInternal(int n, int
30 #else /* #ifndef DEBUG_STACK */
31 #define STACKDUMP(n, x)
32 #define DISASM_RT(i, n)
33 #endif /* #ifndef DEBUG_STACK */
35 -/* Global symbols and function definitions */
36 -static Symbol *GlobalSymList = NULL;
37 +/* Global symbols and function definitions, is null initialized */
38 +#define GLOBAL_SYMTAB_SIZE 256u
39 +static Symbol *GlobalSymTab[GLOBAL_SYMTAB_SIZE];
41 /* List of all memory allocated for strings */
42 static char *AllocatedStrings = NULL;
44 typedef struct SparseArrayEntryWrapperTag {
45 @@ -395,11 +402,11 @@ Program *FinishCreatingProgram(const cha
49 void FreeProgram(Program *prog)
51 - freeSymbolTable(prog->localSymList);
52 + freeSymbolList(prog->localSymList);
53 XtFree((char *)prog->code);
55 XtFree((char *)prog->name);
58 @@ -789,18 +796,18 @@ void SetMacroFocusWindow(WindowInfo *win
61 ** install an array iteration symbol
62 ** it is tagged as an integer but holds an array node pointer
64 -#define ARRAY_ITER_SYM_PREFIX "aryiter "
65 +#define ARRAY_ITER_SYM_PREFIX "aryiter #"
66 Symbol *InstallIteratorSymbol(void)
68 char symbolName[sizeof(ARRAY_ITER_SYM_PREFIX) + TYPE_INT_STR_SIZE(int)];
70 - static int interatorNameIndex = 0;
71 + static int interatorNameIndex;
73 - sprintf(symbolName, ARRAY_ITER_SYM_PREFIX "#%d", interatorNameIndex);
74 + sprintf(symbolName, ARRAY_ITER_SYM_PREFIX "%d", interatorNameIndex);
77 value.val.arrayPtr = NULL;
78 return(InstallSymbol(symbolName, LOCAL_SYM, value));
80 @@ -809,36 +816,42 @@ Symbol *InstallIteratorSymbol(void)
81 ** Lookup a constant string by its value. This allows reuse of string
82 ** constants and fixing a leak in the interpreter.
84 Symbol *LookupStringConstSymbol(const char *value)
89 - for (s = GlobalSymList; s != NULL; s = s->next) {
90 - if (s->type == CONST_SYM &&
91 - s->value.tag == STRING_TAG &&
92 - !strcmp(s->value.val.str.rep, value)) {
94 + for (idx = 0; idx < GLOBAL_SYMTAB_SIZE; idx++) {
95 + for (s = GlobalSymTab[idx]; s != NULL; s = s->next) {
96 + if (s->type == CONST_SYM
97 + && s->value.tag == STRING_TAG
98 + && !strcmp(s->value.val.str.rep, value)) {
108 ** install string str in the global symbol table with a string name
110 +#define STRING_CONST_SYM_PREFIX "string #"
111 Symbol *InstallStringConstSymbol(const char *str)
113 - static int stringConstIndex = 0;
114 - char stringName[35];
115 + static int stringConstIndex;
116 + char stringName[sizeof(STRING_CONST_SYM_PREFIX) + TYPE_INT_STR_SIZE(int)];
119 Symbol *sym = LookupStringConstSymbol(str);
124 - sprintf(stringName, "string #%d", stringConstIndex++);
125 + sprintf(stringName, STRING_CONST_SYM_PREFIX "%d", stringConstIndex++);
126 value.tag = STRING_TAG;
127 AllocNStringCpy(&value.val.str, str);
128 return(InstallSymbol(stringName, CONST_SYM, value));
131 @@ -850,14 +863,12 @@ Symbol *LookupSymbol(const char *name)
134 for (s = LocalSymList; s != NULL; s = s->next)
135 if (strcmp(s->name, name) == 0)
137 - for (s = GlobalSymList; s != NULL; s = s->next)
138 - if (strcmp(s->name, name) == 0)
142 + return lookUpInSymTab(GlobalSymTab, GLOBAL_SYMTAB_SIZE, name);
146 ** install symbol name in symbol table
148 @@ -873,12 +884,11 @@ Symbol *InstallSymbol(const char *name,
150 if (type == LOCAL_SYM) {
151 s->next = LocalSymList;
154 - s->next = GlobalSymList;
156 + addToSymTab(GlobalSymTab, GLOBAL_SYMTAB_SIZE, s);
162 @@ -907,12 +917,11 @@ Symbol *PromoteToGlobal(Symbol *sym)
163 s = LookupSymbol(sym->name);
167 sym->type = GLOBAL_SYM;
168 - sym->next = GlobalSymList;
169 - GlobalSymList = sym;
170 + addToSymTab(GlobalSymTab, GLOBAL_SYMTAB_SIZE, sym);
176 @@ -1131,10 +1140,11 @@ static void MarkArrayContentsAsUsed(Spar
177 void GarbageCollectStrings(void)
179 SparseArrayEntryWrapper *nextAP, *thisAP;
184 /* mark all strings as unreferenced */
185 for (p = AllocatedStrings; p != NULL; p = *((char **)p)) {
186 *(p + sizeof(char *)) = 0;
188 @@ -1144,19 +1154,21 @@ void GarbageCollectStrings(void)
192 /* Sweep the global symbol list, marking which strings are still
194 - for (s = GlobalSymList; s != NULL; s = s->next) {
195 - if (s->value.tag == STRING_TAG) {
196 - /* test first because it may be read-only static string */
197 - if (!(*(s->value.val.str.rep - 1))) {
198 - *(s->value.val.str.rep - 1) = 1;
199 + for (idx = 0; idx < GLOBAL_SYMTAB_SIZE; idx++) {
200 + for (s = GlobalSymTab[idx]; s != NULL; s = s->next) {
201 + if (s->value.tag == STRING_TAG) {
202 + /* test first because it may be read-only static string */
203 + if (!(*(s->value.val.str.rep - 1))) {
204 + *(s->value.val.str.rep - 1) = 1;
207 + else if (s->value.tag == ARRAY_TAG) {
208 + MarkArrayContentsAsUsed(s->value.val.arrayPtr);
211 - else if (s->value.tag == ARRAY_TAG) {
212 - MarkArrayContentsAsUsed(s->value.val.arrayPtr);
216 /* Collect all of the strings which remain unreferenced */
217 next = AllocatedStrings;
218 @@ -1219,21 +1231,71 @@ static void restoreContext(RestartData *
220 InitiatingWindow = context->runWindow;
221 FocusWindow = context->focusWindow;
224 -static void freeSymbolTable(Symbol *symTab)
225 +static void freeSymbolList(Symbol *symList)
229 - while(symTab != NULL) {
232 + while (symList != NULL) {
239 +static unsigned int hashNameWith(unsigned int hash, const char *name)
242 + unsigned char c = *name++;
243 + hash = (hash * 16777619u) + c;
249 +static unsigned int hashName(const char *name)
251 + return hashNameWith(2166136261u, name);
254 +static void addToSymTab(Symbol **symTab, unsigned int symTabSize,
259 + sym->hash = hashName(sym->name);
261 + idx = sym->hash % symTabSize;
263 + sym->next = symTab[idx];
267 +static Symbol *lookUpInSymTab(Symbol **symTab, unsigned int symTabSize,
274 + hash = hashName(name);
276 + idx = hash % symTabSize;
280 + if (sym->hash == hash && !strcmp(name, sym->name)) {
289 #define POP(dataVal) \
292 dataVal = *--StackP; \
294 @@ -4417,12 +4479,12 @@ static void disasmInternal(Inst *inst, i
295 if (inst[i].func == OpFns[j]) {
296 printd(" %*s", (int)opLen, opNames[j]);
297 if (j == OP_PUSH_SYM || j == OP_ASSIGN) {
298 Symbol *sym = inst[i+1].sym;
299 printd(" %s", sym->name);
300 - if (sym->value.tag == STRING_TAG &&
301 - strncmp(sym->name, "string #", 8) == 0) {
302 + if (sym->type == CONST_SYM
303 + && sym->value.tag == STRING_TAG) {
309 diff --quilt old/source/interpret.h new/source/interpret.h
310 --- old/source/interpret.h
311 +++ new/source/interpret.h
312 @@ -109,10 +109,11 @@ typedef struct SparseArrayEntryTag {
313 /* symbol table entry */
314 typedef struct SymbolRec {
319 struct SymbolRec *next; /* to link to another */
323 typedef struct ProgramTag {