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

pidgeot at users.sourceforge.net pidgeot at users.sourceforge.net
Tue Jul 6 02:05:37 CEST 2010


Revision: 50717
          http://scummvm.svn.sourceforge.net/scummvm/?rev=50717&view=rev
Author:   pidgeot
Date:     2010-07-06 00:05:37 +0000 (Tue, 06 Jul 2010)

Log Message:
-----------
Annotate edges telling whether or not they represent a jump
In graph output, show jumps using empty arrowheads

Modified Paths:
--------------
    tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
    tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp
    tools/branches/gsoc2010-decompiler/decompiler/graph.h

Modified: tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp	2010-07-05 23:07:24 UTC (rev 50716)
+++ tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp	2010-07-06 00:05:37 UTC (rev 50717)
@@ -29,8 +29,10 @@
 #include <boost/format.hpp>
 
 #define PUT(vertex, group) boost::put(boost::vertex_name, _g, vertex, group);
+#define PUT_EDGE(edge, isJump) boost::put(boost::edge_attribute, _g, edge, isJump);
 #define PUT_ID(vertex, id) boost::put(boost::vertex_index, _g, vertex, id);
 #define GET(vertex) (boost::get(boost::vertex_name, _g, vertex))
+#define GET_EDGE(edge) (boost::get(boost::edge_attribute, _g, edge))
 
 ControlFlow::ControlFlow(const std::vector<Instruction> &insts, Engine *engine) : _insts(insts) {
 	_engine = engine;
@@ -46,8 +48,10 @@
 		PUT_ID(cur, id);
 		id++;
 
-		if (addEdge)
-			boost::add_edge(last, cur, _g);
+		if (addEdge) {
+			GraphEdge e = boost::add_edge(last, cur, _g).first;
+			PUT_EDGE(e, false);
+		}
 		last = cur;
 		addEdge = (it->_type != kJump && it->_type != kJumpRel);
 		prev = GET(cur);
@@ -58,9 +62,11 @@
 		case kJump:
 		case kCondJump:
 		case kJumpRel:
-		case kCondJumpRel:
-			boost::add_edge(find(it), find(_engine->getDestAddress(it)), _g);
+		case kCondJumpRel: {
+			GraphEdge e = boost::add_edge(find(it), find(_engine->getDestAddress(it)), _g).first;
+			PUT_EDGE(e, true);
 			break;
+			}
 		default:
 			break;
 		}
@@ -99,7 +105,8 @@
 	// Add outgoing edges from g2
 	OutEdgeRange r = boost::out_edges(g2, _g);
 	for (OutEdgeIterator e = r.first; e != r.second; ++e) {
-		boost::add_edge(g1, boost::target(*e, _g), _g);
+		GraphEdge newE = boost::add_edge(g1, boost::target(*e, _g), _g).first;
+		PUT_EDGE(newE, GET_EDGE(*e));
 	}
 
 	// Update _next pointer
@@ -111,8 +118,6 @@
 	boost::clear_vertex(g2, _g);
 	// Remove vertex
 	boost::remove_vertex(g2, _g);
-	// Delete old group
-	//delete gr2;
 }
 
 void ControlFlow::setStackLevel(GraphVertex g, int level) {

Modified: tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp	2010-07-05 23:07:24 UTC (rev 50716)
+++ tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp	2010-07-06 00:05:37 UTC (rev 50717)
@@ -144,7 +144,7 @@
 				buf = std::cout.rdbuf(); 
 			} 
  			std::ostream out(buf); 
-			boost::write_graphviz(out, g, boost::make_label_writer(get(boost::vertex_name, g)), boost::default_writer(), GraphProperties());
+			boost::write_graphviz(out, g, boost::make_label_writer(get(boost::vertex_name, g)), boost::makeArrowheadWriter(get(boost::edge_attribute, g)), GraphProperties());
 		}
 
 		delete cf;

Modified: tools/branches/gsoc2010-decompiler/decompiler/graph.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/graph.h	2010-07-05 23:07:24 UTC (rev 50716)
+++ tools/branches/gsoc2010-decompiler/decompiler/graph.h	2010-07-06 00:05:37 UTC (rev 50717)
@@ -32,6 +32,7 @@
 
 #include <boost/graph/graph_traits.hpp>
 #include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/graphviz.hpp>
 
 #include <boost/intrusive_ptr.hpp>
 
@@ -57,7 +58,7 @@
 namespace boost {
 	inline void intrusive_ptr_add_ref(Group *p);
 	inline void intrusive_ptr_release(Group *p);
-}
+} // End of namespace boost
 
 /**
  * Structure representing a group of instructions.
@@ -198,9 +199,89 @@
 typedef boost::property<boost::vertex_index_t, int, GroupProperty> GraphProperty;
 
 /**
+ * Structure representing whether or not an edge is a jump.
+ */ 
+struct IsJump {
+	bool _isJump; ///< Whether or not the edge is a jump.
+
+	/**
+	 * Parameterless constructor for Group. Required for use with STL and Boost, should not be called manually.
+	 */
+	IsJump() { _isJump = false; };
+
+	/**
+	 * Constructor for IsJump.
+	 *
+	 * @param isJump Whether or not the edge is a jump.
+	 */
+	IsJump(bool isJump) : _isJump(isJump) {};
+
+	/**
+	 * Output edge information to an std::ostream as a graphviz edge property.
+	 *
+	 * @param output The std::ostream to output to.
+	 * @param isJump The IsJump to output.
+	 * @return The std::ostream used for output.
+	 */
+	friend std::ostream &operator<<(std::ostream &output, IsJump isJump) {
+		if (isJump._isJump)
+			output << "empty";
+		else
+			output << "normal";
+		return output;
+	}
+};
+
+namespace boost {
+
+/**
+ * Property writer for the isJump property.
+ */
+template <class Name>
+class arrowheadWriter {
+public:
+
+	/**
+	 * Constructor for arrowheadWriter.
+	 *
+	 * @param _name The name of the attribute to use.
+	 */
+	arrowheadWriter(Name _name) : name(_name) {}
+
+	/**
+	 * Outputs the arrowhead edge property.
+	 *
+	 * @param out The std::ostream to output to.
+	 * @param v   The vertex or edge to output the attribute for.
+	 */
+	template <class VertexOrEdge>
+	void operator()(std::ostream& out, const VertexOrEdge& v) const {
+		out << "[arrowhead=\"" << get(name, v) << "\"]";
+	}
+private:
+	Name name;
+};
+
+/**
+ * Creates an arrowhead property writer.
+ *
+ * @param _name The name of the attribute to use.
+ */
+template <class Name>
+inline arrowheadWriter<Name>
+makeArrowheadWriter(Name n) {
+	return arrowheadWriter<Name>(n);
+}
+
+} // End of namespace boost
+
+
+typedef boost::property<boost::edge_attribute_t, IsJump> EdgeProperty;
+
+/**
  * Type used for the code flow graph.
  */
-typedef boost::adjacency_list<boost::setS, boost::listS, boost::bidirectionalS, GraphProperty> Graph;
+typedef boost::adjacency_list<boost::setS, boost::listS, boost::bidirectionalS, GraphProperty, EdgeProperty> Graph;
 
 /**
  * Type representing a vertex in the graph.


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