docs: def filter_actions(self, block_addr=None, block_stmt=None, insn_addr=None, read_from=None, write_to=None):
          """
          Filter self.actions based on some common parameters.
  
          :param block_addr:  Only return actions generated in blocks starting at this address.
          :param block_stmt:  Only return actions generated in the nth statement of each block.
          :param insn_addr:   Only return actions generated in the assembly instruction at this address.
          :param read_from:   Only return actions that perform a read from the specified location.
          :param write_to:    Only return actions that perform a write to the specified location.
  
          Notes:
          If IR optimization is turned on, reads and writes may not occur in the instruction
          they originally came from. Most commonly, If a register is read from twice in the same
          block, the second read will not happen, instead reusing the temp the value is already
          stored in.
  
          Valid values for read_from and write_to are the string literals 'reg' or 'mem' (matching
          any read or write to registers or memory, respectively), any string (representing a read
          or write to the named register), and any integer (representing a read or write to the
          memory at this address).
          """
          if read_from is not None:
              if write_to is not None:
                  raise ValueError("Can't handle read_from and write_to at the same time!")
              if read_from in ('reg', 'mem'):
                  read_type = read_from
                  read_offset = None
              elif isinstance(read_from, str):
                  read_type = 'reg'
                  read_offset = self.state.project.arch.registers[read_from][0]
              else:
                  read_type = 'mem'
                  read_offset = read_from
          if write_to is not None:
              if write_to in ('reg', 'mem'):
                  write_type = write_to
                  write_offset = None
              elif isinstance(write_to, str):
                  write_type = 'reg'
                  write_offset = self.state.project.arch.registers[write_to][0]
              else:
                  write_type = 'mem'
                  write_offset = write_to
  
          #def addr_of_stmt(bbl_addr, stmt_idx):
          #    if stmt_idx is None:
          #        return None
          #    stmts = self.state.project.factory.block(bbl_addr).vex.statements
          #    if stmt_idx >= len(stmts):
          #        return None
          #    for i in reversed(range(stmt_idx + 1)):
          #        if stmts[i].tag == 'Ist_IMark':
          #            return stmts[i].addr + stmts[i].delta
          #    return None
  
          def action_reads(action):
              if action.type != read_type:
                  return False
              if action.action != 'read':
                  return False
              if read_offset is None:
                  return True
              addr = action.addr
              if isinstance(addr, SimActionObject):
                  addr = addr.ast
              if isinstance(addr, claripy.ast.Base):
                  if addr.symbolic:
                      return False
                  addr = self.state.solver.eval(addr)
              if addr != read_offset:
                  return False
              return True
  
          def action_writes(action):
              if action.type != write_type:
                  return False
              if action.action != 'write':
                  return False
              if write_offset is None:
                  return True
              addr = action.addr
              if isinstance(addr, SimActionObject):
                  addr = addr.ast
              if isinstance(addr, claripy.ast.Base):
                  if addr.symbolic:
                      return False
                  addr = self.state.solver.eval(addr)
              if addr != write_offset:
                  return False
              return True
  
          return [x for x in reversed(self.actions) if
                      (block_addr is None or x.bbl_addr == block_addr) and
                      (block_stmt is None or x.stmt_idx == block_stmt) and
                      (read_from is None or action_reads(x)) and
                      (write_to is None or action_writes(x)) and
                      (insn_addr is None or (x.sim_procedure is None and x.ins_addr == insn_addr))
                      #(insn_addr is None or (x.sim_procedure is None and addr_of_stmt(x.bbl_addr, x.stmt_idx) == insn_addr))
              ]