[Scummvm-cvs-logs] SF.net SVN: scummvm:[49608] tools/branches/gsoc2010-decompiler/decompiler
pidgeot at users.sourceforge.net
pidgeot at users.sourceforge.net
Sat Jun 12 21:56:44 CEST 2010
Revision: 49608
http://scummvm.svn.sourceforge.net/scummvm/?rev=49608&view=rev
Author: pidgeot
Date: 2010-06-12 19:56:44 +0000 (Sat, 12 Jun 2010)
Log Message:
-----------
Find stack effect for variable length opcodes in SCUMMv6
Fix parameter list for pickVarRandom
Fix a regression introduced in r49522 for scripts with no instructions:
program would try to read past end of file due to the check used to
prevent repeated disassembly
Modified Paths:
--------------
tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp
tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp
tools/branches/gsoc2010-decompiler/decompiler/disassembler.h
tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp
tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.h
Modified: tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp 2010-06-12 18:20:22 UTC (rev 49607)
+++ tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp 2010-06-12 19:56:44 UTC (rev 49608)
@@ -114,7 +114,7 @@
delete disassembler;
} catch (std::exception& e) {
- std::cerr << "ERROR: " << e.what();
+ std::cerr << "ERROR: " << e.what() << "\n";
return 3;
}
Modified: tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp 2010-06-12 18:20:22 UTC (rev 49607)
+++ tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp 2010-06-12 19:56:44 UTC (rev 49608)
@@ -26,6 +26,7 @@
Disassembler::Disassembler() {
_addressBase = 0;
+ _disassemblyDone = false;
}
void Disassembler::open(const char *filename) {
@@ -33,27 +34,29 @@
}
void Disassembler::doDumpDisassembly(std::ostream &output) {
- std::vector<Instruction>::iterator inst;
+ InstIterator inst;
for (inst = _insts.begin(); inst != _insts.end(); ++inst) {
- output << boost::format("%08x: %s ") % inst->_address % inst->_name;
+ output << boost::format("%08x: %s") % inst->_address % inst->_name;
std::vector<Parameter>::iterator param;
for (param = inst->_params.begin(); param != inst->_params.end(); ++param) {
if (param != inst->_params.begin())
- output << ", ";
- output << param->_value;
+ output << ",";
+ output << " " << param->_value;
}
- output << "\n";
+ output << boost::format(" (%d)") % inst->_stackChange << "\n";
}
}
const std::vector<Instruction> &Disassembler::disassemble() {
- if (_insts.empty())
+ if (_disassemblyDone)
doDisassemble();
+ _disassemblyDone = true;
return _insts;
}
void Disassembler::dumpDisassembly(std::ostream &output) {
- if (_insts.empty())
+ if (_disassemblyDone)
doDisassemble();
+ _disassemblyDone = true;
doDumpDisassembly(output);
}
Modified: tools/branches/gsoc2010-decompiler/decompiler/disassembler.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/disassembler.h 2010-06-12 18:20:22 UTC (rev 49607)
+++ tools/branches/gsoc2010-decompiler/decompiler/disassembler.h 2010-06-12 19:56:44 UTC (rev 49608)
@@ -30,6 +30,8 @@
#include "common/file.h"
#include "unknown_opcode.h"
+typedef std::vector<Instruction>::iterator InstIterator;
+
/**
* Base class for disassemblers.
*/
@@ -38,6 +40,7 @@
Common::File _f; ///< Used to perform file I/O.
std::vector<Instruction> _insts; ///< Container for disassembled instructions.
uint32 _addressBase; ///< Base address where the script starts.
+ bool _disassemblyDone; ///< Indicates whether or not disassembly has already been performed.
/**
* Performs disassembly.
Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp 2010-06-12 18:20:22 UTC (rev 49607)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp 2010-06-12 19:56:44 UTC (rev 49608)
@@ -93,9 +93,9 @@
OPCODE(0x5B, "wordArrayDec", kArithmetic, -1, "s");
OPCODE(0x5C, "jumpTrue", kCondJumpRel, -1, "s");
OPCODE(0x5D, "jumpFalse", kCondJumpRel, -1, "s");
- OPCODE(0x5E, "startScript", kSpecial, -255, ""); //Variable stack arguments
- OPCODE(0x5F, "startScriptQuick", kSpecial, -255, ""); //Variable stack arguments
- OPCODE(0x60, "startObject", kSpecial, -255, ""); //Variable stack arguments
+ OPCODE(0x5E, "startScript", kSpecial, 0x1020, ""); //Variable stack arguments
+ OPCODE(0x5F, "startScriptQuick", kSpecial, 0x1010, ""); //Variable stack arguments
+ OPCODE(0x60, "startObject", kSpecial, 0x1030, ""); //Variable stack arguments
OPCODE(0x61, "drawObject", kSpecial, -2, "");
OPCODE(0x62, "drawObjectAt", kSpecial, -3, "");
OPCODE(0x63, "drawBlastObject", kSpecial, 0, "");
@@ -103,7 +103,7 @@
OPCODE(0x65, "stopObjectCodeA", kSpecial, 0, "");
OPCODE(0x66, "stopObjectCodeB", kSpecial, 0, "");
OPCODE(0x67, "endCutscene", kSpecial, 0, "");
- OPCODE(0x68, "beginCutscene", kSpecial, -255, ""); //Variable stack arguments
+ OPCODE(0x68, "beginCutscene", kSpecial, 0x1000, ""); //Variable stack arguments
OPCODE(0x69, "stopMusic", kSpecial, 0, "");
OPCODE(0x6A, "freezeUnfreeze", kSpecial, -1, "");
START_SUBOPCODE(0x6B); //cursorCommand
@@ -118,12 +118,12 @@
OPCODE(0x99, "cursorCmd_Image", kSpecial, -2, "");
OPCODE(0x9A, "cursorCmd_Hotspot", kSpecial, -2, "");
OPCODE(0x9C, "cursorCmd_CharsetSet", kSpecial, -1, "");
- OPCODE(0x9D, "cursorCmd_CharsetColor", kSpecial, -255, ""); //Variable stack arguments
+ OPCODE(0x9D, "cursorCmd_CharsetColors", kSpecial, 0x1000, ""); //Variable stack arguments
OPCODE(0xD6, "cursorCmd_Transparent", kSpecial, -1, "");
END_SUBOPCODE;
OPCODE(0x6C, "breakHere", kSpecial, 0, "");
- OPCODE(0x6D, "ifClassOfIs", kSpecial, -255, ""); //Variable stack arguments
- OPCODE(0x6E, "setClass", kSpecial, -255, ""); //Variable stack arguments
+ OPCODE(0x6D, "ifClassOfIs", kSpecial, 0x1011, ""); //Variable stack arguments
+ OPCODE(0x6E, "setClass", kSpecial, 0x1010, ""); //Variable stack arguments
OPCODE(0x6F, "getState", kSpecial, 0, "");
OPCODE(0x70, "setState", kSpecial, -2, "");
OPCODE(0x71, "setOwner", kSpecial, -2, "");
@@ -164,7 +164,7 @@
OPCODE(0x96, "endOverride", kSpecial, 0, "");
OPCODE(0x97, "setObjectName", kSpecial, -1, "c");
OPCODE(0x98, "isSoundRunning", kSpecial, 0, "");
- OPCODE(0x99, "setBoxFlags", kSpecial, -255, ""); //Variable stack arguments
+ OPCODE(0x99, "setBoxFlags", kSpecial, 0x1100, ""); //Variable stack arguments
OPCODE(0x9A, "createBoxMatrix", kSpecial, 0, "");
START_SUBOPCODE(0x9B); //resourceRoutines
OPCODE(0x64, "resRoutine_loadScript", kSpecial, -1, "");
@@ -206,7 +206,7 @@
START_SUBOPCODE(0x9D); //actorOps
OPCODE(0x4C, "actorOp_setCostume", kSpecial, -1, "");
OPCODE(0x4D, "actorOp_setWalkSpeed", kSpecial, -2, "");
- OPCODE(0x4E, "actorOp_setSound", kSpecial, -255, ""); //Variable stack arguments
+ OPCODE(0x4E, "actorOp_setSound", kSpecial, 0x1000, ""); //Variable stack arguments
OPCODE(0x4F, "actorOp_setWalkFrame", kSpecial, -1, "");
OPCODE(0x50, "actorOp_setTalkFrame", kSpecial, -2, "");
OPCODE(0x51, "actorOp_setStandFrame", kSpecial, -1, "");
@@ -264,13 +264,13 @@
END_SUBOPCODE;
OPCODE(0x9F, "getActorFromXY", kSpecial, -1, "");
OPCODE(0xA0, "findObject", kSpecial, -1, "");
- OPCODE(0xA1, "pseudoRoom", kSpecial, -255, ""); //Variable stack arguments
+ OPCODE(0xA1, "pseudoRoom", kSpecial, 0x1010, ""); //Variable stack arguments
OPCODE(0xA2, "getActorElevation", kSpecial, 0, "");
OPCODE(0xA3, "getVerbEntrypoint", kSpecial, -1, "");
START_SUBOPCODE(0xA4); //arrayOps
OPCODE(0xCD, "arrayOp_assignString", kSpecial, -1, "sc");
- OPCODE(0xD0, "arrayOp_assignIntList", kSpecial, -255, "s"); //Variable stack arguments
- OPCODE(0xD4, "arrayOp_assign2DimList", kSpecial, -255, "s"); //Variable stack arguments
+ OPCODE(0xD0, "arrayOp_assignIntList", kSpecial, 0x1100, "s"); //Variable stack arguments
+ OPCODE(0xD4, "arrayOp_assign2DimList", kSpecial, 0x1100, "s"); //Variable stack arguments
END_SUBOPCODE;
START_SUBOPCODE(0xA5); //saveRestoreVerbs
OPCODE(0x8D, "srVerb_saveVerbs", kSpecial, -3, "");
@@ -290,8 +290,8 @@
END_SUBOPCODE;
OPCODE(0xAA, "getActorScaleX", kSpecial, 0, "");
OPCODE(0xAB, "getActorAnimCounter", kSpecial, 0, "");
- OPCODE(0xAC, "soundKludge", kSpecial, -255, ""); //Variable stack arguments
- OPCODE(0xAD, "isAnyOf", kSpecial, -255, ""); //Variable stack arguments
+ OPCODE(0xAC, "soundKludge", kSpecial, 0x1000, ""); //Variable stack arguments
+ OPCODE(0xAD, "isAnyOf", kSpecial, 0x1011, ""); //Variable stack arguments
START_SUBOPCODE(0xAE); //systemOps
OPCODE(0x9E, "systemOp_restartGame", kSpecial, 0, "");
OPCODE(0x9F, "systemOp_pauseGame", kSpecial, 0, "");
@@ -384,8 +384,8 @@
OPCODE(0xCB, "dimArrayString", kSpecial, -1, "s");
OPCODE(0xCC, "dimArray_nukeArray", kSpecial, 0, "s");
END_SUBOPCODE;
- OPCODE(0xBE, "startObjectQuick", kSpecial, -255, ""); //Variable stack arguments
- OPCODE(0xBF, "startScriptQuick2", kSpecial, -255, ""); //Variable stack arguments
+ OPCODE(0xBE, "startObjectQuick", kSpecial, 0x1020, ""); //Variable stack arguments
+ OPCODE(0xBF, "startScriptQuick2", kSpecial, 0x1010, ""); //Variable stack arguments
START_SUBOPCODE(0xC0); //dim2DimArray
OPCODE(0xC7, "dim2DimArrayInt", kSpecial, -2, "s");
OPCODE(0xC8, "dim2DimArrayBit", kSpecial, -2, "s");
@@ -400,26 +400,40 @@
OPCODE(0xC8, "kernelGetFunctions", kSpecial, -255, ""); //Variable stack arguments
OPCODE(0xC9, "kernelSetFunctions", kSpecial, -255, ""); //Variable stack arguments
OPCODE(0xCA, "delayFrames", kSpecial, -1, "");
- OPCODE(0xCB, "pickOneOf", kSpecial, -255, ""); //Variable stack arguments
- OPCODE(0xCC, "pickOneOfDefault", kSpecial, -255, ""); //Variable stack arguments
+ OPCODE(0xCB, "pickOneOf", kSpecial, 0x1011, ""); //Variable stack arguments
+ OPCODE(0xCC, "pickOneOfDefault", kSpecial, 0x111, ""); //Variable stack arguments
OPCODE(0xCD, "stampObject", kSpecial, -4, "");
OPCODE(0xD0, "getDateTime", kSpecial, 0, "");
OPCODE(0xD1, "stopTalking", kSpecial, 0, "");
OPCODE(0xD2, "getAnimateVariable", kSpecial, -1, "");
OPCODE(0xD4, "shuffle", kSpecial, -2, "s");
- OPCODE(0xD5, "jumpToScript", kSpecial, -255, ""); //Variable stack arguments
+ OPCODE(0xD5, "jumpToScript", kSpecial, 0x1020, ""); //Variable stack arguments
OPCODE(0xD6, "band", kBoolean, -1, "");
OPCODE(0xD7, "bor", kBoolean, -1, "");
OPCODE(0xD8, "isRoomScriptRunning", kSpecial, 0, "");
OPCODE(0xDD, "findAllObjects", kSpecial, 0, "");
OPCODE(0xE1, "getPixel", kSpecial, -1, "");
- OPCODE(0xE3, "pickVarRandom", kSpecial, -255, ""); //Variable stack arguments
+ OPCODE(0xE3, "pickVarRandom", kSpecial, 0x1001, "s"); //Variable stack arguments
OPCODE(0xE4, "setBoxSet", kSpecial, -1, "");
OPCODE(0xEC, "getActorLayer", kSpecial, 0, "");
OPCODE(0xED, "getObjectNewDir", kSpecial, 0, "");
END_OPCODES;
+
+ InstIterator it;
+ for (it = _insts.begin(); it != _insts.end(); ++it)
+ if (it->_stackChange >= 0x1000)
+ fixStackEffect(it, (it->_stackChange >> 8) & 0xF, (it->_stackChange >> 4) & 0xF, it->_stackChange & 0xF);
}
+void Scumm::v6::Disassembler::fixStackEffect(InstIterator &it, int popBefore, int popAfter, int pushTotal) {
+ it->_stackChange = -popBefore - popAfter + pushTotal;
+ InstIterator it2 = it;
+ for (--it2; popBefore != 0; --it2)
+ if (it2->_type == kLoad)
+ --popBefore;
+ it->_stackChange -= it2->_params[0].getSigned();
+}
+
void Scumm::v6::Disassembler::readParameter(Parameter *p, char type) {
switch (type) {
case 'c': //Character string
Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.h 2010-06-12 18:20:22 UTC (rev 49607)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.h 2010-06-12 19:56:44 UTC (rev 49608)
@@ -37,6 +37,8 @@
void doDisassemble();
void readParameter(Parameter *p, char type);
+
+ void fixStackEffect(InstIterator &it, int popBefore, int popAfter, int pushTotal);
};
} //End of namespace Scumm::v6
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list