@@ -367,14 +367,32 @@ void MCDispatch::removestack(MCStack *sptr)
367367
368368void MCDispatch::destroystack (MCStack *sptr, Boolean needremove)
369369{
370+ /* Make sure no messages are sent when destroying the given stack as this
371+ * destruction method is only ever used for stacks which are not-yet-alive
372+ * (e.g. failed to deserialize) or in restricted contexts (e.g. licensing
373+ * dialog on startup). */
374+ Boolean oldstate = MClockmessages;
375+ MClockmessages = True;
376+
370377 if (needremove)
371378 {
372379 MCStack *t_substacks = sptr -> getsubstacks ();
373- while (t_substacks)
380+ while (t_substacks != nullptr )
374381 {
382+ /* The MCStack::dodel() method removes the stack from its mainstack
383+ * so we must explicitly delete it explicitly. Note that there is
384+ * no need to scheduledelete() in this case as destroystack() is
385+ * only called when it is known that no script is running from the
386+ * stack. */
375387 t_substacks -> dodel ();
388+ delete t_substacks;
389+
390+ /* Refetch the substacks list - the substack we just processed will
391+ * have been removed from it. */
376392 t_substacks = sptr -> getsubstacks ();
377393 }
394+
395+ /* Release any references to the mainstack */
378396 sptr -> dodel ();
379397 }
380398 if (sptr == MCstaticdefaultstackptr)
@@ -383,9 +401,13 @@ void MCDispatch::destroystack(MCStack *sptr, Boolean needremove)
383401 MCdefaultstackptr = MCstaticdefaultstackptr;
384402 if (MCacptr && MCacptr->getmessagestack () == sptr)
385403 MCacptr->setmessagestack (NULL );
386- Boolean oldstate = MClockmessages;
387- MClockmessages = True;
404+
405+ /* Delete the stack explicitly. Note that there is no need to use
406+ * scheduledelete here as destroystack() is only called when it is known
407+ * that no script is running from the stack. */
388408 delete sptr;
409+
410+ /* Restore the previous message lock state. */
389411 MClockmessages = oldstate;
390412}
391413
0 commit comments