aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine/seg_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine/seg_manager.cpp')
-rw-r--r--engines/sci/engine/seg_manager.cpp368
1 files changed, 4 insertions, 364 deletions
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 69a939dae9..dcf7180501 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -135,13 +135,13 @@ void SegManager::setScriptSize(Script &scr, EngineState *s, int script_nr) {
scr.script_size = script->size;
scr.heap_size = 0; // Set later
- if (!script || (s->version >= SCI_VERSION_1_1 && !heap)) {
+ if (!script || (s->_version >= SCI_VERSION_1_1 && !heap)) {
error("SegManager::setScriptSize: failed to load %s", !script ? "script" : "heap");
}
- if (s->flags & GF_SCI0_OLD) {
+ if (s->_flags & GF_SCI0_OLD) {
scr.buf_size = script->size + READ_LE_UINT16(script->data) * 2;
//locals_size = READ_LE_UINT16(script->data) * 2;
- } else if (s->version < SCI_VERSION_1_1) {
+ } else if (s->_version < SCI_VERSION_1_1) {
scr.buf_size = script->size;
} else {
scr.buf_size = script->size + heap->size;
@@ -189,7 +189,7 @@ int SegManager::initialiseScript(Script &scr, EngineState *s, int script_nr) {
scr.obj_indices = new IntMapper();
- if (s->version >= SCI_VERSION_1_1)
+ if (s->_version >= SCI_VERSION_1_1)
scr.heap_start = scr.buf + scr.script_size;
else
scr.heap_start = scr.buf;
@@ -232,49 +232,6 @@ int SegManager::deallocateScript(int script_nr) {
return 1;
}
-MemObject *MemObject::createMemObject(MemObjectType type) {
- MemObject *mem = 0;
- switch (type) {
- case MEM_OBJ_SCRIPT:
- mem = new Script();
- break;
- case MEM_OBJ_CLONES:
- mem = new CloneTable();
- break;
- case MEM_OBJ_LOCALS:
- mem = new LocalVariables();
- break;
- case MEM_OBJ_SYS_STRINGS:
- mem = new SystemStrings();
- break;
- case MEM_OBJ_STACK:
- mem = new DataStack();
- break;
- case MEM_OBJ_HUNK:
- mem = new HunkTable();
- break;
- case MEM_OBJ_STRING_FRAG:
- mem = new StringFrag();
- break;
- case MEM_OBJ_LISTS:
- mem = new ListTable();
- break;
- case MEM_OBJ_NODES:
- mem = new NodeTable();
- break;
- case MEM_OBJ_DYNMEM:
- mem = new DynMem();
- break;
- default:
- error("Unknown MemObject type %d", type);
- break;
- }
-
- assert(mem);
- mem->_type = type;
- return mem;
-}
-
MemObject *SegManager::memObjAllocate(SegmentId segid, int hash_id, MemObjectType type) {
MemObject *mem = MemObject::createMemObject(type);
if (!mem) {
@@ -294,33 +251,6 @@ MemObject *SegManager::memObjAllocate(SegmentId segid, int hash_id, MemObjectTyp
return mem;
}
-void Script::freeScript() {
- free(buf);
- buf = NULL;
- buf_size = 0;
-
- _objects.clear();
-
- delete obj_indices;
- obj_indices = 0;
- _codeBlocks.clear();
-}
-
-// memory operations
-
-void Script::mcpyInOut(int dst, const void *src, size_t n) {
- if (buf) {
- assert(dst + n <= buf_size);
- memcpy(buf + dst, src, n);
- }
-}
-
-int16 Script::getHeap(uint16 offset) const {
- VERIFY(offset + 1 < (int)buf_size, "invalid offset\n");
- return READ_LE_UINT16(buf + offset);
-// return (buf[offset] | (buf[offset+1]) << 8);
-}
-
// return the seg if script_id is valid and in the map, else -1
SegmentId SegManager::segGet(int script_id) const {
return id_seg_map->lookupKey(script_id);
@@ -367,53 +297,10 @@ bool SegManager::scriptIsLoaded(SegmentId seg) {
return getScriptIfLoaded(seg) != 0;
}
-void Script::incrementLockers() {
- lockers++;
-}
-
-void Script::decrementLockers() {
- if (lockers > 0)
- lockers--;
-}
-
-int Script::getLockers() const {
- return lockers;
-}
-
-void Script::setLockers(int lockers_) {
- lockers = lockers_;
-}
-
-void Script::setExportTableOffset(int offset) {
- if (offset) {
- export_table = (uint16 *)(buf + offset + 2);
- exports_nr = READ_LE_UINT16((byte *)(export_table - 1));
- } else {
- export_table = NULL;
- exports_nr = 0;
- }
-}
-
void SegManager::setExportWidth(int flag) {
exports_wide = flag;
}
-void Script::setSynonymsOffset(int offset) {
- synonyms = buf + offset;
-}
-
-byte *Script::getSynonyms() const {
- return synonyms;
-}
-
-void Script::setSynonymsNr(int n) {
- synonyms_nr = n;
-}
-
-int Script::getSynonymsNr() const {
- return synonyms_nr;
-}
-
int SegManager::relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location) {
int rel = location - block_location;
@@ -925,67 +812,6 @@ Hunk *SegManager::alloc_Hunk(reg_t *addr) {
return &(table->_table[offset]);
}
-byte *MemObject::dereference(reg_t pointer, int *size) {
- error("Error: Trying to dereference pointer %04x:%04x to inappropriate segment",
- PRINT_REG(pointer));
- return NULL;
-}
-
-byte *Script::dereference(reg_t pointer, int *size) {
- if (pointer.offset > buf_size) {
- sciprintf("Error: Attempt to dereference invalid pointer %04x:%04x into script segment (script size=%d)\n",
- PRINT_REG(pointer), (uint)buf_size);
- return NULL;
- }
- if (size)
- *size = buf_size - pointer.offset;
- return (byte *)(buf + pointer.offset);
-}
-
-byte *LocalVariables::dereference(reg_t pointer, int *size) {
- // FIXME: The following doesn't seem to be endian safe.
- // To fix this, we'd have to always treat the reg_t
- // values stored here as in the little endian format.
- int count = _locals.size() * sizeof(reg_t);
- byte *base = (byte *)&_locals[0];
-
- if (size)
- *size = count;
-
- return base + pointer.offset;
-}
-
-byte *DataStack::dereference(reg_t pointer, int *size) {
- int count = nr * sizeof(reg_t);
- byte *base = (byte *)entries;
-
- if (size)
- *size = count;
-
- return base + pointer.offset;
-}
-
-byte *DynMem::dereference(reg_t pointer, int *size) {
- int count = _size;
- byte *base = (byte *)_buf;
-
- if (size)
- *size = count;
-
- return base + pointer.offset;
-}
-
-byte *SystemStrings::dereference(reg_t pointer, int *size) {
- if (size)
- *size = strings[pointer.offset].max_size;
- if (pointer.offset < SYS_STRINGS_MAX && strings[pointer.offset].name)
- return (byte *)(strings[pointer.offset].value);
-
- // This occurs in KQ5CD when interacting with certain objects
- warning("Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer));
- return NULL;
-}
-
byte *SegManager::dereference(reg_t pointer, int *size) {
if (!pointer.segment || (pointer.segment >= _heap.size()) || !_heap[pointer.segment]) {
// This occurs in KQ5CD when interacting with certain objects
@@ -1048,191 +874,5 @@ void SegManager::dbgPrint(const char* msg, void *i) {
}
-//-------------------- script --------------------
-reg_t Script::findCanonicAddress(SegManager *segmgr, reg_t addr) {
- addr.offset = 0;
- return addr;
-}
-
-void Script::freeAtAddress(SegManager *segmgr, reg_t addr) {
- /*
- sciprintf("[GC] Freeing script %04x:%04x\n", PRINT_REG(addr));
- if (locals_segment)
- sciprintf("[GC] Freeing locals %04x:0000\n", locals_segment);
- */
-
- if (_markedAsDeleted)
- segmgr->deallocateScript(nr);
-}
-
-void Script::listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {
- (*note)(param, make_reg(segId, 0));
-}
-
-void Script::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
- Script *script = this;
-
- if (addr.offset <= script->buf_size && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(script->buf + addr.offset)) {
- int idx = RAW_GET_CLASS_INDEX(script, addr);
- if (idx >= 0 && (uint)idx < script->_objects.size()) {
- // Note all local variables, if we have a local variable environment
- if (script->locals_segment)
- (*note)(param, make_reg(script->locals_segment, 0));
-
- Object &obj = script->_objects[idx];
- for (uint i = 0; i < obj._variables.size(); i++)
- (*note)(param, obj._variables[i]);
- } else {
- warning("Request for outgoing script-object reference at %04x:%04x yielded invalid index %d", PRINT_REG(addr), idx);
- }
- } else {
- /* warning("Unexpected request for outgoing script-object references at %04x:%04x", PRINT_REG(addr));*/
- /* Happens e.g. when we're looking into strings */
- }
-}
-
-
-//-------------------- clones --------------------
-
-template<typename T>
-void Table<T>::listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {
- for (uint i = 0; i < _table.size(); i++)
- if (isValidEntry(i))
- (*note)(param, make_reg(segId, i));
-}
-
-void CloneTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
- CloneTable *clone_table = this;
- Clone *clone;
-
-// assert(addr.segment == _segId);
-
- if (!clone_table->isValidEntry(addr.offset)) {
- warning("Unexpected request for outgoing references from clone at %04x:%04x", PRINT_REG(addr));
-// BREAKPOINT();
- return;
- }
-
- clone = &(clone_table->_table[addr.offset]);
-
- // Emit all member variables (including references to the 'super' delegate)
- for (uint i = 0; i < clone->_variables.size(); i++)
- (*note)(param, clone->_variables[i]);
-
- // Note that this also includes the 'base' object, which is part of the script and therefore also emits the locals.
- (*note)(param, clone->pos);
- //sciprintf("[GC] Reporting clone-pos %04x:%04x\n", PRINT_REG(clone->pos));
-}
-
-void CloneTable::freeAtAddress(SegManager *segmgr, reg_t addr) {
- CloneTable *clone_table = this;
- Object *victim_obj;
-
-// assert(addr.segment == _segId);
-
- victim_obj = &(clone_table->_table[addr.offset]);
-
-#ifdef GC_DEBUG
- if (!(victim_obj->flags & OBJECT_FLAG_FREED))
- sciprintf("[GC] Warning: Clone %04x:%04x not reachable and not freed (freeing now)\n", PRINT_REG(addr));
-#ifdef GC_DEBUG_VERBOSE
- else
- sciprintf("[GC-DEBUG] Clone %04x:%04x: Freeing\n", PRINT_REG(addr));
-#endif
-#endif
- /*
- sciprintf("[GC] Clone %04x:%04x: Freeing\n", PRINT_REG(addr));
- sciprintf("[GC] Clone had pos %04x:%04x\n", PRINT_REG(victim_obj->pos));
- */
- clone_table->freeEntry(addr.offset);
-}
-
-
-//-------------------- locals --------------------
-reg_t LocalVariables::findCanonicAddress(SegManager *segmgr, reg_t addr) {
- // Reference the owning script
- SegmentId owner_seg = segmgr->segGet(script_id);
-
- assert(owner_seg >= 0);
-
- return make_reg(owner_seg, 0);
-}
-
-void LocalVariables::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
-// assert(addr.segment == _segId);
-
- for (uint i = 0; i < _locals.size(); i++)
- (*note)(param, _locals[i]);
-}
-
-
-//-------------------- stack --------------------
-reg_t DataStack::findCanonicAddress(SegManager *segmgr, reg_t addr) {
- addr.offset = 0;
- return addr;
-}
-
-void DataStack::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
- fprintf(stderr, "Emitting %d stack entries\n", nr);
- for (int i = 0; i < nr; i++)
- (*note)(param, entries[i]);
- fprintf(stderr, "DONE");
-}
-
-
-//-------------------- lists --------------------
-void ListTable::freeAtAddress(SegManager *segmgr, reg_t sub_addr) {
- freeEntry(sub_addr.offset);
-}
-
-void ListTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
- if (!isValidEntry(addr.offset)) {
- warning("Invalid list referenced for outgoing references: %04x:%04x", PRINT_REG(addr));
- return;
- }
-
- List *list = &(_table[addr.offset]);
-
- note(param, list->first);
- note(param, list->last);
- // We could probably get away with just one of them, but
- // let's be conservative here.
-}
-
-
-//-------------------- nodes --------------------
-void NodeTable::freeAtAddress(SegManager *segmgr, reg_t sub_addr) {
- freeEntry(sub_addr.offset);
-}
-
-void NodeTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
- if (!isValidEntry(addr.offset)) {
- warning("Invalid node referenced for outgoing references: %04x:%04x", PRINT_REG(addr));
- return;
- }
- Node *node = &(_table[addr.offset]);
-
- // We need all four here. Can't just stick with 'pred' OR 'succ' because node operations allow us
- // to walk around from any given node
- note(param, node->pred);
- note(param, node->succ);
- note(param, node->key);
- note(param, node->value);
-}
-
-
-//-------------------- hunk --------------------
-
-//-------------------- dynamic memory --------------------
-
-reg_t DynMem::findCanonicAddress(SegManager *segmgr, reg_t addr) {
- addr.offset = 0;
- return addr;
-}
-
-void DynMem::listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {
- (*note)(param, make_reg(segId, 0));
-}
-
} // End of namespace Sci