Exemple #1
0
def program_to_text(program):
  """Generate a text (CFG nodes + assignments) version of a program.

  For debugging only.

  Args:
    program: An instance of cfg.Program

  Returns:
    A string representing all of the data for this program.
  """
  def label(node):
    return "<%d>%s" % (node.id, node.name)
  s = six.StringIO()
  seen = set()
  for node in cfg_utils.order_nodes(program.cfg_nodes):
    seen.add(node)
    s.write("%s\n" % label(node))
    s.write("  From: %s\n" % ", ".join(label(n) for n in node.incoming))
    s.write("  To: %s\n" % ", ".join(label(n) for n in node.outgoing))
    s.write("\n")
    variables = set(value.variable for value in node.bindings)
    for var in sorted(variables, key=lambda v: v.id):
      # If a variable is bound in more than one node then it will be listed
      # redundantly multiple times.  One alternative would be to only list the
      # values that occur in the given node, and then also list the other nodes
      # that assign the same variable.

      # Write the variable, indenting by two spaces.
      s.write("  %s\n" % _pretty_variable(var).replace("\n", "\n  "))
    s.write("\n")

  return s.getvalue()
Exemple #2
0
def compute_order(bytecode):
  """Split bytecode into blocks and order the blocks.

  This builds an "ancestor first" ordering of the basic blocks of the bytecode.

  Args:
    bytecode: A list of instances of opcodes.Opcode. (E.g. returned from
      opcodes.dis())

  Returns:
    A list of Block instances.
  """
  blocks = _split_bytecode(bytecode)
  first_op_to_block = {block.code[0]: block for block in blocks}
  for i, block in enumerate(blocks):
    next_block = blocks[i + 1] if i < len(blocks) - 1 else None
    first_op, last_op = block.code[0], block.code[-1]
    if next_block and not last_op.no_next():
      block.connect_outgoing(next_block)
    if first_op.target:
      # Handles SETUP_EXCEPT -> except block
      block.connect_outgoing(first_op_to_block[first_op.target])
    if last_op.target:
      block.connect_outgoing(first_op_to_block[last_op.target])
    if last_op.block_target:
      block.connect_outgoing(first_op_to_block[last_op.block_target])
  return cfg_utils.order_nodes(blocks)
Exemple #3
0
 def test_order_nodes4(self):
     # n1 --> n3 --> n2
     # ^      |
     # +------+
     n1 = self.prog.NewCFGNode("n1")
     n3 = n1.ConnectNew("n3")
     n2 = n3.ConnectNew("n2")
     n3.ConnectTo(n1)
     order = cfg_utils.order_nodes([n1, n2, n3])
     self.assertCountEqual([n1, n3, n2], order)
Exemple #4
0
 def testOrderNodes3(self):
     # n1 --> n2 --> n3
     # ^             |
     # +-------------+
     n1 = self.prog.NewCFGNode("n1")
     n2 = n1.ConnectNew("n2")
     n3 = n2.ConnectNew("n3")
     n3.ConnectTo(n1)
     order = cfg_utils.order_nodes([n1, n2, n3])
     six.assertCountEqual(self, [n1, n2, n3], order)
Exemple #5
0
 def testOrderNodes5(self):
     # n1 --> n3 --> n2
     # ^      |
     # +------+      n4(dead)
     n1 = self.prog.NewCFGNode("n1")
     n3 = n1.ConnectNew("n3")
     n2 = n3.ConnectNew("n2")
     n3.ConnectTo(n1)
     n4 = self.prog.NewCFGNode("n4")
     order = cfg_utils.order_nodes([n1, n2, n3, n4])
     six.assertCountEqual(self, [n1, n3, n2], order)
Exemple #6
0
 def test_order_nodes6(self):
     #  +-------------------+
     #  |                   v
     # n1 --> n2 --> n3 --> n5
     #        ^      |
     #        +------n4
     n1 = self.prog.NewCFGNode("n1")
     n2 = n1.ConnectNew("n2")
     n3 = n2.ConnectNew("n3")
     n4 = n3.ConnectNew("n4")
     n4.ConnectTo(n2)
     n5 = n3.ConnectNew("n5")
     n1.ConnectTo(n5)
     order = cfg_utils.order_nodes([n1, n5, n4, n3, n2])
     self.assertCountEqual([n1, n2, n3, n4, n5], order)
Exemple #7
0
 def test_order_nodes7(self):
     #  +---------------------------------+
     #  |                                 v
     # n1 --> n2 --> n3 --> n4 --> n5 --> n6
     #        ^      |      ^      |
     #        |      v      |      v
     #        +------n7     +------n8
     n1 = self.prog.NewCFGNode("n1")
     n2 = n1.ConnectNew("n2")
     n3 = n2.ConnectNew("n3")
     n4 = n3.ConnectNew("n4")
     n5 = n4.ConnectNew("n5")
     n6 = n5.ConnectNew("n6")
     n7 = n3.ConnectNew("n7")
     n7.ConnectTo(n2)
     n8 = n5.ConnectNew("n8")
     n8.ConnectTo(n4)
     n1.ConnectTo(n6)
     order = cfg_utils.order_nodes([n1, n2, n3, n4, n5, n6, n7, n8])
     self.assertCountEqual([n1, n2, n3, n7, n4, n5, n8, n6], order)
Exemple #8
0
 def test_order_nodes2(self):
     # n1   n2(dead)
     n1 = self.prog.NewCFGNode("n1")
     n2 = self.prog.NewCFGNode("n2")
     order = cfg_utils.order_nodes([n1, n2])
     self.assertCountEqual([n1], order)
Exemple #9
0
 def test_order_nodes1(self):
     # n1 --> n2
     n1 = self.prog.NewCFGNode("n1")
     n2 = n1.ConnectNew("n2")
     order = cfg_utils.order_nodes([n1, n2])
     self.assertCountEqual([n1, n2], order)
Exemple #10
0
 def test_order_nodes0(self):
     order = cfg_utils.order_nodes([])
     self.assertCountEqual(order, [])
Exemple #11
0
 def testOrderNodes0(self):
     order = cfg_utils.order_nodes([])
     six.assertCountEqual(self, order, [])
Exemple #12
0
 def testOrderNodes0(self):
     order = cfg_utils.order_nodes([])
     self.assertItemsEqual(order, [])