From 7147f8577e08bcb037cba390dbef3e90163fb96f Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 8 Feb 2010 15:51:00 +0000 Subject: Search through arrays for outgoing references to fix possible garbage collector problems; minor cleanup. svn-id: r47989 --- engines/sci/engine/kernel32.cpp | 6 ++---- engines/sci/engine/segment.cpp | 25 +++++++++++++++++++++++++ engines/sci/engine/segment.h | 7 ++++++- 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 *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 *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() { setType(3); } // We overload destroy to ensure the string type is 3 after destroying - void destroy() { _type = 3; } + void destroy() { SciArray::destroy(); _type = 3; } Common::String toString(); void fromString(Common::String string); @@ -805,6 +805,9 @@ public: struct ArrayTable : public Table > { ArrayTable() : Table >(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 > { struct StringTable : public Table { StringTable() : Table(SEG_TYPE_STRING) {} + virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr); + void saveLoadWithSerializer(Common::Serializer &ser); SegmentRef dereference(reg_t pointer); }; -- cgit v1.2.3