SCI: Turn some SegManager methods into Script methods

svn-id: r44127
This commit is contained in:
Max Horn 2009-09-16 23:32:48 +00:00
parent a277123f54
commit 68dfdce043
6 changed files with 105 additions and 97 deletions

View file

@ -318,9 +318,13 @@ reg_t kDisposeScript(EngineState *s, int, int argc, reg_t *argv) {
}
}
int is_heap_object(EngineState *s, reg_t pos) {
bool is_heap_object(EngineState *s, reg_t pos) {
Object *obj = s->segMan->getObject(pos);
return (obj != NULL && (!(obj->flags & OBJECT_FLAG_FREED)) && (!s->segMan->scriptIsMarkedAsDeleted(pos.segment)));
if (obj == NULL)
return false;
if (obj->flags & OBJECT_FLAG_FREED)
return false;
return !s->segMan->scriptIsMarkedAsDeleted(pos.segment);
}
reg_t kIsObject(EngineState *s, int, int argc, reg_t *argv) {

View file

@ -114,7 +114,21 @@ void Script::freeScript() {
_codeBlocks.clear();
}
void Script::init() {
bool Script::init(int script_nr, ResourceManager *resMan) {
setScriptSize(script_nr, resMan);
_buf = (byte *)malloc(_bufSize);
#ifdef DEBUG_segMan
printf("_buf = %p ", _buf);
#endif
if (!_buf) {
freeScript();
warning("Not enough memory space for script size");
_bufSize = 0;
return false;
}
_localsOffset = 0;
_localsBlock = NULL;
@ -124,6 +138,16 @@ void Script::init() {
_markedAsDeleted = false;
_objIndices = new IntMapper();
_nr = script_nr;
_sciVersion = resMan->sciVersion();
if (_sciVersion >= SCI_VERSION_1_1)
_heapStart = _buf + _scriptSize;
else
_heapStart = _buf;
return true;
}
Object *Script::allocateObject(uint16 offset) {

View file

@ -258,6 +258,8 @@ protected:
IntMapper *_objIndices;
SciVersion _sciVersion;
public:
/**
* Table for objects, contains property variables.
@ -279,7 +281,7 @@ public:
~Script();
void freeScript();
void init();
bool init(int script_nr, ResourceManager *resMan);
virtual bool isValidOffset(uint16 offset) const;
virtual byte *dereference(reg_t pointer, int *size);
@ -293,6 +295,43 @@ public:
Object *allocateObject(uint16 offset);
Object *getObject(uint16 offset);
/**
* Informs the segment manager that a code block must be relocated
* @param location Start of block to relocate
*/
void scriptAddCodeBlock(reg_t location);
/**
* Initializes an object within the segment manager
* @param obj_pos Location (segment, offset) of the object. It must
* point to the beginning of the script/class block
* (as opposed to what the VM considers to be the
* object location)
* @returns A newly created Object describing the object,
* stored within the relevant script
*/
Object *scriptObjInit(reg_t obj_pos);
/**
* Processes a relocation block witin a script
* This function is idempotent, but it must only be called after all
* objects have been instantiated, or a run-time error will occur.
* @param obj_pos Location (segment, offset) of the block
* @return Location of the relocation block
*/
void scriptRelocate(reg_t block);
void heapRelocate(reg_t block);
private:
int relocateLocal(SegmentId segment, int location);
int relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location);
int relocateObject(Object *obj, SegmentId segment, int location);
Object *scriptObjInit0(reg_t obj_pos);
Object *scriptObjInit11(reg_t obj_pos);
public:
// script lock operations
/** Increments the number of lockers of this script by one. */
@ -382,6 +421,9 @@ public:
* @return the value read from the specified location
*/
int16 getHeap(uint16 offset) const;
private:
void setScriptSize(int script_nr, ResourceManager *resMan);
};
/** Data stack */

View file

@ -133,7 +133,8 @@ Script *SegManager::allocateScript(int script_nr, SegmentId *seg_id) {
return (Script *)mem;
}
void SegManager::setScriptSize(Script &scr, int script_nr) {
void Script::setScriptSize(int script_nr, ResourceManager *_resMan) {
Script &scr = *this; // FIXME: Hack
Resource *script = _resMan->findResource(ResourceId(kResourceTypeScript, script_nr), 0);
Resource *heap = _resMan->findResource(ResourceId(kResourceTypeHeap, script_nr), 0);
bool oldScriptHeader = (_resMan->sciVersion() == SCI_VERSION_0_EARLY);
@ -169,34 +170,6 @@ void SegManager::setScriptSize(Script &scr, int script_nr) {
}
}
int SegManager::initialiseScript(Script &scr, int script_nr) {
// allocate the script._buf
setScriptSize(scr, script_nr);
scr._buf = (byte *)malloc(scr._bufSize);
#ifdef DEBUG_segMan
printf("scr._buf = %p ", scr._buf);
#endif
if (!scr._buf) {
scr.freeScript();
warning("SegManager: Not enough memory space for script size");
scr._bufSize = 0;
return 0;
}
// Initialize objects
scr.init();
scr._nr = script_nr;
if (_resMan->sciVersion() >= SCI_VERSION_1_1)
scr._heapStart = scr._buf + scr._scriptSize;
else
scr._heapStart = scr._buf;
return 1;
}
int SegManager::deallocate(SegmentId seg, bool recursive) {
MemObject *mobj;
VERIFY(check(seg), "invalid seg id");
@ -332,7 +305,7 @@ void SegManager::setExportAreWide(bool flag) {
_exportsAreWide = flag;
}
int SegManager::relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location) {
int Script::relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location) {
int rel = location - block_location;
if (rel < 0)
@ -348,34 +321,32 @@ int SegManager::relocateBlock(Common::Array<reg_t> &block, int block_location, S
return 0;
}
block[idx].segment = segment; // Perform relocation
if (_resMan->sciVersion() >= SCI_VERSION_1_1)
block[idx].offset += getScript(segment)->_scriptSize;
if (_sciVersion >= SCI_VERSION_1_1)
block[idx].offset += _scriptSize;
return 1;
}
int SegManager::relocateLocal(Script *scr, SegmentId segment, int location) {
if (scr->_localsBlock)
return relocateBlock(scr->_localsBlock->_locals, scr->_localsOffset, segment, location);
int Script::relocateLocal(SegmentId segment, int location) {
if (_localsBlock)
return relocateBlock(_localsBlock->_locals, _localsOffset, segment, location);
else
return 0; // No hands, no cookies
}
int SegManager::relocateObject(Object *obj, SegmentId segment, int location) {
int Script::relocateObject(Object *obj, SegmentId segment, int location) {
return relocateBlock(obj->_variables, obj->pos.offset, segment, location);
}
void SegManager::scriptAddCodeBlock(reg_t location) {
Script *scr = getScript(location.segment);
void Script::scriptAddCodeBlock(reg_t location) {
CodeBlock cb;
cb.pos = location;
cb.size = READ_LE_UINT16(scr->_buf + location.offset - 2);
scr->_codeBlocks.push_back(cb);
cb.size = READ_LE_UINT16(_buf + location.offset - 2);
_codeBlocks.push_back(cb);
}
void SegManager::scriptRelocate(reg_t block) {
Script *scr = getScript(block.segment);
void Script::scriptRelocate(reg_t block) {
Script *scr = this; // FIXME: Hack
VERIFY(block.offset < (uint16)scr->_bufSize && READ_LE_UINT16(scr->_buf + block.offset) * 2 + block.offset < (uint16)scr->_bufSize,
"Relocation block outside of script\n");
@ -387,7 +358,7 @@ void SegManager::scriptRelocate(reg_t block) {
if (!pos)
continue; // FIXME: A hack pending investigation
if (!relocateLocal(scr, block.segment, pos)) {
if (!relocateLocal(block.segment, pos)) {
bool done = false;
uint k;
@ -418,8 +389,8 @@ void SegManager::scriptRelocate(reg_t block) {
}
}
void SegManager::heapRelocate(reg_t block) {
Script *scr = getScript(block.segment);
void Script::heapRelocate(reg_t block) {
Script *scr = this; // FIXME: Hack
VERIFY(block.offset < (uint16)scr->_heapSize && READ_LE_UINT16(scr->_heapStart + block.offset) * 2 + block.offset < (uint16)scr->_bufSize,
"Relocation block outside of script\n");
@ -432,7 +403,7 @@ void SegManager::heapRelocate(reg_t block) {
for (int i = 0; i < count; i++) {
int pos = READ_LE_UINT16(scr->_heapStart + block.offset + 2 + (i * 2)) + scr->_scriptSize;
if (!relocateLocal(scr, block.segment, pos)) {
if (!relocateLocal(block.segment, pos)) {
bool done = false;
uint k;
@ -504,12 +475,12 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller
}
}
Object *SegManager::scriptObjInit0(reg_t obj_pos) {
Object *Script::scriptObjInit0(reg_t obj_pos) {
Object *obj;
SciVersion version = _resMan->sciVersion(); // for the offset defines
SciVersion version = _sciVersion; // for the offset defines
uint base = obj_pos.offset - SCRIPT_OBJECT_MAGIC_OFFSET;
Script *scr = getScript(obj_pos.segment);
Script *scr = this; // FIXME: Hack
VERIFY(base < scr->_bufSize, "Attempt to initialize object beyond end of script\n");
@ -553,11 +524,11 @@ Object *SegManager::scriptObjInit0(reg_t obj_pos) {
return obj;
}
Object *SegManager::scriptObjInit11(reg_t obj_pos) {
Object *Script::scriptObjInit11(reg_t obj_pos) {
Object *obj;
uint base = obj_pos.offset;
Script *scr = getScript(obj_pos.segment);
Script *scr = this; // FIXME: Hack
VERIFY(base < scr->_bufSize, "Attempt to initialize object beyond end of script\n");
@ -602,8 +573,8 @@ Object *SegManager::scriptObjInit11(reg_t obj_pos) {
return obj;
}
Object *SegManager::scriptObjInit(reg_t obj_pos) {
if (_resMan->sciVersion() < SCI_VERSION_1_1)
Object *Script::scriptObjInit(reg_t obj_pos) {
if (_sciVersion < SCI_VERSION_1_1)
return scriptObjInit0(obj_pos);
else
return scriptObjInit11(obj_pos);
@ -715,7 +686,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {
reg.segment = seg;
reg.offset = seeker - scr->_buf;
obj = scriptObjInit(reg);
obj = scr->scriptObjInit(reg);
#if 0
if (obj->_variables[5].offset != 0xffff) {

View file

@ -155,38 +155,12 @@ public:
*/
void scriptInitialiseLocals(reg_t location);
/**
* Initializes an object within the segment manager
* @param obj_pos Location (segment, offset) of the object. It must
* point to the beginning of the script/class block
* (as opposed to what the VM considers to be the
* object location)
* @returns A newly created Object describing the object,
* stored within the relevant script
*/
Object *scriptObjInit(reg_t obj_pos);
/**
* Informs the segment manager that a code block must be relocated
* @param location Start of block to relocate
*/
void scriptAddCodeBlock(reg_t location);
/**
* Tells the segment manager whether exports are wide (32-bit) or not.
* @param flag true if exports are wide, false otherwise
*/
void setExportAreWide(bool flag);
/**
* Processes a relocation block witin a script
* This function is idempotent, but it must only be called after all
* objects have been instantiated, or a run-time error will occur.
* @param obj_pos Location (segment, offset) of the block
* @return Location of the relocation block
*/
void scriptRelocate(reg_t block);
/**
* Determines whether the script referenced by the indicated segment
* is marked as being deleted.
@ -387,10 +361,8 @@ public:
*/
const char *getObjectName(reg_t pos);
void heapRelocate(reg_t block);
void scriptRelocateExportsSci11(SegmentId seg);
void scriptInitialiseObjectsSci11(SegmentId seg);
int initialiseScript(Script &scr, int script_nr);
SciVersion sciVersion() { return _resMan->sciVersion(); }
@ -417,12 +389,7 @@ private:
Hunk *alloc_Hunk(reg_t *);
int relocateLocal(Script *scr, SegmentId segment, int location);
int relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location);
int relocateObject(Object *obj, SegmentId segment, int location);
SegmentId findFreeSegment() const;
void setScriptSize(Script &scr, int script_nr);
Object *scriptObjInit0(reg_t obj_pos);
Object *scriptObjInit11(reg_t obj_pos);

View file

@ -1546,7 +1546,7 @@ int script_instantiate_common(ResourceManager *resMan, SegManager *segMan, int s
}
}
segMan->initialiseScript(*scr, script_nr);
scr->init(script_nr, resMan);
reg.segment = seg_id;
reg.offset = 0;
@ -1688,11 +1688,11 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr
switch (objtype) {
case SCI_OBJ_CODE:
segMan->scriptAddCodeBlock(addr);
scr->scriptAddCodeBlock(addr);
break;
case SCI_OBJ_OBJECT:
case SCI_OBJ_CLASS: { // object or class?
Object *obj = segMan->scriptObjInit(addr);
Object *obj = scr->scriptObjInit(addr);
Object *base_obj;
// Instantiate the superclass, if neccessary
@ -1717,7 +1717,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr
} while (objtype != 0 && reg.offset < script->size - 2);
if (relocation >= 0)
segMan->scriptRelocate(make_reg(seg_id, relocation));
scr->scriptRelocate(make_reg(seg_id, relocation));
return reg.segment; // instantiation successful
}
@ -1753,7 +1753,7 @@ int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int sc
segMan->scriptInitialiseObjectsSci11(seg_id);
reg.offset = READ_LE_UINT16(heap->data);
segMan->heapRelocate(reg);
scr->heapRelocate(reg);
return seg_id;
}