@@ -132,43 +132,70 @@ void MCKeywordsExecResolveCommandOrFunction(MCExecContext& ctxt, MCNameRef p_nam
132132 r_handler = t_resolved_handler;
133133}
134134
135+ bool MCKeywordsExecSetupCommandOrFunction (MCExecContext& ctxt, MCParameter *params, MCContainer *containers, uint2 line, uint2 pos, bool is_function)
136+ {
137+ MCParameter *tptr = params;
138+ uindex_t t_container_index = 0 ;
139+ while (tptr != NULL )
140+ {
141+ /* If the parameter evaluates as a container, then place the result
142+ * into the next available container slot and bump the index; otherwise
143+ * evaluate as an expression. */
144+ if (tptr -> evalcontainer (ctxt, containers[t_container_index]))
145+ {
146+ tptr -> set_argument_container (&containers[t_container_index]);
147+ t_container_index += 1 ;
148+ }
149+ else
150+ {
151+ MCExecValue t_value;
152+
153+ if (!ctxt.TryToEvaluateParameter (tptr,
154+ line,
155+ pos,
156+ is_function ? EE_FUNCTION_BADSOURCE : EE_STATEMENT_BADPARAM,
157+ t_value))
158+ {
159+ return false ;
160+ }
161+
162+ tptr -> clear_argument ();
163+ tptr->give_exec_argument (t_value);
164+ }
165+
166+ tptr = tptr->getnext ();
167+ }
168+
169+ return true ;
170+ }
171+
172+ void MCKeywordsExecTeardownCommandOrFunction (MCParameter *params)
173+ {
174+ // AL-2014-09-17: [[ Bug 13465 ]] Clear parameters after executing dispatch
175+ MCParameter *tptr = params;
176+ while (tptr != NULL )
177+ {
178+ tptr -> clear_argument ();
179+ tptr = tptr->getnext ();
180+ }
181+ }
182+
135183void MCKeywordsExecCommandOrFunction (MCExecContext& ctxt, MCHandler *handler, MCParameter *params, MCNameRef name, uint2 line, uint2 pos, bool global_handler, bool is_function)
136184{
137185 if (MCscreen->abortkey ())
138186 {
139187 ctxt . LegacyThrow (EE_HANDLER_ABORT);
140188 return ;
141189 }
142-
190+
143191 if (is_function)
144192 MCexitall = False;
145-
146- // Go through all the parameters to the function, if they are not variables, clear their current value. Each parameter stores an expression
147- // which allows its value to be re-evaluated in a given context. Re-evaluate each in the context of ep and set it to the new value.
148- // As the ep should contain the context of the caller at this point, the expression should be evaluated in that context.
193+
149194 Exec_stat stat;
150- MCParameter *tptr = params;
151- while (tptr != NULL )
152- {
153- // AL-2014-08-20: [[ ArrayElementRefParams ]] Use containers for potential reference parameters
154- MCAutoPointer<MCContainer> t_container = new (nothrow) MCContainer;
155- if (tptr -> evalcontainer (ctxt, **t_container))
156- tptr -> set_argument_container (t_container.Release ());
157- else
158- {
159- tptr -> clear_argument ();
160- MCExecValue t_value;
161- if (!ctxt . TryToEvaluateParameter (tptr, line, pos, is_function ? EE_FUNCTION_BADSOURCE : EE_STATEMENT_BADPARAM, t_value))
162- return ;
163- tptr->give_exec_argument (t_value);
164- }
165-
166- tptr = tptr->getnext ();
167- }
168- MCObject *p = ctxt . GetObject ();
195+ stat = ES_NOT_HANDLED;
196+ MCObject *p = ctxt . GetObject ();
169197 MCExecContext *oldctxt = MCECptr;
170198 MCECptr = &ctxt;
171- stat = ES_NOT_HANDLED;
172199 Boolean added = False;
173200 if (MCnexecutioncontexts < MAX_CONTEXTS)
174201 {
@@ -218,6 +245,21 @@ void MCKeywordsExecCommandOrFunction(MCExecContext& ctxt, MCHandler *handler, MC
218245 stat = p->handle (HT_FUNCTION, name, params, p);
219246 if (oldstat == ES_PASS && stat == ES_NOT_HANDLED)
220247 stat = ES_PASS;
248+
249+ /* The following clause was pulled in from MCFuncref::eval_ctxt
250+ * it is not quite clear why this code path is different from
251+ * commands; however without the clause a test failure occurs
252+ * in 'TestExtensionLibraryHandlerCallErrors'. */
253+ // MW-2007-08-09: [[ Bug 5705 ]] Throws inside private functions don't trigger an
254+ // exception.
255+ if (!global_handler &&
256+ stat != ES_NORMAL &&
257+ stat != ES_PASS &&
258+ stat != ES_EXIT_HANDLER)
259+ {
260+ MCeerror->add (EE_FUNCTION_BADFUNCTION, line, pos, name);
261+ stat = ES_ERROR;
262+ }
221263 }
222264 else
223265 {
@@ -265,14 +307,6 @@ void MCKeywordsExecCommandOrFunction(MCExecContext& ctxt, MCHandler *handler, MC
265307 ctxt . SetExecStat (stat);
266308 else
267309 ctxt . SetExecStat (ES_NORMAL);
268-
269- // AL-2014-09-17: [[ Bug 13465 ]] Clear parameters after executing command/function
270- tptr = params;
271- while (tptr != NULL )
272- {
273- tptr -> clear_argument ();
274- tptr = tptr->getnext ();
275- }
276310}
277311
278312// //////////////////////////////////////////////////////////////////////////////
0 commit comments