3 source/interpret.c | 118 ++++++++++++++++++++++++++++++++++-------------------
5 source/macro.c | 11 ++++
6 3 files changed, 87 insertions(+), 44 deletions(-)
8 diff --quilt old/source/macro.c new/source/macro.c
10 +++ new/source/macro.c
11 @@ -1065,8 +1065,15 @@ static void runMacro(WindowInfo *window,
12 instead of starting a new one, so we don't have to keep a separate
13 context, and the macros will serialize themselves automatically */
14 if (window->macroCmdData != NULL) {
15 - RunMacroAsSubrCall(prog);
17 + macroCmdInfo *cmdData = window->macroCmdData;
18 + stat = RunMacroAsSubrCall(cmdData->context, prog, &errMsg);
19 + if (stat == MACRO_ERROR) {
20 + finishMacroCmdExecution(window);
22 + DialogF(DF_ERR, window->shell, 1, "Macro Error",
23 + "Error executing macro: %s", "OK", errMsg);
28 /* put up a watch cursor over the waiting window */
29 diff --quilt old/source/interpret.c new/source/interpret.c
30 --- old/source/interpret.c
31 +++ new/source/interpret.c
32 @@ -512,19 +512,34 @@ void FillLoopAddrs(Inst *breakAddr, Inst
34 ** helper function to setup the next frame
36 -static void setupFrame(DataValue **frameP, DataValue **stackP,
37 - Inst **pc, Program *prog,
38 +static int setupFrame(RestartData *context, Program *prog,
39 int nArgs, DataValue *args, DataValue argArray,
42 static DataValue noValue = {NO_TAG, {0}};
44 + int i, totalPushs = 7;
48 + ** we push only if we have room for the whole frame, so pre-calc the
49 + ** needed space and check for the room
52 + totalPushs += nArgs;
54 + for (s = prog->localSymList; s != NULL; s = s->next) {
58 + /* !OK_TO_PUSH(totalPushs) */
59 + if (!((context->stackP + totalPushs) <= &context->stack[STACK_SIZE])) {
60 + return execError(StackOverflowMsg, "");
63 /* Push arguments and caller information onto the stack */
65 for (i = 0; i < nArgs; i++) {
66 - *((*stackP)++) = args[i];
67 + *(context->stackP++) = args[i];
71 @@ -535,48 +550,50 @@ static void setupFrame(DataValue **frame
74 /* cached arg array */
75 - *((*stackP)++) = argArray;
76 + *(context->stackP++) = argArray;
78 /* prog to free, if requested */
79 - (*stackP)->tag = NO_TAG;
80 - (*stackP)->val.prog = prog;
82 + context->stackP->tag = NO_TAG;
83 + context->stackP->val.prog = prog;
87 - (*stackP)->tag = NO_TAG;
88 - (*stackP)->val.inst = *pc;
90 + context->stackP->tag = NO_TAG;
91 + context->stackP->val.inst = context->pc;
95 - (*stackP)->tag = NO_TAG;
96 - (*stackP)->val.dataval = *frameP;
98 + context->stackP->tag = NO_TAG;
99 + context->stackP->val.dataval = context->frameP;
103 - (*stackP)->tag = NO_TAG;
104 - (*stackP)->val.sym = prog->localSymList;
106 + context->stackP->tag = NO_TAG;
107 + context->stackP->val.sym = prog->localSymList;
111 - (*stackP)->tag = STRING_TAG;
112 - (*stackP)->val.str.rep = name;
113 - (*stackP)->val.str.len = strlen(name);
115 + context->stackP->tag = STRING_TAG;
116 + context->stackP->val.str.rep = name;
117 + context->stackP->val.str.len = strlen(name);
121 - (*stackP)->tag = INT_TAG;
122 - (*stackP)->val.n = nArgs;
124 + context->stackP->tag = INT_TAG;
125 + context->stackP->val.n = nArgs;
129 + context->frameP = context->stackP;
131 /* Initialize and make room on the stack for local variables */
132 for (s = prog->localSymList; s != NULL; s = s->next) {
133 - FP_GET_SYM_VAL(*frameP, s) = noValue;
135 + FP_GET_SYM_VAL(context->frameP, s) = noValue;
140 + context->pc = prog->code;
145 static Inst *rewindFrame(DataValue **frameP, DataValue **stackP)
146 @@ -599,10 +616,10 @@ static Inst *rewindFrame(DataValue **fra
150 -static void rewindStack(Inst *pc, DataValue *frameP, DataValue *stackP)
151 +static void rewindStack(RestartData *context)
154 - pc = rewindFrame(&frameP, &stackP);
155 + while (context->pc) {
156 + context->pc = rewindFrame(&context->frameP, &context->stackP);
160 @@ -618,9 +635,8 @@ int ExecuteMacro(WindowInfo *window, Pro
162 RestartData *context;
163 static DataValue argArray = {NO_TAG, {0}};
169 haveNamedArgs = (nArgs < 0);
171 @@ -642,10 +658,15 @@ int ExecuteMacro(WindowInfo *window, Pro
173 /* prog will be freed by cller, but by stack also, so inc refcount */
175 - setupFrame(&context->frameP, &context->stackP, &context->pc,
176 - prog, nArgs, args, argArray,
177 + status = setupFrame(context, prog, nArgs, args, argArray,
178 prog->name ? prog->name : "<exec-macro>");
180 + if (status == STAT_ERROR) {
182 + FreeRestartData(context);
183 + return MACRO_ERROR;
186 /* Begin execution, return on error or preemption */
187 return ContinueMacro(context, result, msg);
189 @@ -732,17 +753,29 @@ int ContinueMacro(RestartData *continuat
190 ** separate contexts, and serializes processing of the two macros without
193 -void RunMacroAsSubrCall(Program *prog)
194 +int RunMacroAsSubrCall(RestartData *context, Program *prog, char **msg)
196 static DataValue noValue = {NO_TAG, {0}};
199 - setupFrame(&FrameP, &StackP, &PC, prog, 0, NULL, noValue,
200 + status = setupFrame(context, prog, 0, NULL, noValue,
201 prog->name ? prog->name : "<run-macro>");
203 + if (status == STAT_ERROR) {
205 + FreeRestartData(context);
206 + return MACRO_ERROR;
209 + /* we could invent a MACRO_READY_TO_GO, but the error case is the only
210 + ** important thing here, so stick at MACRO_DONE
215 void FreeRestartData(RestartData *context)
217 - rewindStack(context->pc, context->frameP, context->stackP);
218 + rewindStack(context);
219 XtFree((char *)context->stack);
220 XtFree((char *)context);
222 @@ -2728,12 +2761,15 @@ static int callSubroutineFromSymbol(Symb
223 ** values which are already there.
225 if (sym->type == MACRO_FUNCTION_SYM) {
226 + RestartData context;
228 prog = sym->value.val.prog;
230 /* -nArgs means 'arguments are on stack' */
231 - setupFrame(&FrameP, &StackP, &PC, prog, -nArgs, NULL, argArray,
234 + saveContext(&context);
235 + status = setupFrame(&context, prog, -nArgs, NULL, argArray, sym->name);
236 + restoreContext(&context);
241 diff --quilt old/source/interpret.h new/source/interpret.h
242 --- old/source/interpret.h
243 +++ new/source/interpret.h
244 @@ -180,7 +180,7 @@ void FillLoopAddrs(Inst *breakAddr, Inst
245 int ExecuteMacro(WindowInfo *window, Program *prog, int nArgs, DataValue *args,
246 DataValue *result, RestartData **continuation, char **msg);
247 int ContinueMacro(RestartData *continuation, DataValue *result, char **msg);
248 -void RunMacroAsSubrCall(Program *prog);
249 +int RunMacroAsSubrCall(RestartData *context, Program *prog, char **msg);
250 void PreemptMacro(void);
252 int OverlayRoutineFromProg(Program *prog, int nArgs, int removeArgs);