3 source/interpret.c | 143 +++++++++++++++++++++++++++++++++--------------------
5 source/macro.c | 11 +++-
6 3 files changed, 101 insertions(+), 55 deletions(-)
8 diff --quilt old/source/macro.c new/source/macro.c
10 +++ new/source/macro.c
11 @@ -693,8 +693,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 @@ -516,19 +516,34 @@ int 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 @@ -539,74 +554,76 @@ 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 = (char *)name;
113 - (*stackP)->val.str.len = strlen(name);
115 + context->stackP->tag = STRING_TAG;
116 + context->stackP->val.str.rep = (char *)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 +static void rewindFrame(RestartData *context)
148 /* get stored return information */
149 - int nArgs = FP_GET_ARG_COUNT(*frameP);
150 - DataValue *newFrameP = FP_GET_OLD_FP(*frameP);
151 - Inst *newPC = FP_GET_RET_PC(*frameP);
152 - Program *prog = FP_GET_PROG(*frameP);
153 + int nArgs = FP_GET_ARG_COUNT(context->frameP);
154 + DataValue *newFrameP = FP_GET_OLD_FP(context->frameP);
155 + Inst *newPC = FP_GET_RET_PC(context->frameP);
156 + Program *prog = FP_GET_PROG(context->frameP);
158 /* pop past local variables */
160 + context->stackP = context->frameP;
161 /* pop past arguments */
162 - *stackP -= (FP_TO_ARGS_DIST + nArgs);
163 + context->stackP -= (FP_TO_ARGS_DIST + nArgs);
165 - *frameP = newFrameP;
166 + context->frameP = newFrameP;
171 + context->pc = newPC;
174 -static void rewindStack(Inst *pc, DataValue *frameP, DataValue *stackP)
175 +static void rewindStack(RestartData *context)
178 - pc = rewindFrame(&frameP, &stackP);
179 + while (context->pc) {
180 + rewindFrame(context);
184 @@ -622,9 +639,8 @@ int ExecuteMacro(WindowInfo *window, Pro
186 RestartData *context;
187 static DataValue argArray = {NO_TAG, {0}};
193 haveNamedArgs = (nArgs < 0);
195 @@ -646,10 +662,15 @@ int ExecuteMacro(WindowInfo *window, Pro
197 /* prog will be freed by cller, but by stack also, so inc refcount */
199 - setupFrame(&context->frameP, &context->stackP, &context->pc,
200 - prog, nArgs, args, argArray,
201 + status = setupFrame(context, prog, nArgs, args, argArray,
202 prog->name ? prog->name : "<exec-macro>");
204 + if (status == STAT_ERROR) {
206 + FreeRestartData(context);
207 + return MACRO_ERROR;
210 /* Begin execution, return on error or preemption */
211 return ContinueMacro(context, result, msg);
213 @@ -736,17 +757,29 @@ int ContinueMacro(RestartData *continuat
214 ** separate contexts, and serializes processing of the two macros without
217 -void RunMacroAsSubrCall(Program *prog)
218 +int RunMacroAsSubrCall(RestartData *context, Program *prog, char **msg)
220 static DataValue noValue = {NO_TAG, {0}};
223 - setupFrame(&FrameP, &StackP, &PC, prog, 0, NULL, noValue,
224 + status = setupFrame(context, prog, 0, NULL, noValue,
225 prog->name ? prog->name : "<run-macro>");
227 + if (status == STAT_ERROR) {
229 + FreeRestartData(context);
230 + return MACRO_ERROR;
233 + /* we could invent a MACRO_READY_TO_GO, but the error case is the only
234 + ** important thing here, so stick at MACRO_DONE
239 void FreeRestartData(RestartData *context)
241 - rewindStack(context->pc, context->frameP, context->stackP);
242 + rewindStack(context);
243 XtFree((char *)context->stack);
244 XtFree((char *)context);
246 @@ -2703,12 +2736,15 @@ static int callSubroutineFromSymbol(Symb
247 ** values which are already there.
249 if (sym->type == MACRO_FUNCTION_SYM) {
250 + RestartData context;
252 prog = sym->value.val.prog;
254 /* -nArgs means 'arguments are on stack' */
255 - setupFrame(&FrameP, &StackP, &PC, prog, -nArgs, NULL, argArray,
258 + saveContext(&context);
259 + status = setupFrame(&context, prog, -nArgs, NULL, argArray, sym->name);
260 + restoreContext(&context);
265 @@ -2961,6 +2997,7 @@ static int returnValOrNone(int valOnStac
268 static DataValue noValue = {NO_TAG, {0}};
269 + RestartData context;
272 STACKDUMP(StackP - FrameP + FP_GET_ARG_COUNT(FrameP) + FP_TO_ARGS_DIST, 3);
273 @@ -2972,8 +3009,10 @@ static int returnValOrNone(int valOnStac
278 - PC = rewindFrame(&FrameP, &StackP);
280 + saveContext(&context);
281 + rewindFrame(&context);
282 + restoreContext(&context);
284 /* push returned value, if requsted */
285 PUSH_RET_VAL(retVal);
286 diff --quilt old/source/interpret.h new/source/interpret.h
287 --- old/source/interpret.h
288 +++ new/source/interpret.h
289 @@ -179,7 +179,7 @@ int FillLoopAddrs(Inst *breakAddr, Inst
290 int ExecuteMacro(WindowInfo *window, Program *prog, int nArgs, DataValue *args,
291 DataValue *result, RestartData **continuation, char **msg);
292 int ContinueMacro(RestartData *continuation, DataValue *result, char **msg);
293 -void RunMacroAsSubrCall(Program *prog);
294 +int RunMacroAsSubrCall(RestartData *context, Program *prog, char **msg);
295 void PreemptMacro(void);
297 int OverlayRoutineFromProg(Program *prog, int nArgs, int removeArgs);