aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorJordi Vilalta Prat2009-02-21 23:27:24 +0000
committerJordi Vilalta Prat2009-02-21 23:27:24 +0000
commit817fde6cdddc700650e16018e9d6184ae29d1ecf (patch)
tree64379a245f082d7384bd45c015c8795a257d530c /engines/sci
parentb5b4cb66a173bfea3792058e160f6b9a0b30e2ff (diff)
downloadscummvm-rg350-817fde6cdddc700650e16018e9d6184ae29d1ecf.tar.gz
scummvm-rg350-817fde6cdddc700650e16018e9d6184ae29d1ecf.tar.bz2
scummvm-rg350-817fde6cdddc700650e16018e9d6184ae29d1ecf.zip
SCI: Convert the segment manager into a class
svn-id: r38767
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/game.cpp14
-rw-r--r--engines/sci/engine/gc.cpp16
-rw-r--r--engines/sci/engine/kernel.cpp22
-rw-r--r--engines/sci/engine/kgraphics.cpp6
-rw-r--r--engines/sci/engine/klists.cpp16
-rw-r--r--engines/sci/engine/kmovement.cpp2
-rw-r--r--engines/sci/engine/kpathing.cpp8
-rw-r--r--engines/sci/engine/kscripts.cpp18
-rw-r--r--engines/sci/engine/kstring.cpp10
-rw-r--r--engines/sci/engine/savegame.cfsml47
-rw-r--r--engines/sci/engine/savegame.cpp87
-rw-r--r--engines/sci/engine/scriptconsole.cpp6
-rw-r--r--engines/sci/engine/scriptdebug.cpp38
-rw-r--r--engines/sci/engine/seg_manager.cpp658
-rw-r--r--engines/sci/engine/seg_manager.h750
-rw-r--r--engines/sci/engine/vm.cpp108
-rw-r--r--engines/sci/include/engine.h2
-rw-r--r--engines/sci/include/vm.h17
18 files changed, 921 insertions, 904 deletions
diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp
index 4fd9b0208c..6d0dd3b925 100644
--- a/engines/sci/engine/game.cpp
+++ b/engines/sci/engine/game.cpp
@@ -467,7 +467,7 @@ int script_init_engine(EngineState *s, sci_version_t version) {
else
result = create_class_table_sci0(s);
- sm_init(&s->seg_manager, s->version >= SCI_VERSION(1, 001, 000));
+ s->seg_manager = new SegManager(s->version >= SCI_VERSION(1, 001, 000));
s->gc_countdown = GC_INTERVAL - 1;
if (result) {
@@ -482,9 +482,9 @@ int script_init_engine(EngineState *s, sci_version_t version) {
return 1;
}
- s->script_000 = &(s->seg_manager.heap[s->script_000_segment]->data.script);
+ s->script_000 = &(s->seg_manager->heap[s->script_000_segment]->data.script);
- s->sys_strings = sm_allocate_sys_strings(&s->seg_manager, &s->sys_strings_segment);
+ s->sys_strings = s->seg_manager->allocateSysStrings(&s->sys_strings_segment);
// Allocate static buffer for savegame and CWD directories
sys_string_acquire(s->sys_strings, SYS_STRING_SAVEDIR, "savedir", MAX_SAVE_DIR_SIZE);
@@ -523,9 +523,9 @@ int script_init_engine(EngineState *s, sci_version_t version) {
if (s->version >= SCI_VERSION_FTU_LOFS_ABSOLUTE &&
s->version < SCI_VERSION(1, 001, 000))
- sm_set_export_width(&s->seg_manager, 1);
+ s->seg_manager->setExportWidth(1);
else
- sm_set_export_width(&s->seg_manager, 0);
+ s->seg_manager->setExportWidth(0);
sciprintf("Engine initialized\n");
@@ -600,7 +600,7 @@ int game_init(EngineState *s) {
reg_t game_obj; // Address of the game object
dstack_t *stack;
- stack = sm_allocate_stack(&s->seg_manager, VM_STACK_SIZE, &s->stack_segment);
+ stack = s->seg_manager->allocateStack(VM_STACK_SIZE, &s->stack_segment);
s->stack_base = stack->entries;
s->stack_top = s->stack_base + VM_STACK_SIZE;
@@ -679,7 +679,7 @@ int game_exit(EngineState *s) {
// Reinit because some other code depends on having a valid state
game_init_sound(s, SFX_STATE_FLAG_NOSOUND);
- sm_destroy(&s->seg_manager);
+ delete s->seg_manager;
if (s->synonyms_nr) {
free(s->synonyms);
diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp
index 0a0097aad5..94632a6b7c 100644
--- a/engines/sci/engine/gc.cpp
+++ b/engines/sci/engine/gc.cpp
@@ -100,11 +100,11 @@ static void free_worklist(worklist_t *wl) {
}
}
-static reg_t_hash_map * normalise_hashmap_ptrs(reg_t_hash_map *nonnormal_map, seg_interface_t **interfaces, int interfaces_nr) {
+static reg_t_hash_map * normalise_hashmap_ptrs(reg_t_hash_map *nonnormal_map, SegInterface **interfaces, int interfaces_nr) {
reg_t_hash_map *normal_map = new reg_t_hash_map();
for (reg_t_hash_map::iterator i = nonnormal_map->begin(); i != nonnormal_map->end(); ++i) {
- seg_interface_t *interfce;
+ SegInterface *interfce;
reg_t reg = i->_key;
interfce = (reg.segment < interfaces_nr) ? interfaces[reg.segment] : NULL;
@@ -129,8 +129,8 @@ void add_outgoing_refs(void *pre_wm, reg_t addr) {
}
reg_t_hash_map *find_all_used_references(EngineState *s) {
- SegManager *sm = &(s->seg_manager);
- seg_interface_t **interfaces = (seg_interface_t**)sci_calloc(sizeof(seg_interface_t *), sm->heap_size);
+ SegManager *sm = s->seg_manager;
+ SegInterface **interfaces = (SegInterface **)sci_calloc(sizeof(SegInterface *), sm->heap_size);
reg_t_hash_map *nonnormal_map = new reg_t_hash_map();
reg_t_hash_map *normal_map = NULL;
worklist_t *worklist = new_worklist();
@@ -144,7 +144,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
if (sm->heap[i] == NULL)
interfaces[i] = NULL;
else
- interfaces[i] = get_seg_interface(sm, i);
+ interfaces[i] = sm->getSegInterface(i);
// Initialise
// Init: Registers
@@ -229,7 +229,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
}
struct deallocator_t {
- seg_interface_t *interfce;
+ SegInterface *interfce;
#ifdef DEBUG_GC
char *segnames[MEM_OBJ_MAX + 1];
int segcount[MEM_OBJ_MAX + 1];
@@ -255,7 +255,7 @@ void free_unless_used(void *pre_use_map, reg_t addr) {
void run_gc(EngineState *s) {
int seg_nr;
deallocator_t deallocator;
- SegManager *sm = &(s->seg_manager);
+ SegManager *sm = s->seg_manager;
#ifdef DEBUG_GC
c_segtable(s);
@@ -267,7 +267,7 @@ void run_gc(EngineState *s) {
for (seg_nr = 1; seg_nr < sm->heap_size; seg_nr++) {
if (sm->heap[seg_nr] != NULL) {
- deallocator.interfce = get_seg_interface(sm, seg_nr);
+ deallocator.interfce = sm->getSegInterface(seg_nr);
#ifdef DEBUG_GC
deallocator.segnames[deallocator.interfce->type_id] = deallocator.interfce->type;
#endif
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index d01451f2e3..5c5cf51a04 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -370,7 +370,7 @@ int kernel_oops(EngineState *s, const char *file, int line, const char *reason)
reg_t kalloc(EngineState *s, const char *type, int space) {
reg_t reg;
- sm_alloc_hunk_entry(&s->seg_manager, type, space, &reg);
+ s->seg_manager->alloc_hunk_entry(type, space, &reg);
SCIkdebug(SCIkMEM, "Allocated %d at hunk "PREG" (%s)\n", space, PRINT_REG(reg), type);
return reg;
@@ -390,7 +390,7 @@ int has_kernel_function(EngineState *s, const char *kname) {
// Returns a pointer to the memory indicated by the specified handle
byte *kmem(EngineState *s, reg_t handle) {
- mem_obj_t *mobj = GET_SEGMENT(s->seg_manager, handle.segment, MEM_OBJ_HUNK);
+ mem_obj_t *mobj = GET_SEGMENT(*s->seg_manager, handle.segment, MEM_OBJ_HUNK);
hunk_table_t *ht = &(mobj->data.hunks);
if (!mobj || !ENTRY_IS_VALID(ht, handle.offset)) {
@@ -403,7 +403,7 @@ byte *kmem(EngineState *s, reg_t handle) {
// Frees the specified handle. Returns 0 on success, 1 otherwise.
int kfree(EngineState *s, reg_t handle) {
- sm_free_hunk_entry(&s->seg_manager, handle);
+ s->seg_manager->free_hunk_entry(handle);
return 0;
}
@@ -567,17 +567,17 @@ reg_t kGetTime(EngineState *s, int funct_nr, int argc, reg_t *argv) {
reg_t kMemory(EngineState *s, int funct_nr, int argc, reg_t *argv) {
switch (UKPV(0)) {
case K_MEMORY_ALLOCATE_CRITICAL :
- if (!sm_alloc_dynmem(&s->seg_manager, UKPV(1), "kMemory() critical", &s->r_acc)) {
+ if (!s->seg_manager->allocDynmem(UKPV(1), "kMemory() critical", &s->r_acc)) {
SCIkwarn(SCIkERROR, "Critical heap allocation failed\n");
script_error_flag = script_debug_flag = 1;
}
return s->r_acc;
break;
case K_MEMORY_ALLOCATE_NONCRITICAL :
- sm_alloc_dynmem(&s->seg_manager, UKPV(1), "kMemory() non-critical", &s->r_acc);
+ s->seg_manager->allocDynmem(UKPV(1), "kMemory() non-critical", &s->r_acc);
break;
case K_MEMORY_FREE :
- if (sm_free_dynmem(&s->seg_manager, argv[1])) {
+ if (s->seg_manager->freeDynmem(argv[1])) {
SCIkwarn(SCIkERROR, "Attempt to kMemory::free() non-dynmem pointer "PREG"!\n", PRINT_REG(argv[1]));
}
break;
@@ -606,7 +606,7 @@ reg_t kMemory(EngineState *s, int funct_nr, int argc, reg_t *argv) {
SCIkdebug(SCIkERROR, "Attempt to poke invalid memory at "PREG"!\n", PRINT_REG(argv[1]));
return s->r_acc;
}
- if (s->seg_manager.heap[argv[1].segment]->type == MEM_OBJ_LOCALS)
+ if (s->seg_manager->heap[argv[1].segment]->type == MEM_OBJ_LOCALS)
return *((reg_t *) ref);
else
return make_reg(0, getInt16(ref));
@@ -620,7 +620,7 @@ reg_t kMemory(EngineState *s, int funct_nr, int argc, reg_t *argv) {
return s->r_acc;
}
- if (s->seg_manager.heap[argv[1].segment]->type == MEM_OBJ_LOCALS)
+ if (s->seg_manager->heap[argv[1].segment]->type == MEM_OBJ_LOCALS)
*((reg_t *) ref) = argv[2];
else {
if (argv[2].segment) {
@@ -828,10 +828,10 @@ int determine_reg_type(EngineState *s, reg_t reg, int allow_invalid) {
return KSIG_ARITHMETIC;
}
- if ((reg.segment >= s->seg_manager.heap_size) || !s->seg_manager.heap[reg.segment])
+ if ((reg.segment >= s->seg_manager->heap_size) || !s->seg_manager->heap[reg.segment])
return 0; // Invalid
- mobj = s->seg_manager.heap[reg.segment];
+ mobj = s->seg_manager->heap[reg.segment];
switch (mobj->type) {
case MEM_OBJ_SCRIPT:
@@ -937,7 +937,7 @@ int kernel_matches_signature(EngineState *s, const char *sig, int argc, reg_t *a
static inline void *_kernel_dereference_pointer(EngineState *s, reg_t pointer, int entries, int align) {
int maxsize;
- void *retval = sm_dereference(&s->seg_manager, pointer, &maxsize);
+ void *retval = s->seg_manager->dereference(pointer, &maxsize);
if (pointer.offset & (align - 1)) {
SCIkdebug(SCIkERROR, "Unaligned pointer read: "PREG" expected with %d alignment!\n", PRINT_REG(pointer), align);
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index c4cf477e42..ff31b4b2bd 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -1308,7 +1308,7 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse);
static void _k_disable_delete_for_now(EngineState *s, reg_t obj) {
reg_t text_pos = GET_SEL32(obj, text);
- char *text = IS_NULL_REG(text_pos) ? NULL : (char *) sm_dereference(&s->seg_manager, text_pos, NULL);
+ char *text = IS_NULL_REG(text_pos) ? NULL : (char *)s->seg_manager->dereference(text_pos, NULL);
int type = GET_SEL32V(obj, type);
int state = GET_SEL32V(obj, state);
@@ -1378,7 +1378,7 @@ reg_t kEditControl(EngineState *s, int funct_nr, int argc, reg_t *argv) {
reg_t text_pos = GET_SEL32(obj, text);
int display_offset = 0;
- char *text = (char *) sm_dereference(&s->seg_manager, text_pos, NULL);
+ char *text = (char *)s->seg_manager->dereference(text_pos, NULL);
int textlen;
if (!text) {
@@ -1545,7 +1545,7 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse) {
int font_nr = GET_SEL32V(obj, font);
reg_t text_pos = GET_SEL32(obj, text);
- char *text = IS_NULL_REG(text_pos) ? NULL : (char *)sm_dereference(&s->seg_manager, text_pos, NULL);
+ char *text = IS_NULL_REG(text_pos) ? NULL : (char *)s->seg_manager->dereference(text_pos, NULL);
int view = GET_SEL32V(obj, view);
int cel = sign_extend_byte(GET_SEL32V(obj, cel));
int loop = sign_extend_byte(GET_SEL32V(obj, loop));
diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp
index e2cd12d7c7..7693e835a8 100644
--- a/engines/sci/engine/klists.cpp
+++ b/engines/sci/engine/klists.cpp
@@ -39,7 +39,7 @@ inline node_t *inline_lookup_node(EngineState *s, reg_t addr, const char *file,
if (!addr.offset && !addr.segment)
return NULL; // Non-error null
- mobj = GET_SEGMENT(s->seg_manager, addr.segment, MEM_OBJ_NODES);
+ mobj = GET_SEGMENT(*s->seg_manager, addr.segment, MEM_OBJ_NODES);
if (!mobj) {
sciprintf("%s, L%d: Attempt to use non-node "PREG" as list node\n", __FILE__, __LINE__, PRINT_REG(addr));
script_debug_flag = script_error_flag = 1;
@@ -70,7 +70,7 @@ inline list_t *_lookup_list(EngineState *s, reg_t addr, const char *file, int li
if (may_be_null && !addr.segment && !addr.offset)
return NULL;
- mobj = GET_SEGMENT(s->seg_manager, addr.segment, MEM_OBJ_LISTS);
+ mobj = GET_SEGMENT(*s->seg_manager, addr.segment, MEM_OBJ_LISTS);
if (!mobj) {
sciprintf("%s, L%d: Attempt to use non-list "PREG" as list\n", __FILE__, __LINE__, PRINT_REG(addr));
@@ -159,7 +159,7 @@ int sane_listp(EngineState *s, reg_t addr) {
reg_t kNewList(EngineState *s, int funct_nr, int argc, reg_t *argv) {
reg_t listbase;
list_t *l;
- l = sm_alloc_list(&s->seg_manager, &listbase);
+ l = s->seg_manager->alloc_list(&listbase);
l->first = l->last = NULL_REG;
SCIkdebug(SCIkNODES, "New listbase at "PREG"\n", PRINT_REG(listbase));
@@ -182,19 +182,19 @@ reg_t kDisposeList(EngineState *s, int funct_nr, int argc, reg_t *argv) {
while (!IS_NULL_REG(n_addr)) { // Free all nodes
node_t *n = LOOKUP_NODE(n_addr);
- sm_free_node(&s->seg_manager, n_addr);
+ s->seg_manager->free_node(n_addr);
n_addr = n->succ;
}
}
- sm_free_list(&s->seg_manager, argv[0]);
+ s->seg_manager->free_list(argv[0]);
*/
return s->r_acc;
}
inline reg_t _k_new_node(EngineState *s, reg_t value, reg_t key) {
reg_t nodebase;
- node_t *n = sm_alloc_node(&s->seg_manager, &nodebase);
+ node_t *n = s->seg_manager->alloc_node(&nodebase);
if (!n) {
KERNEL_OOPS("Out of memory while creating a node");
@@ -422,7 +422,7 @@ reg_t kDeleteKey(EngineState *s, int funct_nr, int argc, reg_t *argv) {
if (!IS_NULL_REG(n->succ))
LOOKUP_NODE(n->succ)->pred = n->pred;
- //sm_free_node(&s->seg_manager, node_pos);
+ //s->seg_manager->free_node(node_pos);
return make_reg(0, 1); // Signal success
}
@@ -465,7 +465,7 @@ reg_t kSort(EngineState *s, int funct_nr, int argc, reg_t *argv) {
return s->r_acc;
if (IS_NULL_REG(output_data)) {
- list = sm_alloc_list(&s->seg_manager, &output_data);
+ list = s->seg_manager->alloc_list(&output_data);
list->first = list->last = NULL_REG;
PUT_SEL32(dest, elements, output_data);
}
diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp
index c9a7718f9c..25161890c7 100644
--- a/engines/sci/engine/kmovement.cpp
+++ b/engines/sci/engine/kmovement.cpp
@@ -270,7 +270,7 @@ static void bresenham_autodetect(EngineState *s) {
return;
}
- buf = s->seg_manager.heap[fptr.segment]->data.script.buf + fptr.offset;
+ buf = s->seg_manager->heap[fptr.segment]->data.script.buf + fptr.offset;
handle_movecnt = (SCI_VERSION_MAJOR(s->version) == 0 || checksum_bytes(buf, 8) == 0x216) ? INCREMENT_MOVECNT : IGNORE_MOVECNT;
sciprintf("b-moveCnt action based on checksum: %s\n", handle_movecnt == IGNORE_MOVECNT ? "ignore" : "increment");
} else {
diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp
index b84ea704f0..204dae4258 100644
--- a/engines/sci/engine/kpathing.cpp
+++ b/engines/sci/engine/kpathing.cpp
@@ -1381,7 +1381,7 @@ static reg_t output_path(pf_state_t *p, EngineState *s) {
if (unreachable) {
// If pathfinding failed we only return the path up to vertex_start
- oref = sm_alloc_dynmem(&s->seg_manager, POLY_POINT_SIZE * 3, AVOIDPATH_DYNMEM_STRING, &output);
+ oref = s->seg_manager->allocDynmem(POLY_POINT_SIZE * 3, AVOIDPATH_DYNMEM_STRING, &output);
if (p->keep_start)
POLY_SET_POINT(oref, 0, p->start.x, p->start.y);
@@ -1400,7 +1400,7 @@ static reg_t output_path(pf_state_t *p, EngineState *s) {
vertex = vertex->path_prev;
}
- oref = sm_alloc_dynmem(&s->seg_manager, POLY_POINT_SIZE * (path_len + 1 + p->keep_start + p->keep_end), AVOIDPATH_DYNMEM_STRING, &output);
+ oref = s->seg_manager->allocDynmem(POLY_POINT_SIZE * (path_len + 1 + p->keep_start + p->keep_end), AVOIDPATH_DYNMEM_STRING, &output);
// Sentinel
POLY_SET_POINT(oref, path_len + p->keep_start + p->keep_end, POLY_LAST_POINT, POLY_LAST_POINT);
@@ -1504,8 +1504,8 @@ reg_t kAvoidPath(EngineState *s, int funct_nr, int argc, reg_t *argv) {
sciprintf("[avoidpath] Error: pathfinding failed for following input:\n");
print_input(s, poly_list, start, end, opt);
sciprintf("[avoidpath] Returning direct path from start point to end point\n");
- oref = sm_alloc_dynmem(&s->seg_manager, POLY_POINT_SIZE * 3,
- AVOIDPATH_DYNMEM_STRING, &output);
+ oref = s->seg_manager->allocDynmem(POLY_POINT_SIZE * 3,
+ AVOIDPATH_DYNMEM_STRING, &output);
POLY_SET_POINT(oref, 0, start.x, start.y);
POLY_SET_POINT(oref, 1, end.x, end.y);
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index df36d41708..d3fb235120 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -166,7 +166,7 @@ reg_t kClone(EngineState *s, int funct_nr, int argc, reg_t *argv) {
SCIkdebug(SCIkMEM, "Attempting to clone from "PREG"\n", PRINT_REG(parent_addr));
- clone_obj = sm_alloc_clone(&s->seg_manager, &clone_addr);
+ clone_obj = s->seg_manager->alloc_clone(&clone_addr);
if (!clone_obj) {
SCIkwarn(SCIkERROR, "Cloning "PREG" failed-- internal error!\n", PRINT_REG(parent_addr));
@@ -184,8 +184,8 @@ reg_t kClone(EngineState *s, int funct_nr, int argc, reg_t *argv) {
clone_obj->variables[SCRIPT_SPECIES_SELECTOR] = clone_obj->pos;
if (IS_CLASS(parent_obj))
clone_obj->variables[SCRIPT_SUPERCLASS_SELECTOR] = parent_obj->pos;
- sm_increment_lockers(&s->seg_manager, parent_obj->pos.segment, SEG_ID);
- sm_increment_lockers(&s->seg_manager, clone_obj->pos.segment, SEG_ID);
+ s->seg_manager->incrementLockers(parent_obj->pos.segment, SEG_ID);
+ s->seg_manager->incrementLockers(clone_obj->pos.segment, SEG_ID);
return clone_addr;
}
@@ -243,7 +243,7 @@ reg_t kScriptID(EngineState *s, int funct_nr, int argc, reg_t *argv) {
if (!scriptid)
return NULL_REG;
- scr = &(s->seg_manager.heap[scriptid]->data.script);
+ scr = &(s->seg_manager->heap[scriptid]->data.script);
if (!scr->exports_nr) {
SCIkdebug(SCIkERROR, "Script 0x%x does not have a dispatch table\n", script);
@@ -255,7 +255,7 @@ reg_t kScriptID(EngineState *s, int funct_nr, int argc, reg_t *argv) {
return NULL_REG;
}
- return make_reg(scriptid, sm_validate_export_func(&s->seg_manager, index, scriptid));
+ return make_reg(scriptid, s->seg_manager->validateExportFunc(index, scriptid));
}
reg_t kDisposeScript(EngineState *s, int funct_nr, int argc, reg_t *argv) {
@@ -265,11 +265,11 @@ reg_t kDisposeScript(EngineState *s, int funct_nr, int argc, reg_t *argv) {
if (argv[0].segment)
return s->r_acc;
- if (sm_script_is_loaded(&(s->seg_manager), script, SCRIPT_ID)) {
- int id = sm_seg_get(&(s->seg_manager), script);
+ if (s->seg_manager->scriptIsLoaded(script, SCRIPT_ID)) {
+ int id = s->seg_manager->segGet(script);
if (s->execution_stack[s->execution_stack_pos].addr.pc.segment != id)
- sm_set_lockers(&(s->seg_manager), 1, script, SCRIPT_ID);
+ s->seg_manager->setLockers(1, script, SCRIPT_ID);
}
script_uninstantiate(s, script);
@@ -279,7 +279,7 @@ reg_t kDisposeScript(EngineState *s, int funct_nr, int argc, reg_t *argv) {
int is_heap_object(EngineState *s, reg_t pos) {
object_t *obj = obj_get(s, pos);
- return (obj != NULL && (!(obj->flags & OBJECT_FLAG_FREED)) && (!sm_script_is_marked_as_deleted(&s->seg_manager, pos.segment)));
+ return (obj != NULL && (!(obj->flags & OBJECT_FLAG_FREED)) && (!s->seg_manager->scriptIsMarkedAsDeleted(pos.segment)));
}
reg_t kIsObject(EngineState *s, int funct_nr, int argc, reg_t *argv) {
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 55a86fcdda..f961515c94 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -200,14 +200,14 @@ reg_t kSetSynonyms(EngineState *s, int funct_nr, int argc, reg_t *argv) {
int synonyms_nr = 0;
script = GET_SEL32V(objpos, number);
- seg = sm_seg_get(&(s->seg_manager), script);
+ seg = s->seg_manager->segGet(script);
- if (seg >= 0) synonyms_nr = sm_get_synonyms_nr(&(s->seg_manager), seg, SEG_ID);
+ if (seg >= 0) synonyms_nr = s->seg_manager->getSynonymsNr(seg, SEG_ID);
if (synonyms_nr) {
byte *synonyms;
- synonyms = sm_get_synonyms(&(s->seg_manager), seg, SEG_ID);
+ synonyms = s->seg_manager->getSynonyms(seg, SEG_ID);
if (synonyms) {
int i;
if (s->synonyms_nr)
@@ -389,7 +389,7 @@ reg_t kStrCpy(EngineState *s, int funct_nr, int argc, reg_t *argv) {
if (length >= 0)
strncpy(dest, src, length);
else {
- if (s->seg_manager.heap[argv[0].segment]->type == MEM_OBJ_DYNMEM) {
+ if (s->seg_manager->heap[argv[0].segment]->type == MEM_OBJ_DYNMEM) {
reg_t *srcp = (reg_t *) src;
int i;
@@ -421,7 +421,7 @@ reg_t kStrAt(EngineState *s, int funct_nr, int argc, reg_t *argv) {
if ((argc == 2) &&
/* Our pathfinder already works around the issue we're trying to fix */
- (strcmp(sm_get_description(&(s->seg_manager), argv[0]),
+ (strcmp(s->seg_manager->getDescription(argv[0]),
AVOIDPATH_DYNMEM_STRING) != 0) &&
((strlen((const char*)dest) < 2) || (!is_print_str((char*)dest))))
/* SQ4 array handling detected */
diff --git a/engines/sci/engine/savegame.cfsml b/engines/sci/engine/savegame.cfsml
index d977ec8eb9..e61925329d 100644
--- a/engines/sci/engine/savegame.cfsml
+++ b/engines/sci/engine/savegame.cfsml
@@ -291,7 +291,7 @@ RECORD SegManager "SegManager" {
int heap_size;
int reserved_id;
int exports_wide;
- int sci1_1;
+ int isSci1_1;
int gc_mark_bits;
size_t mem_allocated;
seg_id_t clones_seg_id;
@@ -641,11 +641,13 @@ void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {
case MEM_OBJ_DYNMEM:
%CFSMLWRITE dynmem_t &foo->data.dynmem INTO fh;
break;
+ default:
+ break;
}
}
int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *lastval, int *line, int *hiteof) {
- foo->type = mem_obj_string_to_enum(lastval);
+ foo->type = (memObjType)mem_obj_string_to_enum(lastval);
if (foo->type < 0) {
sciprintf("Unknown mem_obj_t type %s on line %d\n", lastval, *line);
return 1;
@@ -681,6 +683,8 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l
case MEM_OBJ_DYNMEM:
%CFSMLREAD dynmem_t &foo->data.dynmem FROM fh ERRVAR *hiteof LINECOUNTER *line;
break;
+ default:
+ break;
}
return *hiteof;
@@ -787,8 +791,8 @@ static byte *find_unique_script_block(EngineState *s, byte *buf, int type) {
}
static void reconstruct_stack(EngineState *retval) {
- seg_id_t stack_seg = find_unique_seg_by_type(&retval->seg_manager, MEM_OBJ_STACK);
- dstack_t *stack = &(retval->seg_manager.heap[stack_seg]->data.stack);
+ seg_id_t stack_seg = find_unique_seg_by_type(retval->seg_manager, MEM_OBJ_STACK);
+ dstack_t *stack = &(retval->seg_manager->heap[stack_seg]->data.stack);
retval->stack_segment = stack_seg;
retval->stack_base = stack->entries;
@@ -813,7 +817,7 @@ static int clone_entry_used(clone_table_t *table, int n) {
static void load_script(EngineState *s, seg_id_t seg) {
resource_t *script, *heap = NULL;
- script_t *scr = &(s->seg_manager.heap[seg]->data.script);
+ script_t *scr = &(s->seg_manager->heap[seg]->data.script);
scr->buf = (byte *)malloc(scr->buf_size);
@@ -821,13 +825,13 @@ static void load_script(EngineState *s, seg_id_t seg) {
if (s->version >= SCI_VERSION(1,001,000))
heap = scir_find_resource(s->resmgr, sci_heap, scr->nr, 0);
- switch (s->seg_manager.sci1_1) {
+ switch (s->seg_manager->isSci1_1) {
case 0 :
- sm_mcpy_in_out(&s->seg_manager, 0, script->data, script->size, seg, SEG_ID);
+ s->seg_manager->mcpyInOut(0, script->data, script->size, seg, SEG_ID);
break;
case 1 :
- sm_mcpy_in_out(&s->seg_manager, 0, script->data, script->size, seg, SEG_ID);
- sm_mcpy_in_out(&s->seg_manager, scr->script_size, heap->data, heap->size, seg, SEG_ID);
+ s->seg_manager->mcpyInOut(0, script->data, script->size, seg, SEG_ID);
+ s->seg_manager->mcpyInOut(scr->script_size, heap->data, heap->size, seg, SEG_ID);
break;
}
}
@@ -844,14 +848,14 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
script_t *scr = &mobj->data.script;
load_script(s, i);
- scr->locals_block = scr->locals_segment == 0 ? NULL : &s->seg_manager.heap[scr->locals_segment]->data.locals;
+ scr->locals_block = scr->locals_segment == 0 ? NULL : &s->seg_manager->heap[scr->locals_segment]->data.locals;
scr->export_table = (uint16 *) find_unique_script_block(s, scr->buf, sci_obj_exports);
scr->synonyms = find_unique_script_block(s, scr->buf, sci_obj_synonyms);
scr->code = NULL;
scr->code_blocks_nr = 0;
scr->code_blocks_allocated = 0;
- if (!self->sci1_1)
+ if (!self->isSci1_1)
scr->export_table += 3;
for (j = 0; j < scr->objects_nr; j++) {
@@ -859,8 +863,10 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
scr->objects[j].base = scr->buf;
scr->objects[j].base_obj = data;
}
-
+ break;
}
+ default:
+ break;
}
}
}
@@ -876,7 +882,7 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
for (j = 0; j < scr->objects_nr; j++) {
byte *data = scr->buf + scr->objects[j].pos.offset;
- if (self->sci1_1) {
+ if (self->isSci1_1) {
uint16 *funct_area = (uint16 *) (scr->buf + getUInt16( data + 6 ));
uint16 *prop_area = (uint16 *) (scr->buf + getUInt16( data + 4 ));
@@ -900,7 +906,10 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
scr->objects[j].base_vars = (uint16 *) (data + scr->objects[j].variable_names_nr * 2 + SCRIPT_SELECTOR_OFFSET);
}
}
+ break;
}
+ default:
+ break;
}
}
}
@@ -955,6 +964,8 @@ void reconstruct_clones(EngineState *s, SegManager *self) {
break;
}
+ default:
+ break;
}
}
}
@@ -1071,15 +1082,15 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
_reset_graphics_input(retval);
reconstruct_stack(retval);
- reconstruct_scripts(retval, &retval->seg_manager);
- reconstruct_clones(retval, &retval->seg_manager);
+ reconstruct_scripts(retval, retval->seg_manager);
+ reconstruct_clones(retval, retval->seg_manager);
retval->game_obj = s->game_obj;
- retval->script_000 = &retval->seg_manager.heap[script_get_segment(s, 0, SCRIPT_GET_DONT_LOAD)]->data.script;
+ retval->script_000 = &retval->seg_manager->heap[script_get_segment(s, 0, SCRIPT_GET_DONT_LOAD)]->data.script;
retval->gc_countdown = GC_INTERVAL - 1;
retval->save_dir_copy = make_reg(s->sys_strings_segment, SYS_STRING_SAVEDIR);
retval->save_dir_edit_offset = 0;
- retval->sys_strings_segment = find_unique_seg_by_type(&retval->seg_manager, MEM_OBJ_SYS_STRINGS);
- retval->sys_strings = &(((mem_obj_t *)(GET_SEGMENT(retval->seg_manager, retval->sys_strings_segment, MEM_OBJ_SYS_STRINGS)))->data.sys_strings);
+ retval->sys_strings_segment = find_unique_seg_by_type(retval->seg_manager, MEM_OBJ_SYS_STRINGS);
+ retval->sys_strings = &(((mem_obj_t *)(GET_SEGMENT(*retval->seg_manager, retval->sys_strings_segment, MEM_OBJ_SYS_STRINGS)))->data.sys_strings);
sys_strings_restore(retval->sys_strings, s->sys_strings);
// Time state:
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 2fd439bf4f..76ef6f7710 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -1269,8 +1269,8 @@ _cfsml_write_SegManager(Common::WriteStream *fh, SegManager* save_struc)
WSprintf(fh, "exports_wide = ");
_cfsml_write_int(fh, (int*) &(save_struc->exports_wide));
WSprintf(fh, "\n");
- WSprintf(fh, "sci1_1 = ");
- _cfsml_write_int(fh, (int*) &(save_struc->sci1_1));
+ WSprintf(fh, "isSci1_1 = ");
+ _cfsml_write_int(fh, (int*) &(save_struc->isSci1_1));
WSprintf(fh, "\n");
WSprintf(fh, "gc_mark_bits = ");
_cfsml_write_int(fh, (int*) &(save_struc->gc_mark_bits));
@@ -1399,10 +1399,10 @@ _cfsml_read_SegManager(Common::SeekableReadStream *fh, SegManager* save_struc, c
return CFSML_FAILURE;
}
} else
- if (!strcmp(token, "sci1_1")) {
+ if (!strcmp(token, "isSci1_1")) {
#line 690 "engines/sci/engine/savegame.cfsml"
- if (_cfsml_read_int(fh, (int*) &(save_struc->sci1_1), value, line, hiteof)) {
- _cfsml_error("Token expected by _cfsml_read_int() for sci1_1 at line %d\n", *line);
+ if (_cfsml_read_int(fh, (int*) &(save_struc->isSci1_1), value, line, hiteof)) {
+ _cfsml_error("Token expected by _cfsml_read_int() for isSci1_1 at line %d\n", *line);
return CFSML_FAILURE;
}
} else
@@ -4348,11 +4348,13 @@ void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {
// End of auto-generated CFSML data writer code
#line 643 "engines/sci/engine/savegame.cfsml"
break;
+ default:
+ break;
}
}
int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *lastval, int *line, int *hiteof) {
- foo->type = mem_obj_string_to_enum(lastval);
+ foo->type = (memObjType)mem_obj_string_to_enum(lastval);
if (foo->type < 0) {
sciprintf("Unknown mem_obj_t type %s on line %d\n", lastval, *line);
return 1;
@@ -4381,7 +4383,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l
}
}
// End of auto-generated CFSML data reader code
-#line 655 "engines/sci/engine/savegame.cfsml"
+#line 657 "engines/sci/engine/savegame.cfsml"
switch (foo->type) {
case MEM_OBJ_SCRIPT:
// Auto-generated CFSML data reader code
@@ -4407,7 +4409,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l
}
}
// End of auto-generated CFSML data reader code
-#line 658 "engines/sci/engine/savegame.cfsml"
+#line 660 "engines/sci/engine/savegame.cfsml"
break;
case MEM_OBJ_CLONES:
// Auto-generated CFSML data reader code
@@ -4433,7 +4435,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l
}
}
// End of auto-generated CFSML data reader code
-#line 661 "engines/sci/engine/savegame.cfsml"
+#line 663 "engines/sci/engine/savegame.cfsml"
break;
case MEM_OBJ_LOCALS:
// Auto-generated CFSML data reader code
@@ -4459,7 +4461,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l
}
}
// End of auto-generated CFSML data reader code
-#line 664 "engines/sci/engine/savegame.cfsml"
+#line 666 "engines/sci/engine/savegame.cfsml"
break;
case MEM_OBJ_SYS_STRINGS:
// Auto-generated CFSML data reader code
@@ -4485,7 +4487,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l
}
}
// End of auto-generated CFSML data reader code
-#line 667 "engines/sci/engine/savegame.cfsml"
+#line 669 "engines/sci/engine/savegame.cfsml"
break;
case MEM_OBJ_LISTS:
// Auto-generated CFSML data reader code
@@ -4511,7 +4513,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l
}
}
// End of auto-generated CFSML data reader code
-#line 670 "engines/sci/engine/savegame.cfsml"
+#line 672 "engines/sci/engine/savegame.cfsml"
break;
case MEM_OBJ_NODES:
// Auto-generated CFSML data reader code
@@ -4537,7 +4539,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l
}
}
// End of auto-generated CFSML data reader code
-#line 673 "engines/sci/engine/savegame.cfsml"
+#line 675 "engines/sci/engine/savegame.cfsml"
break;
case MEM_OBJ_STACK:
// Auto-generated CFSML data reader code
@@ -4563,7 +4565,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l
}
}
// End of auto-generated CFSML data reader code
-#line 676 "engines/sci/engine/savegame.cfsml"
+#line 678 "engines/sci/engine/savegame.cfsml"
foo->data.stack.entries = (reg_t *)sci_calloc(foo->data.stack.nr, sizeof(reg_t));
break;
case MEM_OBJ_HUNK:
@@ -4593,8 +4595,10 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l
}
}
// End of auto-generated CFSML data reader code
-#line 683 "engines/sci/engine/savegame.cfsml"
+#line 685 "engines/sci/engine/savegame.cfsml"
break;
+ default:
+ break;
}
return *hiteof;
@@ -4607,7 +4611,7 @@ void write_mem_obj_tp(Common::WriteStream *fh, mem_obj_t **foo) {
write_mem_obj_t(fh, (*foo));
WSprintf(fh, "\n");
// End of auto-generated CFSML data writer code
-#line 692 "engines/sci/engine/savegame.cfsml"
+#line 696 "engines/sci/engine/savegame.cfsml"
} else { // Nothing to write
WSprintf(fh, "\\null\\");
}
@@ -4640,7 +4644,7 @@ int read_mem_obj_tp(Common::SeekableReadStream *fh, mem_obj_t **foo, const char
}
}
// End of auto-generated CFSML data reader code
-#line 703 "engines/sci/engine/savegame.cfsml"
+#line 707 "engines/sci/engine/savegame.cfsml"
return *hiteof;
}
return 0;
@@ -4694,13 +4698,13 @@ int gamestate_save(EngineState *s, Common::WriteStream *fh, const char* savename
_cfsml_write_SavegameMetadata(fh, meta);
WSprintf(fh, "\n");
// End of auto-generated CFSML data writer code
-#line 752 "engines/sci/engine/savegame.cfsml"
+#line 756 "engines/sci/engine/savegame.cfsml"
#line 814 "engines/sci/engine/savegame.cfsml"
// Auto-generated CFSML data writer code
_cfsml_write_EngineState(fh, s);
WSprintf(fh, "\n");
// End of auto-generated CFSML data writer code
-#line 753 "engines/sci/engine/savegame.cfsml"
+#line 757 "engines/sci/engine/savegame.cfsml"
delete meta;
@@ -4738,8 +4742,8 @@ static byte *find_unique_script_block(EngineState *s, byte *buf, int type) {
}
static void reconstruct_stack(EngineState *retval) {
- seg_id_t stack_seg = find_unique_seg_by_type(&retval->seg_manager, MEM_OBJ_STACK);
- dstack_t *stack = &(retval->seg_manager.heap[stack_seg]->data.stack);
+ seg_id_t stack_seg = find_unique_seg_by_type(retval->seg_manager, MEM_OBJ_STACK);
+ dstack_t *stack = &(retval->seg_manager->heap[stack_seg]->data.stack);
retval->stack_segment = stack_seg;
retval->stack_base = stack->entries;
@@ -4764,7 +4768,7 @@ static int clone_entry_used(clone_table_t *table, int n) {
static void load_script(EngineState *s, seg_id_t seg) {
resource_t *script, *heap = NULL;
- script_t *scr = &(s->seg_manager.heap[seg]->data.script);
+ script_t *scr = &(s->seg_manager->heap[seg]->data.script);
scr->buf = (byte *)malloc(scr->buf_size);
@@ -4772,13 +4776,13 @@ static void load_script(EngineState *s, seg_id_t seg) {
if (s->version >= SCI_VERSION(1,001,000))
heap = scir_find_resource(s->resmgr, sci_heap, scr->nr, 0);
- switch (s->seg_manager.sci1_1) {
+ switch (s->seg_manager->isSci1_1) {
case 0 :
- sm_mcpy_in_out(&s->seg_manager, 0, script->data, script->size, seg, SEG_ID);
+ s->seg_manager->mcpyInOut(0, script->data, script->size, seg, SEG_ID);
break;
case 1 :
- sm_mcpy_in_out(&s->seg_manager, 0, script->data, script->size, seg, SEG_ID);
- sm_mcpy_in_out(&s->seg_manager, scr->script_size, heap->data, heap->size, seg, SEG_ID);
+ s->seg_manager->mcpyInOut(0, script->data, script->size, seg, SEG_ID);
+ s->seg_manager->mcpyInOut(scr->script_size, heap->data, heap->size, seg, SEG_ID);
break;
}
}
@@ -4795,14 +4799,14 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
script_t *scr = &mobj->data.script;
load_script(s, i);
- scr->locals_block = scr->locals_segment == 0 ? NULL : &s->seg_manager.heap[scr->locals_segment]->data.locals;
+ scr->locals_block = scr->locals_segment == 0 ? NULL : &s->seg_manager->heap[scr->locals_segment]->data.locals;
scr->export_table = (uint16 *) find_unique_script_block(s, scr->buf, sci_obj_exports);
scr->synonyms = find_unique_script_block(s, scr->buf, sci_obj_synonyms);
scr->code = NULL;
scr->code_blocks_nr = 0;
scr->code_blocks_allocated = 0;
- if (!self->sci1_1)
+ if (!self->isSci1_1)
scr->export_table += 3;
for (j = 0; j < scr->objects_nr; j++) {
@@ -4810,8 +4814,10 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
scr->objects[j].base = scr->buf;
scr->objects[j].base_obj = data;
}
-
+ break;
}
+ default:
+ break;
}
}
}
@@ -4827,7 +4833,7 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
for (j = 0; j < scr->objects_nr; j++) {
byte *data = scr->buf + scr->objects[j].pos.offset;
- if (self->sci1_1) {
+ if (self->isSci1_1) {
uint16 *funct_area = (uint16 *) (scr->buf + getUInt16( data + 6 ));
uint16 *prop_area = (uint16 *) (scr->buf + getUInt16( data + 4 ));
@@ -4851,7 +4857,10 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
scr->objects[j].base_vars = (uint16 *) (data + scr->objects[j].variable_names_nr * 2 + SCRIPT_SELECTOR_OFFSET);
}
}
+ break;
}
+ default:
+ break;
}
}
}
@@ -4906,6 +4915,8 @@ void reconstruct_clones(EngineState *s, SegManager *self) {
break;
}
+ default:
+ break;
}
}
}
@@ -5003,7 +5014,7 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
}
}
// End of auto-generated CFSML data reader code
-#line 1027 "engines/sci/engine/savegame.cfsml"
+#line 1038 "engines/sci/engine/savegame.cfsml"
if ((meta->savegame_version < FREESCI_MINIMUM_SAVEGAME_VERSION) ||
(meta->savegame_version > FREESCI_CURRENT_SAVEGAME_VERSION)) {
if (meta->savegame_version < FREESCI_MINIMUM_SAVEGAME_VERSION)
@@ -5055,7 +5066,7 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
}
}
// End of auto-generated CFSML data reader code
-#line 1050 "engines/sci/engine/savegame.cfsml"
+#line 1061 "engines/sci/engine/savegame.cfsml"
sfx_exit(&s->sound);
_gamestate_unfrob(retval);
@@ -5080,15 +5091,15 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
_reset_graphics_input(retval);
reconstruct_stack(retval);
- reconstruct_scripts(retval, &retval->seg_manager);
- reconstruct_clones(retval, &retval->seg_manager);
+ reconstruct_scripts(retval, retval->seg_manager);
+ reconstruct_clones(retval, retval->seg_manager);
retval->game_obj = s->game_obj;
- retval->script_000 = &retval->seg_manager.heap[script_get_segment(s, 0, SCRIPT_GET_DONT_LOAD)]->data.script;
+ retval->script_000 = &retval->seg_manager->heap[script_get_segment(s, 0, SCRIPT_GET_DONT_LOAD)]->data.script;
retval->gc_countdown = GC_INTERVAL - 1;
retval->save_dir_copy = make_reg(s->sys_strings_segment, SYS_STRING_SAVEDIR);
retval->save_dir_edit_offset = 0;
- retval->sys_strings_segment = find_unique_seg_by_type(&retval->seg_manager, MEM_OBJ_SYS_STRINGS);
- retval->sys_strings = &(((mem_obj_t *)(GET_SEGMENT(retval->seg_manager, retval->sys_strings_segment, MEM_OBJ_SYS_STRINGS)))->data.sys_strings);
+ retval->sys_strings_segment = find_unique_seg_by_type(retval->seg_manager, MEM_OBJ_SYS_STRINGS);
+ retval->sys_strings = &(((mem_obj_t *)(GET_SEGMENT(*retval->seg_manager, retval->sys_strings_segment, MEM_OBJ_SYS_STRINGS)))->data.sys_strings);
sys_strings_restore(retval->sys_strings, s->sys_strings);
// Time state:
@@ -5179,7 +5190,7 @@ bool get_savegame_metadata(Common::SeekableReadStream* stream, SavegameMetadata*
}
}
// End of auto-generated CFSML data reader code
-#line 1145 "engines/sci/engine/savegame.cfsml"
+#line 1156 "engines/sci/engine/savegame.cfsml"
if (read_eof)
return false;
diff --git a/engines/sci/engine/scriptconsole.cpp b/engines/sci/engine/scriptconsole.cpp
index 65cf110f61..9384d73467 100644
--- a/engines/sci/engine/scriptconsole.cpp
+++ b/engines/sci/engine/scriptconsole.cpp
@@ -271,7 +271,7 @@ int parse_reg_t(EngineState *s, const char *str, reg_t *dest) { // Returns 0 on
if (*endptr)
return 1;
- dest->segment = sm_seg_get(&s->seg_manager, script_nr);
+ dest->segment = s->seg_manager->segGet(script_nr);
if (!dest->segment) {
return 1;
@@ -307,8 +307,8 @@ int parse_reg_t(EngineState *s, const char *str, reg_t *dest) { // Returns 0 on
str_objname = str + 1;
// Now all values are available; iterate over all objects.
- for (i = 0; i < s->seg_manager.heap_size; i++) {
- mem_obj_t *mobj = s->seg_manager.heap[i];
+ for (i = 0; i < s->seg_manager->heap_size; i++) {
+ mem_obj_t *mobj = s->seg_manager->heap[i];
int idx = 0;
int max_index = 0;
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index bb6ea309d1..4fd1dffc9a 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -277,8 +277,8 @@ int c_segtable(EngineState *s) {
int i;
sciprintf(" ---- segment table ----\n");
- for (i = 0; i < s->seg_manager.heap_size; i++) {
- mem_obj_t *mobj = s->seg_manager.heap[i];
+ for (i = 0; i < s->seg_manager->heap_size; i++) {
+ mem_obj_t *mobj = s->seg_manager->heap[i];
if (mobj && mobj->type) {
sciprintf(" [%04x] ", i);
@@ -345,7 +345,7 @@ static void print_list(EngineState *s, list_t *l) {
while (!IS_NULL_REG(pos)) {
node_t *node;
- mem_obj_t *mobj = GET_SEGMENT(s->seg_manager, pos.segment, MEM_OBJ_NODES);
+ mem_obj_t *mobj = GET_SEGMENT(*s->seg_manager, pos.segment, MEM_OBJ_NODES);
if (!mobj || !ENTRY_IS_VALID(&(mobj->data.nodes), pos.offset)) {
sciprintf(" WARNING: "PREG": Doesn't contain list node!\n",
@@ -482,7 +482,7 @@ static void _c_single_seg_info(EngineState *s, mem_obj_t *mobj) {
}
static int show_node(EngineState *s, reg_t addr) {
- mem_obj_t *mobj = GET_SEGMENT(s->seg_manager, addr.segment, MEM_OBJ_LISTS);
+ mem_obj_t *mobj = GET_SEGMENT(*s->seg_manager, addr.segment, MEM_OBJ_LISTS);
if (mobj) {
list_table_t *lt = &(mobj->data.lists);
@@ -499,7 +499,7 @@ static int show_node(EngineState *s, reg_t addr) {
} else {
node_table_t *nt;
node_t *node;
- mobj = GET_SEGMENT(s->seg_manager, addr.segment, MEM_OBJ_NODES);
+ mobj = GET_SEGMENT(*s->seg_manager, addr.segment, MEM_OBJ_NODES);
if (!mobj) {
sciprintf("Segment #%04x is not a list or node segment\n", addr.segment);
@@ -588,7 +588,7 @@ static int c_vr(EngineState *s) {
case KSIG_REF: {
int size;
- unsigned char *block = sm_dereference(&s->seg_manager, reg, &size);
+ unsigned char *block = s->seg_manager->dereference(reg, &size);
sciprintf("raw data\n");
@@ -631,7 +631,7 @@ int c_segkill(EngineState *s) {
while (i < cmd_paramlength) {
int nr = cmd_params[i++].val;
- sm_set_lockers(&(s->seg_manager), nr, 0, SEG_ID);
+ s->seg_manager->setLockers(nr, 0, SEG_ID);
}
return 0;
}
@@ -654,18 +654,18 @@ int c_seginfo(EngineState *s) {
if (cmd_paramlength) {
while (i < cmd_paramlength) {
int nr = cmd_params[i++].val;
- if (nr < 0 || nr >= s->seg_manager.heap_size || !s->seg_manager.heap[nr]) {
+ if (nr < 0 || nr >= s->seg_manager->heap_size || !s->seg_manager->heap[nr]) {
sciprintf("Segment %04x does not exist\n", nr);
return 1;
}
sciprintf("[%04x] ", nr);
- _c_single_seg_info(s, s->seg_manager.heap[nr]);
+ _c_single_seg_info(s, s->seg_manager->heap[nr]);
}
} else
- for (i = 0; i < (unsigned int)s->seg_manager.heap_size; i++) {
- if (s->seg_manager.heap[i]) {
+ for (i = 0; i < (unsigned int)s->seg_manager->heap_size; i++) {
+ if (s->seg_manager->heap[i]) {
sciprintf("[%04x] ", i);
- _c_single_seg_info(s, s->seg_manager.heap[i]);
+ _c_single_seg_info(s, s->seg_manager->heap[i]);
sciprintf("\n");
}
}
@@ -1213,7 +1213,7 @@ int prop_ofs_to_id(EngineState *s, int prop_ofs, reg_t objp) {
reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecode) {
// Disassembles one command from the heap, returns address of next command or 0 if a ret was encountered.
- mem_obj_t *memobj = GET_SEGMENT(s->seg_manager, pos.segment, MEM_OBJ_SCRIPT);
+ mem_obj_t *memobj = GET_SEGMENT(*s->seg_manager, pos.segment, MEM_OBJ_SCRIPT);
script_t *script_entity = NULL;
byte *scr;
int scr_size;
@@ -1591,7 +1591,7 @@ static int c_backtrace(EngineState *s) {
sciprintf(" argp:"PSTK, PRINT_STK(call->variables_argp));
if (call->type == EXEC_STACK_TYPE_CALL)
- sciprintf(" script: %d", s->seg_manager.heap[call->addr.pc.segment]->data.script.nr);
+ sciprintf(" script: %d", s->seg_manager->heap[call->addr.pc.segment]->data.script.nr);
sciprintf("\n");
}
@@ -2024,7 +2024,7 @@ static int c_disasm_addr(EngineState *s) {
int invalid = 0;
int size;
- sm_dereference(&s->seg_manager, vpc, &size);
+ s->seg_manager->dereference(vpc, &size);
size += vpc.offset; // total segment size
for (i = 1; i < cmd_paramlength; i++) {
@@ -2559,8 +2559,8 @@ int objinfo(EngineState *s, reg_t pos) {
reg_t fptr = VM_OBJECT_READ_FUNCTION(obj, i);
sciprintf(" [%03x] %s = "PREG"\n", VM_OBJECT_GET_FUNCSELECTOR(obj, i), selector_name(s, VM_OBJECT_GET_FUNCSELECTOR(obj, i)), PRINT_REG(fptr));
}
- if (s->seg_manager.heap[pos.segment]->type == MEM_OBJ_SCRIPT)
- sciprintf("\nOwner script:\t%d\n", s->seg_manager.heap[pos.segment]->data.script.nr);
+ if (s->seg_manager->heap[pos.segment]->type == MEM_OBJ_SCRIPT)
+ sciprintf("\nOwner script:\t%d\n", s->seg_manager->heap[pos.segment]->data.script.nr);
return 0;
}
@@ -2795,7 +2795,7 @@ static void _print_address(void * _, reg_t addr) {
}
#define GET_SEG_INTERFACE(seg_id) \
- seg_interface_t * seg_interface = get_seg_interface(&(s->seg_manager), seg_id); \
+ SegInterface *seg_interface = s->seg_manager->getSegInterface(seg_id); \
if (!seg_interface) { \
sciprintf("Unknown segment : %x\n", seg_id); \
return 1; \
@@ -2889,7 +2889,7 @@ void script_debug(EngineState *s, reg_t *pc, stack_ptr_t *sp, stack_ptr_t *pp, r
}
if (_debug_seeking && !bp) { // Are we looking for something special?
- mem_obj_t *memobj = GET_SEGMENT(s->seg_manager, pc->segment, MEM_OBJ_SCRIPT);
+ mem_obj_t *memobj = GET_SEGMENT(*s->seg_manager, pc->segment, MEM_OBJ_SCRIPT);
if (memobj) {
script_t *scr = &(memobj->data.script);
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index ed9d6461a7..bbcc310d74 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -24,125 +24,102 @@
*/
#include "sci/engine/seg_manager.h"
-#include "sci/include/sciresource.h"
-#include "sci/include/versions.h"
#include "sci/include/engine.h"
namespace Sci {
-//#define GC_DEBUG*/ // Debug garbage collection
-//#define GC_DEBUG_VERBOSE*/ // Debug garbage verbosely
+#define DEFAULT_SCRIPTS 32
+#define DEFAULT_OBJECTS 8 // default # of objects per script
+#define DEFAULT_OBJECTS_INCREMENT 4 // Number of additional objects to instantiate if we're running out of them
-#define SM_MEMORY_POISON // Poison memory upon deallocation
-
-mem_obj_t* mem_obj_allocate(SegManager *self, seg_id_t segid, int hash_id, mem_obj_enum type);
+//#define GC_DEBUG // Debug garbage collection
+//#define GC_DEBUG_VERBOSE // Debug garbage verbosely
#undef DEBUG_SEG_MANAGER // Define to turn on debugging
#define GET_SEGID() \
if (flag == SCRIPT_ID) \
- id = sm_seg_get (self, id); \
- VERIFY(sm_check(self, id), "invalid seg id");
+ id = segGet(id); \
+ VERIFY(check(id), "invalid seg id");
+#if 0
+// Unreferenced - removed
#define VERIFY_MEM(mem_ptr, ret) \
if (!(mem_ptr)) {\
sciprintf( "%s, *d, no enough memory", __FILE__, __LINE__ ); \
return ret; \
}
-
-#define INVALID_SCRIPT_ID -1
-
-void dbg_print(const char* msg, void *i) {
-#ifdef DEBUG_SEG_MANAGER
- char buf[1000];
- sprintf(buf, "%s = [0x%x], dec:[%d]", msg, i, i);
- perror(buf);
#endif
-}
-
-//-- forward declarations --
-
-void sm_script_initialise_locals_zero(SegManager *self, seg_id_t seg, int count);
-void sm_script_initialise_locals(SegManager *self, reg_t location);
-static int _sm_deallocate(SegManager* self, int seg, int recursive);
-static hunk_t *sm_alloc_hunk(SegManager *self, reg_t *);
-static void sm_free_hunk(SegManager *self, reg_t addr);
-static int sm_check(SegManager* self, int seg);
-/* Check segment validity
-** Parameters: (int) seg: The segment to validate
-** Returns : (int) 0 if 'seg' is an invalid segment
-** 1 if 'seg' is a valid segment
-*/
-// End of Memory Management
+#define INVALID_SCRIPT_ID -1
-static inline int find_free_id(SegManager *self, int *id) {
+inline int SegManager::findFreeId(int *id) {
char was_added = 0;
int retval = 0;
while (!was_added) {
- retval = self->id_seg_map->check_value(self->reserved_id, true, &was_added);
- *id = self->reserved_id--;
- if (self->reserved_id < -1000000)
- self->reserved_id = -10;
+ retval = id_seg_map->check_value(reserved_id, true, &was_added);
+ *id = reserved_id--;
+ if (reserved_id < -1000000)
+ reserved_id = -10;
// Make sure we don't underflow
}
return retval;
}
-static mem_obj_t * alloc_nonscript_segment(SegManager *self, mem_obj_enum type, seg_id_t *segid) {
+mem_obj_t *SegManager::allocNonscriptSegment(memObjType type, seg_id_t *segid) {
// Allocates a non-script segment
int id;
- *segid = find_free_id(self, &id);
- return mem_obj_allocate(self, *segid, id, type);
+ *segid = findFreeId(&id);
+ return memObjAllocate(*segid, id, type);
}
-void sm_init(SegManager* self, int sci1_1) {
+SegManager::SegManager(bool sci1_1) {
int i;
- self->mem_allocated = 0; // Initialise memory count
+ // Initialise memory count
+ mem_allocated = 0;
- self->id_seg_map = new int_hash_map_t();
- self->reserved_id = INVALID_SCRIPT_ID;
- self->id_seg_map->check_value(self->reserved_id, true); // reserve 0 for seg_id
- self->reserved_id--; // reserved_id runs in the reversed direction to make sure no one will use it.
+ id_seg_map = new int_hash_map_t();
+ reserved_id = INVALID_SCRIPT_ID;
+ id_seg_map->check_value(reserved_id, true); // reserve 0 for seg_id
+ reserved_id--; // reserved_id runs in the reversed direction to make sure no one will use it.
- self->heap_size = DEFAULT_SCRIPTS;
- self->heap = (mem_obj_t**)sci_calloc(self->heap_size, sizeof(mem_obj_t *));
+ heap_size = DEFAULT_SCRIPTS;
+ heap = (mem_obj_t **)sci_calloc(heap_size, sizeof(mem_obj_t *));
- self->clones_seg_id = 0;
- self->lists_seg_id = 0;
- self->nodes_seg_id = 0;
- self->hunks_seg_id = 0;
+ clones_seg_id = 0;
+ lists_seg_id = 0;
+ nodes_seg_id = 0;
+ hunks_seg_id = 0;
- self->exports_wide = 0;
- self->sci1_1 = sci1_1;
+ exports_wide = 0;
+ isSci1_1 = sci1_1;
// initialize the heap pointers
- for (i = 0; i < self->heap_size; i++) {
- self->heap[i] = NULL;
+ for (i = 0; i < heap_size; i++) {
+ heap[i] = NULL;
}
// gc initialisation
- self->gc_mark_bits = 0;
+ gc_mark_bits = 0;
}
-// destroy the object, free the memorys if allocated before
-void sm_destroy(SegManager* self) {
+// Destroy the object, free the memorys if allocated before
+SegManager::~SegManager() {
int i;
- // free memory
- for (i = 0; i < self->heap_size; i++) {
- if (self->heap[i])
- _sm_deallocate(self, i, 0);
+ // Free memory
+ for (i = 0; i < heap_size; i++) {
+ if (heap[i])
+ deallocate(i, false);
}
- delete self->id_seg_map;
+ delete id_seg_map;
- free(self->heap);
- self->heap = NULL;
+ free(heap);
}
// allocate a memory for script from heap
@@ -151,19 +128,19 @@ void sm_destroy(SegManager* self) {
// Returns : 0 - allocation failure
// 1 - allocated successfully
// seg_id - allocated segment id
-mem_obj_t *sm_allocate_script(SegManager* self, EngineState *s, int script_nr, int* seg_id) {
+mem_obj_t *SegManager::allocateScript(EngineState *s, int script_nr, int* seg_id) {
int seg;
char was_added;
mem_obj_t* mem;
- seg = self->id_seg_map->check_value(script_nr, true, &was_added);
+ seg = id_seg_map->check_value(script_nr, true, &was_added);
if (!was_added) {
*seg_id = seg;
- return self->heap[*seg_id];
+ return heap[*seg_id];
}
// allocate the mem_obj_t
- mem = mem_obj_allocate(self, seg, script_nr, MEM_OBJ_SCRIPT);
+ mem = memObjAllocate(seg, script_nr, MEM_OBJ_SCRIPT);
if (!mem) {
sciprintf("%s, %d, Not enough memory, ", __FILE__, __LINE__);
return NULL;
@@ -173,7 +150,7 @@ mem_obj_t *sm_allocate_script(SegManager* self, EngineState *s, int script_nr, i
return mem;
}
-static void sm_set_script_size(mem_obj_t *mem, EngineState *s, int script_nr) {
+void SegManager::setScriptSize(mem_obj_t *mem, EngineState *s, int script_nr) {
resource_t *script = scir_find_resource(s->resmgr, sci_script, script_nr, 0);
resource_t *heap = scir_find_resource(s->resmgr, sci_heap, script_nr, 0);
@@ -209,17 +186,17 @@ static void sm_set_script_size(mem_obj_t *mem, EngineState *s, int script_nr) {
}
}
-int sm_initialise_script(mem_obj_t *mem, EngineState *s, int script_nr) {
+int SegManager::initialiseScript(mem_obj_t *mem, EngineState *s, int script_nr) {
// allocate the script.buf
script_t *scr;
- sm_set_script_size(mem, s, script_nr);
+ setScriptSize(mem, s, script_nr);
mem->data.script.buf = (byte*) sci_malloc(mem->data.script.buf_size);
- dbg_print("mem->data.script.buf ", mem->data.script.buf);
+ dbgPrint("mem->data.script.buf ", mem->data.script.buf);
if (!mem->data.script.buf) {
- sm_free_script(mem);
- sciprintf("seg_manager.c: Not enough memory space for script size");
+ freeScript(mem);
+ sciprintf("SegManager: Not enough memory space for script size");
mem->data.script.buf_size = 0;
return 0;
}
@@ -251,20 +228,20 @@ int sm_initialise_script(mem_obj_t *mem, EngineState *s, int script_nr) {
return 1;
}
-int _sm_deallocate(SegManager *self, int seg, int recursive) {
+int SegManager::deallocate(int seg, bool recursive) {
mem_obj_t *mobj;
- VERIFY(sm_check(self, seg), "invalid seg id");
+ VERIFY(check(seg), "invalid seg id");
- mobj = self->heap[seg];
- self->id_seg_map->remove_value(mobj->segmgr_id);
+ mobj = heap[seg];
+ id_seg_map->remove_value(mobj->segmgr_id);
switch (mobj->type) {
case MEM_OBJ_SCRIPT:
- sm_free_script(mobj);
+ freeScript(mobj);
mobj->data.script.buf = NULL;
if (recursive && mobj->data.script.locals_segment)
- _sm_deallocate(self, mobj->data.script.locals_segment, recursive);
+ deallocate(mobj->data.script.locals_segment, recursive);
break;
case MEM_OBJ_LOCALS:
@@ -314,105 +291,105 @@ int _sm_deallocate(SegManager *self, int seg, int recursive) {
}
free(mobj);
- self->heap[seg] = NULL;
+ heap[seg] = NULL;
return 1;
}
-int sm_script_marked_deleted(SegManager *self, int script_nr) {
+int SegManager::scriptMarkedDeleted(int script_nr) {
script_t *scr;
- int seg = sm_seg_get(self, script_nr);
- VERIFY(sm_check(self, seg), "invalid seg id");
+ int seg = segGet(script_nr);
+ VERIFY(check(seg), "invalid seg id");
- scr = &(self->heap[seg]->data.script);
+ scr = &(heap[seg]->data.script);
return scr->marked_as_deleted;
}
-void sm_mark_script_deleted(SegManager *self, int script_nr) {
+void SegManager::markScriptDeleted(int script_nr) {
script_t *scr;
- int seg = sm_seg_get(self, script_nr);
- VERIFY(sm_check(self, seg), "invalid seg id");
+ int seg = segGet(script_nr);
+ VERIFY(check(seg), "invalid seg id");
- scr = &(self->heap[seg]->data.script);
+ scr = &(heap[seg]->data.script);
scr->marked_as_deleted = 1;
}
-void sm_unmark_script_deleted(SegManager* self, int script_nr) {
+void SegManager::unmarkScriptDeleted(int script_nr) {
script_t *scr;
- int seg = sm_seg_get(self, script_nr);
- VERIFY(sm_check(self, seg), "invalid seg id");
+ int seg = segGet(script_nr);
+ VERIFY(check(seg), "invalid seg id");
- scr = &(self->heap[seg]->data.script);
+ scr = &(heap[seg]->data.script);
scr->marked_as_deleted = 0;
}
-int sm_script_is_marked_as_deleted(SegManager* self, seg_id_t seg) {
+int SegManager::scriptIsMarkedAsDeleted(seg_id_t seg) {
script_t *scr;
- if (!sm_check(self, seg))
+ if (!check(seg))
return 0;
- if (self->heap[seg]->type != MEM_OBJ_SCRIPT)
+ if (heap[seg]->type != MEM_OBJ_SCRIPT)
return 0;
- scr = &(self->heap[seg]->data.script);
+ scr = &(heap[seg]->data.script);
return scr->marked_as_deleted;
}
-int sm_deallocate_script(SegManager* self, int script_nr) {
- int seg = sm_seg_get(self, script_nr);
+int SegManager::deallocateScript(int script_nr) {
+ int seg = segGet(script_nr);
- _sm_deallocate(self, seg, 1);
+ deallocate(seg, true);
return 1;
}
-mem_obj_t* mem_obj_allocate(SegManager *self, seg_id_t segid, int hash_id, mem_obj_enum type) {
- mem_obj_t* mem = (mem_obj_t*) sci_calloc(sizeof(mem_obj_t), 1);
+mem_obj_t *SegManager::memObjAllocate(seg_id_t segid, int hash_id, memObjType type) {
+ mem_obj_t *mem = (mem_obj_t *)sci_calloc(sizeof(mem_obj_t), 1);
if (!mem) {
- sciprintf("seg_manager.c: invalid mem_obj ");
+ sciprintf("SegManager: invalid mem_obj ");
return NULL;
}
- if (segid >= self->heap_size) {
+ if (segid >= heap_size) {
void *temp;
- int oldhs = self->heap_size;
+ int oldhs = heap_size;
- if (segid >= self->heap_size * 2) {
- sciprintf("seg_manager.c: hash_map error or others??");
+ if (segid >= heap_size * 2) {
+ sciprintf("SegManager: hash_map error or others??");
return NULL;
}
- self->heap_size *= 2;
- temp = sci_realloc((void*)self->heap, self->heap_size * sizeof(mem_obj_t*));
+ heap_size *= 2;
+ temp = sci_realloc((void *)heap, heap_size * sizeof(mem_obj_t *));
if (!temp) {
- sciprintf("seg_manager.c: Not enough memory space for script size");
+ sciprintf("SegManager: Not enough memory space for script size");
return NULL;
}
- self->heap = (mem_obj_t**) temp;
+ heap = (mem_obj_t **)temp;
// Clear pointers
- memset(self->heap + oldhs, 0, sizeof(mem_obj_t *) * (self->heap_size - oldhs));
+ memset(heap + oldhs, 0, sizeof(mem_obj_t *) * (heap_size - oldhs));
}
mem->segmgr_id = hash_id;
mem->type = type;
// hook it to the heap
- self->heap[segid] = mem;
+ heap[segid] = mem;
return mem;
}
/* No longer in use?
-void sm_object_init(object_t *object) {
+void SegManager::sm_object_init(object_t *object) {
if (!object)
return;
object->variables_nr = 0;
object->variables = NULL;
};*/
-void sm_free_script(mem_obj_t *mem) {
+void SegManager::freeScript(mem_obj_t *mem) {
if (!mem)
return;
if (mem->data.script.buf) {
@@ -445,10 +422,10 @@ void sm_free_script(mem_obj_t *mem) {
// memory operations
#if 0
// Unreferenced - removed
-static void sm_mset(SegManager *self, int offset, int c, size_t n, int id, int flag) {
+static void SegManager::sm_mset(int offset, int c, size_t n, int id, int flag) {
mem_obj_t *mem_obj;
GET_SEGID();
- mem_obj = self->heap[id];
+ mem_obj = heap[id];
switch (mem_obj->type) {
case MEM_OBJ_SCRIPT:
if (mem_obj->data.script.buf) {
@@ -467,10 +444,10 @@ static void sm_mset(SegManager *self, int offset, int c, size_t n, int id, int f
#if 0
// Unreferenced - removed
-static void sm_mcpy_in_in(SegManager *self, int dst, const int src, size_t n, int id, int flag) {
+static void SegManager::sm_mcpy_in_in(int dst, const int src, size_t n, int id, int flag) {
mem_obj_t *mem_obj;
GET_SEGID();
- mem_obj = self->heap[id];
+ mem_obj = heap[id];
switch (mem_obj->type) {
case MEM_OBJ_SCRIPT:
if (mem_obj->data.script.buf) {
@@ -487,10 +464,10 @@ static void sm_mcpy_in_in(SegManager *self, int dst, const int src, size_t n, in
}
#endif
-void sm_mcpy_in_out(SegManager *self, int dst, const void *src, size_t n, int id, int flag) {
+void SegManager::mcpyInOut(int dst, const void *src, size_t n, int id, int flag) {
mem_obj_t *mem_obj;
GET_SEGID();
- mem_obj = self->heap[id];
+ mem_obj = heap[id];
switch (mem_obj->type) {
case MEM_OBJ_SCRIPT:
if (mem_obj->data.script.buf) {
@@ -508,10 +485,10 @@ void sm_mcpy_in_out(SegManager *self, int dst, const void *src, size_t n, int id
#if 0
// Unreferenced - removed
-static void sm_mcpy_out_in(SegManager *self, void *dst, const int src, size_t n, int id, int flag) {
+static void SegManager::sm_mcpy_out_in(void *dst, const int src, size_t n, int id, int flag) {
mem_obj_t *mem_obj;
GET_SEGID();
- mem_obj = self->heap[id];
+ mem_obj = heap[id];
switch (mem_obj->type) {
case MEM_OBJ_SCRIPT:
if (mem_obj->data.script.buf) {
@@ -528,12 +505,12 @@ static void sm_mcpy_out_in(SegManager *self, void *dst, const int src, size_t n,
}
#endif
-int16 sm_get_heap(SegManager *self, reg_t reg) {
+int16 SegManager::getHeap(reg_t reg) {
mem_obj_t *mem_obj;
- mem_obj_enum mem_type;
+ memObjType mem_type;
- VERIFY(sm_check(self, reg.segment), "Invalid seg id");
- mem_obj = self->heap[reg.segment];
+ VERIFY(check(reg.segment), "Invalid seg id");
+ mem_obj = heap[reg.segment];
mem_type = mem_obj->type;
switch (mem_type) {
@@ -550,12 +527,14 @@ int16 sm_get_heap(SegManager *self, reg_t reg) {
return 0; // never get here
}
-void sm_put_heap(SegManager *self, reg_t reg, int16 value) {
+#if 0
+// Unreferenced - removed
+void SegManager::sm_put_heap(reg_t reg, int16 value) {
mem_obj_t *mem_obj;
- mem_obj_enum mem_type;
+ memObjType mem_type;
- VERIFY(sm_check(self, reg.segment), "Invalid seg id");
- mem_obj = self->heap[reg.segment];
+ VERIFY(check(reg.segment), "Invalid seg id");
+ mem_obj = heap[reg.segment];
mem_type = mem_obj->type;
switch (mem_type) {
@@ -572,67 +551,68 @@ void sm_put_heap(SegManager *self, reg_t reg, int16 value) {
break;
}
}
+#endif
// return the seg if script_id is valid and in the map, else -1
-int sm_seg_get(SegManager *self, int script_id) {
- return self->id_seg_map->check_value(script_id, false);
+int SegManager::segGet(int script_id) {
+ return id_seg_map->check_value(script_id, false);
}
// validate the seg
// return:
-// 0 - invalid seg
-// 1 - valid seg
-static int sm_check(SegManager *self, int seg) {
- if (seg < 0 || seg >= self->heap_size) {
- return 0;
+// false - invalid seg
+// true - valid seg
+bool SegManager::check(int seg) {
+ if (seg < 0 || seg >= heap_size) {
+ return false;
}
- if (!self->heap[seg]) {
- sciprintf("seg_manager.c: seg %x is removed from memory, but not removed from hash_map\n", seg);
- return 0;
+ if (!heap[seg]) {
+ sciprintf("SegManager: seg %x is removed from memory, but not removed from hash_map\n", seg);
+ return false;
}
- return 1;
+ return true;
}
-int sm_script_is_loaded(SegManager *self, int id, id_flag flag) {
+int SegManager::scriptIsLoaded(int id, idFlag flag) {
if (flag == SCRIPT_ID)
- id = sm_seg_get(self, id);
+ id = segGet(id);
- return sm_check(self, id);
+ return check(id);
}
-void sm_increment_lockers(SegManager *self, int id, id_flag flag) {
+void SegManager::incrementLockers(int id, idFlag flag) {
if (flag == SCRIPT_ID)
- id = sm_seg_get(self, id);
- VERIFY(sm_check(self, id), "invalid seg id");
- self->heap[id]->data.script.lockers++;
+ id = segGet(id);
+ VERIFY(check(id), "invalid seg id");
+ heap[id]->data.script.lockers++;
}
-void sm_decrement_lockers(SegManager *self, int id, id_flag flag) {
+void SegManager::decrementLockers(int id, idFlag flag) {
if (flag == SCRIPT_ID)
- id = sm_seg_get(self, id);
- VERIFY(sm_check(self, id), "invalid seg id");
+ id = segGet(id);
+ VERIFY(check(id), "invalid seg id");
- if (self->heap[id]->data.script.lockers > 0)
- self->heap[id]->data.script.lockers--;
+ if (heap[id]->data.script.lockers > 0)
+ heap[id]->data.script.lockers--;
}
-int sm_get_lockers(SegManager *self, int id, id_flag flag) {
+int SegManager::getLockers(int id, idFlag flag) {
if (flag == SCRIPT_ID)
- id = sm_seg_get(self, id);
- VERIFY(sm_check(self, id), "invalid seg id");
+ id = segGet(id);
+ VERIFY(check(id), "invalid seg id");
- return self->heap[id]->data.script.lockers;
+ return heap[id]->data.script.lockers;
}
-void sm_set_lockers(SegManager *self, int lockers, int id, id_flag flag) {
+void SegManager::setLockers(int lockers, int id, idFlag flag) {
if (flag == SCRIPT_ID)
- id = sm_seg_get(self, id);
- VERIFY(sm_check(self, id), "invalid seg id");
- self->heap[id]->data.script.lockers = lockers;
+ id = segGet(id);
+ VERIFY(check(id), "invalid seg id");
+ heap[id]->data.script.lockers = lockers;
}
-void sm_set_export_table_offset(SegManager *self, int offset, int id, id_flag flag) {
- script_t *scr = &(self->heap[id]->data.script);
+void SegManager::setExportTableOffset(int offset, int id, idFlag flag) {
+ script_t *scr = &(heap[id]->data.script);
GET_SEGID();
if (offset) {
@@ -644,62 +624,65 @@ void sm_set_export_table_offset(SegManager *self, int offset, int id, id_flag fl
}
}
-int sm_hash_segment_data(SegManager *self, int id) {
+#if 0
+// Unreferenced - removed
+int SegManager::sm_hash_segment_data(int id) {
int i, len, hash_code = 0x55555555;
char *buf;
- if (self->heap[id]->type == MEM_OBJ_LISTS)
+ if (heap[id]->type == MEM_OBJ_LISTS)
return 0;
- if (self->heap[id]->type == MEM_OBJ_NODES)
+ if (heap[id]->type == MEM_OBJ_NODES)
return 0;
- if (self->heap[id]->type == MEM_OBJ_CLONES)
+ if (heap[id]->type == MEM_OBJ_CLONES)
return 0;
- buf = (char *)sm_dereference(self, make_reg(id, 0), &len);
+ buf = (char *)dereference(make_reg(id, 0), &len);
for (i = 0; i < len; i++)
hash_code = (hash_code * 19) + *(buf + i);
return hash_code;
}
+#endif
-void sm_set_export_width(SegManager *self, int flag) {
- self->exports_wide = flag;
+void SegManager::setExportWidth(int flag) {
+ exports_wide = flag;
}
#if 0
// Unreferenced - removed
-static uint16 *sm_get_export_table_offset(SegManager *self, int id, int flag, int *max) {
+static uint16 *SegManager::sm_get_export_table_offset(int id, int flag, int *max) {
GET_SEGID();
if (max)
- *max = self->heap[id]->data.script.exports_nr;
+ *max = heap[id]->data.script.exports_nr;
- return self->heap[id]->data.script.export_table;
+ return heap[id]->data.script.export_table;
}
#endif
-void sm_set_synonyms_offset(SegManager *self, int offset, int id, id_flag flag) {
+void SegManager::setSynonymsOffset(int offset, int id, idFlag flag) {
GET_SEGID();
- self->heap[id]->data.script.synonyms = self->heap[id]->data.script.buf + offset;
+ heap[id]->data.script.synonyms = heap[id]->data.script.buf + offset;
}
-byte *sm_get_synonyms(SegManager *self, int id, id_flag flag) {
+byte *SegManager::getSynonyms(int id, idFlag flag) {
GET_SEGID();
- return self->heap[id]->data.script.synonyms;
+ return heap[id]->data.script.synonyms;
}
-void sm_set_synonyms_nr(SegManager *self, int nr, int id, id_flag flag) {
+void SegManager::setSynonymsNr(int nr, int id, idFlag flag) {
GET_SEGID();
- self->heap[id]->data.script.synonyms_nr = nr;
+ heap[id]->data.script.synonyms_nr = nr;
}
-int sm_get_synonyms_nr(SegManager *self, int id, id_flag flag) {
+int SegManager::getSynonymsNr(int id, idFlag flag) {
GET_SEGID();
- return self->heap[id]->data.script.synonyms_nr;
+ return heap[id]->data.script.synonyms_nr;
}
#if 0
// Unreferenced - removed
-static int sm_get_heappos(SegManager *self, int id, int flag) {
+static int SegManager::sm_get_heappos(int id, int flag) {
GET_SEGID();
return 0;
}
@@ -707,12 +690,12 @@ static int sm_get_heappos(SegManager *self, int id, int flag) {
#if 0
// Unreferenced - removed
-static void sm_set_variables(SegManager *self, reg_t reg, int obj_index, reg_t variable_reg, int variable_index) {
+static void SegManager::sm_set_variables(reg_t reg, int obj_index, reg_t variable_reg, int variable_index) {
script_t *script;
- VERIFY(sm_check(self, reg.segment), "invalid seg id");
- VERIFY(self->heap[reg.segment], "invalid mem");
+ VERIFY(check(reg.segment), "invalid seg id");
+ VERIFY(heap[reg.segment], "invalid mem");
- script = &(self->heap[reg.segment]->data.script);
+ script = &(heap[reg.segment]->data.script);
VERIFY(obj_index < script->objects_nr, "Invalid obj_index");
@@ -722,7 +705,7 @@ static void sm_set_variables(SegManager *self, reg_t reg, int obj_index, reg_t v
}
#endif
-static inline int _relocate_block(SegManager *self, reg_t *block, int block_location, int block_items, seg_id_t segment, int location) {
+inline int SegManager::relocateBlock(reg_t *block, int block_location, int block_items, seg_id_t segment, int location) {
int rel = location - block_location;
int index;
@@ -739,29 +722,29 @@ static inline int _relocate_block(SegManager *self, reg_t *block, int block_loca
return 0;
}
block[index].segment = segment; // Perform relocation
- if (self->sci1_1)
- block[index].offset += self->heap[segment]->data.script.script_size;
+ if (isSci1_1)
+ block[index].offset += heap[segment]->data.script.script_size;
return 1;
}
-static inline int _relocate_local(SegManager *self, script_t *scr, seg_id_t segment, int location) {
+inline int SegManager::relocateLocal(script_t *scr, seg_id_t segment, int location) {
if (scr->locals_block)
- return _relocate_block(self, scr->locals_block->locals, scr->locals_offset, scr->locals_block->nr, segment, location);
+ return relocateBlock(scr->locals_block->locals, scr->locals_offset, scr->locals_block->nr, segment, location);
else
return 0; // No hands, no cookies
}
-static inline int _relocate_object(SegManager *self, object_t *obj, seg_id_t segment, int location) {
- return _relocate_block(self, obj->variables, obj->pos.offset, obj->variables_nr, segment, location);
+inline int SegManager::relocateObject(object_t *obj, seg_id_t segment, int location) {
+ return relocateBlock(obj->variables, obj->pos.offset, obj->variables_nr, segment, location);
}
-void sm_script_add_code_block(SegManager *self, reg_t location) {
- mem_obj_t *mobj = self->heap[location.segment];
+void SegManager::scriptAddCodeBlock(reg_t location) {
+ mem_obj_t *mobj = heap[location.segment];
script_t *scr;
int index;
- VERIFY(!(location.segment >= self->heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to add a code block to non-script\n");
+ VERIFY(!(location.segment >= heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to add a code block to non-script\n");
scr = &(mobj->data.script);
@@ -775,13 +758,13 @@ void sm_script_add_code_block(SegManager *self, reg_t location) {
scr->code[index].size = getUInt16(scr->buf + location.offset - 2);
}
-void sm_script_relocate(SegManager *self, reg_t block) {
- mem_obj_t *mobj = self->heap[block.segment];
+void SegManager::scriptRelocate(reg_t block) {
+ mem_obj_t *mobj = heap[block.segment];
script_t *scr;
int count;
int i;
- VERIFY(!(block.segment >= self->heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt relocate non-script\n");
+ VERIFY(!(block.segment >= heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt relocate non-script\n");
scr = &(mobj->data.script);
@@ -795,11 +778,11 @@ void sm_script_relocate(SegManager *self, reg_t block) {
if (!pos)
continue; // FIXME: A hack pending investigation
- if (!_relocate_local(self, scr, block.segment, pos)) {
+ if (!relocateLocal(scr, block.segment, pos)) {
int k, done = 0;
for (k = 0; !done && k < scr->objects_nr; k++) {
- if (_relocate_object(self, scr->objects + k, block.segment, pos))
+ if (relocateObject(scr->objects + k, block.segment, pos))
done = 1;
}
@@ -827,13 +810,13 @@ void sm_script_relocate(SegManager *self, reg_t block) {
}
}
-void sm_heap_relocate(SegManager *self, EngineState *s, reg_t block) {
- mem_obj_t *mobj = self->heap[block.segment];
+void SegManager::heapRelocate(EngineState *s, reg_t block) {
+ mem_obj_t *mobj = heap[block.segment];
script_t *scr;
int count;
int i;
- VERIFY(!(block.segment >= self->heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt relocate non-script\n");
+ VERIFY(!(block.segment >= heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt relocate non-script\n");
scr = &(mobj->data.script);
@@ -848,11 +831,11 @@ void sm_heap_relocate(SegManager *self, EngineState *s, reg_t block) {
for (i = 0; i < count; i++) {
int pos = getUInt16(scr->heap_start + block.offset + 2 + (i * 2)) + scr->script_size;
- if (!_relocate_local(self, scr, block.segment, pos)) {
+ if (!relocateLocal(scr, block.segment, pos)) {
int k, done = 0;
for (k = 0; !done && k < scr->objects_nr; k++) {
- if (_relocate_object(self, scr->objects + k, block.segment, pos))
+ if (relocateObject(scr->objects + k, block.segment, pos))
done = 1;
}
@@ -876,15 +859,15 @@ void sm_heap_relocate(SegManager *self, EngineState *s, reg_t block) {
reg_t get_class_address(EngineState *s, int classnr, int lock, reg_t caller);
-static object_t *sm_script_obj_init0(SegManager *self, EngineState *s, reg_t obj_pos) {
- mem_obj_t *mobj = self->heap[obj_pos.segment];
+object_t *SegManager::scriptObjInit0(EngineState *s, reg_t obj_pos) {
+ mem_obj_t *mobj = heap[obj_pos.segment];
script_t *scr;
object_t *obj;
int id;
unsigned int base = obj_pos.offset - SCRIPT_OBJECT_MAGIC_OFFSET;
reg_t temp;
- VERIFY(!(obj_pos.segment >= self->heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to initialize object in non-script\n");
+ VERIFY(!(obj_pos.segment >= heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to initialize object in non-script\n");
scr = &(mobj->data.script);
@@ -944,14 +927,14 @@ static object_t *sm_script_obj_init0(SegManager *self, EngineState *s, reg_t obj
return obj;
}
-static object_t *sm_script_obj_init11(SegManager *self, EngineState *s, reg_t obj_pos) {
- mem_obj_t *mobj = self->heap[obj_pos.segment];
+object_t *SegManager::scriptObjInit11(EngineState *s, reg_t obj_pos) {
+ mem_obj_t *mobj = heap[obj_pos.segment];
script_t *scr;
object_t *obj;
int id;
int base = obj_pos.offset;
- VERIFY(!(obj_pos.segment >= self->heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to initialize object in non-script\n");
+ VERIFY(!(obj_pos.segment >= heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to initialize object in non-script\n");
scr = &(mobj->data.script);
@@ -1011,14 +994,14 @@ static object_t *sm_script_obj_init11(SegManager *self, EngineState *s, reg_t ob
return obj;
}
-object_t *sm_script_obj_init(SegManager *self, EngineState *s, reg_t obj_pos) {
- if (!self->sci1_1)
- return sm_script_obj_init0(self, s, obj_pos);
+object_t *SegManager::scriptObjInit(EngineState *s, reg_t obj_pos) {
+ if (!isSci1_1)
+ return scriptObjInit0(s, obj_pos);
else
- return sm_script_obj_init11(self, s, obj_pos);
+ return scriptObjInit11(s, obj_pos);
}
-static local_variables_t *_sm_alloc_locals_segment(SegManager *self, script_t *scr, int count) {
+local_variables_t *SegManager::allocLocalsSegment(script_t *scr, int count) {
if (!count) { // No locals
scr->locals_segment = 0;
scr->locals_block = NULL;
@@ -1028,12 +1011,12 @@ static local_variables_t *_sm_alloc_locals_segment(SegManager *self, script_t *s
local_variables_t *locals;
if (scr->locals_segment) {
- mobj = self->heap[scr->locals_segment];
+ mobj = heap[scr->locals_segment];
VERIFY(mobj != NULL, "Re-used locals segment was NULL'd out");
VERIFY(mobj->type == MEM_OBJ_LOCALS, "Re-used locals segment did not consist of local variables");
VERIFY(mobj->data.locals.script_id == scr->nr, "Re-used locals segment belonged to other script");
} else
- mobj = alloc_nonscript_segment(self, MEM_OBJ_LOCALS, &scr->locals_segment);
+ mobj = allocNonscriptSegment(MEM_OBJ_LOCALS, &scr->locals_segment);
locals = scr->locals_block = &(mobj->data.locals);
locals->script_id = scr->nr;
@@ -1044,32 +1027,32 @@ static local_variables_t *_sm_alloc_locals_segment(SegManager *self, script_t *s
}
}
-void sm_script_initialise_locals_zero(SegManager *self, seg_id_t seg, int count) {
- mem_obj_t *mobj = self->heap[seg];
+void SegManager::scriptInitialiseLocalsZero(seg_id_t seg, int count) {
+ mem_obj_t *mobj = heap[seg];
script_t *scr;
- VERIFY(!(seg >= self->heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to initialize locals in non-script\n");
+ VERIFY(!(seg >= heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to initialize locals in non-script\n");
scr = &(mobj->data.script);
scr->locals_offset = -count * 2; // Make sure it's invalid
- _sm_alloc_locals_segment(self, scr, count);
+ allocLocalsSegment(scr, count);
}
-void sm_script_initialise_locals(SegManager *self, reg_t location) {
- mem_obj_t *mobj = self->heap[location.segment];
+void SegManager::scriptInitialiseLocals(reg_t location) {
+ mem_obj_t *mobj = heap[location.segment];
unsigned int count;
script_t *scr;
local_variables_t *locals;
- VERIFY(!(location.segment >= self->heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to initialize locals in non-script\n");
+ VERIFY(!(location.segment >= heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to initialize locals in non-script\n");
scr = &(mobj->data.script);
VERIFY(location.offset + 1 < (uint16)scr->buf_size, "Locals beyond end of script\n");
- if (self->sci1_1)
+ if (isSci1_1)
count = getUInt16(scr->buf + location.offset - 2);
else
count = (getUInt16(scr->buf + location.offset - 2) - 4) >> 1;
@@ -1082,7 +1065,7 @@ void sm_script_initialise_locals(SegManager *self, reg_t location) {
count = (scr->buf_size - location.offset) >> 1;
}
- locals = _sm_alloc_locals_segment(self, scr, count);
+ locals = allocLocalsSegment(scr, count);
if (locals) {
uint i;
byte *base = (byte *)(scr->buf + location.offset);
@@ -1092,13 +1075,13 @@ void sm_script_initialise_locals(SegManager *self, reg_t location) {
}
}
-void sm_script_relocate_exports_sci11(SegManager *self, int seg) {
- mem_obj_t *mobj = self->heap[seg];
+void SegManager::scriptRelocateExportsSci11(int seg) {
+ mem_obj_t *mobj = heap[seg];
script_t *scr;
int i;
int location;
- VERIFY(!(seg >= self->heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to relocate exports in non-script\n");
+ VERIFY(!(seg >= heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to relocate exports in non-script\n");
scr = &(mobj->data.script);
for (i = 0; i < scr->exports_nr; i++) {
@@ -1115,12 +1098,12 @@ void sm_script_relocate_exports_sci11(SegManager *self, int seg) {
}
}
-void sm_script_initialise_objects_sci11(SegManager *self, EngineState *s, int seg) {
- mem_obj_t *mobj = self->heap[seg];
+void SegManager::scriptInitialiseObjectsSci11(EngineState *s, int seg) {
+ mem_obj_t *mobj = heap[seg];
script_t *scr;
byte *seeker;
- VERIFY(!(seg >= self->heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to relocate exports in non-script\n");
+ VERIFY(!(seg >= heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to relocate exports in non-script\n");
scr = &(mobj->data.script);
seeker = scr->heap_start + 4 + getUInt16(scr->heap_start + 2) * 2;
@@ -1151,7 +1134,7 @@ void sm_script_initialise_objects_sci11(SegManager *self, EngineState *s, int se
reg.segment = seg;
reg.offset = seeker - scr->buf;
- obj = sm_script_obj_init(&s->seg_manager, s, reg);
+ obj = scriptObjInit(s, reg);
#if 0
if (obj->variables[5].offset != 0xffff) {
@@ -1169,11 +1152,11 @@ void sm_script_initialise_objects_sci11(SegManager *self, EngineState *s, int se
}
}
-void sm_script_free_unused_objects(SegManager *self, seg_id_t seg) {
- mem_obj_t *mobj = self->heap[seg];
+void SegManager::scriptFreeUnusedObjects(seg_id_t seg) {
+ mem_obj_t *mobj = heap[seg];
script_t *scr;
- VERIFY(!(seg >= self->heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to free unused objects in non-script\n");
+ VERIFY(!(seg >= heap_size || mobj->type != MEM_OBJ_SCRIPT), "Attempt to free unused objects in non-script\n");
scr = &(mobj->data.script);
if (scr->objects_allocated > scr->objects_nr) {
@@ -1188,7 +1171,8 @@ void sm_script_free_unused_objects(SegManager *self, seg_id_t seg) {
}
}
-static inline char *dynprintf(char *msg, ...) {
+/*
+static inline char *SegManager::dynprintf(char *msg, ...) {
va_list argp;
char *buf = (char *)sci_malloc(strlen(msg) + 100);
@@ -1198,9 +1182,10 @@ static inline char *dynprintf(char *msg, ...) {
return buf;
}
+*/
-dstack_t *sm_allocate_stack(SegManager *self, int size, seg_id_t *segid) {
- mem_obj_t *memobj = alloc_nonscript_segment(self, MEM_OBJ_STACK, segid);
+dstack_t *SegManager::allocateStack(int size, seg_id_t *segid) {
+ mem_obj_t *memobj = allocNonscriptSegment(MEM_OBJ_STACK, segid);
dstack_t *retval = &(memobj->data.stack);
retval->entries = (reg_t*)sci_calloc(size, sizeof(reg_t));
@@ -1209,8 +1194,8 @@ dstack_t *sm_allocate_stack(SegManager *self, int size, seg_id_t *segid) {
return retval;
}
-sys_strings_t *sm_allocate_sys_strings(SegManager *self, seg_id_t *segid) {
- mem_obj_t *memobj = alloc_nonscript_segment(self, MEM_OBJ_SYS_STRINGS, segid);
+sys_strings_t *SegManager::allocateSysStrings(seg_id_t *segid) {
+ mem_obj_t *memobj = allocNonscriptSegment(MEM_OBJ_SYS_STRINGS, segid);
sys_strings_t *retval = &(memobj->data.sys_strings);
memset(retval, 0, sizeof(sys_string_t)*SYS_STRINGS_MAX);
@@ -1218,29 +1203,32 @@ sys_strings_t *sm_allocate_sys_strings(SegManager *self, seg_id_t *segid) {
return retval;
}
-seg_id_t sm_allocate_reserved_segment(SegManager *self, char *src_name) {
+#if 0
+// Unreferenced - removed
+seg_id_t SegManager::sm_allocate_reserved_segment(char *src_name) {
seg_id_t segid;
- mem_obj_t *memobj = alloc_nonscript_segment(self, MEM_OBJ_RESERVED, &segid);
+ mem_obj_t *memobj = allocNonscriptSegment(MEM_OBJ_RESERVED, &segid);
char *name = sci_strdup(src_name);
memobj->data.reserved = name;
return segid;
}
+#endif
-uint16 sm_validate_export_func(SegManager* self, int pubfunct, int seg) {
+uint16 SegManager::validateExportFunc(int pubfunct, int seg) {
script_t* script;
uint16 offset;
- VERIFY(sm_check(self, seg), "invalid seg id");
- VERIFY(self->heap[seg]->type == MEM_OBJ_SCRIPT, "Can only validate exports on scripts");
+ VERIFY(check(seg), "invalid seg id");
+ VERIFY(heap[seg]->type == MEM_OBJ_SCRIPT, "Can only validate exports on scripts");
- script = &self->heap[seg]->data.script;
+ script = &heap[seg]->data.script;
if (script->exports_nr <= pubfunct) {
sciprintf("pubfunct is invalid");
return 0;
}
- if (self->exports_wide)
+ if (exports_wide)
pubfunct *= 2;
offset = getUInt16((byte *)(script->export_table + pubfunct));
VERIFY(offset < script->buf_size, "invalid export function pointer");
@@ -1248,12 +1236,12 @@ uint16 sm_validate_export_func(SegManager* self, int pubfunct, int seg) {
return offset;
}
-void sm_free_hunk_entry(SegManager *self, reg_t addr) {
- sm_free_hunk(self, addr);
+void SegManager::free_hunk_entry(reg_t addr) {
+ free_hunk(addr);
}
-hunk_t *sm_alloc_hunk_entry(SegManager *self, const char *hunk_type, int size, reg_t *reg) {
- hunk_t *h = sm_alloc_hunk(self, reg);
+hunk_t *SegManager::alloc_hunk_entry(const char *hunk_type, int size, reg_t *reg) {
+ hunk_t *h = alloc_hunk(reg);
if (!h)
return NULL;
@@ -1265,12 +1253,12 @@ hunk_t *sm_alloc_hunk_entry(SegManager *self, const char *hunk_type, int size, r
return h;
}
-static void _clone_cleanup(clone_t *clone) {
+void _clone_cleanup(clone_t *clone) {
if (clone->variables)
free(clone->variables); // Free the dynamically allocated memory part
}
-static void _hunk_cleanup(hunk_t *hunk) {
+void _hunk_cleanup(hunk_t *hunk) {
if (hunk->mem)
free(hunk->mem);
}
@@ -1280,53 +1268,53 @@ DEFINE_HEAPENTRY(node, 32, 16)
DEFINE_HEAPENTRY_WITH_CLEANUP(clone, 16, 4, _clone_cleanup)
DEFINE_HEAPENTRY_WITH_CLEANUP(hunk, 4, 4, _hunk_cleanup)
-#define DEFINE_ALLOC_DEALLOC(STATIC, TYPE, SEGTYPE, PLURAL) \
-STATIC TYPE##_t *sm_alloc_##TYPE(SegManager *self, reg_t *addr) { \
+#define DEFINE_ALLOC_DEALLOC(TYPE, SEGTYPE, PLURAL) \
+TYPE##_t *SegManager::alloc_##TYPE(reg_t *addr) { \
mem_obj_t *mobj; \
TYPE##_table_t *table; \
int offset; \
\
- if (!self->TYPE##s_seg_id) { \
- mobj = alloc_nonscript_segment(self, SEGTYPE, &(self->TYPE##s_seg_id)); \
+ if (!TYPE##s_seg_id) { \
+ mobj = allocNonscriptSegment(SEGTYPE, &(TYPE##s_seg_id)); \
init_##TYPE##_table(&(mobj->data.PLURAL)); \
} else \
- mobj = self->heap[self->TYPE##s_seg_id]; \
+ mobj = heap[TYPE##s_seg_id]; \
\
table = &(mobj->data.PLURAL); \
- offset = alloc_##TYPE##_entry(table); \
+ offset = Sci::alloc_##TYPE##_entry(table); \
\
- *addr = make_reg(self->TYPE##s_seg_id, offset); \
+ *addr = make_reg(TYPE##s_seg_id, offset); \
return &(mobj->data.PLURAL.table[offset].entry); \
} \
\
-STATIC void sm_free_##TYPE(SegManager *self, reg_t addr) { \
- mem_obj_t *mobj = GET_SEGMENT(*self, addr.segment, SEGTYPE); \
+void SegManager::free_##TYPE(reg_t addr) { \
+ mem_obj_t *mobj = GET_SEGMENT(*this, addr.segment, SEGTYPE); \
\
if (!mobj) { \
sciprintf("Attempt to free " #TYPE " from address "PREG": Invalid segment type\n", PRINT_REG(addr)); \
return; \
} \
\
- free_##TYPE##_entry(&(mobj->data.PLURAL), addr.offset); \
+ Sci::free_##TYPE##_entry(&(mobj->data.PLURAL), addr.offset); \
}
-DEFINE_ALLOC_DEALLOC(, clone, MEM_OBJ_CLONES, clones)
-DEFINE_ALLOC_DEALLOC(, list, MEM_OBJ_LISTS, lists)
-DEFINE_ALLOC_DEALLOC(, node, MEM_OBJ_NODES, nodes)
-DEFINE_ALLOC_DEALLOC(static, hunk, MEM_OBJ_HUNK, hunks)
+DEFINE_ALLOC_DEALLOC(clone, MEM_OBJ_CLONES, clones)
+DEFINE_ALLOC_DEALLOC(list, MEM_OBJ_LISTS, lists)
+DEFINE_ALLOC_DEALLOC(node, MEM_OBJ_NODES, nodes)
+DEFINE_ALLOC_DEALLOC(hunk, MEM_OBJ_HUNK, hunks)
-byte *sm_dereference(SegManager *self, reg_t pointer, int *size) {
+byte *SegManager::dereference(reg_t pointer, int *size) {
mem_obj_t *mobj;
byte *base = NULL;
int count;
- if (!pointer.segment || (pointer.segment >= self->heap_size) || !self->heap[pointer.segment]) {
+ if (!pointer.segment || (pointer.segment >= heap_size) || !heap[pointer.segment]) {
sciprintf("Error: Attempt to dereference invalid pointer "PREG"!\n",
PRINT_REG(pointer));
return NULL; /* Invalid */
}
- mobj = self->heap[pointer.segment];
+ mobj = heap[pointer.segment];
switch (mobj->type) {
case MEM_OBJ_SCRIPT:
@@ -1387,9 +1375,9 @@ byte *sm_dereference(SegManager *self, reg_t pointer, int *size) {
base + pointer.offset;
}
-unsigned char *sm_alloc_dynmem(SegManager *self, int size, const char *descr, reg_t *addr) {
+unsigned char *SegManager::allocDynmem(int size, const char *descr, reg_t *addr) {
seg_id_t seg;
- mem_obj_t *mobj = alloc_nonscript_segment(self, MEM_OBJ_DYNMEM, &seg);
+ mem_obj_t *mobj = allocNonscriptSegment(MEM_OBJ_DYNMEM, &seg);
*addr = make_reg(seg, 0);
mobj->data.dynmem.size = size;
@@ -1404,10 +1392,10 @@ unsigned char *sm_alloc_dynmem(SegManager *self, int size, const char *descr, re
return (unsigned char *)(mobj->data.dynmem.buf);
}
-const char *sm_get_description(SegManager *self, reg_t addr) {
- mem_obj_t *mobj = self->heap[addr.segment];
+const char *SegManager::getDescription(reg_t addr) {
+ mem_obj_t *mobj = heap[addr.segment];
- if (addr.segment >= self->heap_size)
+ if (addr.segment >= heap_size)
return "";
switch (mobj->type) {
@@ -1418,50 +1406,58 @@ const char *sm_get_description(SegManager *self, reg_t addr) {
}
}
-int sm_free_dynmem(SegManager *self, reg_t addr) {
- if (addr.segment <= 0 || addr.segment >= self->heap_size || !self->heap[addr.segment] || self->heap[addr.segment]->type != MEM_OBJ_DYNMEM)
+int SegManager::freeDynmem(reg_t addr) {
+ if (addr.segment <= 0 || addr.segment >= heap_size || !heap[addr.segment] || heap[addr.segment]->type != MEM_OBJ_DYNMEM)
return 1; // error
- _sm_deallocate(self, addr.segment, 1);
+ deallocate(addr.segment, true);
return 0; // OK
}
+void SegManager::dbgPrint(const char* msg, void *i) {
+#ifdef DEBUG_SEG_MANAGER
+ char buf[1000];
+ sprintf(buf, "%s = [0x%x], dec:[%d]", msg, i, i);
+ perror(buf);
+#endif
+}
+
// ------------------- Segment interface ------------------
-static void free_at_address_stub(seg_interface_t *self, reg_t sub_addr) {
+static void free_at_address_stub(SegInterface *self, reg_t sub_addr) {
//sciprintf(" Request to free "PREG"\n", PRINT_REG(sub_addr));
// STUB
}
-static reg_t find_canonic_address_base(seg_interface_t *self, reg_t addr) {
+static reg_t find_canonic_address_base(SegInterface *self, reg_t addr) {
addr.offset = 0;
return addr;
}
-static reg_t find_canonic_address_id(seg_interface_t *self, reg_t addr) {
+static reg_t find_canonic_address_id(SegInterface *self, reg_t addr) {
return addr;
}
-static void free_at_address_nop(seg_interface_t *self, reg_t sub_addr) {
+static void free_at_address_nop(SegInterface *self, reg_t sub_addr) {
}
-static void list_all_deallocatable_nop(seg_interface_t *self, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_deallocatable_nop(SegInterface *self, void *param, void (*note)(void*param, reg_t addr)) {
}
-static void list_all_deallocatable_base(seg_interface_t *self, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_deallocatable_base(SegInterface *self, void *param, void (*note)(void*param, reg_t addr)) {
(*note)(param, make_reg(self->seg_id, 0));
}
-static void list_all_outgoing_references_nop(seg_interface_t *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_outgoing_references_nop(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
}
-static void deallocate_self(seg_interface_t *self) {
+static void deallocate_self(SegInterface *self) {
free(self);
}
-static void free_at_address_script(seg_interface_t *self, reg_t addr) {
+static void free_at_address_script(SegInterface *self, reg_t addr) {
script_t *script;
VERIFY(self->mobj->type == MEM_OBJ_SCRIPT, "Trying to free a non-script!");
script = &(self->mobj->data.script);
@@ -1472,10 +1468,10 @@ static void free_at_address_script(seg_interface_t *self, reg_t addr) {
*/
if (script->marked_as_deleted)
- sm_deallocate_script(self->segmgr, script->nr);
+ self->segmgr->deallocateScript(script->nr);
}
-static void list_all_outgoing_references_script(seg_interface_t *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_outgoing_references_script(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
script_t *script = &(self->mobj->data.script);
if (addr.offset <= script->buf_size && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(script->buf + addr.offset)) {
@@ -1500,7 +1496,7 @@ static void list_all_outgoing_references_script(seg_interface_t *self, EngineSta
}
//-------------------- script --------------------
-static seg_interface_t seg_interface_script = {
+static SegInterface seg_interface_script = {
/* segmgr = */ NULL,
/* mobj = */ NULL,
/* seg_id = */ 0,
@@ -1523,11 +1519,11 @@ static seg_interface_t seg_interface_script = {
if (ENTRY_IS_VALID(table, i)) \
(*note) (param, make_reg(self->seg_id, i));
-static void list_all_deallocatable_clones(seg_interface_t *self, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_deallocatable_clones(SegInterface *self, void *param, void (*note)(void*param, reg_t addr)) {
LIST_ALL_DEALLOCATABLE(clone, clones);
}
-static void list_all_outgoing_references_clones(seg_interface_t *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_outgoing_references_clones(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
mem_obj_t *mobj = self->mobj;
clone_table_t *clone_table = &(mobj->data.clones);
clone_t *clone;
@@ -1552,7 +1548,7 @@ static void list_all_outgoing_references_clones(seg_interface_t *self, EngineSta
//sciprintf("[GC] Reporting clone-pos "PREG"\n", PRINT_REG(clone->pos));
}
-void free_at_address_clones(seg_interface_t *self, reg_t addr) {
+void free_at_address_clones(SegInterface *self, reg_t addr) {
object_t *victim_obj;
assert(addr.segment == self->seg_id);
@@ -1573,11 +1569,11 @@ void free_at_address_clones(seg_interface_t *self, reg_t addr) {
*/
free(victim_obj->variables);
victim_obj->variables = NULL;
- sm_free_clone(self->segmgr, addr);
+ self->segmgr->free_clone(addr);
}
//-------------------- clones --------------------
-static seg_interface_t seg_interface_clones = {
+static SegInterface seg_interface_clones = {
/* segmgr = */ NULL,
/* mobj = */ NULL,
/* seg_id = */ 0,
@@ -1590,17 +1586,17 @@ static seg_interface_t seg_interface_clones = {
/* deallocate_self = */ deallocate_self
};
-static reg_t find_canonic_address_locals(seg_interface_t *self, reg_t addr) {
+static reg_t find_canonic_address_locals(SegInterface *self, reg_t addr) {
local_variables_t *locals = &(self->mobj->data.locals);
// Reference the owning script
- seg_id_t owner_seg = sm_seg_get(self->segmgr, locals->script_id);
+ seg_id_t owner_seg = self->segmgr->segGet(locals->script_id);
assert(owner_seg >= 0);
return make_reg(owner_seg, 0);
}
-static void list_all_outgoing_references_locals(seg_interface_t *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_outgoing_references_locals(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
local_variables_t *locals = &(self->mobj->data.locals);
int i;
@@ -1611,7 +1607,7 @@ static void list_all_outgoing_references_locals(seg_interface_t *self, EngineSta
}
//-------------------- locals --------------------
-static seg_interface_t seg_interface_locals = {
+static SegInterface seg_interface_locals = {
/* segmgr = */ NULL,
/* mobj = */ NULL,
/* seg_id = */ 0,
@@ -1624,7 +1620,7 @@ static seg_interface_t seg_interface_locals = {
/* deallocate_self = */ deallocate_self
};
-static void list_all_outgoing_references_stack(seg_interface_t *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_outgoing_references_stack(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
int i;
fprintf(stderr, "Emitting %d stack entries\n", self->mobj->data.stack.nr);
for (i = 0; i < self->mobj->data.stack.nr; i++)
@@ -1634,7 +1630,7 @@ static void list_all_outgoing_references_stack(seg_interface_t *self, EngineStat
//-------------------- stack --------------------
-static seg_interface_t seg_interface_stack = {
+static SegInterface seg_interface_stack = {
/* segmgr = */ NULL,
/* mobj = */ NULL,
/* seg_id = */ 0,
@@ -1648,7 +1644,7 @@ static seg_interface_t seg_interface_stack = {
};
//-------------------- system strings --------------------
-static seg_interface_t seg_interface_sys_strings = {
+static SegInterface seg_interface_sys_strings = {
/* segmgr = */ NULL,
/* mobj = */ NULL,
/* seg_id = */ 0,
@@ -1661,11 +1657,11 @@ static seg_interface_t seg_interface_sys_strings = {
/* deallocate_self = */ deallocate_self
};
-static void list_all_deallocatable_list(seg_interface_t *self, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_deallocatable_list(SegInterface *self, void *param, void (*note)(void*param, reg_t addr)) {
LIST_ALL_DEALLOCATABLE(list, lists);
}
-static void list_all_outgoing_references_list(seg_interface_t *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_outgoing_references_list(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
list_table_t *table = &(self->mobj->data.lists);
list_t *list = &(table->table[addr.offset].entry);
@@ -1680,12 +1676,12 @@ static void list_all_outgoing_references_list(seg_interface_t *self, EngineState
// let's be conservative here.
}
-static void free_at_address_lists(seg_interface_t *self, reg_t sub_addr) {
- sm_free_list(self->segmgr, sub_addr);
+static void free_at_address_lists(SegInterface *self, reg_t sub_addr) {
+ self->segmgr->free_list(sub_addr);
}
//-------------------- lists --------------------
-static seg_interface_t seg_interface_lists = {
+static SegInterface seg_interface_lists = {
/* segmgr = */ NULL,
/* mobj = */ NULL,
/* seg_id = */ 0,
@@ -1698,11 +1694,11 @@ static seg_interface_t seg_interface_lists = {
/* deallocate_self = */ deallocate_self
};
-static void list_all_deallocatable_nodes(seg_interface_t *self, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_deallocatable_nodes(SegInterface *self, void *param, void (*note)(void*param, reg_t addr)) {
LIST_ALL_DEALLOCATABLE(node, nodes);
}
-static void list_all_outgoing_references_nodes(seg_interface_t *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_outgoing_references_nodes(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
node_table_t *table = &(self->mobj->data.nodes);
node_t *node = &(table->table[addr.offset].entry);
@@ -1719,12 +1715,12 @@ static void list_all_outgoing_references_nodes(seg_interface_t *self, EngineStat
note(param, node->value);
}
-static void free_at_address_nodes(seg_interface_t *self, reg_t sub_addr) {
- sm_free_node(self->segmgr, sub_addr);
+static void free_at_address_nodes(SegInterface *self, reg_t sub_addr) {
+ self->segmgr->free_node(sub_addr);
}
//-------------------- nodes --------------------
-static seg_interface_t seg_interface_nodes = {
+static SegInterface seg_interface_nodes = {
/* segmgr = */ NULL,
/* mobj = */ NULL,
/* seg_id = */ 0,
@@ -1737,12 +1733,12 @@ static seg_interface_t seg_interface_nodes = {
/* deallocate_self = */ deallocate_self
};
-static void list_all_deallocatable_hunk(seg_interface_t *self, void *param, void (*note)(void*param, reg_t addr)) {
+static void list_all_deallocatable_hunk(SegInterface *self, void *param, void (*note)(void*param, reg_t addr)) {
LIST_ALL_DEALLOCATABLE(hunk, hunks);
}
//-------------------- hunk --------------------
-static seg_interface_t seg_interface_hunk = {
+static SegInterface seg_interface_hunk = {
/* segmgr = */ NULL,
/* mobj = */ NULL,
/* seg_id = */ 0,
@@ -1756,7 +1752,7 @@ static seg_interface_t seg_interface_hunk = {
};
//-------------------- dynamic memory --------------------
-static seg_interface_t seg_interface_dynmem = {
+static SegInterface seg_interface_dynmem = {
/* segmgr = */ NULL,
/* mobj = */ NULL,
/* seg_id = */ 0,
@@ -1770,7 +1766,7 @@ static seg_interface_t seg_interface_dynmem = {
};
//-------------------- reserved --------------------
-static seg_interface_t seg_interface_reserved = {
+static SegInterface seg_interface_reserved = {
/* segmgr = */ NULL,
/* mobj = */ NULL,
/* seg_id = */ 0,
@@ -1783,7 +1779,7 @@ static seg_interface_t seg_interface_reserved = {
/* deallocate_self = */ deallocate_self
};
-static seg_interface_t* seg_interfaces[MEM_OBJ_MAX] = {
+static SegInterface* seg_interfaces[MEM_OBJ_MAX] = {
&seg_interface_script,
&seg_interface_clones,
&seg_interface_locals,
@@ -1796,22 +1792,22 @@ static seg_interface_t* seg_interfaces[MEM_OBJ_MAX] = {
&seg_interface_reserved
};
-seg_interface_t *get_seg_interface(SegManager *self, seg_id_t segid) {
+SegInterface *SegManager::getSegInterface(seg_id_t segid) {
mem_obj_t *mobj;
- seg_interface_t *retval;
+ SegInterface *retval;
- if (!sm_check(self, segid))
+ if (!check(segid))
return NULL; // Invalid segment
- mobj = self->heap[segid];
- retval = (seg_interface_t *)sci_malloc(sizeof(seg_interface_t));
- memcpy(retval, seg_interfaces[mobj->type - 1], sizeof(seg_interface_t));
+ mobj = heap[segid];
+ retval = (SegInterface *)sci_malloc(sizeof(SegInterface));
+ memcpy(retval, seg_interfaces[mobj->type - 1], sizeof(SegInterface));
if (mobj->type != retval->type_id) {
error("Improper segment interface for %d", mobj->type);
}
- retval->segmgr = self;
+ retval->segmgr = this;
retval->mobj = mobj;
retval->seg_id = segid;
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 54b6a5ce97..9adf332ea4 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -23,29 +23,21 @@
*
*/
-
#ifndef _SCI_SEG_MANAGER_H
#define _SCI_SEG_MANAGER_H
#include "sci/engine/int_hashmap.h"
-#include "sci/include/sys_strings.h"
#include "sci/include/vm.h"
namespace Sci {
-#define DEFAULT_SCRIPTS 32
-#define DEFAULT_OBJECTS 8 // default # of objects per script
-#define DEFAULT_OBJECTS_INCREMENT 4 // Number of additional objects to instantiate if we're running out of them
-
// SCRIPT_ID must be 0
-typedef enum {
+enum idFlag {
SCRIPT_ID,
SEG_ID
-} id_flag;
-
-//void dbg_print( const char* msg, void *i ); // for debug only
+};
-// verify the the given condition is true, output the message if condition is false, and exit
+// Verify the the given condition is true, output the message if condition is false, and exit
// Parameters:
// cond - condition to be verified
// msg - the message to be printed if condition fails
@@ -56,21 +48,6 @@ typedef enum {
BREAKPOINT(); \
}
-#define MEM_OBJ_INVALID 0
-#define MEM_OBJ_SCRIPT 1
-#define MEM_OBJ_CLONES 2
-#define MEM_OBJ_LOCALS 3
-#define MEM_OBJ_STACK 4
-#define MEM_OBJ_SYS_STRINGS 5
-#define MEM_OBJ_LISTS 6
-#define MEM_OBJ_NODES 7
-#define MEM_OBJ_HUNK 8
-#define MEM_OBJ_DYNMEM 9
-#define MEM_OBJ_RESERVED 10
-#define MEM_OBJ_MAX MEM_OBJ_RESERVED // For sanity checking
-
-typedef int mem_obj_enum;
-
#define GET_SEGMENT(mgr, index, rtype) ((index) > 0 && (mgr).heap_size > index) ? \
(((mgr).heap[index] && (mgr).heap[index]->type == rtype)? (mgr).heap[index] : NULL) : NULL
@@ -81,417 +58,432 @@ typedef int mem_obj_enum;
(((mgr).heap[index] && ((mgr).heap[index]->type == MEM_OBJ_SCRIPT || (mgr).heap[index]->type == MEM_OBJ_CLONES))? (mgr).heap[index] \
: NULL): NULL
-struct SegManager {
- int_hash_map_t *id_seg_map; // id - script id; seg - index of heap
- mem_obj_t **heap;
- int heap_size; // size of the heap
- int reserved_id;
- int exports_wide;
- int sci1_1;
-
- int gc_mark_bits;
- // For standard Mark&Sweep:
- // 1 or 0, depending on what unreachable/freshly allocated
- // memory is tagged as
- size_t mem_allocated; // Total amount of memory allocated
-
- seg_id_t clones_seg_id; // ID of the (a) clones segment
- seg_id_t lists_seg_id; // ID of the (a) list segment
- seg_id_t nodes_seg_id; // ID of the (a) node segment
- seg_id_t hunks_seg_id; // ID of the (a) hunk segment
-};
-
-// Toplevel functionality
-
-void sm_init(SegManager *self, int sci1_1);
-// Initialize the segment manager
-
-void sm_destroy(SegManager *self);
-// Deallocate all memory associated with the segment manager
-
-void sm_gc(SegManager *self, EngineState *s);
-// Perform garbage collection
-// Parameters: (state_t *) s: The state to operate on
-// Effects : Unreachable objects in 's' are deallocated
-
-// 1. Scripts
-
-void sm_free_script(mem_obj_t* mem);
-
-mem_obj_t *sm_allocate_script(SegManager* self, EngineState *s, int script_nr, int* seg_id);
-// Allocate a script into the segment manager
-// Parameters: (int) script_nr: number of the script to load
-// (state_t *) s: The state containing resource manager handlers to load the
-// script data
-// Returns : (int) 0 on failure, 1 on success
-// (int) *seg_id: The segment ID of the newly allocated segment, on success
-
-// The script must then be initialised; see section (1b.), below.
-
-int sm_deallocate_script(SegManager* self, int script_nr);
-// Forcefully deallocate a previously allocated script
-// Parameters: (int) script_nr: number of the script to deallocate
-// Returns : (int) 1 on success, 0 on failure
-
-int sm_script_is_loaded(SegManager* self, int id, id_flag flag);
-// Determines whether a script has been loaded yet
-// Parameters: (int) id: number of the script or ID of the script segment to check for
-// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
-// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
-// but less convenient.
-
-uint16 sm_validate_export_func(SegManager* self, int pubfunct, int seg);
-// Validate whether the specified public function is exported by the script in the specified segment
-// Parameters: (int) pubfunct: Index of the function to validate
-// (int) seg: Segment ID of the script the check is to be performed for
-// Returns : (uint16) 0 if the public function is invalid, its offset into the script's segment
-// otherwise
-
-int sm_seg_get(SegManager* self, int script_nr);
-// Get the segment ID associated with a script number
-// Parameters: (int) script_nr: Number of the script to look up
-// Returns : (int) The associated segment ID, or -1 if no matching segment exists
-// This function is "pure" (i.e, it doesn't modify anything).
-
-
-
-// script lock operations
-
-void sm_increment_lockers(SegManager *self, int id, id_flag flag);
-// Increments the number of lockers of the script in question by one
-// Parameters: (int) id: ID of the script or script segment to modify
-// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
-// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
-// but less convenient.
-
-
-void sm_decrement_lockers(SegManager *self, int id, id_flag flag);
-// Decrements the number of lockers of the script in question by one
-// Parameters: (int) id: ID of the script or script segment to modify
-// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
-// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
-// but less convenient.
-
-int sm_get_lockers(SegManager *self, int id, id_flag flag);
-// Retrieves the number of locks held on this script
-// Parameters: (int) id: ID of the script or script segment to read from
-// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
-// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
-// but less convenient.
-// Returns : (int) The number of locks held on the previously identified script
-
-
-void sm_set_lockers(SegManager *self, int lockers, int id, id_flag flag);
-// Sets the number of locks held on the specified script
-// Parameters: (int) id: ID of the script or script segment to modify
-// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
-// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
-// but less convenient.
-
-
-byte *sm_get_synonyms(SegManager *self, int id, id_flag flag);
-// Retrieves a pointer to the synonyms associated with the specified script
-// Parameters: (int) id: ID of the script or script segment to read from
-// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
-// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
-// but less convenient.
-// Returns : (byte *) Pointer to the synonyms, in non-parsed format.
-// A dynamic failure is issued if the specified ID does not reference a proper script.
-
-
-int sm_get_synonyms_nr(SegManager *self, int id, id_flag flag);
-// Retrieves the number of synonyms associated with the specified script
-// Parameters: (int) id: ID of the script or script segment to read from
-// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
-// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
-// but less convenient.
-// Returns : (int) The number of synonyms associated with the specified script
-// A dynamic failure is issued if the specified ID does not reference a proper script.
-
-
-
-// 1b. Script Initialisation
-
-// The set of functions below are intended
-// to be used during script instantiation,
-// i.e. loading and linking.
-
-void sm_script_initialise_locals_zero(SegManager *self, seg_id_t seg, int nr);
-// Initializes a script's local variable block
-// Parameters: (seg_id_t) seg: Segment containing the script to initialize
-// (int) nr: Number of local variables to allocate
-// All variables are initialized to zero.
-
-
-void sm_script_initialise_locals(SegManager *self, reg_t location);
-// Initializes a script's local variable block according to a prototype
-// Parameters: (reg_t) location: Location to initialize from
-
+struct SegInterface;
+
+class SegManager {
+public:
+ // Initialize the segment manager
+ SegManager(bool sci1_1);
+
+ // Deallocate all memory associated with the segment manager
+ ~SegManager();
+
+ // 1. Scripts
+
+ void freeScript(mem_obj_t* mem);
+
+ // Allocate a script into the segment manager
+ // Parameters: (int) script_nr: number of the script to load
+ // (state_t *) s: The state containing resource manager handlers to load the
+ // script data
+ // Returns : (int) 0 on failure, 1 on success
+ // (int) *seg_id: The segment ID of the newly allocated segment, on success
+ mem_obj_t *allocateScript(EngineState *s, int script_nr, int* seg_id);
+
+ // The script must then be initialised; see section (1b.), below.
+
+ // Forcefully deallocate a previously allocated script
+ // Parameters: (int) script_nr: number of the script to deallocate
+ // Returns : (int) 1 on success, 0 on failure
+ int deallocateScript(int script_nr);
+
+ // Determines whether a script has been loaded yet
+ // Parameters: (int) id: number of the script or ID of the script segment to check for
+ // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
+ // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+ // but less convenient.
+ int scriptIsLoaded(int id, idFlag flag);
+
+ // Validate whether the specified public function is exported by the script in the specified segment
+ // Parameters: (int) pubfunct: Index of the function to validate
+ // (int) seg: Segment ID of the script the check is to be performed for
+ // Returns : (uint16) 0 if the public function is invalid, its offset into the script's segment
+ // otherwise
+ uint16 validateExportFunc(int pubfunct, int seg);
+
+ // Get the segment ID associated with a script number
+ // Parameters: (int) script_nr: Number of the script to look up
+ // Returns : (int) The associated segment ID, or -1 if no matching segment exists
+ // This function is "pure" (i.e, it doesn't modify anything).
+ int segGet(int script_nr);
+
+
+ // script lock operations
+
+ // Increments the number of lockers of the script in question by one
+ // Parameters: (int) id: ID of the script or script segment to modify
+ // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
+ // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+ // but less convenient.
+ void incrementLockers(int id, idFlag flag);
+
+ // Decrements the number of lockers of the script in question by one
+ // Parameters: (int) id: ID of the script or script segment to modify
+ // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
+ // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+ // but less convenient.
+ void decrementLockers(int id, idFlag flag);
+
+ // Retrieves the number of locks held on this script
+ // Parameters: (int) id: ID of the script or script segment to read from
+ // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
+ // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+ // but less convenient.
+ // Returns : (int) The number of locks held on the previously identified script
+ int getLockers(int id, idFlag flag);
+
+ // Sets the number of locks held on the specified script
+ // Parameters: (int) id: ID of the script or script segment to modify
+ // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
+ // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+ // but less convenient.
+ void setLockers(int lockers, int id, idFlag flag);
+
+ // Retrieves a pointer to the synonyms associated with the specified script
+ // Parameters: (int) id: ID of the script or script segment to read from
+ // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
+ // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+ // but less convenient.
+ // Returns : (byte *) Pointer to the synonyms, in non-parsed format.
+ // A dynamic failure is issued if the specified ID does not reference a proper script.
+ byte *getSynonyms(int id, idFlag flag);
+
+ // Retrieves the number of synonyms associated with the specified script
+ // Parameters: (int) id: ID of the script or script segment to read from
+ // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
+ // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+ // but less convenient.
+ // Returns : (int) The number of synonyms associated with the specified script
+ // A dynamic failure is issued if the specified ID does not reference a proper script.
+ int getSynonymsNr(int id, idFlag flag);
+
+
+ // 1b. Script Initialisation
+
+ // The set of functions below are intended
+ // to be used during script instantiation,
+ // i.e. loading and linking.
+
+ // Initializes a script's local variable block
+ // Parameters: (seg_id_t) seg: Segment containing the script to initialize
+ // (int) nr: Number of local variables to allocate
+ // All variables are initialized to zero.
+ void scriptInitialiseLocalsZero(seg_id_t seg, int nr);
+
+ // Initializes a script's local variable block according to a prototype
+ // Parameters: (reg_t) location: Location to initialize from
+ void scriptInitialiseLocals(reg_t location);
+
+ // Initializes an object within the segment manager
+ // Parameters: (reg_t) obj_pos: Location (segment, offset) of the object
+ // Returns : (object_t *) A newly created object_t describing the object
+ // obj_pos must point to the beginning of the script/class block (as opposed
+ // to what the VM considers to be the object location)
+ // The corresponding object_t is stored within the relevant script.
+ object_t *scriptObjInit(EngineState *s, reg_t obj_pos);
+
+ // Informs the segment manager that a code block must be relocated
+ // Parameters: (reg_t) location: Start of block to relocate
+ void scriptAddCodeBlock(reg_t location);
+
+ // Tells the segment manager whether exports are wide (32-bit) or not.
+ // Parameters: (int) flag: 1 if exports are wide, 0 otherwise
+ void setExportWidth(int flag);
+
+ // Processes a relocation block witin a script
+ // Parameters: (reg_t) obj_pos: Location (segment, offset) of the block
+ // Returns : (object_t *) Location of the relocation block
+ // This function is idempotent, but it must only be called after all
+ // 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: (seg_id_t) 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(seg_id_t 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
+ // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
+ // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+ // but less convenient.
+ // A dynamic failure is issued if the specified ID does not reference a proper script.
+ void setExportTableOffset(int offset, int id, idFlag flag);
+
+ // Sets the script-relative offset of the synonyms associated with the specified script
+ // Parameters: (int) offset: The script-relative offset of the synonyms block
+ // (int) id: ID of the script or script segment to write to
+ // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
+ // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+ // but less convenient.
+ // A dynamic failure is issued if the specified ID does not reference a proper script.
+ void setSynonymsOffset(int offset, int id, idFlag flag);
+
+ // Sets the number of synonyms associated with the specified script
+ // Parameters: (int) nr: The number of synonyms, as to be stored within the script
+ // (int) id: ID of the script or script segment to write to
+ // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
+ // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+ // but less convenient.
+ // A dynamic failure is issued if the specified ID does not reference a proper script.
+ void setSynonymsNr(int nr, int id, idFlag flag);
+
+ // Marks the script identified by its script number as deleted
+ // Parameters: (int) script_nr: Script number to mark as deleted
+ // This will not actually delete the script. If references remain present on the
+ // heap or the stack, the script will stay in memory in a quasi-deleted state until
+ // either unreachable (resulting in its eventual deletion) or reloaded (resulting
+ // in its data being updated).
+ void markScriptDeleted(int script_nr);
+
+ // Marks the script identified by its script number as not deleted
+ // Parameters: (int) script_nr: Script number to mark as not deleted
+ void unmarkScriptDeleted(int script_nr);
+
+ // Determines whether the script referenced by the indicated segment is marked as being deleted.
+ // Parameters: (seg_id_t) Segment ID of the script to investigate
+ // Returns : (int) 1 iff seg points to a script and the segment is deleted, 0 otherwise
+ // Will return 0 when applied to an invalid or non-script seg.
+ int scriptIsMarkedAsDeleted(seg_id_t seg);
+
+
+ // 2. Clones
+
+ // Allocate a fresh clone
+ // Returns : (clone_t*): Reference to the memory allocated for the clone
+ // (reg_t) *addr: The offset of the freshly allocated clone
+ clone_t *alloc_clone(reg_t *addr);
+
+ // Deallocates a clone
+ // Parameters: (reg_t) addr: Offset of the clone scheduled for termination
+ void free_clone(reg_t addr);
+
+
+ // 3. Objects (static, from Scripts, and dynmic, from Clones)
+
+ // Not all of these functions are fully operational for clones ATM
+
+ // Retrieves a 16 bit value from within a script's heap representation
+ // Parameters: (reg_t) reg: The address to read from
+ // Returns : (int16) The value read from the specified location
+ int16 getHeap(reg_t reg);
+
+ // Writes a 16 bit value into a script's heap representation
+ // Parameters: (reg_t) reg: The address to write to
+ // (int16) value: The value to write
+ //void putHeap(reg_t reg, int16 value);
+
+ // Copies a byte string into a script's heap representation
+ // Parameters: (int) dst: The script-relative offset of the destination area
+ // (const void *) src: Pointer to the data source location
+ // (size_t) n: Number of bytes to copy
+ // (int) id: ID of the script or script segment to write to
+ // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
+ // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+ // but less convenient.
+ // A dynamic failure is issued if the specified ID does not reference a proper script.
+ void mcpyInOut(int dst, const void *src, size_t n, int id, int flag);
+
+
+ // 4. Stack
+
+ // Allocates a data stack
+ // Parameters: (int) size: Number of stack entries to reserve
+ // Returns : (dstack_t *): The physical stack
+ // (seg_id_t) segid: Segment ID of the stack
+ dstack_t *allocateStack(int size, seg_id_t *segid);
+
+
+ // 5. System Strings
+
+ // Allocates a system string table
+ // Returns : (dstack_t *): The physical stack
+ // (seg_id_t) segid: Segment ID of the stack
+ // See also sys_string_acquire();
+ sys_strings_t *allocateSysStrings(seg_id_t *segid);
+
+
+ // 6, 7. Lists and Nodes
-object_t *sm_script_obj_init(SegManager *self, EngineState *s, reg_t obj_pos);
-// Initializes an object within the segment manager
-// Parameters: (reg_t) obj_pos: Location (segment, offset) of the object
-// Returns : (object_t *) A newly created object_t describing the object
-// obj_pos must point to the beginning of the script/class block (as opposed
-// to what the VM considers to be the object location)
-// The corresponding object_t is stored within the relevant script.
+ // Allocate a fresh list
+ // Returns : (listY_t*): Reference to the memory allocated for the list
+ // (reg_t) *addr: The offset of the freshly allocated list
+ list_t *alloc_list(reg_t *addr);
+ // Deallocates a list
+ // Parameters: (reg_t) addr: Offset of the list scheduled for termination
+ void free_list(reg_t addr);
-void sm_script_add_code_block(SegManager *self, reg_t location);
-// Informs the segment manager that a code block must be relocated
-// Parameters: (reg_t) location: Start of block to relocate
+ // Allocate a fresh node
+ // Returns : (node_t*): Reference to the memory allocated for the node
+ // (reg_t) *addr: The offset of the freshly allocated node
+ node_t *alloc_node(reg_t *addr);
+ // Deallocates a list node
+ // Parameters: (reg_t) addr: Offset of the node scheduled for termination
+ void free_node(reg_t addr);
-void sm_set_export_width(SegManager *self, int flag);
-// Tells the segment manager whether exports are wide (32-bit) or not.
-// Parameters: (int) flag: 1 if exports are wide, 0 otherwise
-void sm_script_relocate(SegManager *self, reg_t block);
-// Processes a relocation block witin a script
-// Parameters: (reg_t) obj_pos: Location (segment, offset) of the block
-// Returns : (object_t *) Location of the relocation block
-// This function is idempotent, but it must only be called after all
-// objects have been instantiated, or a run-time error will occur.
+ // 8. Hunk Memory
+ // Allocate a fresh chunk of the hunk
+ // Parameters: (int) size: Number of bytes to allocate for the hunk entry
+ // (const char *) hunk_type: A descriptive string for the hunk entry,
+ // for debugging purposes
+ // Returns : (hunk_t*): Reference to the memory allocated for the hunk piece
+ // (reg_t) *addr: The offset of the freshly allocated hunk entry
+ hunk_t *alloc_hunk_entry(const char *hunk_type, int size, reg_t *addr);
-void sm_script_free_unused_objects(SegManager *self, seg_id_t segid);
-// Deallocates all unused but allocated entries for objects
-// Parameters: (seg_id_t) segid: segment of the script to prune in this way
-// These entries are created during script instantiation; deallocating them
-// frees up some additional memory.
+ // Deallocates a hunk entry
+ // Parameters: (reg_t) addr: Offset of the hunk entry to delete
+ void free_hunk_entry(reg_t addr);
+ // 9. Dynamic Memory
-void sm_set_export_table_offset(SegManager *self, int offset, int id, id_flag flag);
-// 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
-// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
-// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
-// but less convenient.
-// A dynamic failure is issued if the specified ID does not reference a proper script.
+ // Allocate some dynamic memory
+ // Parameters: (int) size: Number of bytes to allocate
+ // (const char_ *) description: A descriptive string,
+ // for debugging purposes
+ // Returns : (unsigned char*): Raw pointer into the allocated dynamic memory
+ // (reg_t) *addr: The offset of the freshly allocated X
+ unsigned char *allocDynmem(int size, const char *description, reg_t *addr);
+ // Deallocates a piece of dynamic memory
+ // Parameters: (reg_t) addr: Offset of the dynmem chunk to free
+ int freeDynmem(reg_t addr);
-void sm_set_synonyms_offset(SegManager *self, int offset, int id, id_flag flag);
-// Sets the script-relative offset of the synonyms associated with the specified script
-// Parameters: (int) offset: The script-relative offset of the synonyms block
-// (int) id: ID of the script or script segment to write to
-// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
-// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
-// but less convenient.
-// A dynamic failure is issued if the specified ID does not reference a proper script.
+ // Gets the description of a dynmem segment
+ // Parameters: (reg_t) addr: Segment to describe
+ // Returns : (const char *): Pointer to the descriptive string set in
+ // allocDynmem
+ const char *getDescription(reg_t addr);
-void sm_set_synonyms_nr(SegManager *self, int nr, int id, id_flag flag);
-// Sets the number of synonyms associated with the specified script
-// Parameters: (int) nr: The number of synonyms, as to be stored within the script
-// (int) id: ID of the script or script segment to write to
-// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
-// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
-// but less convenient.
-// A dynamic failure is issued if the specified ID does not reference a proper script.
+ // 10. Reserved segments
+ // Reserves a special-purpose segment
+ // Parameters: (char *) name: A string name identifying the segment (the string is cloned and retained)
+ // Returns : A fresh segment ID for the segment in question
+ // Reserved segments are never used by the segment manager. They can be used to tag special-purpose addresses.
+ // Segment 0 is implicitly reserved for numbers.
+ //seg_id_t sm_allocate_reserved_segment(char *name);
-void sm_mark_script_deleted(SegManager *self, int script_nr);
-// Marks the script identified by its script number as deleted
-// Parameters: (int) script_nr: Script number to mark as deleted
-// This will not actually delete the script. If references remain present on the
-// heap or the stack, the script will stay in memory in a quasi-deleted state until
-// either unreachable (resulting in its eventual deletion) or reloaded (resulting
-// in its data being updated).
+ // Generic Operations on Segments and Addresses
-void sm_unmark_script_deleted(SegManager *self, int script_nr);
-// Marks the script identified by its script number as not deleted
-// Parameters: (int) script_nr: Script number to mark as not deleted
+ // Dereferences a raw memory pointer
+ // Parameters: (reg_t) reg: The reference to dereference
+ // Returns : (byte *) The data block referenced
+ // (int) size: (optionally) the theoretical maximum size of it
+ byte *dereference(reg_t reg, int *size);
-int sm_script_is_marked_as_deleted(SegManager *self, seg_id_t seg);
-// Determines whether the script referenced by the indicated segment is marked as being deleted.
-// Parameters: (seg_id_t) Segment ID of the script to investigate
-// Returns : (int) 1 iff seg points to a script and the segment is deleted, 0 otherwise
-// Will return 0 when applied to an invalid or non-script seg.
+ // Segment Interface
+ // Retrieves the segment interface to the specified segment
+ // Parameters: (seg_id_t) segid: ID of the segment to look up
+ // Returns : (SegInterface *): An interface to the specified segment ID, or NULL on error
+ // The returned interface 'si' must be freed after use by calling 'si->dealloc_self(si)';
+ SegInterface *getSegInterface(seg_id_t segid);
-// 2. Clones
-clone_t *sm_alloc_clone(SegManager *self, reg_t *addr);
-// Allocate a fresh clone
-// Returns : (clone_t*): Reference to the memory allocated for the clone
-// (reg_t) *addr: The offset of the freshly allocated clone
+ void heapRelocate(EngineState *s, reg_t block);
+ void scriptRelocateExportsSci11(int seg);
+ void scriptInitialiseObjectsSci11(EngineState *s, int seg);
+ int scriptMarkedDeleted(int script_nr);
+ int initialiseScript(mem_obj_t *mem, EngineState *s, int script_nr);
+public: // TODO: make private
+ int_hash_map_t *id_seg_map; // id - script id; seg - index of heap
+ mem_obj_t **heap;
+ int heap_size; // size of the heap
+ int reserved_id;
+ int exports_wide;
+ bool isSci1_1;
-void sm_free_clone(SegManager *self, reg_t addr);
-// Deallocates a clone
-// Parameters: (reg_t) addr: Offset of the clone scheduled for termination
-
-
-// Objects (static, from Scripts, and dynmic, from Clones)
-
-// Not all of these functions are fully operational for clones ATM
-
-int16 sm_get_heap(SegManager* self, reg_t reg);
-// Retrieves a 16 bit value from within a script's heap representation
-// Parameters: (reg_t) reg: The address to read from
-// Returns : (int16) The value read from the specified location
-
-
-void sm_put_heap(SegManager *self, reg_t reg, int16 value);
-// Writes a 16 bit value into a script's heap representation
-// Parameters: (reg_t) reg: The address to write to
-// (int16) value: The value to write
-
-
-void sm_mcpy_in_out(SegManager* self, int dst, const void *src, size_t n, int id, int flag);
-// Copies a byte string into a script's heap representation
-// Parameters: (int) dst: The script-relative offset of the destination area
-// (const void *) src: Pointer to the data source location
-// (size_t) n: Number of bytes to copy
-// (int) id: ID of the script or script segment to write to
-// (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
-// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
-// but less convenient.
-// A dynamic failure is issued if the specified ID does not reference a proper script.
-
-
-// 4. Stack
-
-dstack_t *sm_allocate_stack(SegManager *self, int size, seg_id_t *segid);
-// Allocates a data stack
-// Parameters: (int) size: Number of stack entries to reserve
-// Returns : (dstack_t *): The physical stack
-// (seg_id_t) segid: Segment ID of the stack
-
-
-// 5. System Strings
-
-sys_strings_t *sm_allocate_sys_strings(SegManager *self, seg_id_t *segid);
-// Allocates a system string table
-// Returns : (dstack_t *): The physical stack
-// (seg_id_t) segid: Segment ID of the stack
-// See also sys_string_acquire();
-
-
-// 6, 7. Lists and Nodes
-
-list_t *sm_alloc_list(SegManager *self, reg_t *addr);
-// Allocate a fresh list
-// Returns : (listY_t*): Reference to the memory allocated for the list
-// (reg_t) *addr: The offset of the freshly allocated list
-
-
-void sm_free_list(SegManager *self, reg_t addr);
-// Deallocates a list
-// Parameters: (reg_t) addr: Offset of the list scheduled for termination
-
-
-node_t *sm_alloc_node(SegManager *self, reg_t *addr);
-// Allocate a fresh node
-// Returns : (node_t*): Reference to the memory allocated for the node
-// (reg_t) *addr: The offset of the freshly allocated node
-
-void sm_free_node(SegManager *self, reg_t addr);
-// Deallocates a list node
-// Parameters: (reg_t) addr: Offset of the node scheduled for termination
-
-
-// 8. Hunk Memory
-
-hunk_t *sm_alloc_hunk_entry(SegManager *self, const char *hunk_type, int size, reg_t *addr);
-// Allocate a fresh chunk of the hunk
-// Parameters: (int) size: Number of bytes to allocate for the hunk entry
-// (const char *) hunk_type: A descriptive string for the hunk entry,
-// for debugging purposes
-// Returns : (hunk_t*): Reference to the memory allocated for the hunk piece
-// (reg_t) *addr: The offset of the freshly allocated hunk entry
-
-
-void sm_free_hunk_entry(SegManager *self, reg_t addr);
-// Deallocates a hunk eentry
-// Parameters: (reg_t) addr: Offset of the hunk entry to delete
-
-
-// 9. Dynamic Memory
-
-unsigned char *sm_alloc_dynmem(SegManager *self, int size, const char *description, reg_t *addr);
-// Allocate some dynamic memory
-// Parameters: (int) size: Number of bytes to allocate
-// (const char_ *) description: A descriptive string,
-// for debugging purposes
-// Returns : (unsigned char*): Raw pointer into the allocated dynamic memory
-// (reg_t) *addr: The offset of the freshly allocated X
-
-int sm_free_dynmem(SegManager *self, reg_t addr);
-// Deallocates a piece of dynamic memory
-// Parameters: (reg_t) addr: Offset of the dynmem chunk to free
-
-
-const char *sm_get_description(SegManager *self, reg_t addr);
-// Gets the description of a dynmem segment
-// Parameters: (reg_t) addr: Segment to describe
-// Returns : (const char *): Pointer to the descriptive string set in
-// sm_alloc_dynmem
-
-
-// 10. Reserved segments
-
-seg_id_t sm_allocate_reserved_segment(SegManager *self, char *name);
-// Reserves a special-purpose segment
-// Parameters: (char *) name: A string name identifying the segment (the string is cloned and retained)
-// Returns : A fresh segment ID for the segment in question
-// Reserved segments are never used by the segment manager. They can be used to tag special-purpose addresses.
-// Segment 0 is implicitly reserved for numbers.
+ int gc_mark_bits;
+ // For standard Mark&Sweep:
+ // 1 or 0, depending on what unreachable/freshly allocated
+ // memory is tagged as
+ size_t mem_allocated; // Total amount of memory allocated
+ seg_id_t clones_seg_id; // ID of the (a) clones segment
+ seg_id_t lists_seg_id; // ID of the (a) list segment
+ seg_id_t nodes_seg_id; // ID of the (a) node segment
+ seg_id_t hunks_seg_id; // ID of the (a) hunk segment
-// Generic Operations on Segments and Addresses
+private:
+ mem_obj_t *allocNonscriptSegment(memObjType type, seg_id_t *segid);
+ local_variables_t *allocLocalsSegment(script_t *scr, int count);
+ mem_obj_t *memObjAllocate(seg_id_t segid, int hash_id, memObjType type);
+ int deallocate(int seg, bool recursive);
+
+ hunk_t *alloc_hunk(reg_t *);
+ void free_hunk(reg_t addr);
+
+ inline int relocateLocal(script_t *scr, seg_id_t segment, int location);
+ inline int relocateBlock(reg_t *block, int block_location, int block_items, seg_id_t segment, int location);
+ inline int relocateObject(object_t *obj, seg_id_t segment, int location);
+
+ inline int findFreeId(int *id);
+ static void setScriptSize(mem_obj_t *mem, EngineState *s, int script_nr);
+ object_t *scriptObjInit0(EngineState *s, reg_t obj_pos);
+ object_t *scriptObjInit11(EngineState *s, reg_t obj_pos);
+
+ /* Check segment validity
+ ** Parameters: (int) seg: The segment to validate
+ ** Returns : (bool) false if 'seg' is an invalid segment
+ ** true if 'seg' is a valid segment
+ */
+ bool check(int seg);
+
+ void dbgPrint(const char* msg, void *i); // for debug only
+
+ // Perform garbage collection
+ // Parameters: (EngineState *) s: The state to operate on
+ // Effects : Unreachable objects in 's' are deallocated
+ //void sm_gc(EngineState *s);
+};
-byte *sm_dereference(SegManager *self, reg_t reg, int *size);
-// Dereferences a raw memory pointer
-// Parameters: (reg_t) reg: The reference to dereference
-// Returns : (byte *) The data block referenced
-// (int) size: (optionally) the theoretical maximum size of it
// 11. Segment interface, primarily for GC
-struct seg_interface_t {
+struct SegInterface {
SegManager *segmgr;
mem_obj_t *mobj;
seg_id_t seg_id;
- mem_obj_enum type_id; // Segment type
+ memObjType type_id; // Segment type
const char *type; // String description of the segment type
- reg_t (*find_canonic_address)(seg_interface_t *self, reg_t sub_addr);
+ reg_t (*find_canonic_address)(SegInterface *self, reg_t sub_addr);
// Finds the canonic address associated with sub_reg
// Parameters: (reg_t) sub_addr: The base address whose canonic address is to be found
// For each valid address a, there exists a canonic address c(a) such that c(a) = c(c(a)).
// This address "governs" a in the sense that deallocating c(a) will deallocate a.
- void (*free_at_address)(seg_interface_t *self, reg_t sub_addr);
+ void (*free_at_address)(SegInterface *self, reg_t sub_addr);
// Deallocates all memory associated with the specified address
// Parameters: (reg_t) sub_addr: The address (within the given segment) to deallocate
- void (*list_all_deallocatable)(seg_interface_t *self, void *param, void (*note)(void *param, reg_t addr));
+ void (*list_all_deallocatable)(SegInterface *self, void *param, void (*note)(void *param, reg_t addr));
// Iterates over and reports all addresses within the current segment
// Parameters: note : (voidptr * addr) -> (): Invoked for each address on which free_at_address()
// makes sense
// (void *) param: Parameter passed to 'note'
- void (*list_all_outgoing_references)(seg_interface_t *self, EngineState *s, reg_t object, void *param, void (*note)(void *param, reg_t addr));
+ void (*list_all_outgoing_references)(SegInterface *self, EngineState *s, reg_t object, void *param, void (*note)(void *param, reg_t addr));
// Iterates over all references reachable from the specified object
// Parameters: (reg_t) object: The object (within the current segment) to analyse
// (void *) param: Parameter passed to 'note'
// note : (voidptr * addr) -> (): Invoked for each outgoing reference within the object
// Note: This function may also choose to report numbers (segment 0) as adresses
- void (*deallocate_self)(seg_interface_t *self);
+ void (*deallocate_self)(SegInterface *self);
// Deallocates the segment interface
};
-seg_interface_t *get_seg_interface(SegManager *self, seg_id_t segid);
-// Retrieves the segment interface to the specified segment
-// Parameters: (seg_id_t) segid: ID of the segment to look up
-// Returns : (seg_interface_t *): An interface to the specified segment ID, or NULL on error
-// The returned interface 'si' must be freed after use by calling 'si->dealloc_self(si)';
-
} // End of namespace Sci
#endif
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 3c5b1f5393..ef57b73214 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -221,7 +221,7 @@ reg_t get_class_address(EngineState *s, int classnr, int lock, reg_t caller) {
}
} else
if (caller.segment != the_class->reg.segment)
- sm_increment_lockers(&s->seg_manager, the_class->reg.segment, SEG_ID);
+ s->seg_manager->incrementLockers(the_class->reg.segment, SEG_ID);
return the_class->reg;
}
@@ -243,7 +243,7 @@ reg_t get_class_address(EngineState *s, int classnr, int lock, reg_t caller) {
#define GET_OP_SIGNED_WORD() ((getInt16(code_buf + ((xs->addr.pc.offset) += 2) - 2)))
#define GET_OP_SIGNED_FLEX() ((opcode & 1)? GET_OP_SIGNED_BYTE() : GET_OP_SIGNED_WORD())
-#define SEG_GET_HEAP(s, reg) sm_get_heap(&s->seg_manager, reg)
+#define SEG_GET_HEAP(s, reg) s->seg_manager->getHeap(reg)
#define OBJ_SPECIES(s, reg) SEG_GET_HEAP(s, make_reg(reg.segment, reg.offset + SCRIPT_SPECIES_OFFSET))
// Returns an object's species
@@ -254,14 +254,14 @@ inline exec_stack_t *execute_method(EngineState *s, uint16 script, uint16 pubfun
int seg;
uint16 temp;
- if (!sm_script_is_loaded(&s->seg_manager, script, SCRIPT_ID)) // Script not present yet?
+ if (!s->seg_manager->scriptIsLoaded(script, SCRIPT_ID)) // Script not present yet?
script_instantiate(s, script);
else
- sm_unmark_script_deleted(&s->seg_manager, script);
+ s->seg_manager->unmarkScriptDeleted(script);
- seg = sm_seg_get(&s->seg_manager, script);
+ seg = s->seg_manager->segGet(script);
- temp = sm_validate_export_func(&s->seg_manager, pubfunct, seg);
+ temp = s->seg_manager->validateExportFunc(pubfunct, seg);
VERIFY(temp, "Invalid pubfunct in export table");
if (!temp) {
sciprintf("Request for invalid exported function 0x%x of script 0x%x\n", pubfunct, script);
@@ -533,7 +533,7 @@ void vm_handle_fatal_error(EngineState *s, int line, const char *file) {
}
static inline script_t *script_locate_by_segment(EngineState *s, seg_id_t seg) {
- mem_obj_t *memobj = GET_SEGMENT(s->seg_manager, seg, MEM_OBJ_SCRIPT);
+ mem_obj_t *memobj = GET_SEGMENT(*s->seg_manager, seg, MEM_OBJ_SCRIPT);
if (memobj)
return &(memobj->data.script);
@@ -541,7 +541,7 @@ static inline script_t *script_locate_by_segment(EngineState *s, seg_id_t seg) {
}
static reg_t pointer_add(EngineState *s, reg_t base, int offset) {
- mem_obj_t *mobj = GET_SEGMENT_ANY(s->seg_manager, base.segment);
+ mem_obj_t *mobj = GET_SEGMENT_ANY(*s->seg_manager, base.segment);
if (!mobj) {
script_debug_flag = script_error_flag = 1;
@@ -1617,11 +1617,11 @@ seg_id_t script_get_segment(EngineState *s, int script_nr, int load) {
if ((load & SCRIPT_GET_LOAD) == SCRIPT_GET_LOAD)
script_instantiate(s, script_nr);
- segment = sm_seg_get(&s->seg_manager, script_nr);
+ segment = s->seg_manager->segGet(script_nr);
if (segment > 0) {
if ((load & SCRIPT_GET_LOCK) == SCRIPT_GET_LOCK)
- sm_increment_lockers(&s->seg_manager, segment, SEG_ID);
+ s->seg_manager->incrementLockers(segment, SEG_ID);
return segment;
} else
@@ -1642,7 +1642,7 @@ reg_t script_lookup_export(EngineState *s, int script_nr, int export_index) {
}
#endif
- memobj = GET_SEGMENT(s->seg_manager, seg, MEM_OBJ_SCRIPT);
+ memobj = GET_SEGMENT(*s->seg_manager, seg, MEM_OBJ_SCRIPT);
if (memobj)
script = &(memobj->data.script);
@@ -1668,8 +1668,6 @@ reg_t script_lookup_export(EngineState *s, int script_nr, int export_index) {
#define INST_LOOKUP_CLASS(id) ((id == 0xffff)? NULL_REG : get_class_address(s, id, SCRIPT_GET_LOCK, reg))
-int sm_script_marked_deleted(SegManager* self, int script_nr);
-int sm_initialise_script(mem_obj_t *mem, EngineState *s, int script_nr);
int script_instantiate_common(EngineState *s, int script_nr, resource_t **script, resource_t **heap, int *was_new) {
int seg;
int seg_id;
@@ -1700,33 +1698,33 @@ int script_instantiate_common(EngineState *s, int script_nr, resource_t **script
return 0;
}
- seg = sm_seg_get(&s->seg_manager, script_nr);
- if (sm_script_is_loaded(&s->seg_manager, script_nr, SCRIPT_ID)) {
- marked_for_deletion = sm_script_marked_deleted(&s->seg_manager, script_nr);
+ seg = s->seg_manager->segGet(script_nr);
+ if (s->seg_manager->scriptIsLoaded(script_nr, SCRIPT_ID)) {
+ marked_for_deletion = s->seg_manager->scriptMarkedDeleted(script_nr);
if (!marked_for_deletion) {
- sm_increment_lockers(&s->seg_manager, seg, SEG_ID);
+ s->seg_manager->incrementLockers(seg, SEG_ID);
return seg;
} else {
seg_id = seg;
- mem = s->seg_manager.heap[seg];
- sm_free_script(mem);
+ mem = s->seg_manager->heap[seg];
+ s->seg_manager->freeScript(mem);
}
- } else if (!(mem = sm_allocate_script(&s->seg_manager, s, script_nr, &seg_id))) { // ALL YOUR SCRIPT BASE ARE BELONG TO US
+ } else if (!(mem = s->seg_manager->allocateScript(s, script_nr, &seg_id))) { // ALL YOUR SCRIPT BASE ARE BELONG TO US
sciprintf("Not enough heap space for script size 0x%x of script 0x%x, should this happen?`\n", (*script)->size, script_nr);
script_debug_flag = script_error_flag = 1;
return 0;
}
- sm_initialise_script(mem, s, script_nr);
+ s->seg_manager->initialiseScript(mem, s, script_nr);
reg.segment = seg_id;
reg.offset = 0;
// Set heap position (beyond the size word)
- sm_set_lockers(&s->seg_manager, 1, reg.segment, SEG_ID);
- sm_set_export_table_offset(&s->seg_manager, 0, reg.segment, SEG_ID);
- sm_set_synonyms_offset(&s->seg_manager, 0, reg.segment, SEG_ID);
- sm_set_synonyms_nr(&s->seg_manager, 0, reg.segment, SEG_ID);
+ s->seg_manager->setLockers(1, reg.segment, SEG_ID);
+ s->seg_manager->setExportTableOffset(0, reg.segment, SEG_ID);
+ s->seg_manager->setSynonymsOffset(0, reg.segment, SEG_ID);
+ s->seg_manager->setSynonymsNr(0, reg.segment, SEG_ID);
*was_new = 0;
@@ -1760,14 +1758,14 @@ int script_instantiate_sci0(EngineState *s, int script_nr) {
// Instead, the script starts with a 16 bit int specifying the
// number of locals we need; these are then allocated and zeroed.
- sm_mcpy_in_out(&s->seg_manager, 0, script->data, script->size, reg.segment, SEG_ID);
+ s->seg_manager->mcpyInOut(0, script->data, script->size, reg.segment, SEG_ID);
magic_pos_adder = 2; // Step over the funny prefix
if (locals_nr)
- sm_script_initialise_locals_zero(&s->seg_manager, reg.segment, locals_nr);
+ s->seg_manager->scriptInitialiseLocalsZero(reg.segment, locals_nr);
} else {
- sm_mcpy_in_out(&s->seg_manager, 0, script->data, script->size, reg.segment, SEG_ID);
+ s->seg_manager->mcpyInOut(0, script->data, script->size, reg.segment, SEG_ID);
magic_pos_adder = 0;
}
@@ -1794,17 +1792,17 @@ int script_instantiate_sci0(EngineState *s, int script_nr) {
switch (objtype) {
case sci_obj_exports: {
- sm_set_export_table_offset(&s->seg_manager, data_base.offset, reg.segment, SEG_ID);
+ s->seg_manager->setExportTableOffset(data_base.offset, reg.segment, SEG_ID);
}
break;
case sci_obj_synonyms:
- sm_set_synonyms_offset(&s->seg_manager, addr.offset, reg.segment, SEG_ID); // +4 is to step over the header
- sm_set_synonyms_nr(&s->seg_manager, (objlength) / 4, reg.segment, SEG_ID);
+ s->seg_manager->setSynonymsOffset(addr.offset, reg.segment, SEG_ID); // +4 is to step over the header
+ s->seg_manager->setSynonymsNr((objlength) / 4, reg.segment, SEG_ID);
break;
case sci_obj_localvars:
- sm_script_initialise_locals(&s->seg_manager, data_base);
+ s->seg_manager->scriptInitialiseLocals(data_base);
break;
case sci_obj_class: {
@@ -1849,11 +1847,11 @@ int script_instantiate_sci0(EngineState *s, int script_nr) {
switch (objtype) {
case sci_obj_code:
- sm_script_add_code_block(&s->seg_manager, addr);
+ s->seg_manager->scriptAddCodeBlock(addr);
break;
case sci_obj_object:
case sci_obj_class: { // object or class?
- object_t *obj = sm_script_obj_init(&s->seg_manager, s, addr);
+ object_t *obj = s->seg_manager->scriptObjInit(s, addr);
object_t *base_obj;
// Instantiate the superclass, if neccessary
@@ -1880,17 +1878,13 @@ int script_instantiate_sci0(EngineState *s, int script_nr) {
} while ((objtype != 0) && (((unsigned)reg.offset) < script->size - 2));
if (relocation >= 0)
- sm_script_relocate(&s->seg_manager, make_reg(reg.segment, relocation));
+ s->seg_manager->scriptRelocate(make_reg(reg.segment, relocation));
- sm_script_free_unused_objects(&s->seg_manager, reg.segment);
+ s->seg_manager->scriptFreeUnusedObjects(reg.segment);
return reg.segment; // instantiation successful
}
-void sm_script_relocate_exports_sci11(SegManager *self, int seg);
-void sm_script_initialise_objects_sci11(SegManager *self, EngineState *s, int seg);
-void sm_heap_relocate(SegManager *self, EngineState *s, reg_t block);
-
int script_instantiate_sci11(EngineState *s, int script_nr) {
resource_t *script, *heap;
int seg_id;
@@ -1907,21 +1901,21 @@ int script_instantiate_sci11(EngineState *s, int script_nr) {
if (script->size & 2)
heap_start ++;
- sm_mcpy_in_out(&s->seg_manager, 0, script->data, script->size, seg_id, SEG_ID);
- sm_mcpy_in_out(&s->seg_manager, heap_start, heap->data, heap->size, seg_id, SEG_ID);
+ s->seg_manager->mcpyInOut(0, script->data, script->size, seg_id, SEG_ID);
+ s->seg_manager->mcpyInOut(heap_start, heap->data, heap->size, seg_id, SEG_ID);
if (getUInt16(script->data + 6) > 0)
- sm_set_export_table_offset(&s->seg_manager, 6, seg_id, SEG_ID);
+ s->seg_manager->setExportTableOffset(6, seg_id, SEG_ID);
reg.segment = seg_id;
reg.offset = heap_start + 4;
- sm_script_initialise_locals(&s->seg_manager, reg);
+ s->seg_manager->scriptInitialiseLocals(reg);
- sm_script_relocate_exports_sci11(&s->seg_manager, seg_id);
- sm_script_initialise_objects_sci11(&s->seg_manager, s, seg_id);
+ s->seg_manager->scriptRelocateExportsSci11(seg_id);
+ s->seg_manager->scriptInitialiseObjectsSci11(s, seg_id);
reg.offset = getUInt16(heap->data);
- sm_heap_relocate(&s->seg_manager, s, reg);
+ s->seg_manager->heapRelocate(s, reg);
return seg_id;
}
@@ -1933,8 +1927,6 @@ int script_instantiate(EngineState *s, int script_nr) {
return script_instantiate_sci0(s, script_nr);
}
-void sm_mark_script_deleted(SegManager* self, int script_nr);
-
void script_uninstantiate_sci0(EngineState *s, int script_nr, seg_id_t seg) {
reg_t reg = make_reg(seg, (s->version < SCI_VERSION_FTU_NEW_SCRIPT_HEADER) ? 2 : 0);
int objtype, objlength;
@@ -1962,8 +1954,8 @@ void script_uninstantiate_sci0(EngineState *s, int script_nr, seg_id_t seg) {
int superclass_script = s->classtable[superclass].script;
if (superclass_script == script_nr) {
- if (sm_get_lockers(&s->seg_manager, reg.segment, SEG_ID))
- sm_decrement_lockers(&s->seg_manager, reg.segment, SEG_ID); // Decrease lockers if this is us ourselves
+ if (s->seg_manager->getLockers(reg.segment, SEG_ID))
+ s->seg_manager->decrementLockers(reg.segment, SEG_ID); // Decrease lockers if this is us ourselves
} else
script_uninstantiate(s, superclass_script);
// Recurse to assure that the superclass lockers number gets decreased
@@ -1981,17 +1973,17 @@ void script_uninstantiate(EngineState *s, int script_nr) {
reg_t reg = make_reg(0, (s->version < SCI_VERSION_FTU_NEW_SCRIPT_HEADER) ? 2 : 0);
int i;
- reg.segment = sm_seg_get(&s->seg_manager, script_nr);
+ reg.segment = s->seg_manager->segGet(script_nr);
- if (!sm_script_is_loaded(&s->seg_manager, script_nr, SCRIPT_ID) || reg.segment <= 0) { // Is it already loaded?
+ if (!s->seg_manager->scriptIsLoaded(script_nr, SCRIPT_ID) || reg.segment <= 0) { // Is it already loaded?
//sciprintf("Warning: unloading script 0x%x requested although not loaded\n", script_nr);
// This is perfectly valid SCI behaviour
return;
}
- sm_decrement_lockers(&s->seg_manager, reg.segment, SEG_ID); // One less locker
+ s->seg_manager->decrementLockers(reg.segment, SEG_ID); // One less locker
- if (sm_get_lockers(&s->seg_manager, reg.segment, SEG_ID) > 0)
+ if (s->seg_manager->getLockers(reg.segment, SEG_ID) > 0)
return;
// Free all classtable references to this script
@@ -2004,12 +1996,12 @@ void script_uninstantiate(EngineState *s, int script_nr) {
else
sciprintf("FIXME: Add proper script uninstantiation for SCI 1.1\n");
- if (sm_get_lockers(&s->seg_manager, reg.segment, SEG_ID))
+ if (s->seg_manager->getLockers(reg.segment, SEG_ID))
return; // if xxx.lockers > 0
// Otherwise unload it completely
// Explanation: I'm starting to believe that this work is done by SCI itself.
- sm_mark_script_deleted(&s->seg_manager, script_nr);
+ s->seg_manager->markScriptDeleted(script_nr);
if (script_checkloads_flag)
sciprintf("Unloaded script 0x%x.\n", script_nr);
@@ -2130,7 +2122,7 @@ int game_restore(EngineState **_s, char *game_name) {
#endif
object_t *obj_get(EngineState *s, reg_t offset) {
- mem_obj_t *memobj = GET_OBJECT_SEGMENT(s->seg_manager, offset.segment);
+ mem_obj_t *memobj = GET_OBJECT_SEGMENT(*s->seg_manager, offset.segment);
object_t *obj = NULL;
int idx;
diff --git a/engines/sci/include/engine.h b/engines/sci/include/engine.h
index 5c2ace7ee0..8265088b89 100644
--- a/engines/sci/include/engine.h
+++ b/engines/sci/include/engine.h
@@ -234,7 +234,7 @@ struct EngineState {
int classtable_size; /* Number of classes in the table- for debugging */
class_t *classtable; /* Table of all classes */
- SegManager seg_manager;
+ SegManager *seg_manager;
int gc_countdown; /* Number of kernel calls until next gc */
int selector_names_nr; /* Number of selector names */
diff --git a/engines/sci/include/vm.h b/engines/sci/include/vm.h
index 05585632e8..6362c2f072 100644
--- a/engines/sci/include/vm.h
+++ b/engines/sci/include/vm.h
@@ -256,8 +256,23 @@ struct dynmem_t {
byte *buf;
}; /* Free-style memory */
+enum memObjType {
+ MEM_OBJ_INVALID = 0,
+ MEM_OBJ_SCRIPT = 1,
+ MEM_OBJ_CLONES = 2,
+ MEM_OBJ_LOCALS = 3,
+ MEM_OBJ_STACK = 4,
+ MEM_OBJ_SYS_STRINGS = 5,
+ MEM_OBJ_LISTS = 6,
+ MEM_OBJ_NODES = 7,
+ MEM_OBJ_HUNK = 8,
+ MEM_OBJ_DYNMEM = 9,
+ MEM_OBJ_RESERVED = 10,
+ MEM_OBJ_MAX = MEM_OBJ_RESERVED // For sanity checking
+};
+
struct mem_obj_t {
- int type;
+ memObjType type;
int segmgr_id; /* Internal value used by the seg_manager's hash map */
union {
script_t script;