diff options
| author | Jordi Vilalta Prat | 2009-02-22 12:18:22 +0000 | 
|---|---|---|
| committer | Jordi Vilalta Prat | 2009-02-22 12:18:22 +0000 | 
| commit | ac409a2ab7a15c08bde95f0647847dc71407ed88 (patch) | |
| tree | acbd1a57b0d6f50c460c27ae39d8373196df3b45 | |
| parent | 7d21acd18b65d8d213755754ce16f7b075c52039 (diff) | |
| download | scummvm-rg350-ac409a2ab7a15c08bde95f0647847dc71407ed88.tar.gz scummvm-rg350-ac409a2ab7a15c08bde95f0647847dc71407ed88.tar.bz2 scummvm-rg350-ac409a2ab7a15c08bde95f0647847dc71407ed88.zip  | |
SCI: Converted "segment interfaces" into classes
svn-id: r38782
| -rw-r--r-- | engines/sci/engine/gc.cpp | 18 | ||||
| -rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 12 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.cpp | 398 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.h | 45 | 
4 files changed, 238 insertions, 235 deletions
diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp index 94632a6b7c..531ecf8d19 100644 --- a/engines/sci/engine/gc.cpp +++ b/engines/sci/engine/gc.cpp @@ -100,7 +100,7 @@ static void free_worklist(worklist_t *wl) {  	}  } -static reg_t_hash_map * normalise_hashmap_ptrs(reg_t_hash_map *nonnormal_map, SegInterface **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) { @@ -109,7 +109,7 @@ static reg_t_hash_map * normalise_hashmap_ptrs(reg_t_hash_map *nonnormal_map, Se  		interfce = (reg.segment < interfaces_nr) ? interfaces[reg.segment] : NULL;  		if (interfce) { -			reg = interfce->find_canonic_address(interfce, reg); +			reg = interfce->findCanonicAddress(reg);  			normal_map->setVal(reg, true);  		}  	} @@ -181,8 +181,8 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {  	// Init: Explicitly loaded scripts  	for (i = 1; i < sm->heap_size; i++)  		if (interfaces[i] -		        && interfaces[i]->type_id == MEM_OBJ_SCRIPT) { -			script_t *script = &(interfaces[i]->mobj->data.script); +		        && interfaces[i]->getType() == MEM_OBJ_SCRIPT) { +			script_t *script = &(interfaces[i]->getMobj()->data.script);  			if (script->lockers) { // Explicitly loaded?  				int obj_nr; @@ -209,7 +209,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {  			sciprintf("[GC] Checking "PREG"\n", PRINT_REG(reg));  #endif  			if (reg.segment < sm->heap_size && interfaces[reg.segment]) -				interfaces[reg.segment]->list_all_outgoing_references(interfaces[reg.segment], s, reg, +				interfaces[reg.segment]->listAllOutgoingReferences(s, reg,  																		&worklist_manager, add_outgoing_refs);  		}  	} @@ -220,7 +220,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {  	// Cleanup  	for (i = 1; i < sm->heap_size; i++)  		if (interfaces[i]) -			interfaces[i]->deallocate_self(interfaces[i]); +			delete interfaces[i];  	free(interfaces);  	delete nonnormal_map; @@ -243,7 +243,7 @@ void free_unless_used(void *pre_use_map, reg_t addr) {  	if (!use_map->contains(addr)) {  		// Not found -> we can free it -		deallocator->interfce->free_at_address(deallocator->interfce, addr); +		deallocator->interfce->freeAtAddress(addr);  #ifdef DEBUG_GC  		sciprintf("[GC] Deallocating "PREG"\n", PRINT_REG(addr));  		deallocator->segcount[deallocator->interfce->type_id]++; @@ -271,8 +271,8 @@ void run_gc(EngineState *s) {  #ifdef DEBUG_GC  			deallocator.segnames[deallocator.interfce->type_id] = deallocator.interfce->type;  #endif -			deallocator.interfce->list_all_deallocatable(deallocator.interfce, &deallocator, free_unless_used); -			deallocator.interfce->deallocate_self(deallocator.interfce); +			deallocator.interfce->listAllDeallocatable(&deallocator, free_unless_used); +			delete deallocator.interfce;  		}  	} diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 4fd1dffc9a..b5b8da4c0b 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -2807,9 +2807,9 @@ static int c_gc_show_reachable(EngineState *s) {  	GET_SEG_INTERFACE(addr.segment);  	sciprintf("Reachable from "PREG":\n", PRINT_REG(addr)); -	seg_interface->list_all_outgoing_references(seg_interface, s, addr, NULL, _print_address); +	seg_interface->listAllOutgoingReferences(s, addr, NULL, _print_address); -	seg_interface->deallocate_self(seg_interface); +	delete seg_interface;  	return 0;  } @@ -2820,9 +2820,9 @@ static int c_gc_show_freeable(EngineState *s) {  	GET_SEG_INTERFACE(addr.segment);  	sciprintf("Freeable in segment %04x:\n", addr.segment); -	seg_interface->list_all_deallocatable(seg_interface, NULL, _print_address); +	seg_interface->listAllDeallocatable(NULL, _print_address); -	seg_interface->deallocate_self(seg_interface); +	delete seg_interface;  	return 0;  } @@ -2832,10 +2832,10 @@ static int c_gc_normalise(EngineState *s) {  	GET_SEG_INTERFACE(addr.segment); -	addr = seg_interface->find_canonic_address(seg_interface, addr); +	addr = seg_interface->findCanonicAddress(addr);  	sciprintf(" "PREG"\n", PRINT_REG(addr)); -	seg_interface->deallocate_self(seg_interface); +	delete seg_interface;  	return 0;  } diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index bbcc310d74..ebdfc61b28 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -1423,44 +1423,58 @@ void SegManager::dbgPrint(const char* msg, void *i) {  #endif  } -// ------------------- Segment interface ------------------ -static void free_at_address_stub(SegInterface *self, reg_t sub_addr) { -	//sciprintf("  Request to free "PREG"\n", PRINT_REG(sub_addr)); -	// STUB +// ------------------- Segment interface ------------------ +SegInterface::SegInterface(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId, memObjType typeId) : +	_segmgr(segmgr), _mobj(mobj), _segId(segId), _typeId(typeId) { +	VERIFY(_mobj->type == _typeId, "Invalid mem_obj_t type");  } -static reg_t find_canonic_address_base(SegInterface *self, reg_t addr) { -	addr.offset = 0; - +reg_t SegInterface::findCanonicAddress(reg_t addr) {  	return addr;  } -static reg_t find_canonic_address_id(SegInterface *self, reg_t addr) { -	return addr; +void SegInterface::freeAtAddress(reg_t sub_addr) {  } -static void free_at_address_nop(SegInterface *self, reg_t sub_addr) { +void SegInterface::listAllDeallocatable(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)) { +void SegInterface::listAllOutgoingReferences(EngineState *s, reg_t object, 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(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) { +//-------------------- base -------------------- +class SegInterfaceBase : public SegInterface { +protected: +	SegInterfaceBase(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId, memObjType typeId) : +		SegInterface(segmgr, mobj, segId, typeId) {} +public: +	reg_t findCanonicAddress(reg_t addr); +	void listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr)); +}; + +reg_t SegInterfaceBase::findCanonicAddress(reg_t addr) { +	addr.offset = 0; +	return addr;  } -static void deallocate_self(SegInterface *self) { -	free(self); +void SegInterfaceBase::listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr)) { +	(*note)(param, make_reg(_segId, 0));  } -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); + +//-------------------- script -------------------- +class SegInterfaceScript : public SegInterfaceBase { +public: +	SegInterfaceScript(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) : +		SegInterfaceBase(segmgr, mobj, segId, MEM_OBJ_SCRIPT) {} +	void freeAtAddress(reg_t addr); +	void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void *param, reg_t addr)); +}; + +void SegInterfaceScript::freeAtAddress(reg_t addr) { +	script_t *script = &(_mobj->data.script);  	/*  		sciprintf("[GC] Freeing script "PREG"\n", PRINT_REG(addr));  		if (script->locals_segment) @@ -1468,11 +1482,11 @@ static void free_at_address_script(SegInterface *self, reg_t addr) {  	*/  	if (script->marked_as_deleted) -		self->segmgr->deallocateScript(script->nr); +		_segmgr->deallocateScript(script->nr);  } -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); +void SegInterfaceScript::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void *param, reg_t addr)) { +	script_t *script = &(_mobj->data.script);  	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); @@ -1495,41 +1509,36 @@ static void list_all_outgoing_references_script(SegInterface *self, EngineState  	}  } -//-------------------- script -------------------- -static SegInterface seg_interface_script = { -	/* segmgr = */	NULL, -	/* mobj = */	NULL, -	/* seg_id = */	0, -	/* type_id = */	MEM_OBJ_SCRIPT, -	/* type = */	"script", -	/* find_canonic_address = */		find_canonic_address_base, -	/* free_at_address = */			free_at_address_script, -	/* list_all_deallocatable = */		list_all_deallocatable_base, -	/* list_all_outgoing_references = */	list_all_outgoing_references_script, -	/* deallocate_self = */			deallocate_self -}; -  #define LIST_ALL_DEALLOCATABLE(kind, kind_field) \ -	mem_obj_t *mobj = self->mobj;					\ -	kind##_table_t * table = &(mobj->data.kind_field);		\ +	kind##_table_t * table = &(_mobj->data.kind_field);		\  	int i;								\  									\  	for (i = 0; i < table->max_entry; i++)				\  		if (ENTRY_IS_VALID(table, i))				\ -			(*note) (param, make_reg(self->seg_id, i)); +			(*note) (param, make_reg(_segId, i)); + + +//-------------------- clones -------------------- +class SegInterfaceClones : public SegInterface { +public: +	SegInterfaceClones(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) : +		SegInterface(segmgr, mobj, segId, MEM_OBJ_CLONES) {} +	void freeAtAddress(reg_t addr); +	void listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr)); +	void listAllOutgoingReferences(EngineState *s, reg_t addr, 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)) { +void SegInterfaceClones::listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr)) {  	LIST_ALL_DEALLOCATABLE(clone, clones);  } -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); +void SegInterfaceClones::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void *param, reg_t addr)) { +	clone_table_t *clone_table = &(_mobj->data.clones);  	clone_t *clone;  	int i; -	assert(addr.segment == self->seg_id); +	assert(addr.segment == _segId);  	if (!(ENTRY_IS_VALID(clone_table, addr.offset))) {  		fprintf(stderr, "Unexpected request for outgoing references from clone at "PREG"\n", PRINT_REG(addr)); @@ -1548,12 +1557,12 @@ static void list_all_outgoing_references_clones(SegInterface *self, EngineState  	//sciprintf("[GC] Reporting clone-pos "PREG"\n", PRINT_REG(clone->pos));  } -void free_at_address_clones(SegInterface *self, reg_t addr) { +void SegInterfaceClones::freeAtAddress(reg_t addr) {  	object_t *victim_obj; -	assert(addr.segment == self->seg_id); +	assert(addr.segment == _segId); -	victim_obj = &(self->mobj->data.clones.table[addr.offset].entry); +	victim_obj = &(_mobj->data.clones.table[addr.offset].entry);  #ifdef GC_DEBUG  	if (!(victim_obj->flags & OBJECT_FLAG_FREED)) @@ -1569,100 +1578,97 @@ void free_at_address_clones(SegInterface *self, reg_t addr) {  	*/  	free(victim_obj->variables);  	victim_obj->variables = NULL; -	self->segmgr->free_clone(addr); +	_segmgr->free_clone(addr);  } -//-------------------- clones -------------------- -static SegInterface seg_interface_clones = { -	/* segmgr = */	NULL, -	/* mobj = */	NULL, -	/* seg_id = */	0, -	/* type_id = */	MEM_OBJ_CLONES, -	/* type = */	"clones", -	/* find_canonic_address = */		find_canonic_address_id, -	/* free_at_address = */			free_at_address_clones, -	/* list_all_deallocatable = */		list_all_deallocatable_clones, -	/* list_all_outgoing_references = */	list_all_outgoing_references_clones, -	/* deallocate_self = */			deallocate_self + +//-------------------- locals -------------------- +class SegInterfaceLocals : public SegInterface { +public: +	SegInterfaceLocals(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) : +		SegInterface(segmgr, mobj, segId, MEM_OBJ_LOCALS) {} +	reg_t findCanonicAddress(reg_t addr); +	void freeAtAddress(reg_t addr); +	void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void *param, reg_t addr));  }; -static reg_t find_canonic_address_locals(SegInterface *self, reg_t addr) { -	local_variables_t *locals = &(self->mobj->data.locals); +reg_t SegInterfaceLocals::findCanonicAddress(reg_t addr) { +	local_variables_t *locals = &(_mobj->data.locals);  	// Reference the owning script -	seg_id_t owner_seg = self->segmgr->segGet(locals->script_id); +	seg_id_t owner_seg = _segmgr->segGet(locals->script_id);  	assert(owner_seg >= 0);  	return make_reg(owner_seg, 0);  } -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); +void SegInterfaceLocals::freeAtAddress(reg_t sub_addr) { +	//sciprintf("  Request to free "PREG"\n", PRINT_REG(sub_addr)); +	// STUB +} + +void SegInterfaceLocals::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) { +	local_variables_t *locals = &(_mobj->data.locals);  	int i; -	assert(addr.segment == self->seg_id); +	assert(addr.segment == _segId);  	for (i = 0; i < locals->nr; i++)  		(*note)(param, locals->locals[i]);  } -//-------------------- locals -------------------- -static SegInterface seg_interface_locals = { -	/* segmgr = */	NULL, -	/* mobj = */	NULL, -	/* seg_id = */	0, -	/* type_id = */	MEM_OBJ_LOCALS, -	/* type = */	"locals", -	/* find_canonic_address = */		find_canonic_address_locals, -	/* free_at_address = */			free_at_address_stub, -	/* list_all_deallocatable = */		list_all_deallocatable_nop, -	/* list_all_outgoing_references = */	list_all_outgoing_references_locals, -	/* deallocate_self = */			deallocate_self + +//-------------------- stack -------------------- +class SegInterfaceStack : public SegInterface { +public: +	SegInterfaceStack(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) : +		SegInterface(segmgr, mobj, segId, MEM_OBJ_STACK) {} +	reg_t findCanonicAddress(reg_t addr); +	void listAllOutgoingReferences(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)) { +reg_t SegInterfaceStack::findCanonicAddress(reg_t addr) { +	addr.offset = 0; +	return addr; +} + +void SegInterfaceStack::listAllOutgoingReferences(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++) -		(*note)(param, self->mobj->data.stack.entries[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]);  	fprintf(stderr, "DONE");  } -//-------------------- stack -------------------- -static SegInterface seg_interface_stack = { -	/* segmgr = */	NULL, -	/* mobj = */	NULL, -	/* seg_id = */	0, -	/* type_id = */	MEM_OBJ_STACK, -	/* type = */	"stack", -	/* find_canonic_address = */		find_canonic_address_base, -	/* free_at_address = */			free_at_address_nop, -	/* list_all_deallocatable = */		list_all_deallocatable_nop, -	/* list_all_outgoing_references = */	list_all_outgoing_references_stack, -	/* deallocate_self = */			deallocate_self +//-------------------- system strings -------------------- +class SegInterfaceSysStrings : public SegInterface { +public: +	SegInterfaceSysStrings(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) : +		SegInterface(segmgr, mobj, segId, MEM_OBJ_SYS_STRINGS) {}  }; -//-------------------- system strings -------------------- -static SegInterface seg_interface_sys_strings = { -	/* segmgr = */	NULL, -	/* mobj = */	NULL, -	/* seg_id = */	0, -	/* type_id = */	MEM_OBJ_SYS_STRINGS, -	/* type = */	"system strings", -	/* find_canonic_address = */		find_canonic_address_id, -	/* free_at_address = */			free_at_address_nop, -	/* list_all_deallocatable = */		list_all_deallocatable_nop, -	/* list_all_outgoing_references = */	list_all_outgoing_references_nop, -	/* deallocate_self = */			deallocate_self + +//-------------------- lists -------------------- +class SegInterfaceLists : public SegInterface { +public: +	SegInterfaceLists(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) : +		SegInterface(segmgr, mobj, segId, MEM_OBJ_LISTS) {} +	void freeAtAddress(reg_t addr); +	void listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr)); +	void listAllOutgoingReferences(EngineState *s, reg_t addr, 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)) { +void SegInterfaceLists::freeAtAddress(reg_t sub_addr) { +	_segmgr->free_list(sub_addr); +} + +void SegInterfaceLists::listAllDeallocatable(void *param, void (*note)(void*param, reg_t addr)) {  	LIST_ALL_DEALLOCATABLE(list, lists);  } -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); +void SegInterfaceLists::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) { +	list_table_t *table = &(_mobj->data.lists);  	list_t *list = &(table->table[addr.offset].entry);  	if (!ENTRY_IS_VALID(table, addr.offset)) { @@ -1676,30 +1682,27 @@ static void list_all_outgoing_references_list(SegInterface *self, EngineState *s  	// let's be conservative here.  } -static void free_at_address_lists(SegInterface *self, reg_t sub_addr) { -	self->segmgr->free_list(sub_addr); -} -//-------------------- lists -------------------- -static SegInterface seg_interface_lists = { -	/* segmgr = */	NULL, -	/* mobj = */	NULL, -	/* seg_id = */	0, -	/* type_id = */	MEM_OBJ_LISTS, -	/* type = */	"lists", -	/* find_canonic_address = */		find_canonic_address_id, -	/* free_at_address = */			free_at_address_lists, -	/* list_all_deallocatable = */		list_all_deallocatable_list, -	/* list_all_outgoing_references = */	list_all_outgoing_references_list, -	/* deallocate_self = */			deallocate_self +//-------------------- nodes -------------------- +class SegInterfaceNodes : public SegInterface { +public: +	SegInterfaceNodes(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) : +		SegInterface(segmgr, mobj, segId, MEM_OBJ_NODES) {} +	void freeAtAddress(reg_t addr); +	void listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr)); +	void listAllOutgoingReferences(EngineState *s, reg_t addr, 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)) { +void SegInterfaceNodes::freeAtAddress(reg_t sub_addr) { +	_segmgr->free_node(sub_addr); +} + +void SegInterfaceNodes::listAllDeallocatable(void *param, void (*note)(void*param, reg_t addr)) {  	LIST_ALL_DEALLOCATABLE(node, nodes);  } -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); +void SegInterfaceNodes::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) { +	node_table_t *table = &(_mobj->data.nodes);  	node_t *node = &(table->table[addr.offset].entry);  	if (!ENTRY_IS_VALID(table, addr.offset)) { @@ -1715,102 +1718,89 @@ static void list_all_outgoing_references_nodes(SegInterface *self, EngineState *  	note(param, node->value);  } -static void free_at_address_nodes(SegInterface *self, reg_t sub_addr) { -	self->segmgr->free_node(sub_addr); -} -//-------------------- nodes -------------------- -static SegInterface seg_interface_nodes = { -	/* segmgr = */	NULL, -	/* mobj = */	NULL, -	/* seg_id = */	0, -	/* type_id = */	MEM_OBJ_NODES, -	/* type = */	"nodes", -	/* find_canonic_address = */		find_canonic_address_id, -	/* free_at_address = */			free_at_address_nodes, -	/* list_all_deallocatable = */		list_all_deallocatable_nodes, -	/* list_all_outgoing_references = */	list_all_outgoing_references_nodes, -	/* deallocate_self = */			deallocate_self +//-------------------- hunk -------------------- +class SegInterfaceHunk : public SegInterface { +public: +	SegInterfaceHunk(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) : +		SegInterface(segmgr, mobj, segId, MEM_OBJ_HUNK) {} +	void freeAtAddress(reg_t addr); +	void listAllDeallocatable(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)) { +void SegInterfaceHunk::freeAtAddress(reg_t sub_addr) { +	//sciprintf("  Request to free "PREG"\n", PRINT_REG(sub_addr)); +	// STUB +} + +void SegInterfaceHunk::listAllDeallocatable(void *param, void (*note)(void*param, reg_t addr)) {  	LIST_ALL_DEALLOCATABLE(hunk, hunks);  } -//-------------------- hunk -------------------- -static SegInterface seg_interface_hunk = { -	/* segmgr = */	NULL, -	/* mobj = */	NULL, -	/* seg_id = */	0, -	/* type_id = */	MEM_OBJ_HUNK, -	/* type = */	"hunk", -	/* find_canonic_address = */		find_canonic_address_id, -	/* free_at_address = */			free_at_address_stub, -	/* list_all_deallocatable = */		list_all_deallocatable_hunk, -	/* list_all_outgoing_references = */	list_all_outgoing_references_nop, -	/* deallocate_self = */			deallocate_self -};  //-------------------- dynamic memory -------------------- -static SegInterface seg_interface_dynmem = { -	/* segmgr = */	NULL, -	/* mobj = */	NULL, -	/* seg_id = */	0, -	/* type_id = */	MEM_OBJ_DYNMEM, -	/* type = */	"dynamic memory", -	/* find_canonic_address = */		find_canonic_address_base, -	/* free_at_address = */			free_at_address_stub, -	/* list_all_deallocatable = */		list_all_deallocatable_base, -	/* list_all_outgoing_references = */	list_all_outgoing_references_nop, -	/* deallocate_self = */			deallocate_self +class SegInterfaceDynMem : public SegInterfaceBase { +public: +	SegInterfaceDynMem(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) : +		SegInterfaceBase(segmgr, mobj, segId, MEM_OBJ_DYNMEM) {} +	void freeAtAddress(reg_t addr);  }; +void SegInterfaceDynMem::freeAtAddress(reg_t sub_addr) { +	//sciprintf("  Request to free "PREG"\n", PRINT_REG(sub_addr)); +	// STUB +} + +  //-------------------- reserved -------------------- -static SegInterface seg_interface_reserved = { -	/* segmgr = */	NULL, -	/* mobj = */	NULL, -	/* seg_id = */	0, -	/* type_id = */	MEM_OBJ_RESERVED, -	/* type = */	"reserved", -	/* find_canonic_address = */		find_canonic_address_id, -	/* free_at_address = */			free_at_address_nop, -	/* list_all_deallocatable = */		list_all_deallocatable_nop, -	/* list_all_outgoing_references = */	list_all_outgoing_references_nop, -	/* deallocate_self = */			deallocate_self +class SegInterfaceReserved : public SegInterface { +public: +	SegInterfaceReserved(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) : +		SegInterface(segmgr, mobj, segId, MEM_OBJ_RESERVED) {}  }; -static SegInterface* seg_interfaces[MEM_OBJ_MAX] = { -	&seg_interface_script, -	&seg_interface_clones, -	&seg_interface_locals, -	&seg_interface_stack, -	&seg_interface_sys_strings, -	&seg_interface_lists, -	&seg_interface_nodes, -	&seg_interface_hunk, -	&seg_interface_dynmem, -	&seg_interface_reserved -};  SegInterface *SegManager::getSegInterface(seg_id_t segid) { -	mem_obj_t *mobj; -	SegInterface *retval; -  	if (!check(segid))  		return NULL; // Invalid segment -	mobj = heap[segid]; -	retval = (SegInterface *)sci_malloc(sizeof(SegInterface)); -	memcpy(retval, seg_interfaces[mobj->type - 1], sizeof(SegInterface)); - -	if (mobj->type != retval->type_id) { +	SegInterface *retval = NULL; +	mem_obj_t *mobj = heap[segid]; +	switch (mobj->type) { +	case MEM_OBJ_SCRIPT: +		retval = new SegInterfaceScript(this, mobj, segid); +		break; +	case MEM_OBJ_CLONES: +		retval = new SegInterfaceClones(this, mobj, segid); +		break; +	case MEM_OBJ_LOCALS: +		retval = new SegInterfaceLocals(this, mobj, segid); +		break; +	case MEM_OBJ_STACK: +		retval = new SegInterfaceStack(this, mobj, segid); +		break; +	case MEM_OBJ_SYS_STRINGS: +		retval = new SegInterfaceSysStrings(this, mobj, segid); +		break; +	case MEM_OBJ_LISTS: +		retval = new SegInterfaceLists(this, mobj, segid); +		break; +	case MEM_OBJ_NODES: +		retval = new SegInterfaceNodes(this, mobj, segid); +		break; +	case MEM_OBJ_HUNK: +		retval = new SegInterfaceHunk(this, mobj, segid); +		break; +	case MEM_OBJ_DYNMEM: +		retval = new SegInterfaceDynMem(this, mobj, segid); +		break; +	case MEM_OBJ_RESERVED: +		retval = new SegInterfaceReserved(this, mobj, segid); +		break; +	default:  		error("Improper segment interface for %d", mobj->type);  	} -	retval->segmgr = this; -	retval->mobj = mobj; -	retval->seg_id = segid; -  	return retval;  } diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 9adf332ea4..1671619368 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -58,7 +58,7 @@ enum idFlag {  		(((mgr).heap[index]	&& ((mgr).heap[index]->type == MEM_OBJ_SCRIPT || (mgr).heap[index]->type == MEM_OBJ_CLONES))? (mgr).heap[index]	\  		: NULL): NULL -struct SegInterface; +class SegInterface;  class SegManager {  public: @@ -340,6 +340,7 @@ public:  	// Parameters: (reg_t) addr: Offset of the hunk entry to delete  	void free_hunk_entry(reg_t addr); +  	// 9. Dynamic Memory  	// Allocate some dynamic memory @@ -385,7 +386,7 @@ public:  	// 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)'; +	// The returned interface must be deleted after use  	SegInterface *getSegInterface(seg_id_t segid); @@ -450,38 +451,50 @@ private:  // 11. Segment interface, primarily for GC			 -struct SegInterface { -	SegManager *segmgr; -	mem_obj_t *mobj; -	seg_id_t seg_id; -	memObjType type_id;	// Segment type  -	const char *type;	// String description of the segment type  +class SegInterface { +protected: +	SegInterface(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId, memObjType typeId); + +public: +	// Deallocates the segment interface +	virtual ~SegInterface() {} -	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. +	virtual reg_t findCanonicAddress(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)(SegInterface *self, void *param, void (*note)(void *param, reg_t addr)); +	virtual void freeAtAddress(reg_t sub_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' +	virtual void listAllDeallocatable(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)(SegInterface *self); -	// Deallocates the segment interface +	virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, void (*note)(void *param, reg_t addr)); + +	// Get the memory object +	mem_obj_t *getMobj() { return _mobj; } + +	// Get the segment type +	memObjType getType() { return _typeId; } + +protected: +	SegManager *_segmgr; +	mem_obj_t *_mobj; +	seg_id_t _segId; + +private: +	memObjType _typeId; // Segment type  };  } // End of namespace Sci  | 
