[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