Search through arrays for outgoing references to fix possible garbage collector problems; minor cleanup.

svn-id: r47989
This commit is contained in:
Matthew Hoops 2010-02-08 15:51:00 +00:00
parent 6938ca072a
commit 7147f8577e
3 changed files with 33 additions and 5 deletions

View file

@ -439,8 +439,7 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) {
return argv[1]; // We also have to return the handle return argv[1]; // We also have to return the handle
} }
case 4: // Free case 4: // Free
if (!argv[1].isNull()) // Freeing of arrays is handled by the garbage collector
s->_segMan->freeArray(argv[1]);
return s->r_acc; return s->r_acc;
case 5: { // Fill case 5: { // Fill
SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]); 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 return argv[1]; // We also have to return the handle
} }
case 4: // Free case 4: // Free
if (!argv[1].isNull()) // Freeing of strings is handled by the garbage collector
s->_segMan->freeString(argv[1]);
return s->r_acc; return s->r_acc;
case 5: { // Fill case 5: { // Fill
SciString *string = s->_segMan->lookupString(argv[1]); SciString *string = s->_segMan->lookupString(argv[1]);

View file

@ -695,6 +695,26 @@ SegmentRef ArrayTable::dereference(reg_t pointer) {
return ret; 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() { Common::String SciString::toString() {
if (_type != 3) if (_type != 3)
error("SciString::toString(): Array is not a string"); error("SciString::toString(): Array is not a string");
@ -725,6 +745,11 @@ SegmentRef StringTable::dereference(reg_t pointer) {
return ret; return ret;
} }
void StringTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) {
_table[sub_addr.offset].destroy();
freeEntry(sub_addr.offset);
}
#endif #endif
} // End of namespace Sci } // End of namespace Sci

View file

@ -796,7 +796,7 @@ public:
SciString() : SciArray<char>() { setType(3); } SciString() : SciArray<char>() { setType(3); }
// We overload destroy to ensure the string type is 3 after destroying // 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(); Common::String toString();
void fromString(Common::String string); void fromString(Common::String string);
@ -805,6 +805,9 @@ public:
struct ArrayTable : public Table<SciArray<reg_t> > { struct ArrayTable : public Table<SciArray<reg_t> > {
ArrayTable() : Table<SciArray<reg_t> >(SEG_TYPE_ARRAY) {} 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); void saveLoadWithSerializer(Common::Serializer &ser);
SegmentRef dereference(reg_t pointer); SegmentRef dereference(reg_t pointer);
}; };
@ -812,6 +815,8 @@ struct ArrayTable : public Table<SciArray<reg_t> > {
struct StringTable : public Table<SciString> { struct StringTable : public Table<SciString> {
StringTable() : Table<SciString>(SEG_TYPE_STRING) {} StringTable() : Table<SciString>(SEG_TYPE_STRING) {}
virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr);
void saveLoadWithSerializer(Common::Serializer &ser); void saveLoadWithSerializer(Common::Serializer &ser);
SegmentRef dereference(reg_t pointer); SegmentRef dereference(reg_t pointer);
}; };