aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Hoops2010-02-08 15:51:00 +0000
committerMatthew Hoops2010-02-08 15:51:00 +0000
commit7147f8577e08bcb037cba390dbef3e90163fb96f (patch)
tree2ebed6871a7f97b2b8ed92a232092585c2dd6bac
parent6938ca072aa05600ece0b7041e47a0fe8e4abba4 (diff)
downloadscummvm-rg350-7147f8577e08bcb037cba390dbef3e90163fb96f.tar.gz
scummvm-rg350-7147f8577e08bcb037cba390dbef3e90163fb96f.tar.bz2
scummvm-rg350-7147f8577e08bcb037cba390dbef3e90163fb96f.zip
Search through arrays for outgoing references to fix possible garbage collector problems; minor cleanup.
svn-id: r47989
-rw-r--r--engines/sci/engine/kernel32.cpp6
-rw-r--r--engines/sci/engine/segment.cpp25
-rw-r--r--engines/sci/engine/segment.h7
3 files changed, 33 insertions, 5 deletions
diff --git a/engines/sci/engine/kernel32.cpp b/engines/sci/engine/kernel32.cpp
index 4669256df4..8d70cdf45b 100644
--- a/engines/sci/engine/kernel32.cpp
+++ b/engines/sci/engine/kernel32.cpp
@@ -439,8 +439,7 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) {
return argv[1]; // We also have to return the handle
}
case 4: // Free
- if (!argv[1].isNull())
- s->_segMan->freeArray(argv[1]);
+ // Freeing of arrays is handled by the garbage collector
return s->r_acc;
case 5: { // Fill
SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]);
@@ -542,8 +541,7 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
return argv[1]; // We also have to return the handle
}
case 4: // Free
- if (!argv[1].isNull())
- s->_segMan->freeString(argv[1]);
+ // Freeing of strings is handled by the garbage collector
return s->r_acc;
case 5: { // Fill
SciString *string = s->_segMan->lookupString(argv[1]);
diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp
index 5419de6f0b..49328c7775 100644
--- a/engines/sci/engine/segment.cpp
+++ b/engines/sci/engine/segment.cpp
@@ -695,6 +695,26 @@ SegmentRef ArrayTable::dereference(reg_t pointer) {
return ret;
}
+void ArrayTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) {
+ _table[sub_addr.offset].destroy();
+ freeEntry(sub_addr.offset);
+}
+
+void ArrayTable::listAllOutgoingReferences(reg_t addr, void *param, NoteCallback note) {
+ if (!isValidEntry(addr.offset)) {
+ warning("Invalid array referenced for outgoing references: %04x:%04x", PRINT_REG(addr));
+ return;
+ }
+
+ SciArray<reg_t> *array = &(_table[addr.offset]);
+
+ for (uint32 i = 0; i < array->getSize(); i++) {
+ reg_t value = array->getValue(i);
+ if (value.segment != 0)
+ note(param, value);
+ }
+}
+
Common::String SciString::toString() {
if (_type != 3)
error("SciString::toString(): Array is not a string");
@@ -725,6 +745,11 @@ SegmentRef StringTable::dereference(reg_t pointer) {
return ret;
}
+void StringTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) {
+ _table[sub_addr.offset].destroy();
+ freeEntry(sub_addr.offset);
+}
+
#endif
} // End of namespace Sci
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index 8108e0695e..5651e2ef21 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -796,7 +796,7 @@ public:
SciString() : SciArray<char>() { setType(3); }
// We overload destroy to ensure the string type is 3 after destroying
- void destroy() { _type = 3; }
+ void destroy() { SciArray<char>::destroy(); _type = 3; }
Common::String toString();
void fromString(Common::String string);
@@ -805,6 +805,9 @@ public:
struct ArrayTable : public Table<SciArray<reg_t> > {
ArrayTable() : Table<SciArray<reg_t> >(SEG_TYPE_ARRAY) {}
+ virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr);
+ virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note);
+
void saveLoadWithSerializer(Common::Serializer &ser);
SegmentRef dereference(reg_t pointer);
};
@@ -812,6 +815,8 @@ struct ArrayTable : public Table<SciArray<reg_t> > {
struct StringTable : public Table<SciString> {
StringTable() : Table<SciString>(SEG_TYPE_STRING) {}
+ virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr);
+
void saveLoadWithSerializer(Common::Serializer &ser);
SegmentRef dereference(reg_t pointer);
};