SCI: Turn some SegManager methods into Script methods
svn-id: r44127
This commit is contained in:
parent
a277123f54
commit
68dfdce043
6 changed files with 105 additions and 97 deletions
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue