aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2009-05-10 19:17:51 +0000
committerMax Horn2009-05-10 19:17:51 +0000
commit019f87fd1b25f88c46615edbe09de6618d4b3bf7 (patch)
treee1948dd0ee65fb7cec3b59f5bc59bf2cc0946631
parent36818ced2a546ccb5318adaa22f8d90794edca8a (diff)
downloadscummvm-rg350-019f87fd1b25f88c46615edbe09de6618d4b3bf7.tar.gz
scummvm-rg350-019f87fd1b25f88c46615edbe09de6618d4b3bf7.tar.bz2
scummvm-rg350-019f87fd1b25f88c46615edbe09de6618d4b3bf7.zip
SCI: Changed object list in Script instances to use Common:::Array
svn-id: r40431
-rw-r--r--engines/sci/engine/gc.cpp7
-rw-r--r--engines/sci/engine/kernel.cpp2
-rw-r--r--engines/sci/engine/savegame.cpp61
-rw-r--r--engines/sci/engine/scriptconsole.cpp4
-rw-r--r--engines/sci/engine/scriptdebug.cpp7
-rw-r--r--engines/sci/engine/seg_manager.cpp104
-rw-r--r--engines/sci/engine/seg_manager.h6
-rw-r--r--engines/sci/engine/vm.cpp6
-rw-r--r--engines/sci/engine/vm.h17
9 files changed, 81 insertions, 133 deletions
diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp
index 7487e7a0c6..9de5357b38 100644
--- a/engines/sci/engine/gc.cpp
+++ b/engines/sci/engine/gc.cpp
@@ -118,15 +118,12 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
Script *script = (Script *)sm->_heap[i];
if (script->lockers) { // Explicitly loaded?
- int obj_nr;
-
// Locals, if present
wm.push(make_reg(script->locals_segment, 0));
// All objects (may be classes, may be indirectly reachable)
- for (obj_nr = 0; obj_nr < script->objects_nr; obj_nr++) {
- Object *obj = script->objects + obj_nr;
- wm.push(obj->pos);
+ for (uint obj_nr = 0; obj_nr < script->_objects.size(); obj_nr++) {
+ wm.push(script->_objects[obj_nr].pos);
}
}
}
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index a049abb735..43e78866ad 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -673,7 +673,7 @@ int determine_reg_type(EngineState *s, reg_t reg, int allow_invalid) {
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 && idx < (*(Script *)mobj).objects_nr)
+ if (idx >= 0 && (uint)idx < (*(Script *)mobj)._objects.size())
return KSIG_OBJECT;
else
return KSIG_REF;
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 3c9ccdcfc0..b913891d9d 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -277,7 +277,8 @@ static void sync_LocalVariables(Common::Serializer &s, LocalVariables &obj) {
sync_reg_t(s, obj.locals[i]);
}
-static void sync_Object(Common::Serializer &s, Object &obj) {
+template <>
+void syncWithSerializer(Common::Serializer &s, Object &obj) {
s.syncAsSint32LE(obj.flags);
sync_reg_t(s, obj.pos);
s.syncAsSint32LE(obj.variables_nr);
@@ -291,11 +292,6 @@ static void sync_Object(Common::Serializer &s, Object &obj) {
}
template <>
-void syncWithSerializer(Common::Serializer &s, Clone &obj) {
- sync_Object(s, obj);
-}
-
-template <>
void syncWithSerializer(Common::Serializer &s, List &obj) {
sync_reg_t(s, obj.first);
sync_reg_t(s, obj.last);
@@ -341,13 +337,22 @@ static void sync_Script(Common::Serializer &s, Script &obj) {
s.syncAsSint32LE(obj.exports_nr);
s.syncAsSint32LE(obj.synonyms_nr);
s.syncAsSint32LE(obj.lockers);
- s.syncAsSint32LE(obj.objects_allocated);
- s.syncAsSint32LE(obj.objects_nr);
- if (!obj.objects && obj.objects_allocated)
- obj.objects = (Object *)sci_calloc(obj.objects_allocated, sizeof(Object));
- for (int i = 0; i < obj.objects_allocated; ++i)
- sync_Object(s, obj.objects[i]);
+#if 1
+ uint len = obj._objects.size();
+ s.syncAsUint32LE(len); // Used to be obj.objects_allocated
+ s.skip(4); // Used to be obj.objects_nr
+ // Resize the array if loading.
+ if (s.isLoading())
+ obj._objects.resize(len);
+ Common::Array<Object>::iterator i;
+ for (i = obj._objects.begin(); i != obj._objects.end(); ++i) {
+ syncWithSerializer<Object>(s, *i);
+ }
+#else
+ s.skip(4); // Used to be obj.objects_allocated
+ syncArray<Object>(s, obj._objects);
+#endif
s.syncAsSint32LE(obj.locals_offset);
s.syncAsSint32LE(obj.locals_segment);
@@ -585,14 +590,13 @@ static void load_script(EngineState *s, SegmentId seg) {
// FIXME: The following should likely become a SegManager method
static void reconstruct_scripts(EngineState *s, SegManager *self) {
- uint i;
+ uint i, j;
MemObject *mobj;
for (i = 0; i < self->_heap.size(); i++) {
if (self->_heap[i]) {
mobj = self->_heap[i];
switch (mobj->getType()) {
case MEM_OBJ_SCRIPT: {
- int j;
Script *scr = (Script *)mobj;
load_script(s, i);
@@ -606,10 +610,10 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
if (!self->isSci1_1)
scr->export_table += 3;
- for (j = 0; j < scr->objects_nr; j++) {
- byte *data = scr->buf + scr->objects[j].pos.offset;
- scr->objects[j].base = scr->buf;
- scr->objects[j].base_obj = data;
+ for (j = 0; j < scr->_objects.size(); j++) {
+ byte *data = scr->buf + scr->_objects[j].pos.offset;
+ scr->_objects[j].base = scr->buf;
+ scr->_objects[j].base_obj = data;
}
break;
}
@@ -624,34 +628,33 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
mobj = self->_heap[i];
switch (mobj->getType()) {
case MEM_OBJ_SCRIPT: {
- int j;
Script *scr = (Script *)mobj;
- for (j = 0; j < scr->objects_nr; j++) {
- byte *data = scr->buf + scr->objects[j].pos.offset;
+ for (j = 0; j < scr->_objects.size(); j++) {
+ byte *data = scr->buf + scr->_objects[j].pos.offset;
if (self->isSci1_1) {
uint16 *funct_area = (uint16 *) (scr->buf + READ_LE_UINT16( data + 6 ));
uint16 *prop_area = (uint16 *) (scr->buf + READ_LE_UINT16( data + 4 ));
- scr->objects[j].base_method = funct_area;
- scr->objects[j].base_vars = prop_area;
+ scr->_objects[j].base_method = funct_area;
+ scr->_objects[j].base_vars = prop_area;
} else {
int funct_area = READ_LE_UINT16( data + SCRIPT_FUNCTAREAPTR_OFFSET );
Object *base_obj;
- base_obj = obj_get(s, scr->objects[j].variables[SCRIPT_SPECIES_SELECTOR]);
+ base_obj = obj_get(s, scr->_objects[j].variables[SCRIPT_SPECIES_SELECTOR]);
if (!base_obj) {
sciprintf("Object without a base class: Script %d, index %d (reg address "PREG"\n",
- scr->nr, j, PRINT_REG(scr->objects[j].variables[SCRIPT_SPECIES_SELECTOR]));
+ scr->nr, j, PRINT_REG(scr->_objects[j].variables[SCRIPT_SPECIES_SELECTOR]));
continue;
}
- scr->objects[j].variable_names_nr = base_obj->variables_nr;
- scr->objects[j].base_obj = base_obj->base_obj;
+ scr->_objects[j].variable_names_nr = base_obj->variables_nr;
+ scr->_objects[j].base_obj = base_obj->base_obj;
- scr->objects[j].base_method = (uint16 *) (data + funct_area);
- scr->objects[j].base_vars = (uint16 *) (data + scr->objects[j].variable_names_nr * 2 + SCRIPT_SELECTOR_OFFSET);
+ scr->_objects[j].base_method = (uint16 *)(data + funct_area);
+ scr->_objects[j].base_vars = (uint16 *)(data + scr->_objects[j].variable_names_nr * 2 + SCRIPT_SELECTOR_OFFSET);
}
}
break;
diff --git a/engines/sci/engine/scriptconsole.cpp b/engines/sci/engine/scriptconsole.cpp
index 53d8856a2c..137374f549 100644
--- a/engines/sci/engine/scriptconsole.cpp
+++ b/engines/sci/engine/scriptconsole.cpp
@@ -312,7 +312,7 @@ int parse_reg_t(EngineState *s, const char *str, reg_t *dest) { // Returns 0 on
if (mobj) {
if (mobj->getType() == MEM_OBJ_SCRIPT)
- max_index = (*(Script *)mobj).objects_nr;
+ max_index = (*(Script *)mobj)._objects.size();
else if (mobj->getType() == MEM_OBJ_CLONES)
max_index = (*(CloneTable *)mobj).max_entry;
}
@@ -325,7 +325,7 @@ int parse_reg_t(EngineState *s, const char *str, reg_t *dest) { // Returns 0 on
objpos.segment = i;
if (mobj->getType() == MEM_OBJ_SCRIPT) {
- obj = (*(Script *)mobj).objects + idx;
+ obj = &(*(Script *)mobj)._objects[idx];
objpos.offset = obj->pos.offset;
} else if (mobj->getType() == MEM_OBJ_CLONES) {
obj = &((*(CloneTable *)mobj).table[idx]);
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 555cef9dc2..d8181b93ed 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -388,7 +388,6 @@ static void _c_single_seg_info(EngineState *s, MemObject *mobj) {
switch (mobj->getType()) {
case MEM_OBJ_SCRIPT: {
- int i;
Script *scr = (Script *)mobj;
sciprintf("script.%03d locked by %d, bufsize=%d (%x)\n", scr->nr, scr->lockers, (uint)scr->buf_size, (uint)scr->buf_size);
if (scr->export_table)
@@ -403,10 +402,10 @@ static void _c_single_seg_info(EngineState *s, MemObject *mobj) {
else
sciprintf(" Locals : none\n");
- sciprintf(" Objects: %4d\n", scr->objects_nr);
- for (i = 0; i < scr->objects_nr; i++) {
+ sciprintf(" Objects: %4d\n", scr->_objects.size());
+ for (uint i = 0; i < scr->_objects.size(); i++) {
sciprintf(" ");
- print_obj_head(s, scr->objects + i);
+ print_obj_head(s, &scr->_objects[i]);
}
}
break;
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 35c46f5bc0..57cd0bc576 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -189,10 +189,6 @@ int SegManager::initialiseScript(Script &scr, EngineState *s, int script_nr) {
}
// Initialize objects
- scr.objects = NULL;
- scr.objects_allocated = 0;
- scr.objects_nr = 0; // No objects recorded yet
-
scr.locals_offset = 0;
scr.locals_block = NULL;
@@ -370,19 +366,10 @@ void Script::freeScript() {
buf = NULL;
buf_size = 0;
- if (objects) {
- for (int i = 0; i < objects_nr; i++) {
- Object *object = &objects[i];
- if (object->variables) {
- free(object->variables);
- object->variables = NULL;
- object->variables_nr = 0;
- }
- }
- free(objects);
- objects = NULL;
- objects_nr = 0;
+ for (uint i = 0; i < _objects.size(); i++) {
+ free(_objects[i].variables);
}
+ _objects.clear();
delete obj_indices;
obj_indices = 0;
@@ -578,17 +565,18 @@ void SegManager::scriptRelocate(reg_t block) {
continue; // FIXME: A hack pending investigation
if (!relocateLocal(scr, block.segment, pos)) {
- int k, done = 0;
+ bool done = false;
+ uint k;
- for (k = 0; !done && k < scr->objects_nr; k++) {
- if (relocateObject(scr->objects + k, block.segment, pos))
- done = 1;
+ for (k = 0; !done && k < scr->_objects.size(); k++) {
+ if (relocateObject(&scr->_objects[k], block.segment, pos))
+ done = true;
}
- for (k = 0; !done && k < scr->code_blocks_nr; k++) {
+ for (k = 0; !done && (int)k < scr->code_blocks_nr; k++) {
if (pos >= scr->code[k].pos.offset &&
pos < scr->code[k].pos.offset + scr->code[k].size)
- done = 1;
+ done = true;
}
if (!done) {
@@ -598,8 +586,8 @@ void SegManager::scriptRelocate(reg_t block) {
sciprintf("- locals: %d at %04x\n", scr->locals_block->nr, scr->locals_offset);
else
sciprintf("- No locals\n");
- for (k = 0; k < scr->objects_nr; k++)
- sciprintf("- obj#%d at %04x w/ %d vars\n", k, scr->objects[k].pos.offset, scr->objects[k].variables_nr);
+ for (k = 0; k < scr->_objects.size(); k++)
+ sciprintf("- obj#%d at %04x w/ %d vars\n", k, scr->_objects[k].pos.offset, scr->_objects[k].variables_nr);
// SQ3 script 71 has broken relocation entries.
// Since this is mainstream, we can't break out as we used to do.
sciprintf("Trying to continue anyway...\n");
@@ -624,11 +612,12 @@ void SegManager::heapRelocate(EngineState *s, reg_t block) {
int pos = READ_LE_UINT16(scr->heap_start + block.offset + 2 + (i * 2)) + scr->script_size;
if (!relocateLocal(scr, block.segment, pos)) {
- int k, done = 0;
+ bool done = false;
+ uint k;
- for (k = 0; !done && k < scr->objects_nr; k++) {
- if (relocateObject(scr->objects + k, block.segment, pos))
- done = 1;
+ for (k = 0; !done && k < scr->_objects.size(); k++) {
+ if (relocateObject(&scr->_objects[k], block.segment, pos))
+ done = true;
}
if (!done) {
@@ -638,8 +627,8 @@ void SegManager::heapRelocate(EngineState *s, reg_t block) {
sciprintf("- locals: %d at %04x\n", scr->locals_block->nr, scr->locals_offset);
else
sciprintf("- No locals\n");
- for (k = 0; k < scr->objects_nr; k++)
- sciprintf("- obj#%d at %04x w/ %d vars\n", k, scr->objects[k].pos.offset, scr->objects[k].variables_nr);
+ for (k = 0; k < scr->_objects.size(); k++)
+ sciprintf("- obj#%d at %04x w/ %d vars\n", k, scr->_objects[k].pos.offset, scr->_objects[k].variables_nr);
sciprintf("Triggering breakpoint...\n");
BREAKPOINT();
}
@@ -661,20 +650,13 @@ Object *SegManager::scriptObjInit0(EngineState *s, reg_t obj_pos) {
VERIFY(base < scr->buf_size, "Attempt to initialize object beyond end of script\n");
- if (!scr->objects) {
- scr->objects_allocated = DEFAULT_OBJECTS;
- scr->objects = (Object *)sci_malloc(sizeof(Object) * scr->objects_allocated);
- }
- if (scr->objects_nr == scr->objects_allocated) {
- scr->objects_allocated += DEFAULT_OBJECTS_INCREMENT;
- scr->objects = (Object *)sci_realloc(scr->objects, sizeof(Object) * scr->objects_allocated);
- }
-
temp = make_reg(obj_pos.segment, base);
+
id = scr->obj_indices->checkKey(base, true);
- scr->objects_nr++;
+ if ((uint)id == scr->_objects.size())
+ scr->_objects.push_back(Object());
- obj = scr->objects + id;
+ obj = &scr->_objects[id];
VERIFY(base + SCRIPT_FUNCTAREAPTR_OFFSET < scr->buf_size, "Function area pointer stored beyond end of script\n");
@@ -724,19 +706,11 @@ Object *SegManager::scriptObjInit11(EngineState *s, reg_t obj_pos) {
VERIFY(base < (uint16)scr->buf_size, "Attempt to initialize object beyond end of script\n");
- if (!scr->objects) {
- scr->objects_allocated = DEFAULT_OBJECTS;
- scr->objects = (Object *)sci_malloc(sizeof(Object) * scr->objects_allocated);
- }
- if (scr->objects_nr == scr->objects_allocated) {
- scr->objects_allocated += DEFAULT_OBJECTS_INCREMENT;
- scr->objects = (Object *)sci_realloc(scr->objects, sizeof(Object) * scr->objects_allocated);
- }
-
id = scr->obj_indices->checkKey(obj_pos.offset, true);
- scr->objects_nr++;
+ if ((uint)id == scr->_objects.size())
+ scr->_objects.push_back(Object());
- obj = scr->objects + id;
+ obj = &scr->_objects[id];
VERIFY(base + SCRIPT_FUNCTAREAPTR_OFFSET < (uint16)scr->buf_size, "Function area pointer stored beyond end of script\n");
@@ -912,20 +886,6 @@ void SegManager::scriptInitialiseObjectsSci11(EngineState *s, int seg) {
}
}
-void SegManager::scriptFreeUnusedObjects(SegmentId seg) {
- Script *scr = getScript(seg, SEG_ID);
- if (scr->objects_allocated > scr->objects_nr) {
- if (scr->objects_nr)
- scr->objects = (Object *)sci_realloc(scr->objects, sizeof(Object) * scr->objects_nr);
- else {
- if (scr->objects_allocated)
- free(scr->objects);
- scr->objects = NULL;
- }
- scr->objects_allocated = scr->objects_nr;
- }
-}
-
/*
static char *SegManager::dynprintf(char *msg, ...) {
va_list argp;
@@ -1208,18 +1168,16 @@ void Script::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param,
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 && idx < script->objects_nr) {
- Object *obj = script->objects + idx;
- int i;
-
+ 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));
- for (i = 0; i < obj->variables_nr; i++)
- (*note)(param, obj->variables[i]);
+ Object &obj = script->_objects[idx];
+ for (int i = 0; i < obj.variables_nr; i++)
+ (*note)(param, obj.variables[i]);
} else {
- fprintf(stderr, "Request for outgoing script-object reference at "PREG" yielded invalid index %d\n", PRINT_REG(addr), idx);
+ warning("Request for outgoing script-object reference at "PREG" yielded invalid index %d", PRINT_REG(addr), idx);
}
} else {
/* fprintf(stderr, "Unexpected request for outgoing script-object references at "PREG"\n", PRINT_REG(addr));*/
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 75e75d2c90..9ebdd60837 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -186,12 +186,6 @@ public:
// objects have been instantiated, or a run-time error will occur.
void scriptRelocate(reg_t block);
- // Deallocates all unused but allocated entries for objects
- // Parameters: (SegmentId) segid: segment of the script to prune in this way
- // These entries are created during script instantiation; deallocating them
- // frees up some additional memory.
- void scriptFreeUnusedObjects(SegmentId segid);
-
// Sets the script-relative offset of the exports table
// Parameters: (int) offset: The script-relative exports table offset
// (int) id: ID of the script or script segment to write to
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 65c3b6f5c2..60faca0425 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -1876,8 +1876,6 @@ int script_instantiate_sci0(EngineState *s, int script_nr) {
if (relocation >= 0)
s->seg_manager->scriptRelocate(make_reg(reg.segment, relocation));
- s->seg_manager->scriptFreeUnusedObjects(reg.segment);
-
return reg.segment; // instantiation successful
}
@@ -2094,8 +2092,8 @@ Object *obj_get(EngineState *s, reg_t offset) {
if (offset.offset <= (*(Script *)memobj).buf_size && offset.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET
&& RAW_IS_OBJECT((*(Script *)memobj).buf + offset.offset)) {
idx = RAW_GET_CLASS_INDEX((Script *)memobj, offset);
- if (idx >= 0 && idx < (*(Script *)memobj).objects_nr)
- obj = (*(Script *)memobj).objects + idx;
+ if (idx >= 0 && (uint)idx < (*(Script *)memobj)._objects.size())
+ obj = &(*(Script *)memobj)._objects[idx];
}
}
}
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index 65ecb0584f..0f3ed5f0ab 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -277,6 +277,8 @@ struct Object {
uint16 *base_method; /**< Pointer to the method selector area for this object */
uint16 *base_vars; /**< Pointer to the varselector area for this object */
reg_t *variables;
+
+ Object() { memset(this, 0, sizeof(*this)); }
};
struct CodeBlock {
@@ -323,11 +325,12 @@ struct Script : public MemObject {
int synonyms_nr; /**< Number of entries in the synonyms block */
int lockers; /**< Number of classes and objects that require this script */
- Object *objects; /**< Table for objects, contains property variables */
- /* Indexed by the value stored at SCRIPT_LOCALVARPTR_OFFSET,
- ** see VM_OBJECT_[GS]ET_INDEX() */
- int objects_nr; /**< Number of objects and classes */
- int objects_allocated; /**< Number of allocated objects */
+ /**
+ * Table for objects, contains property variables.
+ * Indexed by the value stored at SCRIPT_LOCALVARPTR_OFFSET,
+ * see VM_OBJECT_[GS]ET_INDEX()
+ */
+ Common::Array<Object> _objects;
int locals_offset;
int locals_segment; /**< The local variable segment */
@@ -353,10 +356,6 @@ public:
obj_indices = NULL;
- objects = NULL;
- objects_allocated = 0;
- objects_nr = 0;
-
locals_offset = 0;
locals_segment = 0;
locals_block = NULL;