From 019f87fd1b25f88c46615edbe09de6618d4b3bf7 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sun, 10 May 2009 19:17:51 +0000 Subject: SCI: Changed object list in Script instances to use Common:::Array svn-id: r40431 --- engines/sci/engine/gc.cpp | 7 +-- engines/sci/engine/kernel.cpp | 2 +- engines/sci/engine/savegame.cpp | 61 ++++++++++---------- engines/sci/engine/scriptconsole.cpp | 4 +- engines/sci/engine/scriptdebug.cpp | 7 +-- engines/sci/engine/seg_manager.cpp | 104 +++++++++++------------------------ engines/sci/engine/seg_manager.h | 6 -- engines/sci/engine/vm.cpp | 6 +- engines/sci/engine/vm.h | 17 +++--- 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); @@ -290,11 +291,6 @@ static void sync_Object(Common::Serializer &s, Object &obj) { sync_reg_t(s, obj.variables[i]); } -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); @@ -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::iterator i; + for (i = obj._objects.begin(); i != obj._objects.end(); ++i) { + syncWithSerializer(s, *i); + } +#else + s.skip(4); // Used to be obj.objects_allocated + syncArray(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 _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; -- cgit v1.2.3