From a3a07f19fcf6a001e5981d3efe66e834a404f1e3 Mon Sep 17 00:00:00 2001 From: Walter van Niftrik Date: Fri, 12 Feb 2010 02:23:28 +0000 Subject: SCI: Revert r47929 (bad idea, as we may run out of offsets). Instead, adapt SCI32 list iteration code to store node successor before invoking. svn-id: r48036 --- engines/sci/engine/klists.cpp | 31 ++++++++++--------------------- engines/sci/engine/vm.cpp | 12 ++---------- 2 files changed, 12 insertions(+), 31 deletions(-) (limited to 'engines') diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp index 9a63b39f18..f36e776d08 100644 --- a/engines/sci/engine/klists.cpp +++ b/engines/sci/engine/klists.cpp @@ -521,14 +521,15 @@ reg_t kListIndexOf(EngineState *s, int argc, reg_t *argv) { reg_t kListEachElementDo(EngineState *s, int argc, reg_t *argv) { List *list = s->_segMan->lookupList(argv[0]); - reg_t curAddress = list->first; - Node *curNode = s->_segMan->lookupNode(curAddress); + Node *curNode = s->_segMan->lookupNode(list->first); reg_t curObject; Selector slc = argv[1].toUint16(); ObjVarRef address; while (curNode) { + // We get the next node here as the current node might be gone after the invoke + reg_t nextNode = curNode->succ; curObject = curNode->value; // First, check if the target selector is a variable @@ -543,11 +544,7 @@ reg_t kListEachElementDo(EngineState *s, int argc, reg_t *argv) { invoke_selector_argv(s, curObject, slc, kContinueOnInvalidSelector, argc, argv, argc - 2, argv + 2); } - // Lookup node again, since the nodetable it was in may have been reallocated - curNode = s->_segMan->lookupNode(curAddress); - - curAddress = curNode->succ; - curNode = s->_segMan->lookupNode(curAddress); + curNode = s->_segMan->lookupNode(nextNode); } return s->r_acc; @@ -556,8 +553,7 @@ reg_t kListEachElementDo(EngineState *s, int argc, reg_t *argv) { reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv) { List *list = s->_segMan->lookupList(argv[0]); - reg_t curAddress = list->first; - Node *curNode = s->_segMan->lookupNode(curAddress); + Node *curNode = s->_segMan->lookupNode(list->first); reg_t curObject; Selector slc = argv[1].toUint16(); @@ -566,6 +562,7 @@ reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv) { s->r_acc = NULL_REG; // reset the accumulator while (curNode) { + reg_t nextNode = curNode->succ; curObject = curNode->value; // First, check if the target selector is a variable @@ -580,11 +577,7 @@ reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv) { return curObject; } - // Lookup node again, since the nodetable it was in may have been reallocated - curNode = s->_segMan->lookupNode(curAddress); - - curAddress = curNode->succ; - curNode = s->_segMan->lookupNode(curAddress); + curNode = s->_segMan->lookupNode(nextNode); } // No selector returned true @@ -594,8 +587,7 @@ reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv) { reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv) { List *list = s->_segMan->lookupList(argv[0]); - reg_t curAddress = list->first; - Node *curNode = s->_segMan->lookupNode(curAddress); + Node *curNode = s->_segMan->lookupNode(list->first); reg_t curObject; Selector slc = argv[1].toUint16(); @@ -604,6 +596,7 @@ reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv) { s->r_acc = make_reg(0, 1); // reset the accumulator while (curNode) { + reg_t nextNode = curNode->succ; curObject = curNode->value; // First, check if the target selector is a variable @@ -618,11 +611,7 @@ reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv) { break; } - // Lookup node again, since the nodetable it was in may have been reallocated - curNode = s->_segMan->lookupNode(curAddress); - - curAddress = curNode->succ; - curNode = s->_segMan->lookupNode(curAddress); + curNode = s->_segMan->lookupNode(nextNode); } return s->r_acc; diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index b3c5333832..262773a0ed 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -621,16 +621,8 @@ static void callKernelFunc(EngineState *s, int kernelFuncNum, int argc) { static void gc_countdown(EngineState *s) { if (s->gc_countdown-- <= 0) { - // Only run garbage collection when execution stack base - // is zero, as it cannot count references inside kernel - // functions - if (s->execution_stack_base == 0) { - s->gc_countdown = script_gc_interval; - run_gc(s); - } else { - // Try again later - s->gc_countdown = 1; - } + s->gc_countdown = script_gc_interval; + run_gc(s); } } -- cgit v1.2.3