aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
authorMax Horn2009-09-06 13:01:00 +0000
committerMax Horn2009-09-06 13:01:00 +0000
commitfdaa3d423c3789a05f100e9302dce3fc69034e76 (patch)
tree7a094bc20be9143ce43576f30fa1d33d8da4d214 /engines/sci/engine
parenta550e2ea10a44b2f5482af17be2cb473b9e4a0ce (diff)
downloadscummvm-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
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/kernel.cpp4
-rw-r--r--engines/sci/engine/memobj.cpp39
-rw-r--r--engines/sci/engine/memobj.h6
-rw-r--r--engines/sci/engine/seg_manager.cpp37
-rw-r--r--engines/sci/engine/vm.cpp5
-rw-r--r--engines/sci/engine/vm.h1
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)