[Scummvm-cvs-logs] SF.net SVN: scummvm:[51189] tools/branches/gsoc2010-decompiler/decompiler

pidgeot at users.sourceforge.net pidgeot at users.sourceforge.net
Fri Jul 23 03:38:35 CEST 2010


Revision: 51189
          http://scummvm.svn.sourceforge.net/scummvm/?rev=51189&view=rev
Author:   pidgeot
Date:     2010-07-23 01:38:34 +0000 (Fri, 23 Jul 2010)

Log Message:
-----------
Add handling of kSpecial metadata for SCUMMv6

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-23 01:05:26 UTC (rev 51188)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp	2010-07-23 01:38:34 UTC (rev 51189)
@@ -38,7 +38,7 @@
 		return this;
 
 	EntryPtr dupEntry = new DupEntry(++dupindex);
-	output << dupEntry << " = " << (EntryPtr)this;
+	output << dupEntry << " = " << (EntryPtr)this << ";";
 	return dupEntry;
 }
 
@@ -222,11 +222,17 @@
 				break;
 			case kSpecial:
 				{
-					std::stringstream s;
-					s << it->_name << "(";
-					// TODO: Process metadata
-					s << ")";
-					addOutputLine(s.str());
+					_argList.clear();
+					bool returnsValue = (it->_codeGenData.find("r") == 0);
+					std::string metadata = (!returnsValue ? it->_codeGenData : it->_codeGenData.substr(1) );
+					for (size_t i = 0; i < metadata.length(); i++)
+						processSpecialMetadata(*it, metadata[i]);
+					_stack.push(new CallEntry(it->_name, _argList));
+					if (!returnsValue) {
+						std::stringstream stream;
+						stream << _stack.pop() << ";";
+						addOutputLine(stream.str());
+					}
 					break;
 				}
 			default:
@@ -240,3 +246,15 @@
 	if (_curGroup->_endElse != NULL)
 		addOutputLine("}");
 }
+
+void CodeGenerator::processSpecialMetadata(const Instruction inst, char c) {
+	// TODO: Allow subclasses to decide if they want push_front or push_back.
+	switch (c) {
+		case 'p':
+			_argList.push_front(_stack.pop());
+			break;
+		default:
+			std::cerr << boost::format("Unknown character in metadata: %c\n") % c ;
+			break;
+	}
+}

Modified: tools/branches/gsoc2010-decompiler/decompiler/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/codegen.h	2010-07-23 01:05:26 UTC (rev 51188)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.h	2010-07-23 01:38:34 UTC (rev 51189)
@@ -43,6 +43,7 @@
 const StackEntryType seArray = 5;
 const StackEntryType seString = 6;
 const StackEntryType seList = 7;
+const StackEntryType seCall = 8;
 
 class StackEntry;
 
@@ -66,7 +67,7 @@
 	friend void ::boost::intrusive_ptr_release(StackEntry *p); ///< Allow access by reference counting methods in boost namespace.
 
 public:
-	const StackEntryType _type;
+	const StackEntryType _type; ///< Type of the stack entry.
 
 	/**
 	 * Constructor for StackEntry.
@@ -264,7 +265,7 @@
 class ArrayEntry : public StackEntry {
 private:
 	const std::string _arrayName; ///< The name of the array.
-	EntryList _idxs;              ///< std::deque of stack entries representing the indexes used (left-to-right).
+	const EntryList _idxs;              ///< std::deque of stack entries representing the indexes used (left-to-right).
 
 public:
 	/**
@@ -291,6 +292,11 @@
 	const std::string _str; ///< The string in the entry.
 
 public:
+	/**
+	 * Constructor for StringEntry.
+	 *
+	 * @param str The string in the entry.
+	 */
 	StringEntry(std::string str) : StackEntry(seString), _str(str) { }
 
 	virtual std::ostream &print(std::ostream &output) const {
@@ -306,6 +312,11 @@
 	const EntryList _items; ///< Vector containing the list items.
 
 public:
+	/**
+	 * Constructor for ListEntry.
+	 *
+	 * @param items The items stored in the list.
+	 */
 	ListEntry(EntryList items) : StackEntry(seList), _items(items) { }
 
 	virtual std::ostream &print(std::ostream &output) const {
@@ -321,6 +332,35 @@
 };
 
 /**
+ * Stack entry representing a function call.
+ */
+class CallEntry : public StackEntry {
+private:
+	const std::string _funcName; ///< The name of the function.
+	const EntryList _args;       ///< std::deque of stack entries representing the arguments used (stored left-to-right).
+
+public:
+	/**
+	 * Constructor for CallEntry.
+	 *
+	 * @param funcName The name of the function.
+	 * @param args std::deque of stack entries representing the arguments used.
+	 */
+	CallEntry(std::string funcName, EntryList args) : StackEntry(seCall), _funcName(funcName), _args(args) { }
+
+	virtual std::ostream &print(std::ostream &output) const {
+		output << _funcName << "(";
+		for (EntryList::const_iterator i = _args.begin(); i != _args.end(); ++i) {
+			if (i != _args.begin())
+				output << ", ";
+			output << *i;
+		}
+		output << ")";
+		return output;
+	}
+};
+
+/**
  * Type representing a stack.
  */
 typedef Stack<EntryPtr> EntryStack;
@@ -347,6 +387,7 @@
 	EntryStack _stack;     ///< The stack currently being processed.
 	uint _indentLevel;     ///< Indentation level.
 	GroupPtr _curGroup;    ///< Pointer to the group currently being processed.
+	EntryList _argList;    ///< Storage for lists of arguments to be built when processing function calls.
 
 	/**
 	 * Processes an instruction.
@@ -378,6 +419,14 @@
 	 */
 	void writeAssignment(EntryPtr dst, EntryPtr src);
 
+	/**
+	 * Process a single character of metadata.
+	 *
+	 * @param it The instruction being processed.
+	 * @param c The character signifying the action to be taken.
+	 */
+	virtual void processSpecialMetadata(const Instruction inst, char c);
+
 public:
 	virtual ~CodeGenerator() {};
 

Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp	2010-07-23 01:05:26 UTC (rev 51188)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp	2010-07-23 01:38:34 UTC (rev 51189)
@@ -424,3 +424,43 @@
 	s << boost::format("array%d") % arrID;
 	return s.str();
 }
+
+void Scumm::v6::CodeGenerator::processSpecialMetadata(const Instruction inst, char c) {
+	switch (c) {
+		// All of these meanings are taken from descumm.
+		case 'l':
+			_argList.push_front(createListEntry());
+			break;
+		// No SCUMMv6 opcodes using these types have more than one parameter, so it's safe to assume it's the first parameter we want.
+		case 'w':
+		case 'j':
+		case 'i':
+			switch (inst._params[0]._type) {
+			case kSByte:
+			case kShort:
+				_argList.push_front(new IntEntry(inst._params[0].getSigned(), false));
+				break;
+			case kByte:
+			case kUShort:
+				_argList.push_front(new IntEntry(inst._params[0].getUnsigned(), false));
+				break;
+			default:
+				std::cerr << boost::format("Unexpected type for parameter 0 @ %08X while processing metadata character %c") % inst._address % c;
+				break;
+			}
+			break;
+		case 'v':
+			_argList.push_front(new VarEntry(decodeVarName(inst._params[0].getUnsigned())));
+			break;
+		case 's':
+			_argList.push_front(new StringEntry(inst._params[0].getString()));
+			break;
+		case 'z':
+			_argList.push_front(_stack.pop());
+			_argList.push_front(_stack.pop());
+			break;
+		default:
+			::CodeGenerator::processSpecialMetadata(inst, c);
+			break;
+	}
+}

Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h	2010-07-23 01:05:26 UTC (rev 51188)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h	2010-07-23 01:38:34 UTC (rev 51189)
@@ -65,9 +65,16 @@
 	 */
 	EntryPtr createListEntry();
 public:
+	/**
+	 * Constructor for Scumm::v6::CodeGenerator.
+	 *
+	 * @param engine Pointer to the Engine used for the script.
+	 * @param output The std::ostream to output the code to.
+	 */
 	CodeGenerator(Engine *engine, std::ostream &output) : ::CodeGenerator(engine, output) {}
 protected:
 	void processInst(const Instruction inst);
+	virtual void processSpecialMetadata(const Instruction inst, char c);
 };
 
 } // End of namespace 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