final step to context based macro interpreter
[nedit-bw.git] / GlobalSymTable.patch
blobe39eb3fd84abf57cbc91500809fce27d7c58ce8a
1 Subject: Use a hashtable for the global symbols
3 ---
5 source/interpret.c | 137 +++++++++++++++++++++++++++++++++++++----------------
6 source/interpret.h | 1
7 source/interpret.c | 137 +++++++++++++++++++++++++++++++++++++----------------
8 source/interpret.h | 1
9 2 files changed, 99 insertions(+), 39 deletions(-)
11 diff --quilt old/source/interpret.c new/source/interpret.c
12 --- old/source/interpret.c
13 +++ new/source/interpret.c
14 @@ -95,7 +95,10 @@ static int callSubroutineFromSymbol(Symb
15 static int concatenateNwithSep(int nVals, const char *sep, char **result,
16 int leaveParams);
17 static int makeArrayKeyFromArgs(int nArgs, char **keyString, int leaveParams);
18 -static void freeSymbolTable(Symbol *symTab);
19 +static void freeSymbolList(Symbol *symList);
20 +static void addToGlobalSymTab(Symbol *sym);
21 +static unsigned int hashNameWith(unsigned int hash, const char *name);
22 +static unsigned int hashName(const char *name);
23 static int errCheck(const char *s);
24 static int execError(const char *s1, const char *s2);
25 static rbTreeNode *arrayEmptyAllocator(void);
26 @@ -138,8 +141,11 @@ static void stackdumpInternal(int n, int
27 #define DISASM_RT(i, n)
28 #endif /* #ifndef DEBUG_STACK */
30 -/* Global symbols and function definitions */
31 -static Symbol *GlobalSymList = NULL;
32 +/* Global symbols and function definitions, is null initialized */
33 +#define GLOBAL_SYMTAB_SHIFT 8
34 +#define GLOBAL_SYMTAB_SIZE (1u << (GLOBAL_SYMTAB_SHIFT))
35 +#define GLOBAL_SYMTAB_MASK ((GLOBAL_SYMTAB_SIZE) - 1)
36 +static Symbol *GlobalSymTab[GLOBAL_SYMTAB_SIZE];
38 /* List of all memory allocated for strings */
39 static char *AllocatedStrings = NULL;
40 @@ -315,7 +321,7 @@ Program *FinishCreatingProgram(Accumulat
41 void FreeProgram(Program *prog)
43 if (--prog->refcount == 0) {
44 - freeSymbolTable(prog->localSymList);
45 + freeSymbolList(prog->localSymList);
46 XtFree((char *)prog->code);
47 XtFree((char *)prog);
49 @@ -760,14 +766,14 @@ Symbol *InstallMultiAssignExpr(void)
50 ** install an array iteration symbol
51 ** it is tagged as an integer but holds an array node pointer
53 -#define ARRAY_ITER_SYM_PREFIX "aryiter "
54 +#define ARRAY_ITER_SYM_PREFIX "aryiter #"
55 Symbol *InstallIteratorSymbol(void)
57 char symbolName[sizeof(ARRAY_ITER_SYM_PREFIX) + TYPE_INT_STR_SIZE(int)];
58 DataValue value;
59 - static int interatorNameIndex = 0;
60 + static int interatorNameIndex;
62 - sprintf(symbolName, ARRAY_ITER_SYM_PREFIX "#%d", interatorNameIndex);
63 + sprintf(symbolName, ARRAY_ITER_SYM_PREFIX "%d", interatorNameIndex);
64 ++interatorNameIndex;
65 value.tag = INT_TAG;
66 value.val.arrayPtr = NULL;
67 @@ -780,50 +786,76 @@ Symbol *InstallIteratorSymbol(void)
69 Symbol *LookupStringConstSymbol(const char *value)
71 + unsigned int idx;
72 Symbol *s;
74 - for (s = GlobalSymList; s != NULL; s = s->next) {
75 - if (s->type == CONST_SYM &&
76 - s->value.tag == STRING_TAG &&
77 - !strcmp(s->value.val.str.rep, value)) {
78 - return(s);
79 + for (idx = 0; idx < GLOBAL_SYMTAB_SIZE; idx++) {
80 + for (s = GlobalSymTab[idx]; s != NULL; s = s->next) {
81 + if (s->type == CONST_SYM
82 + && s->value.tag == STRING_TAG
83 + && !strcmp(s->value.val.str.rep, value)) {
84 + return(s);
85 + }
89 return(NULL);
93 ** install string str in the global symbol table with a string name
95 +#define STRING_CONST_SYM_PREFIX "string #"
96 Symbol *InstallStringConstSymbol(const char *str)
98 - static int stringConstIndex = 0;
99 - char stringName[35];
100 + static int stringConstIndex;
101 + char stringName[sizeof(STRING_CONST_SYM_PREFIX) + TYPE_INT_STR_SIZE(int)];
102 DataValue value;
104 Symbol *sym = LookupStringConstSymbol(str);
105 if (sym) {
106 return sym;
109 - sprintf(stringName, "string #%d", stringConstIndex++);
110 + sprintf(stringName, STRING_CONST_SYM_PREFIX "%d", stringConstIndex++);
111 value.tag = STRING_TAG;
112 AllocNStringCpy(&value.val.str, str);
113 return(InstallSymbol(stringName, CONST_SYM, value));
116 +static Symbol *lookupSymbol(const Symbol *symlist, const char *name,
117 + unsigned int hash)
119 + while (NULL != symlist) {
120 + if (hash == symlist->hash && strcmp(symlist->name, name) == 0)
121 + return symlist;
122 + symlist = symlist->next;
125 + return NULL;
129 ** find a symbol in the symbol table
131 Symbol *LookupSymbol(const char *name)
133 + unsigned int hash;
134 Symbol *s;
136 - for (s = LocalSymList; s != NULL; s = s->next)
137 - if (strcmp(s->name, name) == 0)
138 - return s;
139 - for (s = GlobalSymList; s != NULL; s = s->next)
140 - if (strcmp(s->name, name) == 0)
141 - return s;
142 + /* calculate hash for name */
143 + hash = hashName(name);
145 + /* search in local symbols */
146 + s = lookupSymbol(LocalSymList, name, hash);
147 + if (NULL != s)
148 + return s;
150 + /* search in global symbols */
151 + s = lookupSymbol(GlobalSymTab[hash & GLOBAL_SYMTAB_MASK], name, hash);
152 + if (NULL != s)
153 + return s;
155 return NULL;
158 @@ -840,12 +872,12 @@ Symbol *InstallSymbol(const char *name,
159 s->type = type;
160 s->value = value;
161 s->added = 0;
162 + s->hash = hashName(s->name);
163 if (type == LOCAL_SYM) {
164 s->next = LocalSymList;
165 LocalSymList = s;
166 } else {
167 - s->next = GlobalSymList;
168 - GlobalSymList = s;
169 + addToGlobalSymTab(s);
171 return s;
173 @@ -909,8 +941,7 @@ Symbol *PromoteToGlobal(Symbol *sym)
174 but this symbol has no program attached and ProgramFree() is not NULL
175 pointer safe */
176 sym->type = GLOBAL_SYM;
177 - sym->next = GlobalSymList;
178 - GlobalSymList = sym;
179 + addToGlobalSymTab(sym);
181 return sym;
183 @@ -1133,6 +1164,7 @@ void GarbageCollectStrings(void)
184 SparseArrayEntryWrapper *nextAP, *thisAP;
185 char *p, *next;
186 Symbol *s;
187 + unsigned int idx;
189 /* mark all strings as unreferenced */
190 for (p = AllocatedStrings; p != NULL; p = *((char **)p)) {
191 @@ -1146,15 +1178,17 @@ void GarbageCollectStrings(void)
193 /* Sweep the global symbol list, marking which strings are still
194 referenced */
195 - for (s = GlobalSymList; s != NULL; s = s->next) {
196 - if (s->value.tag == STRING_TAG) {
197 - /* test first because it may be read-only static string */
198 - if (!(*(s->value.val.str.rep - 1))) {
199 - *(s->value.val.str.rep - 1) = 1;
200 + for (idx = 0; idx < GLOBAL_SYMTAB_SIZE; idx++) {
201 + for (s = GlobalSymTab[idx]; s != NULL; s = s->next) {
202 + if (s->value.tag == STRING_TAG) {
203 + /* test first because it may be read-only static string */
204 + if (!(*(s->value.val.str.rep - 1))) {
205 + *(s->value.val.str.rep - 1) = 1;
208 + else if (s->value.tag == ARRAY_TAG) {
209 + MarkArrayContentsAsUsed(s->value.val.arrayPtr);
212 - else if (s->value.tag == ARRAY_TAG) {
213 - MarkArrayContentsAsUsed(s->value.val.arrayPtr);
217 @@ -1221,17 +1255,42 @@ static void restoreContext(RestartData *
218 FocusWindow = context->focusWindow;
221 -static void freeSymbolTable(Symbol *symTab)
222 +static void freeSymbolList(Symbol *symList)
224 Symbol *s;
226 - while(symTab != NULL) {
227 - s = symTab;
228 - symTab = s->next;
229 + while (symList != NULL) {
230 + s = symList;
231 + symList = s->next;
232 free(s);
236 +static unsigned int hashNameWith(unsigned int hash, const char *name)
238 + while (*name) {
239 + unsigned int c = *name++;
240 + hash = (hash * 16777619u) + c;
243 + return hash;
246 +static unsigned int hashName(const char *name)
248 + return hashNameWith(2166136261u, name);
251 +static void addToGlobalSymTab(Symbol *sym)
253 + unsigned int idx;
255 + idx = sym->hash & GLOBAL_SYMTAB_MASK;
257 + sym->next = GlobalSymTab[idx];
258 + GlobalSymTab[idx] = sym;
261 /* true, if you can pop n values */
262 #define OK_TO_POP(n) \
263 ((StackP - (n)) >= TheStack)
264 @@ -4413,8 +4472,8 @@ static void disasmInternal(Inst *inst, i
265 if (j == OP_PUSH_SYM || j == OP_ASSIGN) {
266 Symbol *sym = inst[i+1].sym;
267 printd(" %s", sym->name);
268 - if (sym->value.tag == STRING_TAG &&
269 - strncmp(sym->name, "string #", 8) == 0) {
270 + if (sym->type == CONST_SYM
271 + && sym->value.tag == STRING_TAG) {
272 printd(" ");
273 dumpVal(sym->value);
275 diff --quilt old/source/interpret.h new/source/interpret.h
276 --- old/source/interpret.h
277 +++ new/source/interpret.h
278 @@ -101,6 +101,7 @@ typedef struct SymbolRec {
279 enum symTypes type;
280 DataValue value;
281 int added;
282 + unsigned int hash;
283 struct SymbolRec *next; /* to link to another */
284 char name[1];
285 } Symbol;