Limit access to the _classTable array (now it's directly accessible only inside saveLoadWithSerializer()

svn-id: r49318
This commit is contained in:
Filippos Karapetis 2010-05-29 23:56:37 +00:00
parent 67de5b1bd3
commit 5f2ff0b1e7
6 changed files with 35 additions and 30 deletions

View File

@ -277,8 +277,8 @@ void Console::postEnter() {
#if 0
// Unused
#define LOOKUP_SPECIES(species) (\
(species >= 1000) ? species : *(s->_classtable[species].scriptposp) \
+ s->_classtable[species].class_offset)
(species >= 1000) ? species : *(s->_classTable[species].scriptposp) \
+ s->_classTable[species].class_offset)
#endif
bool Console::cmdHelp(int argc, const char **argv) {
@ -929,11 +929,11 @@ bool Console::cmdRestartGame(int argc, const char **argv) {
bool Console::cmdClassTable(int argc, const char **argv) {
DebugPrintf("Available classes:\n");
for (uint i = 0; i < _engine->_gamestate->_segMan->_classtable.size(); i++) {
if (_engine->_gamestate->_segMan->_classtable[i].reg.segment) {
for (uint i = 0; i < _engine->_gamestate->_segMan->classTableSize(); i++) {
if (_engine->_gamestate->_segMan->_classTable[i].reg.segment) {
DebugPrintf(" Class 0x%x at %04x:%04x (script 0x%x)\n", i,
PRINT_REG(_engine->_gamestate->_segMan->_classtable[i].reg),
_engine->_gamestate->_segMan->_classtable[i].script);
PRINT_REG(_engine->_gamestate->_segMan->_classTable[i].reg),
_engine->_gamestate->_segMan->_classTable[i].script);
}
}

View File

@ -383,7 +383,7 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) {
sync_SegManagerPtr(s, _segMan);
syncArray<Class>(s, _segMan->_classtable);
syncArray<Class>(s, _segMan->_classTable);
#ifdef USE_OLD_MUSIC_FUNCTIONS
sync_songlib(s, _sound._songlib);

View File

@ -123,13 +123,13 @@ void SegManager::createClassTable() {
error("SegManager: failed to open vocab 996");
int totalClasses = vocab996->size >> 2;
_classtable.resize(totalClasses);
_classTable.resize(totalClasses);
for (uint16 classNr = 0; classNr < totalClasses; classNr++) {
uint16 scriptNr = READ_SCI11ENDIAN_UINT16(vocab996->data + classNr * 4 + 2);
_classtable[classNr].reg = NULL_REG;
_classtable[classNr].script = scriptNr;
_classTable[classNr].reg = NULL_REG;
_classTable[classNr].script = scriptNr;
}
_resMan->unlockResource(vocab996);
@ -139,11 +139,11 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller
if (classnr == 0xffff)
return NULL_REG;
if (classnr < 0 || (int)_classtable.size() <= classnr || _classtable[classnr].script < 0) {
error("[VM] Attempt to dereference class %x, which doesn't exist (max %x)", classnr, _classtable.size());
if (classnr < 0 || (int)_classTable.size() <= classnr || _classTable[classnr].script < 0) {
error("[VM] Attempt to dereference class %x, which doesn't exist (max %x)", classnr, _classTable.size());
return NULL_REG;
} else {
Class *the_class = &_classtable[classnr];
Class *the_class = &_classTable[classnr];
if (!the_class->reg.segment) {
getScriptSegment(the_class->script, lock);
@ -209,14 +209,14 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {
int classpos = seeker - scr->_buf;
int species = READ_SCI11ENDIAN_UINT16(seeker + 10);
if (species < 0 || species >= (int)_classtable.size()) {
if (species < 0 || species >= (int)_classTable.size()) {
error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d",
species, species, _classtable.size(), scr->_nr);
species, species, _classTable.size(), scr->_nr);
return;
}
_classtable[species].reg.segment = seg;
_classtable[species].reg.offset = classpos;
_classTable[species].reg.segment = seg;
_classTable[species].reg.offset = classpos;
}
seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2;
}
@ -372,22 +372,21 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr
case SCI_OBJ_CLASS: {
int classpos = curOffset - SCRIPT_OBJECT_MAGIC_OFFSET;
int species = scr->getHeap(curOffset - SCRIPT_OBJECT_MAGIC_OFFSET + SCRIPT_SPECIES_OFFSET);
if (species < 0 || species >= (int)segMan->_classtable.size()) {
if (species == (int)segMan->_classtable.size()) {
if (species < 0 || species >= (int)segMan->classTableSize()) {
if (species == (int)segMan->classTableSize()) {
// Happens in the LSL2 demo
warning("Applying workaround for an off-by-one invalid species access");
segMan->_classtable.resize(segMan->_classtable.size() + 1);
segMan->resizeClassTable(segMan->classTableSize() + 1);
} else {
warning("Invalid species %d(0x%x) not in interval "
"[0,%d) while instantiating script %d\n",
species, species, segMan->_classtable.size(),
species, species, segMan->classTableSize(),
script_nr);
return 0;
}
}
segMan->_classtable[species].reg.segment = seg_id;
segMan->_classtable[species].reg.offset = classpos;
segMan->setClassOffset(species, make_reg(seg_id, classpos));
// Set technical class position-- into the block allocated for it
}
break;
@ -507,7 +506,7 @@ void script_uninstantiate_sci0(SegManager *segMan, int script_nr, SegmentId seg)
superclass = scr->getHeap(reg.offset + SCRIPT_SUPERCLASS_OFFSET); // Get superclass...
if (superclass >= 0) {
int superclass_script = segMan->_classtable[superclass].script;
int superclass_script = segMan->getClass(superclass).script;
if (superclass_script == script_nr) {
if (scr->getLockers())
@ -541,9 +540,9 @@ void script_uninstantiate(SegManager *segMan, int script_nr) {
return;
// Free all classtable references to this script
for (uint i = 0; i < segMan->_classtable.size(); i++)
if (segMan->_classtable[i].reg.segment == segment)
segMan->_classtable[i].reg = NULL_REG;
for (uint i = 0; i < segMan->classTableSize(); i++)
if (segMan->getClass(i).reg.segment == segment)
segMan->setClassOffset(i, NULL_REG);
if (getSciVersion() < SCI_VERSION_1_1)
script_uninstantiate_sci0(segMan, script_nr, segment);

View File

@ -77,7 +77,7 @@ void SegManager::resetSegMan() {
Hunks_seg_id = 0;
// Reinitialize class table
_classtable.clear();
_classTable.clear();
createClassTable();
}

View File

@ -436,9 +436,15 @@ public:
void scriptInitialiseObjectsSci11(SegmentId seg);
uint32 classTableSize() { return _classTable.size(); }
Class getClass(int index) { return _classTable[index]; }
void setClassOffset(int index, reg_t offset) { _classTable[index].reg = offset; }
void resizeClassTable(uint32 size) { _classTable.resize(size); }
public: // TODO: make private
Common::Array<SegmentObj *> _heap;
Common::Array<Class> _classtable; /**< Table of all classes */
// Only accessible from saveLoadWithSerializer()
Common::Array<Class> _classTable; /**< Table of all classes */
#ifdef ENABLE_SCI32
SciArray<reg_t> *allocateArray(reg_t *addr);

View File

@ -46,7 +46,7 @@ class ResourceManager;
/** Maximum number of calls residing on the stack */
#define SCRIPT_MAX_EXEC_STACK 256
/** Maximum number of entries in the class table */
#define SCRIPT_MAX_CLASSTABLE_SIZE 256
#define SCRIPT_MAX_classTable_SIZE 256
/** Maximum number of cloned objects on the heap */
#define SCRIPT_MAX_CLONES 256