diff options
author | Max Horn | 2009-09-06 13:01:00 +0000 |
---|---|---|
committer | Max Horn | 2009-09-06 13:01:00 +0000 |
commit | fdaa3d423c3789a05f100e9302dce3fc69034e76 (patch) | |
tree | 7a094bc20be9143ce43576f30fa1d33d8da4d214 | |
parent | a550e2ea10a44b2f5482af17be2cb473b9e4a0ce (diff) | |
download | scummvm-rg350-fdaa3d423c3789a05f100e9302dce3fc69034e76.tar.gz scummvm-rg350-fdaa3d423c3789a05f100e9302dce3fc69034e76.tar.bz2 scummvm-rg350-fdaa3d423c3789a05f100e9302dce3fc69034e76.zip |
SCI: Script::obj_indices is now protected
Add new methods init, allocateObject and getObject to class Script, and use them instead of directly accessing Script::obj_indices. Replace RAW_GET_CLASS_INDEX with Script::getObject()
svn-id: r43987
-rw-r--r-- | engines/sci/engine/kernel.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/memobj.cpp | 39 | ||||
-rw-r--r-- | engines/sci/engine/memobj.h | 6 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 37 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 5 | ||||
-rw-r--r-- | engines/sci/engine/vm.h | 1 |
6 files changed, 50 insertions, 42 deletions
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 41622dbfbb..140e0113e7 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -643,8 +643,8 @@ int determine_reg_type(SegManager *segMan, reg_t reg, bool allow_invalid) { case MEM_OBJ_SCRIPT: if (reg.offset <= (*(Script *)mobj).buf_size && reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT((*(Script *)mobj).buf + reg.offset)) { - int idx = RAW_GET_CLASS_INDEX((Script *)mobj, reg); - if (idx >= 0 && (uint)idx < (*(Script *)mobj)._objects.size()) + Object *obj = ((Script *)mobj)->getObject(reg.offset); + if (obj) return KSIG_OBJECT; else return KSIG_REF; diff --git a/engines/sci/engine/memobj.cpp b/engines/sci/engine/memobj.cpp index 97572664de..f3af7ea20c 100644 --- a/engines/sci/engine/memobj.cpp +++ b/engines/sci/engine/memobj.cpp @@ -89,6 +89,34 @@ void Script::freeScript() { _codeBlocks.clear(); } +void Script::init() { + locals_offset = 0; + locals_block = NULL; + + _codeBlocks.clear(); + + _markedAsDeleted = false; + relocated = 0; + + obj_indices = new IntMapper(); +} + +Object *Script::allocateObject(uint16 offset) { + int idx = obj_indices->checkKey(offset, true); + if ((uint)idx == _objects.size()) + _objects.push_back(Object()); + + return &_objects[idx]; +} + +Object *Script::getObject(uint16 offset) { + int idx = obj_indices->checkKey(offset, false); + if (idx >= 0 && (uint)idx < _objects.size()) + return &_objects[idx]; + else + return 0; +} + void Script::incrementLockers() { lockers++; } @@ -248,17 +276,16 @@ void Script::listAllOutgoingReferences(reg_t addr, void *param, NoteCallback not 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()) { + Object *obj = getObject(addr.offset); + if (obj) { // 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]); + 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); + warning("Request for outgoing script-object reference at %04x:%04x failed", PRINT_REG(addr)); } } else { /* warning("Unexpected request for outgoing script-object references at %04x:%04x", PRINT_REG(addr));*/ diff --git a/engines/sci/engine/memobj.h b/engines/sci/engine/memobj.h index ac630ade4d..f8cbb53060 100644 --- a/engines/sci/engine/memobj.h +++ b/engines/sci/engine/memobj.h @@ -248,8 +248,10 @@ struct Script : public MemObject { byte *heap_start; /**< Start of heap if SCI1.1, NULL otherwise */ uint16 *export_table; /**< Abs. offset of the export table or 0 if not present */ +protected: IntMapper *obj_indices; +public: int exports_nr; /**< Number of entries in the exports table */ int synonyms_nr; /**< Number of entries in the synonyms block */ int lockers; /**< Number of classes and objects that require this script */ @@ -296,6 +298,7 @@ public: } void freeScript(); + void init(); virtual bool isValidOffset(uint16 offset) const; virtual byte *dereference(reg_t pointer, int *size); @@ -306,6 +309,9 @@ public: virtual void saveLoadWithSerializer(Common::Serializer &ser); + Object *allocateObject(uint16 offset); + Object *getObject(uint16 offset); + // script lock operations /** Increments the number of lockers of this script by one. */ diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 175a3021c4..25c74b9be0 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -186,16 +186,8 @@ int SegManager::initialiseScript(Script &scr, int script_nr) { } // Initialize objects - scr.locals_offset = 0; - scr.locals_block = NULL; - - scr._codeBlocks.clear(); - + scr.init(); scr.nr = script_nr; - scr._markedAsDeleted = false; - scr.relocated = 0; - - scr.obj_indices = new IntMapper(); if (_resMan->sciVersion() >= SCI_VERSION_1_1) scr.heap_start = scr.buf + scr.script_size; @@ -463,22 +455,14 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller Object *SegManager::scriptObjInit0(reg_t obj_pos) { Object *obj; - int id; SciVersion version = _resMan->sciVersion(); // for the offset defines - unsigned int base = obj_pos.offset - SCRIPT_OBJECT_MAGIC_OFFSET; - reg_t temp; + uint base = obj_pos.offset - SCRIPT_OBJECT_MAGIC_OFFSET; Script *scr = getScript(obj_pos.segment); VERIFY(base < scr->buf_size, "Attempt to initialize object beyond end of script\n"); - temp = make_reg(obj_pos.segment, base); - - id = scr->obj_indices->checkKey(base, true); - if ((uint)id == scr->_objects.size()) - scr->_objects.push_back(Object()); - - obj = &scr->_objects[id]; + obj = scr->allocateObject(base); VERIFY(base + SCRIPT_FUNCTAREAPTR_OFFSET < scr->buf_size, "Function area pointer stored beyond end of script\n"); @@ -491,7 +475,7 @@ Object *SegManager::scriptObjInit0(reg_t obj_pos) { int i; obj->flags = 0; - obj->pos = temp; + obj->pos = make_reg(obj_pos.segment, base); VERIFY(base + funct_area < scr->buf_size, "Function area pointer references beyond end of script"); @@ -520,20 +504,15 @@ Object *SegManager::scriptObjInit0(reg_t obj_pos) { Object *SegManager::scriptObjInit11(reg_t obj_pos) { Object *obj; - int id; - int base = obj_pos.offset; + uint base = obj_pos.offset; Script *scr = getScript(obj_pos.segment); - VERIFY(base < (uint16)scr->buf_size, "Attempt to initialize object beyond end of script\n"); - - id = scr->obj_indices->checkKey(obj_pos.offset, true); - if ((uint)id == scr->_objects.size()) - scr->_objects.push_back(Object()); + VERIFY(base < scr->buf_size, "Attempt to initialize object beyond end of script\n"); - obj = &scr->_objects[id]; + obj = scr->allocateObject(base); - VERIFY(base + SCRIPT_FUNCTAREAPTR_OFFSET < (uint16)scr->buf_size, "Function area pointer stored beyond end of script\n"); + VERIFY(base + SCRIPT_FUNCTAREAPTR_OFFSET < scr->buf_size, "Function area pointer stored beyond end of script\n"); { byte *data = (byte *)(scr->buf + base); diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 520910b1a7..a1cdf2b822 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -1936,7 +1936,6 @@ Object *obj_get(SegManager *segMan, reg_t offset) { MemObject *mobj = GET_OBJECT_SEGMENT(*segMan, offset.segment); SciVersion version = segMan->sciVersion(); Object *obj = NULL; - int idx; if (mobj != NULL) { if (mobj->getType() == MEM_OBJ_CLONES) { @@ -1947,9 +1946,7 @@ Object *obj_get(SegManager *segMan, reg_t offset) { Script *scr = (Script *)mobj; if (offset.offset <= scr->buf_size && offset.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(scr->buf + offset.offset)) { - idx = RAW_GET_CLASS_INDEX(scr, offset); - if (idx >= 0 && (uint)idx < scr->_objects.size()) - obj = &scr->_objects[idx]; + obj = scr->getObject(offset.offset); } } } diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index 50eb59571d..5d1532d3bd 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -117,7 +117,6 @@ struct Class { reg_t reg; /**< offset; script-relative offset, segment: 0 if not instantiated */ }; -#define RAW_GET_CLASS_INDEX(scr, reg) ((scr)->obj_indices->checkKey(reg.offset, false)) #define RAW_IS_OBJECT(datablock) (READ_LE_UINT16(((byte *) datablock) + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER) #define IS_CLASS(obj) (obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS) |