- Simplified the parameters of some functions

- Replaced some EngineState parameters
- The SCI version is now obtained from the resource manager or the segment manager, thereby simplifying several functions
- Plugged 2 leaks in the fallback detector
- Renamed the segment manager and resource manager to "segmentManager" and "resourceManager" in all places, for consistency

svn-id: r43722
This commit is contained in:
Filippos Karapetis 2009-08-25 08:38:14 +00:00
parent bc20237ae3
commit ed66cad677
44 changed files with 578 additions and 573 deletions

View file

@ -204,15 +204,15 @@ static void validate_write_var(reg_t *r, reg_t *stack_base, int type, int max, i
#define GET_OP_SIGNED_FLEX() ((opcode & 1)? GET_OP_SIGNED_BYTE() : GET_OP_SIGNED_WORD())
ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackPtr sp, reg_t calling_obj, uint16 argc, StackPtr argp) {
int seg = s->seg_manager->segGet(script);
Script *scr = s->seg_manager->getScriptIfLoaded(seg);
int seg = s->segmentManager->segGet(script);
Script *scr = s->segmentManager->getScriptIfLoaded(seg);
if (!scr) // Script not present yet?
seg = script_instantiate(s->resmgr, s->seg_manager, s->_version, script);
seg = script_instantiate(s->resourceManager, s->segmentManager, script);
else
scr->unmarkDeleted();
int temp = s->seg_manager->validateExportFunc(pubfunct, seg);
int temp = s->segmentManager->validateExportFunc(pubfunct, seg);
if (!temp) {
error("Request for invalid exported function 0x%x of script 0x%x", pubfunct, script);
return NULL;
@ -285,7 +285,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt
Breakpoint *bp;
char method_name [256];
sprintf(method_name, "%s::%s", obj_get_name(s->seg_manager, s->_version, send_obj), ((SciEngine*)g_engine)->getKernel()->getSelectorName(selector).c_str());
sprintf(method_name, "%s::%s", obj_get_name(s->segmentManager, send_obj), ((SciEngine*)g_engine)->getKernel()->getSelectorName(selector).c_str());
bp = s->bp_list;
while (bp) {
@ -310,7 +310,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt
#endif // VM_DEBUG_SEND
ObjVarRef varp;
switch (lookup_selector(s, send_obj, selector, &varp, &funcp)) {
switch (lookup_selector(s->segmentManager, send_obj, selector, &varp, &funcp)) {
case kSelectorNone:
error("Send to invalid selector 0x%x of object at %04x:%04x", 0xffff & selector, PRINT_REG(send_obj));
@ -467,7 +467,7 @@ void vm_handle_fatal_error(EngineState *s, int line, const char *file) {
}
static reg_t pointer_add(EngineState *s, reg_t base, int offset) {
MemObject *mobj = GET_SEGMENT_ANY(*s->seg_manager, base.segment);
MemObject *mobj = GET_SEGMENT_ANY(*s->segmentManager, base.segment);
if (!mobj) {
error("[VM] Error: Attempt to add %d to invalid pointer %04x:%04x", offset, PRINT_REG(base));
@ -520,8 +520,8 @@ void run_vm(EngineState *s, int restoring) {
// Current execution data:
scriptState.xs = &(s->_executionStack.back());
ExecStack *xs_new = NULL;
Object *obj = obj_get(s->seg_manager, s->_version, scriptState.xs->objp);
Script *local_script = s->seg_manager->getScriptIfLoaded(scriptState.xs->local_segment);
Object *obj = obj_get(s->segmentManager, scriptState.xs->objp);
Script *local_script = s->segmentManager->getScriptIfLoaded(scriptState.xs->local_segment);
int old_execution_stack_base = s->execution_stack_base;
// Used to detect the stack bottom, for "physical" returns
const byte *code_buf = NULL; // (Avoid spurious warning)
@ -567,7 +567,7 @@ void run_vm(EngineState *s, int restoring) {
scriptState.xs = &(s->_executionStack.back());
s->_executionStackPosChanged = false;
scr = s->seg_manager->getScriptIfLoaded(scriptState.xs->addr.pc.segment);
scr = s->segmentManager->getScriptIfLoaded(scriptState.xs->addr.pc.segment);
if (!scr) {
// No script? Implicit return via fake instruction buffer
warning("Running on non-existant script in segment %x", scriptState.xs->addr.pc.segment);
@ -580,12 +580,12 @@ void run_vm(EngineState *s, int restoring) {
scr = NULL;
obj = NULL;
} else {
obj = obj_get(s->seg_manager, s->_version, scriptState.xs->objp);
obj = obj_get(s->segmentManager, scriptState.xs->objp);
code_buf = scr->buf;
#ifndef DISABLE_VALIDATIONS
code_buf_size = scr->buf_size;
#endif
local_script = s->seg_manager->getScriptIfLoaded(scriptState.xs->local_segment);
local_script = s->segmentManager->getScriptIfLoaded(scriptState.xs->local_segment);
if (!local_script) {
warning("Could not find local script from segment %x", scriptState.xs->local_segment);
local_script = NULL;
@ -917,17 +917,22 @@ void run_vm(EngineState *s, int restoring) {
gc_countdown(s);
scriptState.xs->sp -= (opparams[1] >> 1) + 1;
if (!((SciEngine*)g_engine)->getKernel()->hasOldScriptHeader()) {
scriptState.xs->sp -= scriptState.restAdjust;
s->restAdjust = 0; // We just used up the scriptState.restAdjust, remember?
{
bool oldScriptHeader = (s->segmentManager->sciVersion() == SCI_VERSION_0_EARLY);
if (!oldScriptHeader) {
scriptState.xs->sp -= scriptState.restAdjust;
s->restAdjust = 0; // We just used up the scriptState.restAdjust, remember?
}
}
if (opparams[0] >= (int)((SciEngine*)g_engine)->getKernel()->_kernelFuncs.size()) {
error("Invalid kernel function 0x%x requested", opparams[0]);
} else {
int argc = ASSERT_ARITHMETIC(scriptState.xs->sp[0]);
bool oldScriptHeader = (s->segmentManager->sciVersion() == SCI_VERSION_0_EARLY);
if (!((SciEngine*)g_engine)->getKernel()->hasOldScriptHeader())
if (!oldScriptHeader)
argc += scriptState.restAdjust;
if (((SciEngine*)g_engine)->getKernel()->_kernelFuncs[opparams[0]].signature
@ -947,8 +952,11 @@ void run_vm(EngineState *s, int restoring) {
xs_new = &(s->_executionStack.back());
s->_executionStackPosChanged = true;
if (!((SciEngine*)g_engine)->getKernel()->hasOldScriptHeader())
scriptState.restAdjust = s->restAdjust;
{
bool oldScriptHeader = (s->segmentManager->sciVersion() == SCI_VERSION_0_EARLY);
if (!oldScriptHeader)
scriptState.restAdjust = s->restAdjust;
}
}
break;
@ -1038,7 +1046,7 @@ void run_vm(EngineState *s, int restoring) {
break;
case 0x28: // class
s->r_acc = s->seg_manager->get_class_address((unsigned)opparams[0], SCRIPT_GET_LOCK,
s->r_acc = s->segmentManager->get_class_address((unsigned)opparams[0], SCRIPT_GET_LOCK,
scriptState.xs->addr.pc);
break;
@ -1058,7 +1066,7 @@ void run_vm(EngineState *s, int restoring) {
break;
case 0x2b: // super
r_temp = s->seg_manager->get_class_address(opparams[0], SCRIPT_GET_LOAD, scriptState.xs->addr.pc);
r_temp = s->segmentManager->get_class_address(opparams[0], SCRIPT_GET_LOAD, scriptState.xs->addr.pc);
if (!r_temp.segment)
error("[VM]: Invalid superclass in object");
@ -1156,7 +1164,7 @@ void run_vm(EngineState *s, int restoring) {
case 0x39: // lofsa
s->r_acc.segment = scriptState.xs->addr.pc.segment;
if (s->_version >= SCI_VERSION_1_1) {
if (s->resourceManager->sciVersion() >= SCI_VERSION_1_1) {
s->r_acc.offset = opparams[0] + local_script->script_size;
} else {
if (((SciEngine*)g_engine)->getKernel()->hasLofsAbsolute())
@ -1176,7 +1184,7 @@ void run_vm(EngineState *s, int restoring) {
case 0x3a: // lofss
r_temp.segment = scriptState.xs->addr.pc.segment;
if (s->_version >= SCI_VERSION_1_1) {
if (s->resourceManager->sciVersion() >= SCI_VERSION_1_1) {
r_temp.offset = opparams[0] + local_script->script_size;
} else {
if (((SciEngine*)g_engine)->getKernel()->hasLofsAbsolute())
@ -1390,12 +1398,12 @@ void run_vm(EngineState *s, int restoring) {
}
}
static int _obj_locate_varselector(EngineState *s, Object *obj, Selector slc) {
static int _obj_locate_varselector(SegManager *segManager, Object *obj, Selector slc) {
// Determines if obj explicitly defines slc as a varselector
// Returns -1 if not found
SciVersion version = s->_version; // for the selector defines
SciVersion version = segManager->sciVersion(); // for the selector defines
if (s->_version < SCI_VERSION_1_1) {
if (version < SCI_VERSION_1_1) {
int varnum = obj->variable_names_nr;
int selector_name_offset = varnum * 2 + SCRIPT_SELECTOR_OFFSET;
int i;
@ -1414,7 +1422,7 @@ static int _obj_locate_varselector(EngineState *s, Object *obj, Selector slc) {
int varnum = obj->_variables[1].offset;
if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS))
buf = ((byte *) obj_get(s->seg_manager, s->_version, obj->_variables[SCRIPT_SUPERCLASS_SELECTOR])->base_vars);
buf = ((byte *) obj_get(segManager, obj->_variables[SCRIPT_SUPERCLASS_SELECTOR])->base_vars);
for (i = 0; i < varnum; i++)
if (READ_LE_UINT16(buf + (i << 1)) == slc) // Found it?
@ -1424,7 +1432,7 @@ static int _obj_locate_varselector(EngineState *s, Object *obj, Selector slc) {
}
}
static int _class_locate_funcselector(EngineState *s, Object *obj, Selector slc) {
static int _class_locate_funcselector(Object *obj, Selector slc, SciVersion version) {
// Determines if obj is a class and explicitly defines slc as a funcselector
// Does NOT say anything about obj's superclasses, i.e. failure may be
// returned even if one of the superclasses defines the funcselector.
@ -1438,14 +1446,14 @@ static int _class_locate_funcselector(EngineState *s, Object *obj, Selector slc)
return -1; // Failed
}
static SelectorType _lookup_selector_function(EngineState *s, int seg_id, Object *obj, Selector selector_id, reg_t *fptr) {
static SelectorType _lookup_selector_function(SegManager *segManager, int seg_id, Object *obj, Selector selector_id, reg_t *fptr) {
int index;
SciVersion version = s->_version; // for the selector defines
SciVersion version = segManager->sciVersion(); // for the selector defines
// "recursive" lookup
while (obj) {
index = _class_locate_funcselector(s, obj, selector_id);
index = _class_locate_funcselector(obj, selector_id, version);
if (index >= 0) {
if (fptr) {
@ -1455,22 +1463,23 @@ static SelectorType _lookup_selector_function(EngineState *s, int seg_id, Object
return kSelectorMethod;
} else {
seg_id = obj->_variables[SCRIPT_SUPERCLASS_SELECTOR].segment;
obj = obj_get(s->seg_manager, s->_version, obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]);
obj = obj_get(segManager, obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]);
}
}
return kSelectorNone;
}
SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector selector_id, ObjVarRef *varp, reg_t *fptr) {
Object *obj = obj_get(s->seg_manager, s->_version, obj_location);
SelectorType lookup_selector(SegManager *segManager, reg_t obj_location, Selector selector_id, ObjVarRef *varp, reg_t *fptr) {
Object *obj = obj_get(segManager, obj_location);
Object *species;
int index;
SciVersion version = s->_version; // for the selector defines
SciVersion version = segManager->sciVersion(); // for the selector defines
bool oldScriptHeader = (version == SCI_VERSION_0_EARLY);
// Early SCI versions used the LSB in the selector ID as a read/write
// toggle, meaning that we must remove it for selector lookup.
if (((SciEngine*)g_engine)->getKernel()->hasOldScriptHeader())
if (oldScriptHeader)
selector_id &= ~1;
if (!obj) {
@ -1481,7 +1490,7 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select
if (IS_CLASS(obj))
species = obj;
else
species = obj_get(s->seg_manager, s->_version, obj->_variables[SCRIPT_SPECIES_SELECTOR]);
species = obj_get(segManager, obj->_variables[SCRIPT_SPECIES_SELECTOR]);
if (!obj) {
@ -1490,7 +1499,7 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select
return kSelectorNone;
}
index = _obj_locate_varselector(s, obj, selector_id);
index = _obj_locate_varselector(segManager, obj, selector_id);
if (index >= 0) {
// Found it as a variable
@ -1501,7 +1510,7 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select
return kSelectorVariable;
}
return _lookup_selector_function(s, obj_location.segment, obj, selector_id, fptr);
return _lookup_selector_function(segManager, obj_location.segment, obj, selector_id, fptr);
}
reg_t script_lookup_export(SegManager *segManager, int script_nr, int export_index) {
@ -1512,19 +1521,19 @@ reg_t script_lookup_export(SegManager *segManager, int script_nr, int export_ind
#define INST_LOOKUP_CLASS(id) ((id == 0xffff)? NULL_REG : segManager->get_class_address(id, SCRIPT_GET_LOCK, reg))
int script_instantiate_common(ResourceManager *resMgr, SegManager *segManager, SciVersion version, int script_nr, Resource **script, Resource **heap, int *was_new) {
int script_instantiate_common(ResourceManager *resourceManager, SegManager *segManager, int script_nr, Resource **script, Resource **heap, int *was_new) {
int seg_id;
reg_t reg;
*was_new = 1;
*script = resMgr->findResource(ResourceId(kResourceTypeScript, script_nr), 0);
if (version >= SCI_VERSION_1_1)
*heap = resMgr->findResource(ResourceId(kResourceTypeHeap, script_nr), 0);
*script = resourceManager->findResource(ResourceId(kResourceTypeScript, script_nr), 0);
if (resourceManager->sciVersion() >= SCI_VERSION_1_1)
*heap = resourceManager->findResource(ResourceId(kResourceTypeHeap, script_nr), 0);
if (!*script || (version >= SCI_VERSION_1_1 && !heap)) {
if (!*script || (resourceManager->sciVersion() >= SCI_VERSION_1_1 && !heap)) {
warning("Script 0x%x requested but not found", script_nr);
if (version >= SCI_VERSION_1_1) {
if (resourceManager->sciVersion() >= SCI_VERSION_1_1) {
if (*heap)
warning("Inconsistency: heap resource WAS found");
else if (*script)
@ -1566,7 +1575,7 @@ int script_instantiate_common(ResourceManager *resMgr, SegManager *segManager, S
return seg_id;
}
int script_instantiate_sci0(ResourceManager *resMgr, SegManager *segManager, SciVersion version, bool oldScriptHeader, int script_nr) {
int script_instantiate_sci0(ResourceManager *resourceManager, SegManager *segManager, int script_nr) {
int objtype;
unsigned int objlength;
reg_t reg;
@ -1575,8 +1584,10 @@ int script_instantiate_sci0(ResourceManager *resMgr, SegManager *segManager, Sci
int magic_pos_adder; // Usually 0; 2 for older SCI versions
Resource *script;
int was_new;
SciVersion version = resourceManager->sciVersion();
bool oldScriptHeader = (version == SCI_VERSION_0_EARLY);
seg_id = script_instantiate_common(resMgr, segManager, version, script_nr, &script, NULL, &was_new);
seg_id = script_instantiate_common(resourceManager, segManager, script_nr, &script, NULL, &was_new);
if (was_new)
return seg_id;
@ -1690,7 +1701,7 @@ int script_instantiate_sci0(ResourceManager *resMgr, SegManager *segManager, Sci
// Instantiate the superclass, if neccessary
obj->_variables[SCRIPT_SPECIES_SELECTOR] = INST_LOOKUP_CLASS(obj->_variables[SCRIPT_SPECIES_SELECTOR].offset);
base_obj = obj_get(segManager, version, obj->_variables[SCRIPT_SPECIES_SELECTOR]);
base_obj = obj_get(segManager, obj->_variables[SCRIPT_SPECIES_SELECTOR]);
obj->variable_names_nr = base_obj->_variables.size();
obj->base_obj = base_obj->base_obj;
// Copy base from species class, as we need its selector IDs
@ -1716,14 +1727,14 @@ int script_instantiate_sci0(ResourceManager *resMgr, SegManager *segManager, Sci
return reg.segment; // instantiation successful
}
int script_instantiate_sci11(ResourceManager *resMgr, SegManager *segManager, SciVersion version, int script_nr) {
int script_instantiate_sci11(ResourceManager *resourceManager, SegManager *segManager, int script_nr) {
Resource *script, *heap;
int seg_id;
int heap_start;
reg_t reg;
int was_new;
seg_id = script_instantiate_common(resMgr, segManager, version, script_nr, &script, &heap, &was_new);
seg_id = script_instantiate_common(resourceManager, segManager, script_nr, &script, &heap, &was_new);
if (was_new)
return seg_id;
@ -1753,17 +1764,19 @@ int script_instantiate_sci11(ResourceManager *resMgr, SegManager *segManager, Sc
return seg_id;
}
int script_instantiate(ResourceManager *resMgr, SegManager *segManager, SciVersion version, int script_nr) {
if (version >= SCI_VERSION_1_1)
return script_instantiate_sci11(resMgr, segManager, version, script_nr);
int script_instantiate(ResourceManager *resourceManager, SegManager *segManager, int script_nr) {
if (resourceManager->sciVersion() >= SCI_VERSION_1_1)
return script_instantiate_sci11(resourceManager, segManager, script_nr);
else
return script_instantiate_sci0(resMgr, segManager, version, (version == SCI_VERSION_0_EARLY), script_nr);
return script_instantiate_sci0(resourceManager, segManager, script_nr);
}
void script_uninstantiate_sci0(SegManager *segManager, SciVersion version, int script_nr, SegmentId seg) {
reg_t reg = make_reg(seg, ((SciEngine*)g_engine)->getKernel()->hasOldScriptHeader() ? 2 : 0);
void script_uninstantiate_sci0(SegManager *segManager, int script_nr, SegmentId seg) {
bool oldScriptHeader = (segManager->sciVersion() == SCI_VERSION_0_EARLY);
reg_t reg = make_reg(seg, oldScriptHeader ? 2 : 0);
int objtype, objlength;
Script *scr = segManager->getScript(seg);
SciVersion version = segManager->sciVersion();
// Make a pass over the object in order uninstantiate all superclasses
objlength = 0;
@ -1792,7 +1805,7 @@ void script_uninstantiate_sci0(SegManager *segManager, SciVersion version, int s
if (scr->getLockers())
scr->decrementLockers(); // Decrease lockers if this is us ourselves
} else
script_uninstantiate(segManager, version, superclass_script);
script_uninstantiate(segManager, superclass_script);
// Recurse to assure that the superclass lockers number gets decreased
}
@ -1804,7 +1817,7 @@ void script_uninstantiate_sci0(SegManager *segManager, SciVersion version, int s
} while (objtype != 0);
}
void script_uninstantiate(SegManager *segManager, SciVersion version, int script_nr) {
void script_uninstantiate(SegManager *segManager, int script_nr) {
SegmentId segment = segManager->segGet(script_nr);
Script *scr = segManager->getScriptIfLoaded(segment);
@ -1824,8 +1837,8 @@ void script_uninstantiate(SegManager *segManager, SciVersion version, int script
if (segManager->_classtable[i].reg.segment == segment)
segManager->_classtable[i].reg = NULL_REG;
if (version < SCI_VERSION_1_1)
script_uninstantiate_sci0(segManager, version, script_nr, segment);
if (segManager->sciVersion() < SCI_VERSION_1_1)
script_uninstantiate_sci0(segManager, script_nr, segment);
else
warning("FIXME: Add proper script uninstantiation for SCI 1.1");
@ -1917,8 +1930,9 @@ int game_run(EngineState **_s) {
return 0;
}
Object *obj_get(SegManager *segManager, SciVersion version, reg_t offset) {
Object *obj_get(SegManager *segManager, reg_t offset) {
MemObject *mobj = GET_OBJECT_SEGMENT(*segManager, offset.segment);
SciVersion version = segManager->sciVersion();
Object *obj = NULL;
int idx;
@ -1941,8 +1955,9 @@ Object *obj_get(SegManager *segManager, SciVersion version, reg_t offset) {
return obj;
}
const char *obj_get_name(SegManager *segManager, SciVersion version, reg_t pos) {
Object *obj = obj_get(segManager, version, pos);
const char *obj_get_name(SegManager *segManager, reg_t pos) {
Object *obj = obj_get(segManager, pos);
SciVersion version = segManager->sciVersion();
if (!obj)
return "<no such object>";
@ -1974,7 +1989,7 @@ void shrink_execution_stack(EngineState *s, uint size) {
}
reg_t* ObjVarRef::getPointer(EngineState *s) const {
Object *o = obj_get(s->seg_manager, s->_version, obj);
Object *o = obj_get(s->segmentManager, obj);
if (!o) return 0;
return &(o->_variables[varindex]);
}