aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorWalter van Niftrik2010-02-12 02:23:28 +0000
committerWalter van Niftrik2010-02-12 02:23:28 +0000
commita3a07f19fcf6a001e5981d3efe66e834a404f1e3 (patch)
tree658beda7b401d5678c2eee6c020b2d21f39ffc87 /engines/sci
parent7eb92eb1cd20789ee4450589afdeb66ac2f70c13 (diff)
downloadscummvm-rg350-a3a07f19fcf6a001e5981d3efe66e834a404f1e3.tar.gz
scummvm-rg350-a3a07f19fcf6a001e5981d3efe66e834a404f1e3.tar.bz2
scummvm-rg350-a3a07f19fcf6a001e5981d3efe66e834a404f1e3.zip
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
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/klists.cpp31
-rw-r--r--engines/sci/engine/vm.cpp12
2 files changed, 12 insertions, 31 deletions
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);
}
}