pushString: remove unused variables
[nedit-bw.git] / pushString.patch
blobc257dce5ccf7d76f2a211d01312a6dc400bf85b4
1 ---
3 source/interpret.c | 289 ++++++++++++++++++++++++++++++++++++++---------------
4 source/interpret.h | 17 +--
5 source/ops.h | 1
6 source/parse.y | 21 ++-
7 4 files changed, 235 insertions(+), 93 deletions(-)
9 diff --quilt old/source/interpret.c new/source/interpret.c
10 --- old/source/interpret.c
11 +++ new/source/interpret.c
12 @@ -288,12 +288,11 @@ Program *FinishCreatingProgram(Accumulat
13 Symbol *s;
15 newProg = XtNew(Program);
16 - newProg->name = XtMalloc(strlen(ProgramName) + 1); /* +1 for '\0' */
17 + newProg->name = LookupString(ProgramName, True);
18 progLen = ProgP - Prog;
19 newProg->code = (Inst *)XtCalloc(progLen, sizeof(Inst));
20 memcpy(newProg->code, Prog, progLen * sizeof(Inst));
21 newProg->localSymList = LocalSymList;
22 - strcpy(newProg->name, ProgramName);
23 newProg->refcount = 1;
25 /* Local variables' values are stored on the stack. Here we assign
26 @@ -314,7 +313,6 @@ void FreeProgram(Program *prog)
27 if (--prog->refcount == 0) {
28 freeSymbolList(prog->localSymList);
29 XtFree((char *)prog->code);
30 - XtFree((char *)prog->name);
31 XtFree((char *)prog);
34 @@ -365,6 +363,21 @@ int AddImmediate(int immed, char **msg)
38 +** Add an string value operand to the current program
39 +*/
40 +int AddString(const char *str, char **msg)
42 + if (ProgP >= &Prog[PROGRAM_SIZE]) {
43 + *msg = "macro too large";
44 + return 0;
45 + }
46 + ProgP->type = STRING_INST;
47 + ProgP->val.str = str;
48 + ProgP++;
49 + return 1;
52 +/*
53 ** Add a branch offset operand to the current program
55 int AddBranchOffset(Inst *to, char **msg)
56 @@ -817,47 +830,6 @@ void SetMacroFocusWindow(WindowInfo *win
60 -/*
61 -** Lookup a constant string by its value. This allows reuse of string
62 -** constants and fixing a leak in the interpreter.
63 -*/
64 -Symbol *LookupStringConstSymbol(const char *value)
66 - unsigned int idx;
67 - Symbol *s;
69 - for (idx = 0; idx < GLOBAL_SYMTAB_SIZE; idx++) {
70 - for (s = GlobalSymTab[idx]; s != NULL; s = s->next) {
71 - if (s->type == CONST_SYM
72 - && s->value.tag == STRING_TAG
73 - && !strcmp(s->value.val.str.rep, value)) {
74 - return(s);
75 - }
76 - }
77 - }
79 - return(NULL);
82 -/*
83 -** install string str in the global symbol table with a string name
84 -*/
85 -Symbol *InstallStringConstSymbol(const char *str)
87 - static int stringConstIndex = 0;
88 - char stringName[35];
89 - DataValue value;
90 - Symbol *sym = LookupStringConstSymbol(str);
91 - if (sym) {
92 - return sym;
93 - }
95 - sprintf(stringName, "string #%d", stringConstIndex++);
96 - value.tag = STRING_TAG;
97 - AllocNStringCpy(&value.val.str, str);
98 - return(InstallSymbol(stringName, CONST_SYM, value));
101 static Symbol *lookupSymbol(Symbol *symlist, const char *name,
102 unsigned int hash)
104 @@ -904,8 +876,7 @@ Symbol *InstallSymbol(const char *name,
105 Symbol *s;
107 s = XtNew(Symbol);
108 - s->name = (char *)XtMalloc(strlen(name) + 1); /* +1 for '\0' */
109 - strcpy(s->name, name);
110 + s->name = LookupString(name, True);
111 s->type = type;
112 s->value = value;
113 s->hash = hashName(s->name);
114 @@ -1285,7 +1256,6 @@ static void freeSymbolList(Symbol *symLi
115 while (symList != NULL) {
116 s = symList;
117 symList = s->next;
118 - XtFree((char *)s->name);
119 XtFree((char *)s);
122 @@ -1347,6 +1317,16 @@ static void addToGlobalSymTab(Symbol *sy
123 PC++; \
124 } while (0)
126 +#define GET_STR(s) \
127 + do { \
128 + if (PC->type != STRING_INST) { \
129 + EXEC_ERROR("Unexpected instruction, expected <string>: <%s>", \
130 + instTypeToStr(PC->type)); \
131 + } \
132 + s = PC->val.str; \
133 + PC++; \
134 + } while (0)
136 #define JUMP(a) \
137 do { \
138 PC = (a); \
139 @@ -1529,7 +1509,7 @@ static int pushSymVal(void)
141 if (s->type == LOCAL_SYM) {
142 symVal = FP_GET_SYM_VAL(FrameP, s);
143 - } else if (s->type == GLOBAL_SYM || s->type == CONST_SYM) {
144 + } else if (s->type == GLOBAL_SYM) {
145 symVal = s->value;
146 } else if (s->type == ARG_SYM) {
147 nArgs = FP_GET_ARG_COUNT(FrameP);
148 @@ -1581,6 +1561,27 @@ static int pushImmed(void)
149 return STAT_OK;
153 +** push string onto the stack
154 +** Before: Prog-> [string], next, ...
155 +** TheStack-> next, ...
156 +** After: Prog-> string, [next], ...
157 +** TheStack-> [string], next, ...
159 +static int pushString(void)
161 + const char *str;
163 + DISASM_RT();
164 + STACKDUMP(0, 3);
166 + GET_STR(str);
168 + PUSH_STRING((char *)str, strlen(str));
170 + return STAT_OK;
173 static int pushArgVal(void)
175 int nArgs, argNum;
176 @@ -2919,7 +2920,7 @@ int OverlayRoutineFromProg(Program *prog
177 Symbol sym;
179 sym.type = MACRO_FUNCTION_SYM;
180 - sym.name = prog->name;
181 + sym.name = LookupString(prog->name, True);
182 sym.value.tag = NO_TAG;
183 sym.value.val.prog = prog;
184 sym.next = NULL;
185 @@ -4088,6 +4089,108 @@ static int errCheck(const char *s)
189 +** string lookup stuff
192 +/* should be the pagesize */
193 +#define STRING_BLK_SIZE 4096
195 +typedef struct stringEntryTag {
196 + struct stringEntryTag *next;
197 + unsigned int hash;
198 + char str[1]; /* [1] for inUse */
199 +} stringEntry;
201 +struct stringBlkTag;
202 +typedef struct stringBlkHdrTag {
203 + struct stringBlkTag *next;
204 + unsigned size;
205 + unsigned rem;
206 + stringEntry *free;
207 +} stringBlkHdr;
209 +typedef struct stringBlkTag {
210 + stringBlkHdr hdr;
211 + char blk[1];
212 +} stringBlk;
214 +static stringBlk *lookupStringBlks;
215 +#define STR_LOOKUP_TAB_SHIFT 10
216 +#define STR_LOOKUP_TAB_SIZE (1u << (STR_LOOKUP_TAB_SHIFT))
217 +#define STR_LOOKUP_TAB_MASK ((STR_LOOKUP_TAB_SIZE) - 1)
218 +static stringEntry *stringTbl[STR_LOOKUP_TAB_SIZE];
220 +const char *LookupString(const char *str, int create)
222 +#define ROUNDUP(x, align) (void *)(-(-((intptr_t)(x)) & -(align)))
223 + unsigned int len = strlen(str) + 1;
224 + unsigned int hash = hashName(str);
225 + unsigned int idx = hash & STR_LOOKUP_TAB_MASK;
226 + stringBlk **blkp = &lookupStringBlks;
227 + stringBlk *blk;
228 + stringEntry *e;
230 + /* search str in hash table */
231 + for (e = stringTbl[idx]; e; e = e->next) {
232 + if (e->hash == hash && 0 == strcmp(str, &e->str[1]))
233 + return &e->str[1];
235 + if (!create) {
236 + return NULL;
239 + /* find space for str */
240 + while (*blkp) {
241 + if ((*blkp)->hdr.rem >= len) {
242 + break;
244 + blkp = &(*blkp)->hdr.next;
246 + blk = *blkp;
248 + /* no space found, create new string bulk */
249 + if (!blk) {
250 + void *ptr;
251 + unsigned size = (unsigned)ROUNDUP(sizeof(stringBlkHdr), sizeof(void *))
252 + + sizeof(stringEntry) + len;
253 + size = (unsigned)ROUNDUP(size, STRING_BLK_SIZE);
255 + posix_memalign(&ptr, STRING_BLK_SIZE, size);
256 + *blkp = blk = ptr;
257 + blk->hdr.size = size;
258 + blk->hdr.next = NULL;
260 + /* round up to sizeof(void *) */
261 + blk->hdr.free = ROUNDUP(blk->blk, sizeof(void *));
262 + blk->hdr.rem = ((char *)blk + blk->hdr.size)
263 + - blk->hdr.free->str - sizeof(stringEntry);
266 + /* mark string as constant and copy str into bulk */
267 + blk->hdr.free->str[1] = 1;
268 + strcpy(&blk->hdr.free->str[1], str);
269 + str = &blk->hdr.free->str[1];
271 + /* insert string into hash table */
272 + blk->hdr.free->next = stringTbl[idx];
273 + blk->hdr.free->hash = hash;
274 + stringTbl[idx] = blk->hdr.free;
276 + /* calculate remaining space */
277 + blk->hdr.free = ROUNDUP((char *)blk->hdr.free + sizeof(stringEntry) + len,
278 + sizeof(void *));
279 + blk->hdr.rem = ((char *)blk + blk->hdr.size) - blk->hdr.free->str;
280 + if (blk->hdr.rem <= sizeof(stringEntry) + 2) {
281 + blk->hdr.rem = 0;
282 + } else {
283 + blk->hdr.rem -= sizeof(stringEntry);
286 + return str;
287 +#undef ROUNDUP
291 ** build a stack dump string, reallocating s as necessary.
293 static char *stackDumpStr(DataValue *fp, const char *msg, char **s, int *pLen)
294 @@ -4266,6 +4369,8 @@ static const char *instTypeToStr(enum in
295 return "operation";
296 case IMMED_INST:
297 return "immediate";
298 + case STRING_INST:
299 + return "string";
300 case BRANCH_INST:
301 return "branch";
302 case SYM_INST:
303 @@ -4348,6 +4453,41 @@ int outPrintd()
304 #endif /* #ifdef DEBUG_DISASSEMBLER */
306 #ifdef DEBUG_DISASSEMBLER /* dumping values in disassembly or stack dump */
307 +static const char *printableString(const char *src, int *shortaged)
309 + int k, l;
310 + static char s[64];
312 + for (k = 0, l = 0; src[k] && l < sizeof s - 1; k++, l++) {
313 + const char *e;
314 + const char to[] = "\\\"ntbrfave";
315 +#ifdef EBCDIC_CHARSET
316 + const char from[] = "\\\"\n\t\b\r\f\a\v\x27"; /* EBCDIC escape */
317 +#else
318 + const char from[] = "\\\"\n\t\b\r\f\a\v\x1B"; /* ASCII escape */
319 +#endif
320 + if ((e = strchr(from, src[k]))) {
321 + if (l < sizeof s - 2) {
322 + s[l++] = '\\';
323 + s[l] = to[e - from];
326 + else if (isprint(src[k])) {
327 + s[l] = src[k];
329 + else {
330 + s[l] = '?';
333 + s[l] = 0;
335 + if (shortaged) {
336 + *shortaged = !!src[k];
339 + return s;
342 static void dumpVal(DataValue dv)
344 switch (dv.tag) {
345 @@ -4356,37 +4496,16 @@ static void dumpVal(DataValue dv)
346 break;
347 case STRING_TAG:
349 - int k, l;
350 - char s[64];
351 const char *src = dv.val.str.rep;
352 if (!src) {
353 printd(" <%s NULL>", tagToStr(STRING_TAG));
355 else {
356 - for (k = 0, l = 0; src[k] && l < sizeof s - 1; k++, l++) {
357 - char *e;
358 - const char to[] = "\\\"ntbrfave";
359 -#ifdef EBCDIC_CHARSET
360 - const char from[] = "\\\"\n\t\b\r\f\a\v\x27"; /* EBCDIC escape */
361 -#else
362 - const char from[] = "\\\"\n\t\b\r\f\a\v\x1B"; /* ASCII escape */
363 -#endif
364 - if ((e = strchr(from, src[k]))) {
365 - if (l < sizeof s - 2) {
366 - s[l++] = '\\';
367 - s[l] = to[e - from];
370 - else if (isprint(src[k])) {
371 - s[l] = src[k];
373 - else {
374 - s[l] = '?';
377 - s[l] = 0;
378 - printd(" <%s %u:\"%s\"%s>", tagToStr(STRING_TAG),
379 - (unsigned)strlen(src), s, src[k] ? "..." : "");
380 + int cut;
381 + unsigned len = strlen(src);
382 + src = printableString(src, &cut);
383 + printd(" <%s %u:\"%s\"%s>", tagToStr(STRING_TAG), len, src,
384 + cut ? "..." : "");
387 break;
388 @@ -4449,6 +4568,16 @@ static void dumpInst(Inst *inst, const c
389 printd(" <%s %d>", name, inst->val.immed);
390 break;
392 + case STRING_INST: {
393 + const char *str = inst->val.str;
394 + int cut;
395 + unsigned len = strlen(str);
396 + str = printableString(str, &cut);
397 + printd(" <%s %u:\"%s\"%s>", name,
398 + len, str, cut ? "..." : "");
400 + break;
402 case BRANCH_INST:
403 printd(" <%s %+td:%8p>", name,
404 inst->val.branch, inst + inst->val.branch);
405 @@ -4502,10 +4631,6 @@ static void disasmInternal(Inst *inst, i
406 case OP_ASSIGN:
407 CHECK_OPERANDS(1, SYM_INST);
408 dumpInst(&inst[i+1], NULL);
409 - if (inst[i+1].val.sym->type == CONST_SYM
410 - && inst[i+1].val.sym->value.tag == STRING_TAG) {
411 - dumpVal(inst[i+1].val.sym->value);
413 ++i;
414 break;
416 @@ -4515,6 +4640,12 @@ static void disasmInternal(Inst *inst, i
417 ++i;
418 break;
420 + case OP_PUSH_STRING:
421 + CHECK_OPERANDS(1, STRING_INST);
422 + dumpInst(&inst[i+1], NULL);
423 + ++i;
424 + break;
426 case OP_PEEK_PUSH:
427 CHECK_OPERANDS(1, IMMED_INST);
428 dumpInst(&inst[i+1], "index");
429 diff --quilt old/source/interpret.h new/source/interpret.h
430 --- old/source/interpret.h
431 +++ new/source/interpret.h
432 @@ -40,7 +40,7 @@
433 #define LOOP_STACK_SIZE 256 /* (Approx.) Number of break/continue stmts
434 allowed per program */
436 -enum symTypes {CONST_SYM, GLOBAL_SYM, LOCAL_SYM, ARG_SYM, PROC_VALUE_SYM,
437 +enum symTypes {GLOBAL_SYM, LOCAL_SYM, ARG_SYM, PROC_VALUE_SYM,
438 C_FUNCTION_SYM, MACRO_FUNCTION_SYM, ACTION_ROUTINE_SYM};
440 enum operations {
441 @@ -54,7 +54,7 @@ enum typeTags {NO_TAG, INT_TAG, STRING_T
443 enum execReturnCodes {MACRO_TIME_LIMIT, MACRO_PREEMPT, MACRO_DONE, MACRO_ERROR};
445 -enum instTypes {OP_INST, IMMED_INST, BRANCH_INST, SYM_INST};
446 +enum instTypes {OP_INST, IMMED_INST, STRING_INST, BRANCH_INST, SYM_INST};
448 #define ARRAY_DIM_SEP "\034"
450 @@ -68,6 +68,7 @@ typedef struct InstTag {
451 union {
452 enum operations op;
453 int immed;
454 + const char *str;
455 ptrdiff_t branch;
456 struct SymbolRec *sym;
457 } val;
458 @@ -104,7 +105,7 @@ typedef struct SparseArrayEntryTag {
460 /* symbol table entry */
461 typedef struct SymbolRec {
462 - char *name;
463 + const char *name;
464 enum symTypes type;
465 DataValue value;
466 unsigned int hash;
467 @@ -112,7 +113,7 @@ typedef struct SymbolRec {
468 } Symbol;
470 typedef struct ProgramTag {
471 - char *name;
472 + const char *name;
473 Symbol *localSymList;
474 Inst *code;
475 unsigned refcount;
476 @@ -158,21 +159,21 @@ Program *FinishCreatingProgram(Accumulat
477 int AddOp(int op, char **msg);
478 int AddSym(Symbol *sym, char **msg);
479 int AddImmediate(int immed, char **msg);
480 +int AddString(const char *str, char **msg);
481 int AddBranchOffset(Inst *to, char **msg);
482 int SetBranchOffset(Inst *from, Inst *to, char **msg);
483 Inst *GetPC(void);
484 -Symbol *LookupStringConstSymbol(const char *value);
485 -Symbol *InstallStringConstSymbol(const char *str);
486 Symbol *LookupSymbol(const char *name);
487 Symbol *InstallSymbol(const char *name, enum symTypes type, DataValue value);
488 +const char *LookupString(const char *str, int create);
489 Inst *SwapCode(Inst *start, Inst *boundary, Inst *end);
490 int StartLoopAddrList(char **msg);
491 int AddBreakAddr(Inst *addr, char **msg);
492 int AddContinueAddr(Inst *addr, char **msg);
493 void FillLoopAddrs(Inst *breakAddr, Inst *continueAddr);
495 -/* create a permanently allocated static string (only for use with static strings) */
496 -#define PERM_ALLOC_STR(xStr) (((char *)("\001" xStr)) + 1)
497 +/* create a permanently allocated static string */
498 +#define PERM_ALLOC_STR(xStr) (char *)LookupString(xStr, 1)
500 /* Routines for executing programs */
501 int ExecuteMacro(WindowInfo *window, Program *prog, int nArgs, DataValue *args,
502 diff --quilt old/source/ops.h new/source/ops.h
503 --- old/source/ops.h
504 +++ new/source/ops.h
505 @@ -7,6 +7,7 @@ OP(RETURN_NO_VAL, returnNoVal)
506 OP(RETURN, returnVal) /* pop(ret), rewind, push(ret) */
507 OP(PUSH_SYM, pushSymVal) /* sym */ /* push(sym.v) */
508 OP(PUSH_IMMED, pushImmed) /* immed */ /* push(immed) */
509 +OP(PUSH_STRING, pushString) /* str */ /* push(str) */
510 OP(POP, popStack) /* pop(v) */
511 OP(DUP, dupStack) /* pop(v), push(v,v) */
512 OP(PEEK_PUSH, peekPush) /* n */ /* peek(v, n), push(v) */
513 diff --quilt old/source/parse.y new/source/parse.y
514 --- old/source/parse.y
515 +++ new/source/parse.y
516 @@ -47,6 +47,12 @@
517 return 1; \
519 } while (0)
520 +#define ADD_STR(str) \
521 + do { \
522 + if (!AddString(str, &ErrMsg)) { \
523 + return 1; \
524 + } \
525 + } while (0)
526 #define ADD_BR_OFF(to) \
527 do { \
528 if (!AddBranchOffset(to, &ErrMsg)) { \
529 @@ -108,13 +114,15 @@ static int nextSymIsField = 0;
530 Symbol *sym;
531 Inst *inst;
532 int num;
533 + const char *str;
534 enum operations oper;
535 struct {
536 AccumulatorData *acc;
537 Symbol *sym;
538 } define;
540 -%token <sym> STRING SYMBOL FIELD
541 +%token <sym> SYMBOL
542 +%token <str> STRING FIELD
543 %token <num> NUMBER
544 %token DELETE ARG_LOOKUP
545 %token IF WHILE DO ELSE FOR BREAK CONTINUE RETURN DEFINE TYPEOF KEYVAL
546 @@ -624,7 +632,7 @@ arraylv: SYMBOL {
549 field: FIELD {
550 - ADD_OP(OP_PUSH_SYM); ADD_SYM($1);
551 + ADD_OP(OP_PUSH_STRING); ADD_STR($1);
553 /* this bit allows things like array.5 for array[5] **
554 | NUMBER {
555 @@ -674,7 +682,7 @@ arrentry: blank {
557 numexpr: '(' blank expr blank ')'
558 | NUMBER { ADD_OP(OP_PUSH_IMMED); ADD_IMMED($1); }
559 - | STRING { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); }
560 + | STRING { ADD_OP(OP_PUSH_STRING); ADD_STR($1); }
561 | SYMBOL { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); }
562 | funccall {
563 ADD_OP(OP_FETCH_RET_VAL);
564 @@ -925,7 +933,7 @@ static int yylex(void)
565 if (!strcmp(symName, "typeof")) return TYPEOF;
566 if (nextSymIsField) {
567 nextSymIsField = 0;
568 - yylval.sym = InstallStringConstSymbol(symName);
569 + yylval.str = LookupString(symName, True);
570 return FIELD;
572 if ((s=LookupSymbol(symName)) == NULL) {
573 @@ -1260,12 +1268,13 @@ static int scanString(void)
574 if (*InPtr == stopper) {
575 if (!p) {
576 /* this was the size measurement and validation */
577 - p = string = AllocString(len);
578 + p = string = XtMalloc(len);
580 else {
581 /* OK: string now contains our string text */
582 InPtr++; /* skip past stopper */
583 - yylval.sym = InstallStringConstSymbol(string);
584 + yylval.str = LookupString(string, True);
585 + XtFree(string);
586 return STRING;