def get_raises_list(nodes, exit_index):
  """Compute the "raises list" for the control flow graph.

  Args:
    nodes: A list of control_flow.ControlFlowNodes.
    exit_index: The index of the exit node. The top-level "raise index" is assumed
      to be exit_index + 1.
  Returns:
    A Python list indicating where each node would directly raise to if it were to
    raise an exception.
  """
  raise_index = exit_index + 1
  indexes_by_id = {
      id(node): index for index, node in enumerate(nodes)
  }
  raises_list = []
  for node in nodes:
    exits_from_middle = node.block.exits_from_middle
    assert len(exits_from_middle) <= 1
    if exits_from_middle:
      raise_block = next(iter(exits_from_middle))
      if raise_block.label == '<raise>':
        index = raise_index
      elif raise_block.label == '<exit>' or raise_block.label == '<return>':
        index = exit_index
      else:
        raise_node = raise_block.control_flow_nodes[0]
        index = indexes_by_id[id(raise_node)]
    else:
      index = raise_index
    raises_list.append(index)

  # Finally we add an unused raise edge from the exit node to the raise node.
  # The raise edge from the raise node will be added later.
  raises_list.append(raise_index)
  return raises_list