mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-30 23:43:10 +00:00
SCI: Completed transition from MemObject (a union of various structs) to MemObjectNEW (a baseclass for these structs)
svn-id: r40294
This commit is contained in:
parent
82f2672008
commit
d960c1e2a5
@ -123,7 +123,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
|
||||
for (i = 1; i < sm->_heap.size(); i++)
|
||||
if (interfaces[i]
|
||||
&& interfaces[i]->getType() == MEM_OBJ_SCRIPT) {
|
||||
Script *script = &(interfaces[i]->getMobj()->data.script);
|
||||
Script *script = (Script *)(interfaces[i]->getMobj());
|
||||
|
||||
if (script->lockers) { // Explicitly loaded?
|
||||
int obj_nr;
|
||||
|
@ -674,10 +674,10 @@ int determine_reg_type(EngineState *s, reg_t reg, int allow_invalid) {
|
||||
|
||||
switch (mobj->getType()) {
|
||||
case MEM_OBJ_SCRIPT:
|
||||
if (reg.offset <= mobj->data.script.buf_size && reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET
|
||||
&& RAW_IS_OBJECT(mobj->data.script.buf + reg.offset)) {
|
||||
int idx = RAW_GET_CLASS_INDEX(&(mobj->data.script), reg);
|
||||
if (idx >= 0 && idx < mobj->data.script.objects_nr)
|
||||
if (reg.offset <= (*(Script *)mobj).buf_size && reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET
|
||||
&& RAW_IS_OBJECT((*(Script *)mobj).buf + reg.offset)) {
|
||||
int idx = RAW_GET_CLASS_INDEX((Script *)mobj, reg);
|
||||
if (idx >= 0 && idx < (*(Script *)mobj).objects_nr)
|
||||
return KSIG_OBJECT;
|
||||
else
|
||||
return KSIG_REF;
|
||||
@ -691,20 +691,20 @@ int determine_reg_type(EngineState *s, reg_t reg, int allow_invalid) {
|
||||
return KSIG_OBJECT | KSIG_INVALID;
|
||||
|
||||
case MEM_OBJ_LOCALS:
|
||||
if (allow_invalid || reg.offset < mobj->data.locals.nr * sizeof(reg_t))
|
||||
if (allow_invalid || reg.offset < (*(LocalVariables *)mobj).nr * sizeof(reg_t))
|
||||
return KSIG_REF;
|
||||
else
|
||||
return KSIG_REF | KSIG_INVALID;
|
||||
|
||||
case MEM_OBJ_STACK:
|
||||
if (allow_invalid || reg.offset < mobj->data.stack.nr * sizeof(reg_t))
|
||||
if (allow_invalid || reg.offset < (*(dstack_t *)mobj).nr * sizeof(reg_t))
|
||||
return KSIG_REF;
|
||||
else
|
||||
return KSIG_REF | KSIG_INVALID;
|
||||
|
||||
case MEM_OBJ_SYS_STRINGS:
|
||||
if (allow_invalid || (reg.offset < SYS_STRINGS_MAX
|
||||
&& mobj->data.sys_strings.strings[reg.offset].name))
|
||||
&& (*(SystemStrings *)mobj).strings[reg.offset].name))
|
||||
return KSIG_REF;
|
||||
else
|
||||
return KSIG_REF | KSIG_INVALID;
|
||||
@ -722,7 +722,7 @@ int determine_reg_type(EngineState *s, reg_t reg, int allow_invalid) {
|
||||
return KSIG_NODE | KSIG_INVALID;
|
||||
|
||||
case MEM_OBJ_DYNMEM:
|
||||
if (allow_invalid || reg.offset < mobj->data.dynmem.size)
|
||||
if (allow_invalid || reg.offset < (*(DynMem *)mobj).size)
|
||||
return KSIG_REF;
|
||||
else
|
||||
return KSIG_REF | KSIG_INVALID;
|
||||
|
@ -428,63 +428,62 @@ static void sync_songlib_t(Common::Serializer &s, songlib_t &obj) {
|
||||
}
|
||||
}
|
||||
|
||||
static void sync_MemObjPtr(Common::Serializer &s, MemObject *&obj) {
|
||||
static void sync_MemObjPtr(Common::Serializer &s, MemObject *&mobj) {
|
||||
// Sync the memobj type
|
||||
memObjType type = (s.isSaving() && obj) ? obj->getType() : MEM_OBJ_INVALID;
|
||||
MemObjectType type = (s.isSaving() && mobj) ? mobj->getType() : MEM_OBJ_INVALID;
|
||||
s.syncAsUint32LE(type);
|
||||
|
||||
// If we were saving and obj == 0, or if we are loading and this is an
|
||||
// If we were saving and mobj == 0, or if we are loading and this is an
|
||||
// entry marked as empty -> we are done.
|
||||
if (type == MEM_OBJ_INVALID) {
|
||||
obj = 0;
|
||||
mobj = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (s.isLoading()) {
|
||||
//assert(!obj);
|
||||
obj = (MemObject *)sci_calloc(1, sizeof(MemObject));
|
||||
obj->data.tmp_dummy._type = type;
|
||||
//assert(!mobj);
|
||||
mobj = MemObject::createMemObject(type);
|
||||
} else {
|
||||
assert(obj);
|
||||
assert(mobj);
|
||||
}
|
||||
|
||||
s.syncAsSint32LE(obj->data.tmp_dummy._segmgrId);
|
||||
s.syncAsSint32LE(mobj->_segmgrId);
|
||||
switch (type) {
|
||||
case MEM_OBJ_SCRIPT:
|
||||
sync_Script(s, obj->data.script);
|
||||
sync_Script(s, *(Script *)mobj);
|
||||
break;
|
||||
case MEM_OBJ_CLONES:
|
||||
sync_CloneTable(s, obj->data.clones);
|
||||
sync_CloneTable(s, *(CloneTable *)mobj);
|
||||
break;
|
||||
case MEM_OBJ_LOCALS:
|
||||
sync_LocalVariables(s, obj->data.locals);
|
||||
sync_LocalVariables(s, *(LocalVariables *)mobj);
|
||||
break;
|
||||
case MEM_OBJ_SYS_STRINGS:
|
||||
sync_SystemStrings(s, obj->data.sys_strings);
|
||||
sync_SystemStrings(s, *(SystemStrings *)mobj);
|
||||
break;
|
||||
case MEM_OBJ_STACK:
|
||||
// TODO: Switch this stack to use class Common::Stack?
|
||||
s.syncAsUint32LE(obj->data.stack.nr);
|
||||
s.syncAsUint32LE((*(dstack_t *)mobj).nr);
|
||||
if (s.isLoading()) {
|
||||
//free(obj->data.stack.entries);
|
||||
obj->data.stack.entries = (reg_t *)sci_calloc(obj->data.stack.nr, sizeof(reg_t));
|
||||
//free((*(dstack_t *)mobj).entries);
|
||||
(*(dstack_t *)mobj).entries = (reg_t *)sci_calloc((*(dstack_t *)mobj).nr, sizeof(reg_t));
|
||||
}
|
||||
break;
|
||||
case MEM_OBJ_HUNK:
|
||||
if (s.isLoading()) {
|
||||
obj->data.hunks.initTable();
|
||||
(*(HunkTable *)mobj).initTable();
|
||||
}
|
||||
break;
|
||||
case MEM_OBJ_STRING_FRAG:
|
||||
break;
|
||||
case MEM_OBJ_LISTS:
|
||||
sync_ListTable(s, obj->data.lists);
|
||||
sync_ListTable(s, *(ListTable *)mobj);
|
||||
break;
|
||||
case MEM_OBJ_NODES:
|
||||
sync_NodeTable(s, obj->data.nodes);
|
||||
sync_NodeTable(s, *(NodeTable *)mobj);
|
||||
break;
|
||||
case MEM_OBJ_DYNMEM:
|
||||
sync_DynMem(s, obj->data.dynmem);
|
||||
sync_DynMem(s, *(DynMem *)mobj);
|
||||
break;
|
||||
default:
|
||||
error("Unknown MemObject type %d", type);
|
||||
@ -564,7 +563,7 @@ static byte *find_unique_script_block(EngineState *s, byte *buf, int type) {
|
||||
// FIXME: This should probably be turned into an EngineState method
|
||||
static void reconstruct_stack(EngineState *retval) {
|
||||
SegmentId stack_seg = find_unique_seg_by_type(retval->seg_manager, MEM_OBJ_STACK);
|
||||
dstack_t *stack = &(retval->seg_manager->_heap[stack_seg]->data.stack);
|
||||
dstack_t *stack = (dstack_t *)(retval->seg_manager->_heap[stack_seg]);
|
||||
|
||||
retval->stack_segment = stack_seg;
|
||||
retval->stack_base = stack->entries;
|
||||
@ -589,7 +588,7 @@ static int clone_entry_used(CloneTable *table, int n) {
|
||||
|
||||
static void load_script(EngineState *s, SegmentId seg) {
|
||||
Resource *script, *heap = NULL;
|
||||
Script *scr = &(s->seg_manager->_heap[seg]->data.script);
|
||||
Script *scr = (Script *)(s->seg_manager->_heap[seg]);
|
||||
|
||||
scr->buf = (byte *)malloc(scr->buf_size);
|
||||
|
||||
@ -618,10 +617,10 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
|
||||
switch (mobj->getType()) {
|
||||
case MEM_OBJ_SCRIPT: {
|
||||
int j;
|
||||
Script *scr = &mobj->data.script;
|
||||
Script *scr = (Script *)mobj;
|
||||
|
||||
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 : (LocalVariables *)(s->seg_manager->_heap[scr->locals_segment]);
|
||||
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;
|
||||
@ -650,7 +649,7 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
|
||||
switch (mobj->getType()) {
|
||||
case MEM_OBJ_SCRIPT: {
|
||||
int j;
|
||||
Script *scr = &mobj->data.script;
|
||||
Script *scr = (Script *)mobj;
|
||||
|
||||
for (j = 0; j < scr->objects_nr; j++) {
|
||||
byte *data = scr->buf + scr->objects[j].pos.offset;
|
||||
@ -699,27 +698,27 @@ static void reconstruct_clones(EngineState *s, SegManager *self) {
|
||||
switch (mobj->getType()) {
|
||||
case MEM_OBJ_CLONES: {
|
||||
int j;
|
||||
CloneTable::Entry *seeker = mobj->data.clones.table;
|
||||
CloneTable::Entry *seeker = (*(CloneTable *)mobj).table;
|
||||
|
||||
/*
|
||||
sciprintf("Free list: ");
|
||||
for (j = mobj->data.clones.first_free; j != HEAPENTRY_INVALID; j = mobj->data.clones.table[j].next_free) {
|
||||
for (j = (*(CloneTable *)mobj).first_free; j != HEAPENTRY_INVALID; j = (*(CloneTable *)mobj).table[j].next_free) {
|
||||
sciprintf("%d ", j);
|
||||
}
|
||||
sciprintf("\n");
|
||||
|
||||
sciprintf("Entries w/zero vars: ");
|
||||
for (j = 0; j < mobj->data.clones.max_entry; j++) {
|
||||
if (mobj->data.clones.table[j].variables == NULL)
|
||||
for (j = 0; j < (*(CloneTable *)mobj).max_entry; j++) {
|
||||
if ((*(CloneTable *)mobj).table[j].variables == NULL)
|
||||
sciprintf("%d ", j);
|
||||
}
|
||||
sciprintf("\n");
|
||||
*/
|
||||
|
||||
for (j = 0; j < mobj->data.clones.max_entry; j++) {
|
||||
for (j = 0; j < (*(CloneTable *)mobj).max_entry; j++) {
|
||||
Object *base_obj;
|
||||
|
||||
if (!clone_entry_used(&mobj->data.clones, j)) {
|
||||
if (!clone_entry_used(&(*(CloneTable *)mobj), j)) {
|
||||
seeker++;
|
||||
continue;
|
||||
}
|
||||
@ -858,12 +857,12 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
|
||||
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->getScript(script_get_segment(s, 0, SCRIPT_GET_DONT_LOAD), SEG_ID);
|
||||
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 = &(((MemObject *)(GET_SEGMENT(*retval->seg_manager, retval->sys_strings_segment, MEM_OBJ_SYS_STRINGS)))->data.sys_strings);
|
||||
retval->sys_strings = (SystemStrings *)GET_SEGMENT(*retval->seg_manager, retval->sys_strings_segment, MEM_OBJ_SYS_STRINGS);
|
||||
|
||||
// Restore system strings
|
||||
SystemString *str;
|
||||
|
@ -293,19 +293,19 @@ int c_segtable(EngineState *s) {
|
||||
|
||||
switch (mobj->getType()) {
|
||||
case MEM_OBJ_SCRIPT:
|
||||
sciprintf("S script.%03d l:%d ", mobj->data.script.nr, mobj->data.script.lockers);
|
||||
sciprintf("S script.%03d l:%d ", (*(Script *)mobj).nr, (*(Script *)mobj).lockers);
|
||||
break;
|
||||
|
||||
case MEM_OBJ_CLONES:
|
||||
sciprintf("C clones (%d allocd)", mobj->data.clones.entries_used);
|
||||
sciprintf("C clones (%d allocd)", (*(CloneTable *)mobj).entries_used);
|
||||
break;
|
||||
|
||||
case MEM_OBJ_LOCALS:
|
||||
sciprintf("V locals %03d", mobj->data.locals.script_id);
|
||||
sciprintf("V locals %03d", (*(LocalVariables *)mobj).script_id);
|
||||
break;
|
||||
|
||||
case MEM_OBJ_STACK:
|
||||
sciprintf("D data stack (%d)", mobj->data.stack.nr);
|
||||
sciprintf("D data stack (%d)", (*(dstack_t *)mobj).nr);
|
||||
break;
|
||||
|
||||
case MEM_OBJ_SYS_STRINGS:
|
||||
@ -313,19 +313,19 @@ int c_segtable(EngineState *s) {
|
||||
break;
|
||||
|
||||
case MEM_OBJ_LISTS:
|
||||
sciprintf("L lists (%d)", mobj->data.lists.entries_used);
|
||||
sciprintf("L lists (%d)", (*(ListTable *)mobj).entries_used);
|
||||
break;
|
||||
|
||||
case MEM_OBJ_NODES:
|
||||
sciprintf("N nodes (%d)", mobj->data.nodes.entries_used);
|
||||
sciprintf("N nodes (%d)", (*(NodeTable *)mobj).entries_used);
|
||||
break;
|
||||
|
||||
case MEM_OBJ_HUNK:
|
||||
sciprintf("H hunk (%d)", mobj->data.hunks.entries_used);
|
||||
sciprintf("H hunk (%d)", (*(HunkTable *)mobj).entries_used);
|
||||
break;
|
||||
|
||||
case MEM_OBJ_DYNMEM:
|
||||
sciprintf("M dynmem: %d bytes", mobj->data.dynmem.size);
|
||||
sciprintf("M dynmem: %d bytes", (*(DynMem *)mobj).size);
|
||||
break;
|
||||
|
||||
case MEM_OBJ_STRING_FRAG:
|
||||
@ -360,13 +360,13 @@ static void print_list(EngineState *s, List *l) {
|
||||
Node *node;
|
||||
MemObject *mobj = GET_SEGMENT(*s->seg_manager, pos.segment, MEM_OBJ_NODES);
|
||||
|
||||
if (!mobj || !ENTRY_IS_VALID(&(mobj->data.nodes), pos.offset)) {
|
||||
if (!mobj || !ENTRY_IS_VALID((NodeTable *)mobj, pos.offset)) {
|
||||
sciprintf(" WARNING: "PREG": Doesn't contain list node!\n",
|
||||
PRINT_REG(pos));
|
||||
return;
|
||||
}
|
||||
|
||||
node = &(mobj->data.nodes.table[pos.offset]);
|
||||
node = &((*(NodeTable *)mobj).table[pos.offset]);
|
||||
|
||||
sciprintf("\t"PREG" : "PREG" -> "PREG"\n", PRINT_REG(pos), PRINT_REG(node->key), PRINT_REG(node->value));
|
||||
|
||||
@ -389,7 +389,7 @@ static void _c_single_seg_info(EngineState *s, MemObject *mobj) {
|
||||
|
||||
case MEM_OBJ_SCRIPT: {
|
||||
int i;
|
||||
Script *scr = &(mobj->data.script);
|
||||
Script *scr = (Script *)mobj;
|
||||
sciprintf("script.%03d locked by %d, bufsize=%d (%x)\n", scr->nr, scr->lockers, (uint)scr->buf_size, (uint)scr->buf_size);
|
||||
if (scr->export_table)
|
||||
sciprintf(" Exports: %4d at %d\n", scr->exports_nr, (int)(((byte *)scr->export_table) - ((byte *)scr->buf)));
|
||||
@ -412,14 +412,14 @@ static void _c_single_seg_info(EngineState *s, MemObject *mobj) {
|
||||
break;
|
||||
|
||||
case MEM_OBJ_LOCALS: {
|
||||
LocalVariables *locals = &(mobj->data.locals);
|
||||
LocalVariables *locals = (LocalVariables *)mobj;
|
||||
sciprintf("locals for script.%03d\n", locals->script_id);
|
||||
sciprintf(" %d (0x%x) locals\n", locals->nr, locals->nr);
|
||||
}
|
||||
break;
|
||||
|
||||
case MEM_OBJ_STACK: {
|
||||
dstack_t *stack = &(mobj->data.stack);
|
||||
dstack_t *stack = (dstack_t *)mobj;
|
||||
sciprintf("stack\n");
|
||||
sciprintf(" %d (0x%x) entries\n", stack->nr, stack->nr);
|
||||
}
|
||||
@ -439,7 +439,7 @@ static void _c_single_seg_info(EngineState *s, MemObject *mobj) {
|
||||
|
||||
case MEM_OBJ_CLONES: {
|
||||
int i = 0;
|
||||
CloneTable *ct = &(mobj->data.clones);
|
||||
CloneTable *ct = (CloneTable *)mobj;
|
||||
|
||||
sciprintf("clones\n");
|
||||
|
||||
@ -453,7 +453,7 @@ static void _c_single_seg_info(EngineState *s, MemObject *mobj) {
|
||||
|
||||
case MEM_OBJ_LISTS: {
|
||||
int i = 0;
|
||||
ListTable *lt = &(mobj->data.lists);
|
||||
ListTable *lt = (ListTable *)mobj;
|
||||
|
||||
sciprintf("lists\n");
|
||||
for (i = 0; i < lt->max_entry; i++)
|
||||
@ -465,15 +465,15 @@ static void _c_single_seg_info(EngineState *s, MemObject *mobj) {
|
||||
break;
|
||||
|
||||
case MEM_OBJ_NODES: {
|
||||
sciprintf("nodes (total %d)\n", mobj->data.nodes.entries_used);
|
||||
sciprintf("nodes (total %d)\n", (*(NodeTable *)mobj).entries_used);
|
||||
break;
|
||||
}
|
||||
|
||||
case MEM_OBJ_HUNK: {
|
||||
int i;
|
||||
HunkTable *ht = &(mobj->data.hunks);
|
||||
HunkTable *ht = (HunkTable *)mobj;
|
||||
|
||||
sciprintf("hunk (total %d)\n", mobj->data.hunks.entries_used);
|
||||
sciprintf("hunk (total %d)\n", ht->entries_used);
|
||||
for (i = 0; i < ht->max_entry; i++)
|
||||
if (ENTRY_IS_VALID(ht, i)) {
|
||||
sciprintf(" [%04x] %d bytes at %p, type=%s\n",
|
||||
@ -483,9 +483,9 @@ static void _c_single_seg_info(EngineState *s, MemObject *mobj) {
|
||||
|
||||
case MEM_OBJ_DYNMEM: {
|
||||
sciprintf("dynmem (%s): %d bytes\n",
|
||||
mobj->data.dynmem.description ? mobj->data.dynmem.description : "no description", mobj->data.dynmem.size);
|
||||
(*(DynMem *)mobj).description ? (*(DynMem *)mobj).description : "no description", (*(DynMem *)mobj).size);
|
||||
|
||||
sci_hexdump(mobj->data.dynmem.buf, mobj->data.dynmem.size, 0);
|
||||
sci_hexdump((*(DynMem *)mobj).buf, (*(DynMem *)mobj).size, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -504,7 +504,7 @@ static int show_node(EngineState *s, reg_t addr) {
|
||||
MemObject *mobj = GET_SEGMENT(*s->seg_manager, addr.segment, MEM_OBJ_LISTS);
|
||||
|
||||
if (mobj) {
|
||||
ListTable *lt = &(mobj->data.lists);
|
||||
ListTable *lt = (ListTable *)mobj;
|
||||
List *list;
|
||||
|
||||
if (!ENTRY_IS_VALID(lt, addr.offset)) {
|
||||
@ -525,7 +525,7 @@ static int show_node(EngineState *s, reg_t addr) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
nt = &(mobj->data.nodes);
|
||||
nt = (NodeTable *)mobj;
|
||||
|
||||
if (!ENTRY_IS_VALID(nt, addr.offset)) {
|
||||
sciprintf("Address does not contain a node\n");
|
||||
@ -1212,7 +1212,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.
|
||||
MemObject *memobj = GET_SEGMENT(*s->seg_manager, pos.segment, MEM_OBJ_SCRIPT);
|
||||
MemObject *mobj = GET_SEGMENT(*s->seg_manager, pos.segment, MEM_OBJ_SCRIPT);
|
||||
Script *script_entity = NULL;
|
||||
byte *scr;
|
||||
int scr_size;
|
||||
@ -1223,11 +1223,11 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod
|
||||
int bytecount = 1;
|
||||
int i = 0;
|
||||
|
||||
if (!memobj) {
|
||||
if (!mobj) {
|
||||
sciprintf("Disassembly failed: Segment %04x non-existant or not a script\n", pos.segment);
|
||||
return retval;
|
||||
} else
|
||||
script_entity = &(memobj->data.script);
|
||||
script_entity = (Script *)mobj;
|
||||
|
||||
scr = script_entity->buf;
|
||||
scr_size = script_entity->buf_size;
|
||||
@ -1590,7 +1590,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", (*(Script *)s->seg_manager->_heap[call.addr.pc.segment]).nr);
|
||||
sciprintf("\n");
|
||||
}
|
||||
|
||||
@ -2558,7 +2558,7 @@ int objinfo(EngineState *s, reg_t pos) {
|
||||
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]->getType() == MEM_OBJ_SCRIPT)
|
||||
sciprintf("\nOwner script:\t%d\n", s->seg_manager->_heap[pos.segment]->data.script.nr);
|
||||
sciprintf("\nOwner script:\t%d\n", s->seg_manager->getScript(pos.segment, SEG_ID)->nr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2887,10 +2887,10 @@ void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t *
|
||||
}
|
||||
|
||||
if (_debug_seeking && !bp) { // Are we looking for something special?
|
||||
MemObject *memobj = GET_SEGMENT(*s->seg_manager, pc->segment, MEM_OBJ_SCRIPT);
|
||||
MemObject *mobj = GET_SEGMENT(*s->seg_manager, pc->segment, MEM_OBJ_SCRIPT);
|
||||
|
||||
if (memobj) {
|
||||
Script *scr = &(memobj->data.script);
|
||||
if (mobj) {
|
||||
Script *scr = (Script *)mobj;
|
||||
byte *code_buf = scr->buf;
|
||||
int code_buf_size = scr->buf_size;
|
||||
int opcode = pc->offset >= code_buf_size ? 0 : code_buf[pc->offset];
|
||||
|
@ -66,7 +66,7 @@ int SegManager::findFreeId(int *id) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
MemObject *SegManager::allocNonscriptSegment(memObjType type, SegmentId *segid) {
|
||||
MemObject *SegManager::allocNonscriptSegment(MemObjectType type, SegmentId *segid) {
|
||||
// Allocates a non-script segment
|
||||
int id;
|
||||
|
||||
@ -222,27 +222,27 @@ int SegManager::deallocate(int seg, bool recursive) {
|
||||
|
||||
switch (mobj->getType()) {
|
||||
case MEM_OBJ_SCRIPT:
|
||||
freeScript(mobj->data.script);
|
||||
freeScript((*(Script *)mobj));
|
||||
|
||||
mobj->data.script.buf = NULL;
|
||||
if (recursive && mobj->data.script.locals_segment)
|
||||
deallocate(mobj->data.script.locals_segment, recursive);
|
||||
(*(Script *)mobj).buf = NULL;
|
||||
if (recursive && (*(Script *)mobj).locals_segment)
|
||||
deallocate((*(Script *)mobj).locals_segment, recursive);
|
||||
break;
|
||||
|
||||
case MEM_OBJ_LOCALS:
|
||||
free(mobj->data.locals.locals);
|
||||
mobj->data.locals.locals = NULL;
|
||||
free((*(LocalVariables *)mobj).locals);
|
||||
(*(LocalVariables *)mobj).locals = NULL;
|
||||
break;
|
||||
|
||||
case MEM_OBJ_DYNMEM:
|
||||
free(mobj->data.dynmem.description);
|
||||
mobj->data.dynmem.description = NULL;
|
||||
free(mobj->data.dynmem.buf);
|
||||
mobj->data.dynmem.buf = NULL;
|
||||
free((*(DynMem *)mobj).description);
|
||||
(*(DynMem *)mobj).description = NULL;
|
||||
free((*(DynMem *)mobj).buf);
|
||||
(*(DynMem *)mobj).buf = NULL;
|
||||
break;
|
||||
case MEM_OBJ_SYS_STRINGS:
|
||||
for (i = 0; i < SYS_STRINGS_MAX; i++) {
|
||||
SystemString *str = &mobj->data.sys_strings.strings[i];
|
||||
SystemString *str = &(*(SystemStrings *)mobj).strings[i];
|
||||
if (str->name) {
|
||||
free(str->name);
|
||||
str->name = NULL;
|
||||
@ -255,28 +255,28 @@ int SegManager::deallocate(int seg, bool recursive) {
|
||||
}
|
||||
break;
|
||||
case MEM_OBJ_STACK:
|
||||
free(mobj->data.stack.entries);
|
||||
mobj->data.stack.entries = NULL;
|
||||
free((*(dstack_t *)mobj).entries);
|
||||
(*(dstack_t *)mobj).entries = NULL;
|
||||
break;
|
||||
case MEM_OBJ_LISTS:
|
||||
free(mobj->data.lists.table);
|
||||
mobj->data.lists.table = NULL;
|
||||
mobj->data.lists.entries_nr = mobj->data.lists.max_entry = 0;
|
||||
free((*(ListTable *)mobj).table);
|
||||
(*(ListTable *)mobj).table = NULL;
|
||||
(*(ListTable *)mobj).entries_nr = (*(ListTable *)mobj).max_entry = 0;
|
||||
break;
|
||||
case MEM_OBJ_NODES:
|
||||
free(mobj->data.nodes.table);
|
||||
mobj->data.nodes.table = NULL;
|
||||
mobj->data.nodes.entries_nr = mobj->data.nodes.max_entry = 0;
|
||||
free((*(NodeTable *)mobj).table);
|
||||
(*(NodeTable *)mobj).table = NULL;
|
||||
(*(NodeTable *)mobj).entries_nr = (*(NodeTable *)mobj).max_entry = 0;
|
||||
break;
|
||||
case MEM_OBJ_CLONES:
|
||||
free(mobj->data.clones.table);
|
||||
mobj->data.clones.table = NULL;
|
||||
mobj->data.clones.entries_nr = mobj->data.clones.max_entry = 0;
|
||||
free((*(CloneTable *)mobj).table);
|
||||
(*(CloneTable *)mobj).table = NULL;
|
||||
(*(CloneTable *)mobj).entries_nr = (*(CloneTable *)mobj).max_entry = 0;
|
||||
break;
|
||||
case MEM_OBJ_HUNK:
|
||||
free(mobj->data.hunks.table);
|
||||
mobj->data.hunks.table = NULL;
|
||||
mobj->data.hunks.entries_nr = mobj->data.hunks.max_entry = 0;
|
||||
free((*(HunkTable *)mobj).table);
|
||||
(*(HunkTable *)mobj).table = NULL;
|
||||
(*(HunkTable *)mobj).entries_nr = (*(HunkTable *)mobj).max_entry = 0;
|
||||
break;
|
||||
case MEM_OBJ_STRING_FRAG:
|
||||
break;
|
||||
@ -284,7 +284,7 @@ int SegManager::deallocate(int seg, bool recursive) {
|
||||
error("Deallocating segment type %d not supported", mobj->getType());
|
||||
}
|
||||
|
||||
free(mobj);
|
||||
delete mobj;
|
||||
_heap[seg] = NULL;
|
||||
|
||||
return 1;
|
||||
@ -314,7 +314,7 @@ int SegManager::scriptIsMarkedAsDeleted(SegmentId seg) {
|
||||
if (_heap[seg]->getType() != MEM_OBJ_SCRIPT)
|
||||
return 0;
|
||||
|
||||
scr = &(_heap[seg]->data.script);
|
||||
scr = (Script *)_heap[seg];
|
||||
|
||||
return scr->marked_as_deleted;
|
||||
}
|
||||
@ -328,10 +328,53 @@ int SegManager::deallocateScript(int script_nr) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
MemObject *SegManager::memObjAllocate(SegmentId segid, int hash_id, memObjType type) {
|
||||
MemObject *mem = (MemObject *)sci_calloc(1, sizeof(MemObject));
|
||||
MemObject *MemObject::createMemObject(MemObjectType type) {
|
||||
MemObject *mem = 0;
|
||||
switch (type) {
|
||||
case MEM_OBJ_SCRIPT:
|
||||
mem = new Script();
|
||||
break;
|
||||
case MEM_OBJ_CLONES:
|
||||
mem = new CloneTable();
|
||||
break;
|
||||
case MEM_OBJ_LOCALS:
|
||||
mem = new LocalVariables();
|
||||
break;
|
||||
case MEM_OBJ_SYS_STRINGS:
|
||||
mem = new SystemStrings();
|
||||
break;
|
||||
case MEM_OBJ_STACK:
|
||||
mem = new dstack_t();
|
||||
break;
|
||||
case MEM_OBJ_HUNK:
|
||||
mem = new HunkTable();
|
||||
break;
|
||||
case MEM_OBJ_STRING_FRAG:
|
||||
mem = new MemObject(); // FIXME: This is a temporary hack until MEM_OBJ_STRING_FRAG is implemented
|
||||
break;
|
||||
case MEM_OBJ_LISTS:
|
||||
mem = new ListTable();
|
||||
break;
|
||||
case MEM_OBJ_NODES:
|
||||
mem = new NodeTable();
|
||||
break;
|
||||
case MEM_OBJ_DYNMEM:
|
||||
mem = new DynMem();
|
||||
break;
|
||||
default:
|
||||
error("Unknown MemObject type %d", type);
|
||||
break;
|
||||
}
|
||||
|
||||
assert(mem);
|
||||
mem->_type = type;
|
||||
return mem;
|
||||
}
|
||||
|
||||
MemObject *SegManager::memObjAllocate(SegmentId segid, int hash_id, MemObjectType type) {
|
||||
MemObject *mem = MemObject::createMemObject(type);
|
||||
if (!mem) {
|
||||
sciprintf("SegManager: invalid mem_obj ");
|
||||
sciprintf("SegManager: invalid mobj ");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -343,22 +386,13 @@ MemObject *SegManager::memObjAllocate(SegmentId segid, int hash_id, memObjType t
|
||||
_heap.resize(_heap.size() * 2);
|
||||
}
|
||||
|
||||
mem->data.tmp_dummy._segmgrId = hash_id;
|
||||
mem->data.tmp_dummy._type = type;
|
||||
mem->_segmgrId = hash_id;
|
||||
|
||||
// hook it to the heap
|
||||
_heap[segid] = mem;
|
||||
return mem;
|
||||
}
|
||||
|
||||
/* No longer in use?
|
||||
void SegManager::sm_object_init(Object *object) {
|
||||
if (!object)
|
||||
return;
|
||||
object->variables_nr = 0;
|
||||
object->variables = NULL;
|
||||
};*/
|
||||
|
||||
void SegManager::freeScript(Script &scr) {
|
||||
if (scr.buf) {
|
||||
free(scr.buf);
|
||||
@ -395,17 +429,19 @@ void SegManager::mcpyInOut(int dst, const void *src, size_t n, int id, idFlag fl
|
||||
}
|
||||
|
||||
int16 SegManager::getHeap(reg_t reg) {
|
||||
MemObject *mem_obj;
|
||||
MemObject *mobj;
|
||||
Script *scr;
|
||||
|
||||
VERIFY(check(reg.segment), "Invalid seg id");
|
||||
mem_obj = _heap[reg.segment];
|
||||
mobj = _heap[reg.segment];
|
||||
|
||||
switch (mem_obj->getType()) {
|
||||
switch (mobj->getType()) {
|
||||
case MEM_OBJ_SCRIPT:
|
||||
VERIFY(reg.offset + 1 < (uint16)mem_obj->data.script.buf_size, "invalid offset\n");
|
||||
return (mem_obj->data.script.buf[reg.offset] | (mem_obj->data.script.buf[reg.offset+1]) << 8);
|
||||
scr = (Script *)mobj;
|
||||
VERIFY(reg.offset + 1 < (uint16)scr->buf_size, "invalid offset\n");
|
||||
return (scr->buf[reg.offset] | (scr->buf[reg.offset+1]) << 8);
|
||||
default:
|
||||
error("SegManager::getHeap: unsupported mem obj type %d", mem_obj->getType());
|
||||
error("SegManager::getHeap: unsupported mem obj type %d", mobj->getType());
|
||||
break;
|
||||
}
|
||||
return 0; // never get here
|
||||
@ -428,7 +464,7 @@ Script *SegManager::getScript(const int id, idFlag flag) {
|
||||
if (_heap[seg]->getType() != MEM_OBJ_SCRIPT) {
|
||||
error("SegManager::getScript(%d,%d): seg id %x refers to type %d != MEM_OBJ_SCRIPT", id, flag, seg, _heap[seg]->getType());
|
||||
}
|
||||
return &(_heap[seg]->data.script);
|
||||
return (Script *)_heap[seg];
|
||||
}
|
||||
|
||||
// validate the seg
|
||||
@ -528,7 +564,7 @@ int SegManager::relocateBlock(reg_t *block, int block_location, int block_items,
|
||||
}
|
||||
block[index].segment = segment; // Perform relocation
|
||||
if (isSci1_1)
|
||||
block[index].offset += _heap[segment]->data.script.script_size;
|
||||
block[index].offset += getScript(segment, SEG_ID)->script_size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -791,11 +827,11 @@ LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) {
|
||||
mobj = _heap[scr->locals_segment];
|
||||
VERIFY(mobj != NULL, "Re-used locals segment was NULL'd out");
|
||||
VERIFY(mobj->getType() == 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");
|
||||
VERIFY((*(LocalVariables *)mobj).script_id == scr->nr, "Re-used locals segment belonged to other script");
|
||||
} else
|
||||
mobj = allocNonscriptSegment(MEM_OBJ_LOCALS, &scr->locals_segment);
|
||||
|
||||
locals = scr->locals_block = &(mobj->data.locals);
|
||||
locals = scr->locals_block = (LocalVariables *)mobj;
|
||||
locals->script_id = scr->nr;
|
||||
locals->locals = (reg_t *)sci_calloc(count, sizeof(reg_t));
|
||||
locals->nr = count;
|
||||
@ -933,8 +969,8 @@ static char *SegManager::dynprintf(char *msg, ...) {
|
||||
*/
|
||||
|
||||
dstack_t *SegManager::allocateStack(int size, SegmentId *segid) {
|
||||
MemObject *memobj = allocNonscriptSegment(MEM_OBJ_STACK, segid);
|
||||
dstack_t *retval = &(memobj->data.stack);
|
||||
MemObject *mobj = allocNonscriptSegment(MEM_OBJ_STACK, segid);
|
||||
dstack_t *retval = (dstack_t *)mobj;
|
||||
|
||||
retval->entries = (reg_t *)sci_calloc(size, sizeof(reg_t));
|
||||
retval->nr = size;
|
||||
@ -943,8 +979,8 @@ dstack_t *SegManager::allocateStack(int size, SegmentId *segid) {
|
||||
}
|
||||
|
||||
SystemStrings *SegManager::allocateSysStrings(SegmentId *segid) {
|
||||
MemObject *memobj = allocNonscriptSegment(MEM_OBJ_SYS_STRINGS, segid);
|
||||
SystemStrings *retval = &(memobj->data.sys_strings);
|
||||
MemObject *mobj = allocNonscriptSegment(MEM_OBJ_SYS_STRINGS, segid);
|
||||
SystemStrings *retval = (SystemStrings *)mobj;
|
||||
|
||||
memset(retval->strings, 0, sizeof(retval->strings));
|
||||
|
||||
@ -982,7 +1018,7 @@ void SegManager::free_hunk_entry(reg_t addr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sci::free_Hunk_entry(&(mobj->data.hunks), addr.offset);
|
||||
Sci::free_Hunk_entry((HunkTable *)mobj, addr.offset);
|
||||
}
|
||||
|
||||
Hunk *SegManager::alloc_hunk_entry(const char *hunk_type, int size, reg_t *reg) {
|
||||
@ -1052,11 +1088,11 @@ Clone *SegManager::alloc_Clone(reg_t *addr) {
|
||||
|
||||
if (!Clones_seg_id) {
|
||||
mobj = allocNonscriptSegment(MEM_OBJ_CLONES, &(Clones_seg_id));
|
||||
mobj->data.clones.initTable();
|
||||
(*(CloneTable *)mobj).initTable();
|
||||
} else
|
||||
mobj = _heap[Clones_seg_id];
|
||||
|
||||
table = &(mobj->data.clones);
|
||||
table = (CloneTable *)mobj;
|
||||
offset = table->allocEntry();
|
||||
|
||||
*addr = make_reg(Clones_seg_id, offset);
|
||||
@ -1070,11 +1106,11 @@ List *SegManager::alloc_List(reg_t *addr) {
|
||||
|
||||
if (!Lists_seg_id) {
|
||||
mobj = allocNonscriptSegment(MEM_OBJ_LISTS, &(Lists_seg_id));
|
||||
mobj->data.lists.initTable();
|
||||
(*(ListTable *)mobj).initTable();
|
||||
} else
|
||||
mobj = _heap[Lists_seg_id];
|
||||
|
||||
table = &(mobj->data.lists);
|
||||
table = (ListTable *)mobj;
|
||||
offset = table->allocEntry();
|
||||
|
||||
*addr = make_reg(Lists_seg_id, offset);
|
||||
@ -1088,11 +1124,11 @@ Node *SegManager::alloc_Node(reg_t *addr) {
|
||||
|
||||
if (!Nodes_seg_id) {
|
||||
mobj = allocNonscriptSegment(MEM_OBJ_NODES, &(Nodes_seg_id));
|
||||
mobj->data.nodes.initTable();
|
||||
(*(NodeTable *)mobj).initTable();
|
||||
} else
|
||||
mobj = _heap[Nodes_seg_id];
|
||||
|
||||
table = &(mobj->data.nodes);
|
||||
table = (NodeTable *)mobj;
|
||||
offset = table->allocEntry();
|
||||
|
||||
*addr = make_reg(Nodes_seg_id, offset);
|
||||
@ -1106,11 +1142,11 @@ Hunk *SegManager::alloc_Hunk(reg_t *addr) {
|
||||
|
||||
if (!Hunks_seg_id) {
|
||||
mobj = allocNonscriptSegment(MEM_OBJ_HUNK, &(Hunks_seg_id));
|
||||
mobj->data.hunks.initTable();
|
||||
(*(HunkTable *)mobj).initTable();
|
||||
} else
|
||||
mobj = _heap[Hunks_seg_id];
|
||||
|
||||
table = &(mobj->data.hunks);
|
||||
table = (HunkTable *)mobj;
|
||||
offset = table->allocEntry();
|
||||
|
||||
*addr = make_reg(Hunks_seg_id, offset);
|
||||
@ -1134,36 +1170,36 @@ byte *SegManager::dereference(reg_t pointer, int *size) {
|
||||
|
||||
switch (mobj->getType()) {
|
||||
case MEM_OBJ_SCRIPT:
|
||||
if (pointer.offset > mobj->data.script.buf_size) {
|
||||
if (pointer.offset > (*(Script *)mobj).buf_size) {
|
||||
sciprintf("Error: Attempt to dereference invalid pointer "PREG" into script segment (script size=%d)\n",
|
||||
PRINT_REG(pointer), (uint)mobj->data.script.buf_size);
|
||||
PRINT_REG(pointer), (uint)(*(Script *)mobj).buf_size);
|
||||
return NULL;
|
||||
}
|
||||
if (size)
|
||||
*size = mobj->data.script.buf_size - pointer.offset;
|
||||
return (byte *)(mobj->data.script.buf + pointer.offset);
|
||||
*size = (*(Script *)mobj).buf_size - pointer.offset;
|
||||
return (byte *)((*(Script *)mobj).buf + pointer.offset);
|
||||
break;
|
||||
|
||||
case MEM_OBJ_LOCALS:
|
||||
count = mobj->data.locals.nr * sizeof(reg_t);
|
||||
base = (byte *)mobj->data.locals.locals;
|
||||
count = (*(LocalVariables *)mobj).nr * sizeof(reg_t);
|
||||
base = (byte *)(*(LocalVariables *)mobj).locals;
|
||||
break;
|
||||
|
||||
case MEM_OBJ_STACK:
|
||||
count = mobj->data.stack.nr * sizeof(reg_t);
|
||||
base = (byte *)mobj->data.stack.entries;
|
||||
count = (*(dstack_t *)mobj).nr * sizeof(reg_t);
|
||||
base = (byte *)(*(dstack_t *)mobj).entries;
|
||||
break;
|
||||
|
||||
case MEM_OBJ_DYNMEM:
|
||||
count = mobj->data.dynmem.size;
|
||||
base = (byte *)mobj->data.dynmem.buf;
|
||||
count = (*(DynMem *)mobj).size;
|
||||
base = (byte *)(*(DynMem *)mobj).buf;
|
||||
break;
|
||||
|
||||
case MEM_OBJ_SYS_STRINGS:
|
||||
if (size)
|
||||
*size = mobj->data.sys_strings.strings[pointer.offset].max_size;
|
||||
if (pointer.offset < SYS_STRINGS_MAX && mobj->data.sys_strings.strings[pointer.offset].name)
|
||||
return (byte *)(mobj->data.sys_strings.strings[pointer.offset].value);
|
||||
*size = (*(SystemStrings *)mobj).strings[pointer.offset].max_size;
|
||||
if (pointer.offset < SYS_STRINGS_MAX && (*(SystemStrings *)mobj).strings[pointer.offset].name)
|
||||
return (byte *)((*(SystemStrings *)mobj).strings[pointer.offset].value);
|
||||
else {
|
||||
sciprintf("Error: Attempt to dereference invalid pointer "PREG"!\n",
|
||||
PRINT_REG(pointer));
|
||||
@ -1188,16 +1224,18 @@ unsigned char *SegManager::allocDynmem(int size, const char *descr, reg_t *addr)
|
||||
MemObject *mobj = allocNonscriptSegment(MEM_OBJ_DYNMEM, &seg);
|
||||
*addr = make_reg(seg, 0);
|
||||
|
||||
mobj->data.dynmem.size = size;
|
||||
DynMem &d = *(DynMem *)mobj;
|
||||
|
||||
d.size = size;
|
||||
|
||||
if (size == 0)
|
||||
mobj->data.dynmem.buf = NULL;
|
||||
d.buf = NULL;
|
||||
else
|
||||
mobj->data.dynmem.buf = (byte*) sci_malloc(size);
|
||||
d.buf = (byte *)sci_malloc(size);
|
||||
|
||||
mobj->data.dynmem.description = sci_strdup(descr);
|
||||
d.description = sci_strdup(descr);
|
||||
|
||||
return (unsigned char *)(mobj->data.dynmem.buf);
|
||||
return (unsigned char *)(d.buf);
|
||||
}
|
||||
|
||||
const char *SegManager::getDescription(reg_t addr) {
|
||||
@ -1208,7 +1246,7 @@ const char *SegManager::getDescription(reg_t addr) {
|
||||
|
||||
switch (mobj->getType()) {
|
||||
case MEM_OBJ_DYNMEM:
|
||||
return mobj->data.dynmem.description;
|
||||
return (*(DynMem *)mobj).description;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
@ -1233,7 +1271,7 @@ void SegManager::dbgPrint(const char* msg, void *i) {
|
||||
|
||||
|
||||
// ------------------- Segment interface ------------------
|
||||
SegInterface::SegInterface(SegManager *segmgr, MemObject *mobj, SegmentId segId, memObjType typeId) :
|
||||
SegInterface::SegInterface(SegManager *segmgr, MemObject *mobj, SegmentId segId, MemObjectType typeId) :
|
||||
_segmgr(segmgr), _mobj(mobj), _segId(segId), _typeId(typeId) {
|
||||
VERIFY(_mobj->getType() == _typeId, "Invalid MemObject type");
|
||||
}
|
||||
@ -1255,7 +1293,7 @@ void SegInterface::listAllOutgoingReferences(EngineState *s, reg_t object, void
|
||||
//-------------------- base --------------------
|
||||
class SegInterfaceBase : public SegInterface {
|
||||
protected:
|
||||
SegInterfaceBase(SegManager *segmgr, MemObject *mobj, SegmentId segId, memObjType typeId) :
|
||||
SegInterfaceBase(SegManager *segmgr, MemObject *mobj, SegmentId segId, MemObjectType typeId) :
|
||||
SegInterface(segmgr, mobj, segId, typeId) {}
|
||||
public:
|
||||
reg_t findCanonicAddress(reg_t addr);
|
||||
@ -1282,7 +1320,7 @@ public:
|
||||
};
|
||||
|
||||
void SegInterfaceScript::freeAtAddress(reg_t addr) {
|
||||
Script *script = &(_mobj->data.script);
|
||||
Script *script = (Script *)_mobj;
|
||||
/*
|
||||
sciprintf("[GC] Freeing script "PREG"\n", PRINT_REG(addr));
|
||||
if (script->locals_segment)
|
||||
@ -1294,7 +1332,7 @@ void SegInterfaceScript::freeAtAddress(reg_t addr) {
|
||||
}
|
||||
|
||||
void SegInterfaceScript::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
|
||||
Script *script = &(_mobj->data.script);
|
||||
Script *script = (Script *)_mobj;
|
||||
|
||||
if (addr.offset <= script->buf_size && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(script->buf + addr.offset)) {
|
||||
int idx = RAW_GET_CLASS_INDEX(script, addr);
|
||||
@ -1338,7 +1376,7 @@ void SegInterfaceClones::listAllDeallocatable(void *param, NoteCallback note) {
|
||||
}
|
||||
|
||||
void SegInterfaceClones::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
|
||||
CloneTable *clone_table = &(_mobj->data.clones);
|
||||
CloneTable *clone_table = (CloneTable *)_mobj;
|
||||
Clone *clone;
|
||||
int i;
|
||||
|
||||
@ -1366,7 +1404,7 @@ void SegInterfaceClones::freeAtAddress(reg_t addr) {
|
||||
|
||||
assert(addr.segment == _segId);
|
||||
|
||||
victim_obj = &(_mobj->data.clones.table[addr.offset]);
|
||||
victim_obj = &((*(CloneTable *)_mobj).table[addr.offset]);
|
||||
|
||||
#ifdef GC_DEBUG
|
||||
if (!(victim_obj->flags & OBJECT_FLAG_FREED))
|
||||
@ -1382,7 +1420,7 @@ void SegInterfaceClones::freeAtAddress(reg_t addr) {
|
||||
*/
|
||||
free(victim_obj->variables);
|
||||
victim_obj->variables = NULL;
|
||||
Sci::free_Clone_entry(&(_mobj->data.clones), addr.offset);
|
||||
Sci::free_Clone_entry((CloneTable *)_mobj, addr.offset);
|
||||
}
|
||||
|
||||
|
||||
@ -1397,7 +1435,7 @@ public:
|
||||
};
|
||||
|
||||
reg_t SegInterfaceLocals::findCanonicAddress(reg_t addr) {
|
||||
LocalVariables *locals = &(_mobj->data.locals);
|
||||
LocalVariables *locals = (LocalVariables *)_mobj;
|
||||
// Reference the owning script
|
||||
SegmentId owner_seg = _segmgr->segGet(locals->script_id);
|
||||
|
||||
@ -1412,12 +1450,11 @@ void SegInterfaceLocals::freeAtAddress(reg_t sub_addr) {
|
||||
}
|
||||
|
||||
void SegInterfaceLocals::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
|
||||
LocalVariables *locals = &(_mobj->data.locals);
|
||||
int i;
|
||||
LocalVariables *locals = (LocalVariables *)_mobj;
|
||||
|
||||
assert(addr.segment == _segId);
|
||||
|
||||
for (i = 0; i < locals->nr; i++)
|
||||
for (int i = 0; i < locals->nr; i++)
|
||||
(*note)(param, locals->locals[i]);
|
||||
}
|
||||
|
||||
@ -1438,9 +1475,10 @@ reg_t SegInterfaceStack::findCanonicAddress(reg_t addr) {
|
||||
|
||||
void SegInterfaceStack::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
|
||||
int i;
|
||||
fprintf(stderr, "Emitting %d stack entries\n", _mobj->data.stack.nr);
|
||||
for (i = 0; i < _mobj->data.stack.nr; i++)
|
||||
(*note)(param, _mobj->data.stack.entries[i]);
|
||||
dstack_t &d = *(dstack_t *)_mobj;
|
||||
fprintf(stderr, "Emitting %d stack entries\n", d.nr);
|
||||
for (i = 0; i < d.nr; i++)
|
||||
(*note)(param, d.entries[i]);
|
||||
fprintf(stderr, "DONE");
|
||||
}
|
||||
|
||||
@ -1471,7 +1509,7 @@ public:
|
||||
};
|
||||
|
||||
void SegInterfaceLists::freeAtAddress(reg_t sub_addr) {
|
||||
Sci::free_List_entry(&(_mobj->data.lists), sub_addr.offset);
|
||||
Sci::free_List_entry((ListTable *)_mobj, sub_addr.offset);
|
||||
}
|
||||
|
||||
void SegInterfaceLists::listAllDeallocatable(void *param, NoteCallback note) {
|
||||
@ -1484,7 +1522,7 @@ void SegInterfaceLists::listAllDeallocatable(void *param, NoteCallback note) {
|
||||
}
|
||||
|
||||
void SegInterfaceLists::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
|
||||
ListTable *table = &(_mobj->data.lists);
|
||||
ListTable *table = (ListTable *)_mobj;
|
||||
List *list = &(table->table[addr.offset]);
|
||||
|
||||
if (!ENTRY_IS_VALID(table, addr.offset)) {
|
||||
@ -1510,7 +1548,7 @@ public:
|
||||
};
|
||||
|
||||
void SegInterfaceNodes::freeAtAddress(reg_t sub_addr) {
|
||||
Sci::free_Node_entry(&(_mobj->data.nodes), sub_addr.offset);
|
||||
Sci::free_Node_entry((NodeTable *)_mobj, sub_addr.offset);
|
||||
}
|
||||
|
||||
void SegInterfaceNodes::listAllDeallocatable(void *param, NoteCallback note) {
|
||||
@ -1523,7 +1561,7 @@ void SegInterfaceNodes::listAllDeallocatable(void *param, NoteCallback note) {
|
||||
}
|
||||
|
||||
void SegInterfaceNodes::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
|
||||
NodeTable *table = &(_mobj->data.nodes);
|
||||
NodeTable *table = (NodeTable *)_mobj;
|
||||
Node *node = &(table->table[addr.offset]);
|
||||
|
||||
if (!ENTRY_IS_VALID(table, addr.offset)) {
|
||||
|
@ -405,9 +405,9 @@ public: // TODO: make private
|
||||
SegmentId Hunks_seg_id; // ID of the (a) hunk segment
|
||||
|
||||
private:
|
||||
MemObject *allocNonscriptSegment(memObjType type, SegmentId *segid);
|
||||
MemObject *allocNonscriptSegment(MemObjectType type, SegmentId *segid);
|
||||
LocalVariables *allocLocalsSegment(Script *scr, int count);
|
||||
MemObject *memObjAllocate(SegmentId segid, int hash_id, memObjType type);
|
||||
MemObject *memObjAllocate(SegmentId segid, int hash_id, MemObjectType type);
|
||||
int deallocate(int seg, bool recursive);
|
||||
|
||||
Hunk *alloc_Hunk(reg_t *);
|
||||
@ -446,7 +446,7 @@ private:
|
||||
// But note that _mobj->segmgr_id != _segId !
|
||||
class SegInterface {
|
||||
protected:
|
||||
SegInterface(SegManager *segmgr, MemObject *mobj, SegmentId segId, memObjType typeId);
|
||||
SegInterface(SegManager *segmgr, MemObject *mobj, SegmentId segId, MemObjectType typeId);
|
||||
|
||||
public:
|
||||
typedef void (*NoteCallback)(void *param, reg_t addr);
|
||||
@ -481,7 +481,7 @@ public:
|
||||
MemObject *getMobj() { return _mobj; }
|
||||
|
||||
// Get the segment type
|
||||
memObjType getType() { return _typeId; }
|
||||
MemObjectType getType() { return _typeId; }
|
||||
|
||||
protected:
|
||||
SegManager *_segmgr;
|
||||
@ -489,7 +489,7 @@ protected:
|
||||
SegmentId _segId;
|
||||
|
||||
private:
|
||||
memObjType _typeId; // Segment type
|
||||
MemObjectType _typeId; // Segment type
|
||||
};
|
||||
|
||||
} // End of namespace Sci
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
namespace Sci {
|
||||
|
||||
enum memObjType {
|
||||
enum MemObjectType {
|
||||
MEM_OBJ_INVALID = 0,
|
||||
MEM_OBJ_SCRIPT = 1,
|
||||
MEM_OBJ_CLONES = 2,
|
||||
@ -50,9 +50,14 @@ enum memObjType {
|
||||
MEM_OBJ_MAX // For sanity checking
|
||||
};
|
||||
|
||||
struct MemObjectNEW {
|
||||
memObjType _type;
|
||||
struct MemObject {
|
||||
MemObjectType _type;
|
||||
int _segmgrId; /**< Internal value used by the seg_manager's hash map */
|
||||
|
||||
inline MemObjectType getType() const { return _type; }
|
||||
inline int getSegMgrId() const { return _segmgrId; }
|
||||
|
||||
static MemObject *createMemObject(MemObjectType type);
|
||||
};
|
||||
|
||||
|
||||
@ -73,7 +78,7 @@ struct SystemString {
|
||||
reg_t *value;
|
||||
};
|
||||
|
||||
struct SystemStrings : public MemObjectNEW {
|
||||
struct SystemStrings : public MemObject {
|
||||
SystemString strings[SYS_STRINGS_MAX];
|
||||
};
|
||||
|
||||
@ -171,7 +176,7 @@ struct CallsStruct {
|
||||
int type; /**< Same as ExecStack.type */
|
||||
};
|
||||
|
||||
struct LocalVariables : public MemObjectNEW {
|
||||
struct LocalVariables : public MemObject {
|
||||
int script_id; /**< Script ID this local variable block belongs to */
|
||||
reg_t *locals;
|
||||
int nr;
|
||||
@ -220,7 +225,7 @@ struct CodeBlock {
|
||||
|
||||
|
||||
|
||||
struct Script : public MemObjectNEW {
|
||||
struct Script : public MemObject {
|
||||
int nr; /**< Script number */
|
||||
byte* buf; /**< Static data buffer, or NULL if not used */
|
||||
size_t buf_size;
|
||||
@ -255,7 +260,7 @@ struct Script : public MemObjectNEW {
|
||||
};
|
||||
|
||||
/** Data stack */
|
||||
struct dstack_t : MemObjectNEW {
|
||||
struct dstack_t : MemObject {
|
||||
int nr; /**< Number of stack entries */
|
||||
reg_t *entries;
|
||||
};
|
||||
@ -284,7 +289,7 @@ struct Hunk {
|
||||
};
|
||||
|
||||
template<typename T, int INITIAL, int INCREMENT>
|
||||
struct Table : public MemObjectNEW {
|
||||
struct Table : public MemObject {
|
||||
struct Entry : public T {
|
||||
int next_free; /* Only used for free entries */
|
||||
};
|
||||
@ -346,31 +351,12 @@ void free_Hunk_entry(HunkTable *table, int index);
|
||||
|
||||
|
||||
// Free-style memory
|
||||
struct DynMem : public MemObjectNEW {
|
||||
struct DynMem : public MemObject {
|
||||
int size;
|
||||
char *description;
|
||||
byte *buf;
|
||||
};
|
||||
|
||||
struct MemObject {
|
||||
union {
|
||||
MemObjectNEW tmp_dummy;
|
||||
Script script;
|
||||
CloneTable clones;
|
||||
LocalVariables locals;
|
||||
dstack_t stack;
|
||||
SystemStrings sys_strings;
|
||||
ListTable lists;
|
||||
NodeTable nodes;
|
||||
HunkTable hunks;
|
||||
DynMem dynmem;
|
||||
} data;
|
||||
|
||||
inline memObjType getType() const { return data.tmp_dummy._type; }
|
||||
inline int getSegMgrId() const { return data.tmp_dummy._segmgrId; }
|
||||
};
|
||||
|
||||
|
||||
/** Contains selector IDs for a few selected selectors */
|
||||
struct selector_map_t {
|
||||
Selector init; /**< Init function */
|
||||
|
Loading…
x
Reference in New Issue
Block a user