fix nc -do ""
[nedit-bw.git] / global-RestartData.patch
blobd59b84126beff1844765ec3d58b866efbbfe610f
1 ---
3 source/interpret.c | 173 ++++++++++++++++++++++-------------------------------
4 source/interpret.h | 3
5 2 files changed, 76 insertions(+), 100 deletions(-)
7 diff --quilt old/source/interpret.c new/source/interpret.c
8 --- old/source/interpret.c
9 +++ new/source/interpret.c
10 @@ -81,8 +81,7 @@ static const char CVSID[] = "$Id: interp
11 enum opStatusCodes {STAT_OK=2, STAT_DONE, STAT_ERROR, STAT_PREEMPT};
13 static int addLoopAddr(Inst *addr, char **msg);
14 -static void saveContext(RestartData *context);
15 -static void restoreContext(RestartData *context);
16 +static RestartData *setContext(RestartData *context);
18 #define OP(name, fn) static int fn(void);
19 #include "ops.h"
20 @@ -100,7 +99,7 @@ static void addToGlobalSymTab(Symbol *sy
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 int execError(RestartData *context, 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 @@ -133,9 +132,9 @@ static void disasmInternal(Inst *inst, i
30 #endif /* #ifndef DEBUG_ASSEMBLY */
32 #ifdef DEBUG_STACK /* for run-time instruction and stack trace */
33 -static void stackdump(int n, int extra);
34 -static void stackdumpInternal(int n, int extra);
35 -#define STACKDUMP(n, x) stackdump(n, x)
36 +static void stackdump(RestartData *context, int n, int extra);
37 +static void stackdumpInternal(RestartData *context, int n, int extra);
38 +#define STACKDUMP(n, x) stackdump(Interpreter, n, x)
39 #define DISASM_RT() disasm(NULL, PC - 1, 1)
40 #else /* #ifndef DEBUG_STACK */
41 #define STACKDUMP(n, x)
42 @@ -175,16 +174,14 @@ static Inst **LoopStackPtr = LoopStack;
43 static const char *ProgramName = "";
45 /* Global data for the interpreter */
46 -static DataValue *TheStack; /* the stack */
47 -static DataValue *StackP; /* next free spot on stack */
48 -static DataValue *FrameP; /* frame pointer (start of local variables
49 - for the current subroutine invocation) */
50 -static Inst *PC; /* program counter during execution */
51 -static char *ErrMsg; /* global for returning error messages
52 - from executing functions */
53 -static WindowInfo
54 - *InitiatingWindow = NULL; /* window from which macro was run */
55 -static WindowInfo *FocusWindow; /* window on which macro commands operate */
56 +static RestartData *Interpreter;
57 +#define StackP (Interpreter->stackP)
58 +#define TheStack (Interpreter->stack)
59 +#define FrameP (Interpreter->frameP)
60 +#define PC (Interpreter->pc)
61 +#define InitiatingWindow (Interpreter->runWindow)
62 +#define FocusWindow (Interpreter->focusWindow)
63 +#define ErrMsg (Interpreter->errMsg)
64 static int PreemptRequest; /* passes preemption requests from called
65 routines back up to the interpreter */
67 @@ -536,8 +533,8 @@ static int setupFrame(RestartData *conte
70 /* !OK_TO_PUSH(totalPushs) */
71 - if (!((context->stackP + totalPushs) <= &context->stack[STACK_SIZE])) {
72 - return execError(StackOverflowMsg, "");
73 + if (!((context->stackP + totalPushs) <= (context->stack + STACK_SIZE))) {
74 + return execError(context, StackOverflowMsg, "");
77 /* Push arguments and caller information onto the stack */
78 @@ -651,8 +648,7 @@ int ExecuteMacro(WindowInfo *window, Pro
79 /* Create an execution context (a stack, a stack pointer, a frame pointer,
80 and a program counter) which will retain the program state across
81 preemption and resumption of execution */
82 - context = (RestartData *)XtMalloc(sizeof(RestartData));
83 - context->stack = (DataValue *)XtMalloc(sizeof(DataValue) * STACK_SIZE);
84 + context = XtNew(RestartData);
85 *continuation = context;
86 context->stackP = context->stack;
87 context->runWindow = window;
88 @@ -666,7 +662,7 @@ int ExecuteMacro(WindowInfo *window, Pro
89 prog->name ? prog->name : "<exec-macro>");
91 if (status == STAT_ERROR) {
92 - *msg = ErrMsg;
93 + *msg = context->errMsg;
94 FreeRestartData(context);
95 return MACRO_ERROR;
97 @@ -683,25 +679,25 @@ int ContinueMacro(RestartData *continuat
99 register int status, instCount = 0;
100 register Inst *inst;
101 - RestartData oldContext;
103 - /* To allow macros to be invoked arbitrarily (such as those automatically
104 - triggered within smart-indent) within executing macros, this call is
105 - reentrant. */
106 - saveContext(&oldContext);
107 + RestartData *oldContext;
110 + ** To allow macros to be invoked arbitrarily (such as those automatically
111 + ** triggered within smart-indent) within executing macros, this call is
112 + ** reentrant.
113 + **
114 ** Execution Loop: Call the succesive routine addresses in the program
115 ** until one returns something other than STAT_OK, then take action
117 - restoreContext(continuation);
118 + oldContext = setContext(continuation);
119 ErrMsg = NULL;
120 for (;;) {
122 /* Execute an instruction */
123 inst = PC++;
124 if (inst->type != OP_INST) {
125 - status = execError("Unexpected instruction of type <%s>",
126 + status = execError(continuation,
127 + "Unexpected instruction of type <%s>",
128 instTypeToStr(inst->type));
130 else {
131 @@ -712,28 +708,26 @@ int ContinueMacro(RestartData *continuat
132 status = (OpFns[inst->val.op])();
133 break;
134 default:
135 - status = execError("Illegal instruction at %p", (char *)inst);
136 + status = execError(continuation, "Illegal instruction at %p",
137 + (char *)inst);
141 /* If error return was not STAT_OK, return to caller */
142 if (status != STAT_OK) {
143 if (status == STAT_PREEMPT) {
144 - saveContext(continuation);
145 - restoreContext(&oldContext);
146 + setContext(oldContext);
147 return MACRO_PREEMPT;
148 } else if (status == STAT_ERROR) {
149 *msg = ErrMsg;
150 - saveContext(continuation);
151 + setContext(oldContext);
152 FreeRestartData(continuation);
153 - restoreContext(&oldContext);
154 return MACRO_ERROR;
155 } else if (status == STAT_DONE) {
156 *msg = "";
157 *result = *--StackP;
158 - saveContext(continuation);
159 + setContext(oldContext);
160 FreeRestartData(continuation);
161 - restoreContext(&oldContext);
162 return MACRO_DONE;
165 @@ -743,8 +737,7 @@ int ContinueMacro(RestartData *continuat
166 X, other macros, and other shell scripts a chance to execute */
167 instCount++;
168 if (instCount >= INSTRUCTION_LIMIT) {
169 - saveContext(continuation);
170 - restoreContext(&oldContext);
171 + setContext(oldContext);
172 return MACRO_TIME_LIMIT;
175 @@ -766,7 +759,7 @@ int RunMacroAsSubrCall(RestartData *cont
176 prog->name ? prog->name : "<run-macro>");
178 if (status == STAT_ERROR) {
179 - *msg = ErrMsg;
180 + *msg = context->errMsg;
181 FreeRestartData(context);
182 return MACRO_ERROR;
184 @@ -780,7 +773,6 @@ int RunMacroAsSubrCall(RestartData *cont
185 void FreeRestartData(RestartData *context)
187 rewindStack(context);
188 - XtFree((char *)context->stack);
189 XtFree((char *)context);
192 @@ -801,8 +793,8 @@ void PreemptMacro(void)
194 void ModifyReturnedValue(RestartData *context, DataValue dv)
196 - if ((context->pc-1)->val.op == OP_FETCH_RET_VAL)
197 - *(context->stackP-1) = dv;
198 + if ((context->pc - 1)->val.op == OP_FETCH_RET_VAL)
199 + *(context->stackP - 1) = dv;
203 @@ -811,7 +803,7 @@ void ModifyReturnedValue(RestartData *co
205 WindowInfo *MacroRunWindow(void)
207 - return InitiatingWindow;
208 + return Interpreter ? InitiatingWindow : NULL;
212 @@ -821,7 +813,7 @@ WindowInfo *MacroRunWindow(void)
214 WindowInfo *MacroFocusWindow(void)
216 - return FocusWindow;
217 + return Interpreter ? FocusWindow : NULL;
221 @@ -830,7 +822,12 @@ WindowInfo *MacroFocusWindow(void)
223 void SetMacroFocusWindow(WindowInfo *window)
225 - FocusWindow = window;
226 + if (Interpreter) {
227 + FocusWindow = window;
229 + else {
230 + fprintf(stderr, "NEdit: setting FocusWindow while not running a macro\n");
235 @@ -1320,24 +1317,11 @@ void GarbageCollectStrings(void)
237 ** Save and restore execution context to data structure "context"
239 -static void saveContext(RestartData *context)
240 +static RestartData *setContext(RestartData *new)
242 - context->stack = TheStack;
243 - context->stackP = StackP;
244 - context->frameP = FrameP;
245 - context->pc = PC;
246 - context->runWindow = InitiatingWindow;
247 - context->focusWindow = FocusWindow;
250 -static void restoreContext(RestartData *context)
252 - TheStack = context->stack;
253 - StackP = context->stackP;
254 - FrameP = context->frameP;
255 - PC = context->pc;
256 - InitiatingWindow = context->runWindow;
257 - FocusWindow = context->focusWindow;
258 + RestartData *old = Interpreter;
259 + Interpreter = new;
260 + return old;
263 static void freeSymbolList(Symbol *symList)
264 @@ -1377,7 +1361,7 @@ static void addToGlobalSymTab(Symbol *sy
265 GlobalSymTab[idx] = sym;
268 -#define EXEC_ERROR(s1, s2) return execError(s1, s2)
269 +#define EXEC_ERROR(s1, s2) return execError(Interpreter, s1, s2)
271 #define GET_SYM(s) \
272 do { \
273 @@ -1438,7 +1422,7 @@ static void addToGlobalSymTab(Symbol *sy
275 /* true, if you can push n values */
276 #define OK_TO_PUSH(n) \
277 - (StackP + (n) <= &TheStack[STACK_SIZE])
278 + (StackP + (n) <= (TheStack + STACK_SIZE))
280 #define PUSH_CHECK(n) \
281 do { \
282 @@ -1607,9 +1591,8 @@ static int pushSymVal(void)
283 symVal = FP_GET_ARG_N(FrameP, argNum);
285 } else if (s->type == PROC_VALUE_SYM) {
286 - char *errMsg;
287 - if (!(s->value.val.subr)(FocusWindow, NULL, 0,
288 - &symVal, &errMsg)) {
289 + char *errMsg;
290 + if (!s->value.val.subr(FocusWindow, NULL, 0, &symVal, &errMsg)) {
291 EXEC_ERROR(errMsg, s->name);
293 } else
294 @@ -2374,8 +2357,8 @@ static int eq(void)
295 /* negated eq() call */
296 static int ne(void)
298 - eq();
299 - return not();
300 + int status = eq();
301 + return (status == STAT_OK) ? not() : status;
305 @@ -2705,7 +2688,6 @@ static int callSubroutineFromSymbol(Symb
306 static DataValue noValue = {NO_TAG, {0}};
307 DataValue argArray = noValue;
308 Program *prog;
309 - char *errMsg;
310 int haveNamedArgs = (nArgs < 0);
312 if (haveNamedArgs) {
313 @@ -2718,6 +2700,7 @@ static int callSubroutineFromSymbol(Symb
315 if (sym->type == C_FUNCTION_SYM) {
316 DataValue result;
317 + char *errMsg;
319 PUSH(argArray); /* push dummy named arg array */
321 @@ -2726,9 +2709,9 @@ static int callSubroutineFromSymbol(Symb
323 /* Call the function and check for preemption */
324 PreemptRequest = False;
325 - if (!sym->value.val.subr(FocusWindow, StackP,
326 - nArgs, &result, &errMsg))
327 + if (!sym->value.val.subr(FocusWindow, StackP, nArgs, &result, &errMsg)) {
328 EXEC_ERROR(errMsg, sym->name);
330 PUSH_RET_VAL(result);
331 return PreemptRequest ? STAT_PREEMPT : STAT_OK;
333 @@ -2741,15 +2724,10 @@ static int callSubroutineFromSymbol(Symb
334 ** values which are already there.
336 if (sym->type == MACRO_FUNCTION_SYM) {
337 - RestartData context;
338 - int status;
339 prog = sym->value.val.prog;
340 prog->refcount++;
341 /* -nArgs means 'arguments are on stack' */
342 - saveContext(&context);
343 - status = setupFrame(&context, prog, -nArgs, NULL, argArray, sym->name);
344 - restoreContext(&context);
345 - return status;
346 + return setupFrame(Interpreter, prog, -nArgs, NULL, argArray, sym->name);
350 @@ -3002,7 +2980,6 @@ static int returnValOrNone(int valOnStac
352 DataValue retVal;
353 static DataValue noValue = {NO_TAG, {0}};
354 - RestartData context;
356 DISASM_RT();
357 STACKDUMP(StackP - FrameP + FP_GET_ARG_COUNT(FrameP) + FP_TO_ARGS_DIST, 3);
358 @@ -3015,9 +2992,7 @@ static int returnValOrNone(int valOnStac
359 retVal = noValue;
362 - saveContext(&context);
363 - rewindFrame(&context);
364 - restoreContext(&context);
365 + rewindFrame(Interpreter);
367 /* push returned value, if requsted */
368 PUSH_RET_VAL(retVal);
369 @@ -4160,27 +4135,27 @@ static int errCheck(const char *s)
371 ** build a stack dump string, reallocating s as necessary.
373 -static char *stackDumpStr(DataValue *fp, const char *msg, char **s, int *pLen)
374 +static char *stackDumpStr(RestartData *context, const char *msg, char **s, int *pLen)
376 static const char backtraceMsg[] = "\n\nBacktrace:";
377 char frameBuf[TYPE_INT_STR_SIZE(int) + 2];
378 int len, nFrames, frameWidth, thisFrameWidth;
379 const char *op;
380 char *np;
381 - DataValue *nfp = fp;
382 + DataValue *nfp = context->frameP;
383 Inst *pc;
385 #ifdef DEBUG_STACK
386 const char *dump;
387 static const char stackdumpMsg[] = "\n\nStack:\n";
388 - disasmInternal(PC - 1, 1);
389 - stackdumpInternal(0, 50);
390 + disasmInternal(context->pc - 1, 1);
391 + stackdumpInternal(context, 0, 50);
392 dump = printd(NULL);
393 #endif
395 /* first measure the lengths */
396 len = strlen(msg) + strlen(backtraceMsg) + 1;
397 - nfp = fp;
398 + nfp = context->frameP;
399 nFrames = 0;
400 do {
401 nFrames++;
402 @@ -4207,7 +4182,7 @@ static char *stackDumpStr(DataValue *fp,
403 while (*op)
404 *np++ = *op++;
406 - nfp = fp;
407 + nfp = context->frameP;
408 nFrames = 0;
409 do {
410 nFrames++;
411 @@ -4246,14 +4221,14 @@ static char *stackDumpStr(DataValue *fp,
412 ** result. Returns false so a single return execError() statement can
413 ** be used to both process the message and return.
415 -static int execError(const char *s1, const char *s2)
416 +static int execError(RestartData *context, const char *s1, const char *s2)
418 static char msg[MAX_ERR_MSG_LEN];
419 static char *err = NULL;
420 static int errlen = 0;
422 sprintf(msg, s1, s2);
423 - ErrMsg = stackDumpStr(FrameP, msg, &err, &errlen);
424 + context->errMsg = stackDumpStr(context, msg, &err, &errlen);
425 return STAT_ERROR;
428 @@ -4887,25 +4862,25 @@ static void stackdumpframe(DataValue *ar
429 #endif /* #ifdef DEBUG_STACK_HEADFIRST */
432 -static void stackdumpInternal(int n, int extra)
433 +static void stackdumpInternal(RestartData *context, int n, int extra)
435 - DataValue *arrow = StackP - n;
436 - DataValue *outpt = StackP - n - extra;
437 + DataValue *arrow = context->stackP - n;
438 + DataValue *outpt = context->stackP - n - extra;
440 #ifdef DEBUG_STACK_HEADFIRST
441 printd("Stack ----->\n");
442 - stackdumpframe(arrow, outpt, FrameP, StackP, '*');
443 - if (outpt < TheStack)
444 + stackdumpframe(arrow, outpt, context->frameP, context->stackP, '*');
445 + if (outpt < context->stack)
446 printd("--------------Stack base--------------\n");
447 #else
448 - if (outpt < TheStack)
449 + if (outpt < context->stack)
450 printd("--------------Stack base--------------\n");
451 - stackdumpframe(arrow, outpt, FrameP, StackP, '*');
452 + stackdumpframe(arrow, outpt, context->frameP, context->stackP, '*');
453 printd("Stack ----->\n\n");
454 #endif /* #ifdef DEBUG_STACK_HEADFIRST */
457 -static void stackdump(int n, int extra)
458 +static void stackdump(RestartData *context, int n, int extra)
460 static int outIsTTY = -1;
461 if (outIsTTY == -1)
462 @@ -4914,7 +4889,7 @@ static void stackdump(int n, int extra)
463 #ifndef DEBUG_STACKDUMP_EXTRA
464 #define DEBUG_STACKDUMP_EXTRA 0
465 #endif
466 - stackdumpInternal(n, extra + DEBUG_STACKDUMP_EXTRA);
467 + stackdumpInternal(context, n, extra + DEBUG_STACKDUMP_EXTRA);
468 #undef DEBUG_STACKDUMP_EXTRA
470 if (outIsTTY)
471 diff --quilt old/source/interpret.h new/source/interpret.h
472 --- old/source/interpret.h
473 +++ new/source/interpret.h
474 @@ -120,12 +120,13 @@ typedef struct ProgramTag {
476 /* Information needed to re-start a preempted macro */
477 typedef struct {
478 - DataValue *stack;
479 + DataValue stack[STACK_SIZE];
480 DataValue *stackP;
481 DataValue *frameP;
482 Inst *pc;
483 WindowInfo *runWindow;
484 WindowInfo *focusWindow;
485 + char *errMsg;
486 } RestartData;
488 /* state of the accumulator (aka compiler) */