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

pidgeot at users.sourceforge.net pidgeot at users.sourceforge.net
Sat Dec 18 13:22:16 CET 2010


Revision: 54951
          http://scummvm.svn.sourceforge.net/scummvm/?rev=54951&view=rev
Author:   pidgeot
Date:     2010-12-18 12:22:15 +0000 (Sat, 18 Dec 2010)

Log Message:
-----------
DECOMPILER: Remove unnecessary copy function

Modified Paths:
--------------
    tools/branches/gsoc2010-decompiler/decompiler/doc/disassembler.tex
    tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp
    tools/branches/gsoc2010-decompiler/decompiler/instruction.h
    tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp
    tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp
    tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h

Modified: tools/branches/gsoc2010-decompiler/decompiler/doc/disassembler.tex
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/doc/disassembler.tex	2010-12-18 12:17:33 UTC (rev 54950)
+++ tools/branches/gsoc2010-decompiler/decompiler/doc/disassembler.tex	2010-12-18 12:22:15 UTC (rev 54951)
@@ -29,7 +29,6 @@
 	virtual bool isStore() const;
 	virtual uint32 getDestAddress() const;
 	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) = 0;
-	void copy(InstPtr other);
 };
 \end{lstlisting}
 \end{C++}
@@ -86,7 +85,7 @@
 
 When disassembling, you will need to create an instance of the correct instruction type for each of your instructions. For this purpose, \code{Disassembler} defines a factory \code{\_instFactory} where you can register your classes with an integer key. To do this, call \code{\_instFactory.addEntry<Type>(key)} in the constructor for your Disassemlber, where \code{Type} is the name of the type to register, and \code{key} is an integer key. To create an instance of the appropriate type, simply call \code{\_instFactory.create} with your key.
 
-In a few cases, you may not know which instruction type is correct. For example, in Kyra, the same opcode is used for unconditional jumps and script function calls, but the correct type cannot be determined before all of the instructions have been disassembled. In such a case, you will have to correct the instruction before moving on to the code flow analysis. Once you have created the correct instruction type, you can use the \code{copy} method to copy the base fields from the incorrect instruction.
+In a few cases, you may not know which instruction type is correct. For example, in Kyra, the same opcode is used for unconditional jumps and script function calls, but the correct type depends on other instructions. You can handle this is by creating a new Instruction type which can work as both, depending on a flag you declare in your type, and set once you can correctly determine the type. Note that since \code{InstPtr} is not a raw pointer, you must first convert it to one before you can cast it to the pointer type of your choice. This can be done by calling \code{inst.get()}, where \code{inst} is your \code{InstPtr}.
 
 By default, only some of the instruction types are registered automatically; for other types, you will have to register your own classes since it is not possible to fully define them in a generic fashion. The pre-registered types are \code{kBinaryOpInst}, \code{kBoolNegateInst}, \code{kDupInst}, \code{kKernelCallInst}, \code{kReturnInst}, \code{kUnaryOpPreInst} and \code{kUnaryOpPostInst}, but you can substitute any or all of these by registering your own type with the same key.
 

Modified: tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp	2010-12-18 12:17:33 UTC (rev 54950)
+++ tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp	2010-12-18 12:22:15 UTC (rev 54951)
@@ -31,7 +31,7 @@
 }
 
 bool Instruction::isJump() const {
-	return false;
+	return isCondJump() || isUncondJump();
 }
 
 bool Instruction::isCondJump() const {
@@ -70,15 +70,6 @@
 	throw WrongTypeException();
 }
 
-void Instruction::copy(InstPtr other) {
-	_opcode = other->_opcode;
-	_address = other->_address;
-	_stackChange = other->_stackChange;
-	_name = other->_name;
-	_codeGenData = other->_codeGenData;
-	_params = other->_params;
-}
-
 std::ostream &Instruction::print(std::ostream &output) const {
 	output << boost::format("%08x: %s") % _address % _name;
 	std::vector<ValuePtr>::const_iterator param;
@@ -92,10 +83,6 @@
 	return output;
 }
 
-bool JumpInstruction::isJump() const {
-	return true;
-}
-
 bool CondJumpInstruction::isCondJump() const {
 	return true;
 }

Modified: tools/branches/gsoc2010-decompiler/decompiler/instruction.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/instruction.h	2010-12-18 12:17:33 UTC (rev 54950)
+++ tools/branches/gsoc2010-decompiler/decompiler/instruction.h	2010-12-18 12:22:15 UTC (rev 54951)
@@ -177,21 +177,12 @@
 	 * @param codeGen Pointer to the CodeGenerator used for code generation.
 	 */
 	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) = 0;
-
-	/**
-	 * Copies base data from another instruction.
-	 *
-	 * @param other The instruction to copy from.
-	 */
-	void copy(InstPtr other);
 };
 
 /**
  * Instruction performing a jump.
  */
 struct JumpInstruction : public Instruction {
-public:
-	virtual bool isJump() const;
 };
 
 /**

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp	2010-12-18 12:17:33 UTC (rev 54950)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp	2010-12-18 12:22:15 UTC (rev 54951)
@@ -265,7 +265,6 @@
 
 Kyra::Kyra2Disassembler::Kyra2Disassembler(Kyra2Engine *engine, InstVec &insts) : Disassembler(insts), _engine(engine) {
 	setupKyra2Funcs();
-	_instFactory.addEntry<Kyra2CallInstruction>(kCallInst);
 	_instFactory.addEntry<Kyra2CondJumpInstruction>(kCondJumpInst);
 	_instFactory.addEntry<Kyra2UncondJumpInstruction>(kJumpInst);
 	_instFactory.addEntry<Kyra2KernelCallInstruction>(kKernelCallInst);
@@ -592,9 +591,7 @@
 	for (InstIterator it = _insts.begin(); it != _insts.end(); ++it) {
 		if ((*it)->isJump()) {
 			if (lastWasPushPos || _engine->_functions.find((*it)->_params[0]->getUnsigned()) != _engine->_functions.end()) {
-				InstPtr p = _instFactory.create(kCallInst);
-				p->copy(*it);
-				*it = p;
+				((Kyra2UncondJumpInstruction *) (*it).get())->_isCall = true;
 			}
 		}
 		lastWasPushPos = ((*it)->_name.compare("pushPos") == 0);

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp	2010-12-18 12:17:33 UTC (rev 54950)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp	2010-12-18 12:22:15 UTC (rev 54951)
@@ -160,27 +160,37 @@
 	return _params[0]->getUnsigned();
 }
 
+bool Kyra::Kyra2UncondJumpInstruction::isFuncCall() const {
+	return _isCall;
+}
+
+bool Kyra::Kyra2UncondJumpInstruction::isUncondJump() const {
+	return !_isCall;
+}
+
 uint32 Kyra::Kyra2UncondJumpInstruction::getDestAddress() const {
 	return _params[0]->getUnsigned();
 }
 
-void Kyra::Kyra2CallInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
-	Kyra2CodeGenerator *cg = (Kyra2CodeGenerator *)codeGen;
-	cg->_argList.clear();
-	Function f = engine->_functions.find(_params[0]->getUnsigned())->second;
-	for (size_t i = 0; i < f._metadata.length(); i++)
-		cg->processSpecialMetadata(this, f._metadata[i], i);
-	stack.push(new CallValue(f._name, cg->_argList));
-	// Leave call on stack if this is a condition, or other calls follow in same group
-	if (cg->_curGroup->_type == kIfCondGroupType || cg->_curGroup->_type == kWhileCondGroupType || cg->_curGroup->_type == kDoWhileCondGroupType || _address != cg->findLastCall()->_address) {
-		return;
-	}	else if (!f._retVal) {
-		std::stringstream stream;
-		stream << stack.pop() << ";";
-		cg->addOutputLine(stream.str());
-	} else {
-		ValuePtr p = new VarValue("retval");
-		cg->writeAssignment(p, stack.pop());
+void Kyra::Kyra2UncondJumpInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+	if (_isCall) {
+		Kyra2CodeGenerator *cg = (Kyra2CodeGenerator *)codeGen;
+		cg->_argList.clear();
+		Function f = engine->_functions.find(_params[0]->getUnsigned())->second;
+		for (size_t i = 0; i < f._metadata.length(); i++)
+			cg->processSpecialMetadata(this, f._metadata[i], i);
+		stack.push(new CallValue(f._name, cg->_argList));
+		// Leave call on stack if this is a condition, or other calls follow in same group
+		if (cg->_curGroup->_type == kIfCondGroupType || cg->_curGroup->_type == kWhileCondGroupType || cg->_curGroup->_type == kDoWhileCondGroupType || _address != cg->findLastCall()->_address) {
+			return;
+		}	else if (!f._retVal) {
+			std::stringstream stream;
+			stream << stack.pop() << ";";
+			cg->addOutputLine(stream.str());
+		} else {
+			ValuePtr p = new VarValue("retval");
+			cg->writeAssignment(p, stack.pop());
+		}
 	}
 }
 

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h	2010-12-18 12:17:33 UTC (rev 54950)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h	2010-12-18 12:22:15 UTC (rev 54951)
@@ -82,14 +82,15 @@
  */
 class Kyra2UncondJumpInstruction : public UncondJumpInstruction {
 public:
+	bool _isCall;  ///< Whether or not this is really a call to a script function.
+
+	/**
+	 * Constructor for Kyra2UncondJumpInstruction.
+	 */
+	Kyra2UncondJumpInstruction() : _isCall(false) { };
+	virtual bool isFuncCall() const;
+	virtual bool isUncondJump() const;
 	virtual uint32 getDestAddress() const;
-};
-
-/**
- * Kyra2 script function call.
- */
-class Kyra2CallInstruction : public CallInstruction {
-public:
 	virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
 };
 


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