[Scummvm-cvs-logs] SF.net SVN: scummvm:[51127] tools/branches/gsoc2010-decompiler/decompiler
pidgeot at users.sourceforge.net
pidgeot at users.sourceforge.net
Thu Jul 22 02:14:51 CEST 2010
Revision: 51127
http://scummvm.svn.sourceforge.net/scummvm/?rev=51127&view=rev
Author: pidgeot
Date: 2010-07-22 00:14:51 +0000 (Thu, 22 Jul 2010)
Log Message:
-----------
Codegen improvements
Add new entry types for strings and lists
Add final missing opcodes that require special handling
Add function to create SCUMM list from stack
Modified Paths:
--------------
tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp
tools/branches/gsoc2010-decompiler/decompiler/codegen.h
tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp
tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h
Modified: tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp 2010-07-21 23:34:08 UTC (rev 51126)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp 2010-07-22 00:14:51 UTC (rev 51127)
@@ -144,7 +144,7 @@
ConstInstIterator it = _curGroup->_start;
do {
- if (it->_codeGenData.length() > 0 && it->_codeGenData.find("\xC0") == 0)
+ if (it->_codeGenData.find("\xC0") == 0)
processInst(*it);
else {
switch (it->_type) {
@@ -161,7 +161,7 @@
}
case kUnaryOp:
//TODO: Allow operator to be placed on either side of operand
- _stack.push(new UnaryOpEntry(_stack.pop(), inst._codeGenData));
+ _stack.push(new UnaryOpEntry(_stack.pop(), it->_codeGenData));
break;
case kBinaryOp:
case kComparison:
Modified: tools/branches/gsoc2010-decompiler/decompiler/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/codegen.h 2010-07-21 23:34:08 UTC (rev 51126)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.h 2010-07-22 00:14:51 UTC (rev 51127)
@@ -41,6 +41,8 @@
const StackEntryType seUnaryOp = 3;
const StackEntryType seDup = 4;
const StackEntryType seArray = 5;
+const StackEntryType seString = 6;
+const StackEntryType seList = 7;
class StackEntry;
@@ -254,7 +256,7 @@
/**
* Type representing index list for an array.
*/
-typedef std::deque<EntryPtr> ArrayIdxType;
+typedef std::deque<EntryPtr> EntryList;
/**
* Stack entry representing array access.
@@ -262,7 +264,7 @@
class ArrayEntry : public StackEntry {
private:
const std::string _arrayName; ///< The name of the array.
- ArrayIdxType _idxs; ///< std::deque of stack entries representing the indexes used (left-to-right).
+ EntryList _idxs; ///< std::deque of stack entries representing the indexes used (left-to-right).
public:
/**
@@ -275,13 +277,50 @@
virtual std::ostream &print(std::ostream &output) const {
output << _arrayName;
- for (ArrayIdxType::const_iterator i = _idxs.begin(); i != _idxs.end(); ++i)
+ for (EntryList::const_iterator i = _idxs.begin(); i != _idxs.end(); ++i)
output << "[" << *i << "]";
return output;
}
};
/**
+ * Entry containing a string.
+ */
+class StringEntry : public StackEntry {
+private:
+ const std::string _str; ///< The string in the entry.
+
+public:
+ StringEntry(std::string str) : StackEntry(seString), _str(str) { }
+
+ virtual std::ostream &print(std::ostream &output) const {
+ return output << _str;
+ }
+};
+
+/**
+ * Entry representing a list.
+ */
+class ListEntry : public StackEntry {
+private:
+ const EntryList _items; ///< Vector containing the list items.
+
+public:
+ ListEntry(EntryList items) : StackEntry(seList), _items(items) { }
+
+ virtual std::ostream &print(std::ostream &output) const {
+ output << "[";
+ for (EntryList::const_iterator i = _items.begin(); i != _items.end(); ++i) {
+ if (i != _items.begin())
+ output << ", ";
+ output << *i;
+ }
+ output << "]";
+ return output;
+ }
+};
+
+/**
* Type representing a stack.
*/
typedef Stack<EntryPtr> EntryStack;
Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp 2010-07-21 23:34:08 UTC (rev 51126)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp 2010-07-22 00:14:51 UTC (rev 51127)
@@ -22,6 +22,18 @@
#include "codegen.h"
+EntryPtr Scumm::v6::CodeGenerator::createListEntry() {
+ EntryList list;
+ EntryPtr countEntry = _stack.pop();
+ std::stringstream s;
+ s << countEntry;
+ int count = atoi(s.str().c_str());
+ for (int i = 0; i < count; i++) {
+ list.push_front(_stack.pop());
+ }
+ return new ListEntry(list);
+}
+
void Scumm::v6::CodeGenerator::processInst(const Instruction inst) {
// TODO
@@ -31,10 +43,10 @@
case kLoad:
switch (inst._opcode) {
case 0x00: // pushByte
- _stack.push(new IntEntry(inst._params[0].getUnsigned(), true));
+ _stack.push(new IntEntry(inst._params[0].getUnsigned(), false));
break;
case 0x01: // pushWord
- _stack.push(new IntEntry(inst._params[0].getSigned(), false));
+ _stack.push(new IntEntry(inst._params[0].getSigned(), true));
break;
case 0x02: // pushByteVar
case 0x03: // pushWordVar
@@ -43,7 +55,7 @@
case 0x06: // byteArrayRead
case 0x07: // wordArrayRead
{
- ArrayIdxType idxs;
+ EntryList idxs;
idxs.push_front(_stack.pop());
_stack.push(new ArrayEntry(decodeArrayName(inst._params[0].getUnsigned()), idxs));
break;
@@ -51,7 +63,7 @@
case 0x0A: // byteArrayIndexedRead
case 0x0B: // wordArrayIndexedRead
{
- ArrayIdxType idxs;
+ EntryList idxs;
idxs.push_front(_stack.pop());
idxs.push_front(_stack.pop());
_stack.push(new ArrayEntry(decodeArrayName(inst._params[0].getUnsigned()), idxs));
@@ -63,32 +75,39 @@
switch (inst._opcode) {
case 0x42: // writeByteVar
case 0x43: // writeWordVar
- {
- EntryPtr p = new VarEntry(decodeVarName(inst._params[0].getUnsigned()));
- writeAssignment(p, _stack.pop());
+ {
+ EntryPtr p = new VarEntry(decodeVarName(inst._params[0].getUnsigned()));
+ writeAssignment(p, _stack.pop());
+ }
break;
- }
case 0x46: // byteArrayWrite
case 0x47: // wordArrayWrite
- {
- EntryPtr value = _stack.pop();
- ArrayIdxType idxs;
- idxs.push_back(_stack.pop());
- EntryPtr p = new ArrayEntry(decodeArrayName(inst._params[0].getUnsigned()), idxs);
- writeAssignment(p, value);
+ {
+ EntryPtr value = _stack.pop();
+ EntryList idxs;
+ idxs.push_back(_stack.pop());
+ EntryPtr p = new ArrayEntry(decodeArrayName(inst._params[0].getUnsigned()), idxs);
+ writeAssignment(p, value);
+ }
break;
- }
case 0x4A: // byteArrayIndexedWrite
case 0x4B: // wordArrayIndexedWrite
- {
- EntryPtr value = _stack.pop();
- ArrayIdxType idxs;
- idxs.push_front(_stack.pop());
- idxs.push_front(_stack.pop());
- EntryPtr p = new ArrayEntry(decodeArrayName(inst._params[0].getUnsigned()), idxs);
- writeAssignment(p, value);
+ {
+ EntryPtr value = _stack.pop();
+ EntryList idxs;
+ idxs.push_front(_stack.pop());
+ idxs.push_front(_stack.pop());
+ EntryPtr p = new ArrayEntry(decodeArrayName(inst._params[0].getUnsigned()), idxs);
+ writeAssignment(p, value);
+ }
break;
- }
+ default:
+ {
+ std::stringstream s;
+ s << boost::format("Unknown opcode %X at address %08X") % inst._opcode % inst._address;
+ addOutputLine(s.str());
+ }
+ break;
}
break;
case kStack:
@@ -111,8 +130,8 @@
std::stringstream s;
s << boost::format("Couldn't handle conditional jump at address %08X") % inst._address;
addOutputLine(s.str());
- break;
}
+ break;
}
break;
case kUnaryOp:
@@ -126,31 +145,78 @@
EntryPtr p = new UnaryOpEntry(new VarEntry(decodeVarName(inst._params[0].getUnsigned())), inst._codeGenData);
s << p;
addOutputLine(s.str());
- break;
}
+ break;
case 0x52: // byteArrayInc
case 0x53: // wordArrayInc
case 0x5A: // byteArrayDec
case 0x5B: // wordArrayDec
{
std::stringstream s;
- ArrayIdxType idxs;
+ EntryList idxs;
idxs.push_front(_stack.pop());
EntryPtr p = new UnaryOpEntry(new ArrayEntry(decodeVarName(inst._params[0].getUnsigned()), idxs), inst._codeGenData);
s << p;
addOutputLine(s.str());
- break;
}
break;
+ default:
+ {
+ std::stringstream s;
+ s << boost::format("Unknown opcode %X at address %08X") % inst._opcode % inst._address;
+ addOutputLine(s.str());
+ }
+ break;
}
break;
+ case kSpecial:
+ switch (inst._opcode) {
+ case 0xA4CD: // arrayOp_assignString
+ {
+ EntryPtr value = new StringEntry(inst._params[1].getString());
+ EntryList idxs;
+ idxs.push_front(_stack.pop());
+ EntryPtr p = new ArrayEntry(decodeArrayName(inst._params[0].getUnsigned()), idxs);
+ writeAssignment(p, value);
+ }
+ break;
+ case 0xA4D0: // arrayOp_assignIntList
+ {
+ EntryList idxs;
+ idxs.push_front(_stack.pop());
+ EntryPtr value = createListEntry();
+ EntryPtr p = new ArrayEntry(decodeArrayName(inst._params[0].getUnsigned()), idxs);
+ writeAssignment(p, value);
+ }
+
+ break;
+ case 0xA4D4: // arrayOp_assign2DimList
+ {
+ EntryList idxs;
+ idxs.push_front(_stack.pop());
+ EntryPtr value = createListEntry();
+ idxs.push_front(_stack.pop());
+ EntryPtr p = new ArrayEntry(decodeArrayName(inst._params[0].getUnsigned()), idxs);
+ writeAssignment(p, value);
+ }
+
+ break;
+ default:
+ {
+ std::stringstream s;
+ s << boost::format("Unknown opcode %X at address %08X") % inst._opcode % inst._address;
+ addOutputLine(s.str());
+ }
+ break;
+ }
+ break;
default:
{
std::stringstream s;
s << boost::format("Unknown opcode %X at address %08X") % inst._opcode % inst._address;
addOutputLine(s.str());
- break;
}
+ break;
}
}
Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h 2010-07-21 23:34:08 UTC (rev 51126)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h 2010-07-22 00:14:51 UTC (rev 51127)
@@ -57,6 +57,13 @@
* @return The decoded array name.
*/
std::string decodeArrayName(uint16 arrID);
+
+ /**
+ * Creates a ListEntry from the stack.
+ *
+ * @return The ListEntry created from the stack.
+ */
+ EntryPtr createListEntry();
public:
CodeGenerator(Engine *engine, std::ostream &output) : ::CodeGenerator(engine, output) {}
protected:
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