[Scummvm-cvs-logs] SF.net SVN: scummvm:[51960] tools/branches/gsoc2010-decompiler/decompiler/ kyra
pidgeot at users.sourceforge.net
pidgeot at users.sourceforge.net
Wed Aug 11 00:18:53 CEST 2010
Revision: 51960
http://scummvm.svn.sourceforge.net/scummvm/?rev=51960&view=rev
Author: pidgeot
Date: 2010-08-10 22:18:51 +0000 (Tue, 10 Aug 2010)
Log Message:
-----------
DECOMPILER: Proper support for Kyra return values
as parameters and in conditions
Modified Paths:
--------------
tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp
tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h
Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp 2010-08-10 20:54:02 UTC (rev 51959)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp 2010-08-10 22:18:51 UTC (rev 51960)
@@ -40,7 +40,9 @@
case kLoad:
switch (inst._opcode) {
case 2:
- _stack.push(new VarEntry("retval"));
+ // If something has been called previously in this group, don't output retval variable
+ if (inst._address <= findFirstCall()._address)
+ _stack.push(new VarEntry("retval"));
break;
case 3:
case 4:
@@ -141,7 +143,10 @@
for (size_t i = 0; i < f._metadata.length(); i++)
processSpecialMetadata(inst, f._metadata[i]);
_stack.push(new CallEntry(f._name, _argList));
- if (!f._retVal) {
+ // Leave call on stack if this is a condition, or other calls follow in same group
+ if (_curGroup->_type == kIfCond || _curGroup->_type == kWhileCond || _curGroup->_type == kDoWhileCond || inst._address != findLastCall()._address) {
+ break;
+ } else if (!f._retVal) {
std::stringstream stream;
stream << _stack.pop() << ";";
addOutputLine(stream.str());
@@ -153,7 +158,7 @@
}
case kSpecial:
{
- if (inst._opcode == 2)
+ if (inst._opcode != 14)
return;
_argList.clear();
bool returnsValue = (inst._codeGenData.find("r") == 1);
@@ -161,7 +166,10 @@
for (size_t i = 0; i < metadata.length(); i++)
processSpecialMetadata(inst, metadata[i]);
_stack.push(new CallEntry(inst._name, _argList));
- if (!returnsValue) {
+ // Leave call on stack if this is a condition, or other calls follow in same group
+ if (_curGroup->_type == kIfCond || _curGroup->_type == kWhileCond || _curGroup->_type == kDoWhileCond || inst._address != findLastCall()._address) {
+ break;
+ } else if (!returnsValue) {
std::stringstream stream;
stream << _stack.pop() << ";";
addOutputLine(stream.str());
@@ -181,6 +189,26 @@
}
}
+const Instruction &Kyra::CodeGenerator::findFirstCall() {
+ ConstInstIterator it = _curGroup->_start;
+ do {
+ if (it->_type == kCall || (it->_type == kSpecial && it->_opcode == 14))
+ return *it;
+ } while (it++ != _curGroup->_end);
+
+ return *_curGroup->_start;
+}
+
+const Instruction &Kyra::CodeGenerator::findLastCall() {
+ ConstInstIterator it = _curGroup->_end;
+ do {
+ if (it->_type == kCall || (it->_type == kSpecial && it->_opcode == 14))
+ return *it;
+ } while (it-- != _curGroup->_start);
+
+ return *_curGroup->_end;
+}
+
void Kyra::CodeGenerator::processSpecialMetadata(const Instruction inst, char c) {
switch (c) {
case '0':
Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h 2010-08-10 20:54:02 UTC (rev 51959)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h 2010-08-10 22:18:51 UTC (rev 51960)
@@ -33,6 +33,24 @@
class CodeGenerator : public ::CodeGenerator {
private:
int _stackOffset; ///< Running count of where in the stack to look for the next argument.
+
+ /**
+ * Finds the first call instruction in the current group and returns it.
+ * The call may either be a kCall or kSpecial.
+ * Used to check whether retVal should be output by pushRet.
+ *
+ * @return The first call instruction in the current group. If no calls are found, returns the first instruction.
+ */
+ const Instruction &findFirstCall();
+
+ /**
+ * Finds the last call instruction in the current group and returns it.
+ * The call may either be a kCall or kSpecial.
+ * Used to check whether retVal should be output by calls.
+ *
+ * @return The last call instruction in the current group. If no calls are found, returns the last instruction.
+ */
+ const Instruction &findLastCall();
public:
/**
* Constructor for Kyra::CodeGenerator.
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