code: def ccall(self, ret_type, func_obj, args):
          
          # HACK: FIXME: If you're reading this, I'm sorry. It's truly a crime against Python...
  
          from angr.engines.vex import ccall
  
          # Check the args to make sure they're the right type
          list_args = list(args)
          new_args = []
          for arg in list_args:
              if isinstance(arg, VexValue):
                  arg = arg.rdt
              new_args.append(arg)
          args = tuple(new_args)
  
  
          # Support calling ccalls via string name
          if isinstance(func_obj, str):
              func_obj = getattr(ccall, func_obj)
          else:
              # ew, monkey-patch in the user-provided CCall
              if not hasattr(ccall, func_obj.__name__):
                  setattr(ccall, func_obj.__name__, func_obj)
          cc = self.irsb_c.op_ccall(ret_type, func_obj.__name__, args)
          return VexValue(self.irsb_c, cc)
docs: Creates a CCall operation.
          A CCall is a procedure that calculates a value at *runtime*, not at lift-time.
          You can use these for flags, unresolvable jump targets, etc.
          We caution you to avoid using them when at all possible though.
  
          For an example of how to write and use a CCall, see gymrat/bf/lift_bf.py
  
          :param ret_type: The return type of the CCall
          :param func_obj: The function object to eventually call.
          :param args: List of arguments to the function
          :return: A VexValue of the result.