//===-- IRInterpreter.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRMemoryMap.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/ValueObject/ValueObject.h"

#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanCallFunctionUsingABI.h"

#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/Support/raw_ostream.h"

#include <map>

using namespace llvm;
using lldb_private::LLDBLog;

static std::string PrintValue(const Value *value, bool truncate = false) {
  std::string s;
  raw_string_ostream rso(s);
  value->print(rso);
  if (truncate)
    s.resize(s.length() - 1);

  size_t offset;
  while ((offset = s.find('\n')) != s.npos)
    s.erase(offset, 1);
  while (s[0] == ' ' || s[0] == '\t')
    s.erase(0, 1);

  return s;
}

static std::string PrintType(const Type *type, bool truncate = false) {
  std::string s;
  raw_string_ostream rso(s);
  type->print(rso);
  if (truncate)
    s.resize(s.length() - 1);
  return s;
}

static bool CanIgnoreCall(const CallInst *call) {
  const llvm::Function *called_function = call->getCalledFunction();

  if (!called_function)
    return false;

  if (called_function->isIntrinsic()) {
    switch (called_function->getIntrinsicID()) {
    default:
      break;
    case llvm::Intrinsic::dbg_declare:
    case llvm::Intrinsic::dbg_value:
      return true;
    }
  }

  return false;
}

class InterpreterStackFrame {
public:
  typedef std::map<const Value *, lldb::addr_t> ValueMap;

  ValueMap m_values;
  const DataLayout &m_target_data;
  lldb_private::IRExecutionUnit &m_execution_unit;
  const BasicBlock *m_bb = nullptr;
  const BasicBlock *m_prev_bb = nullptr;
  BasicBlock::const_iterator m_ii;
  BasicBlock::const_iterator m_ie;

  lldb::addr_t m_frame_process_address;
  size_t m_frame_size;
  lldb::addr_t m_stack_pointer;

  lldb::ByteOrder m_byte_order;
  size_t m_addr_byte_size;

  InterpreterStackFrame(const DataLayout &target_data,
                        lldb_private::IRExecutionUnit &execution_unit,
                        lldb::addr_t stack_frame_bottom,
                        lldb::addr_t stack_frame_top)
      : m_target_data(target_data), m_execution_unit(execution_unit) {
    m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle
                                                 : lldb::eByteOrderBig);
    m_addr_byte_size = (target_data.getPointerSize(0));

    m_frame_process_address = stack_frame_bottom;
    m_frame_size = stack_frame_top - stack_frame_bottom;
    m_stack_pointer = stack_frame_top;
  }

  ~InterpreterStackFrame() = default;

  void Jump(const BasicBlock *bb) {
    m_prev_bb = m_bb;
    m_bb = bb;
    m_ii = m_bb->begin();
    m_ie = m_bb->end();
  }

  std::string SummarizeValue(const Value *value) {
    lldb_private::StreamString ss;

    ss.Printf("%s", PrintValue(value).c_str());

    ValueMap::iterator i = m_values.find(value);

    if (i != m_values.end()) {
      lldb::addr_t addr = i->second;

      ss.Printf(" 0x%llx", (unsigned long long)addr);
    }

    return std::string(ss.GetString());
  }

  bool AssignToMatchType(lldb_private::Scalar &scalar, llvm::APInt value,
                         Type *type) {
    size_t type_size = m_target_data.getTypeStoreSize(type);

    if (type_size > 8)
      return false;

    if (type_size != 1)
      type_size = PowerOf2Ceil(type_size);

    scalar = value.zextOrTrunc(type_size * 8);
    return true;
  }

  bool EvaluateValue(lldb_private::Scalar &scalar, const Value *value,
                     Module &module) {
    const Constant *constant = dyn_cast<Constant>(value);

    if (constant) {
      if (constant->getValueID() == Value::ConstantFPVal) {
        if (auto *cfp = dyn_cast<ConstantFP>(constant)) {
          if (cfp->getType()->isDoubleTy())
            scalar = cfp->getValueAPF().convertToDouble();
          else if (cfp->getType()->isFloatTy())
            scalar = cfp->getValueAPF().convertToFloat();
          else
            return false;
          return true;
        }
        return false;
      }
      APInt value_apint;

      if (!ResolveConstantValue(value_apint, constant))
        return false;

      return AssignToMatchType(scalar, value_apint, value->getType());
    }

    lldb::addr_t process_address = ResolveValue(value, module);
    size_t value_size = m_target_data.getTypeStoreSize(value->getType());

    lldb_private::DataExtractor value_extractor;
    lldb_private::Status extract_error;

    m_execution_unit.GetMemoryData(value_extractor, process_address,
                                   value_size, extract_error);

    if (!extract_error.Success())
      return false;

    lldb::offset_t offset = 0;
    if (value_size <= 8) {
      Type *ty = value->getType();
      if (ty->isDoubleTy()) {
        scalar = value_extractor.GetDouble(&offset);
        return true;
      } else if (ty->isFloatTy()) {
        scalar = value_extractor.GetFloat(&offset);
        return true;
      } else {
        uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);
        return AssignToMatchType(scalar, llvm::APInt(64, u64value),
                                 value->getType());
      }
    }

    return false;
  }

  bool AssignValue(const Value *value, lldb_private::Scalar scalar,
                   Module &module) {
    lldb::addr_t process_address = ResolveValue(value, module);

    if (process_address == LLDB_INVALID_ADDRESS)
      return false;

    lldb_private::Scalar cast_scalar;
    Type *vty = value->getType();
    if (vty->isFloatTy() || vty->isDoubleTy()) {
      cast_scalar = scalar;
    } else {
      scalar.MakeUnsigned();
      if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()),
                             value->getType()))
        return false;
    }

    size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType());

    lldb_private::DataBufferHeap buf(value_byte_size, 0);

    lldb_private::Status get_data_error;

    if (!cast_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(),
                                     m_byte_order, get_data_error))
      return false;

    lldb_private::Status write_error;

    m_execution_unit.WriteMemory(process_address, buf.GetBytes(),
                                 buf.GetByteSize(), write_error);

    return write_error.Success();
  }

  bool ResolveConstantValue(APInt &value, const Constant *constant) {
    switch (constant->getValueID()) {
    default:
      break;
    case Value::FunctionVal:
      if (const Function *constant_func = dyn_cast<Function>(constant)) {
        lldb_private::ConstString name(
            llvm::GlobalValue::dropLLVMManglingEscape(
                constant_func->getName()));
        bool missing_weak = false;
        lldb::addr_t addr = m_execution_unit.FindSymbol(name, missing_weak);
        if (addr == LLDB_INVALID_ADDRESS)
          return false;
        value = APInt(m_target_data.getPointerSizeInBits(), addr);
        return true;
      }
      break;
    case Value::ConstantIntVal:
      if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant)) {
        value = constant_int->getValue();
        return true;
      }
      break;
    case Value::ConstantFPVal:
      if (const ConstantFP *constant_fp = dyn_cast<ConstantFP>(constant)) {
        value = constant_fp->getValueAPF().bitcastToAPInt();
        return true;
      }
      break;
    case Value::ConstantExprVal:
      if (const ConstantExpr *constant_expr =
              dyn_cast<ConstantExpr>(constant)) {
        switch (constant_expr->getOpcode()) {
        default:
          return false;
        case Instruction::IntToPtr:
        case Instruction::PtrToInt:
        case Instruction::BitCast:
          return ResolveConstantValue(value, constant_expr->getOperand(0));
        case Instruction::GetElementPtr: {
          ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
          ConstantExpr::const_op_iterator op_end = constant_expr->op_end();

          Constant *base = dyn_cast<Constant>(*op_cursor);

          if (!base)
            return false;

          if (!ResolveConstantValue(value, base))
            return false;

          op_cursor++;

          if (op_cursor == op_end)
            return true; // no offset to apply!

          SmallVector<Value *, 8> indices(op_cursor, op_end);
          Type *src_elem_ty =
              cast<GEPOperator>(constant_expr)->getSourceElementType();

          // DataLayout::getIndexedOffsetInType assumes the indices are
          // instances of ConstantInt.
          uint64_t offset =
              m_target_data.getIndexedOffsetInType(src_elem_ty, indices);

          const bool is_signed = true;
          value += APInt(value.getBitWidth(), offset, is_signed);

          return true;
        }
        }
      }
      break;
    case Value::ConstantPointerNullVal:
      if (isa<ConstantPointerNull>(constant)) {
        value = APInt(m_target_data.getPointerSizeInBits(), 0);
        return true;
      }
      break;
    }
    return false;
  }

  bool MakeArgument(const Argument *value, uint64_t address) {
    lldb::addr_t data_address = Malloc(value->getType());

    if (data_address == LLDB_INVALID_ADDRESS)
      return false;

    lldb_private::Status write_error;

    m_execution_unit.WritePointerToMemory(data_address, address, write_error);

    if (!write_error.Success()) {
      lldb_private::Status free_error;
      m_execution_unit.Free(data_address, free_error);
      return false;
    }

    m_values[value] = data_address;

    lldb_private::Log *log(GetLog(LLDBLog::Expressions));

    if (log) {
      LLDB_LOGF(log, "Made an allocation for argument %s",
                PrintValue(value).c_str());
      LLDB_LOGF(log, "  Data region    : %llx", (unsigned long long)address);
      LLDB_LOGF(log, "  Ref region     : %llx",
                (unsigned long long)data_address);
    }

    return true;
  }

  bool ResolveConstant(lldb::addr_t process_address, const Constant *constant) {
    APInt resolved_value;

    if (!ResolveConstantValue(resolved_value, constant))
      return false;

    size_t constant_size = m_target_data.getTypeStoreSize(constant->getType());
    lldb_private::DataBufferHeap buf(constant_size, 0);

    lldb_private::Status get_data_error;

    lldb_private::Scalar resolved_scalar(
        resolved_value.zextOrTrunc(llvm::NextPowerOf2(constant_size) * 8));
    if (!resolved_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(),
                                         m_byte_order, get_data_error))
      return false;

    lldb_private::Status write_error;

    m_execution_unit.WriteMemory(process_address, buf.GetBytes(),
                                 buf.GetByteSize(), write_error);

    return write_error.Success();
  }

  lldb::addr_t Malloc(size_t size, uint8_t byte_alignment) {
    lldb::addr_t ret = m_stack_pointer;

    ret -= size;
    ret -= (ret % byte_alignment);

    if (ret < m_frame_process_address)
      return LLDB_INVALID_ADDRESS;

    m_stack_pointer = ret;
    return ret;
  }

  lldb::addr_t Malloc(llvm::Type *type) {
    lldb_private::Status alloc_error;

    return Malloc(m_target_data.getTypeAllocSize(type),
                  m_target_data.getPrefTypeAlign(type).value());
  }

  std::string PrintData(lldb::addr_t addr, llvm::Type *type) {
    size_t length = m_target_data.getTypeStoreSize(type);

    lldb_private::DataBufferHeap buf(length, 0);

    lldb_private::Status read_error;

    m_execution_unit.ReadMemory(buf.GetBytes(), addr, length, read_error);

    if (!read_error.Success())
      return std::string("<couldn't read data>");

    lldb_private::StreamString ss;

    for (size_t i = 0; i < length; i++) {
      if ((!(i & 0xf)) && i)
        ss.Printf("%02hhx - ", buf.GetBytes()[i]);
      else
        ss.Printf("%02hhx ", buf.GetBytes()[i]);
    }

    return std::string(ss.GetString());
  }

  lldb::addr_t ResolveValue(const Value *value, Module &module) {
    ValueMap::iterator i = m_values.find(value);

    if (i != m_values.end())
      return i->second;

    // Fall back and allocate space [allocation type Alloca]

    lldb::addr_t data_address = Malloc(value->getType());

    if (const Constant *constant = dyn_cast<Constant>(value)) {
      if (!ResolveConstant(data_address, constant)) {
        lldb_private::Status free_error;
        m_execution_unit.Free(data_address, free_error);
        return LLDB_INVALID_ADDRESS;
      }
    }

    m_values[value] = data_address;
    return data_address;
  }
};

static const char *unsupported_opcode_error =
    "Interpreter doesn't handle one of the expression's opcodes";
static const char *unsupported_operand_error =
    "Interpreter doesn't handle one of the expression's operands";
static const char *interpreter_internal_error =
    "Interpreter encountered an internal error";
static const char *interrupt_error =
    "Interrupted while interpreting expression";
static const char *bad_value_error =
    "Interpreter couldn't resolve a value during execution";
static const char *memory_allocation_error =
    "Interpreter couldn't allocate memory";
static const char *memory_write_error = "Interpreter couldn't write to memory";
static const char *memory_read_error = "Interpreter couldn't read from memory";
static const char *timeout_error =
    "Reached timeout while interpreting expression";
static const char *too_many_functions_error =
    "Interpreter doesn't handle modules with multiple function bodies.";

static bool CanResolveConstant(llvm::Constant *constant) {
  switch (constant->getValueID()) {
  default:
    return false;
  case Value::ConstantIntVal:
  case Value::ConstantFPVal:
  case Value::FunctionVal:
    return true;
  case Value::ConstantExprVal:
    if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
      switch (constant_expr->getOpcode()) {
      default:
        return false;
      case Instruction::IntToPtr:
      case Instruction::PtrToInt:
      case Instruction::BitCast:
        return CanResolveConstant(constant_expr->getOperand(0));
      case Instruction::GetElementPtr: {
        // Check that the base can be constant-resolved.
        ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
        Constant *base = dyn_cast<Constant>(*op_cursor);
        if (!base || !CanResolveConstant(base))
          return false;

        // Check that all other operands are just ConstantInt.
        for (Value *op : make_range(constant_expr->op_begin() + 1,
                                    constant_expr->op_end())) {
          ConstantInt *constant_int = dyn_cast<ConstantInt>(op);
          if (!constant_int)
            return false;
        }
        return true;
      }
      }
    } else {
      return false;
    }
  case Value::ConstantPointerNullVal:
    return true;
  }
}

bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
                                 lldb_private::Status &error,
                                 const bool support_function_calls) {
  lldb_private::Log *log(GetLog(LLDBLog::Expressions));

  bool saw_function_with_body = false;
  for (Function &f : module) {
    if (f.begin() != f.end()) {
      if (saw_function_with_body) {
        LLDB_LOGF(log, "More than one function in the module has a body");
        error = lldb_private::Status::FromErrorString(too_many_functions_error);
        return false;
      }
      saw_function_with_body = true;
      LLDB_LOGF(log, "Saw function with body: %s", f.getName().str().c_str());
    }
  }

  for (BasicBlock &bb : function) {
    for (Instruction &ii : bb) {
      switch (ii.getOpcode()) {
      default: {
        LLDB_LOGF(log, "Unsupported instruction: %s", PrintValue(&ii).c_str());
        error = lldb_private::Status::FromErrorString(unsupported_opcode_error);
        return false;
      }
      case Instruction::Add:
      case Instruction::Alloca:
      case Instruction::BitCast:
      case Instruction::Br:
      case Instruction::PHI:
        break;
      case Instruction::Call: {
        CallInst *call_inst = dyn_cast<CallInst>(&ii);

        if (!call_inst) {
          error =
              lldb_private::Status::FromErrorString(interpreter_internal_error);
          return false;
        }

        if (!CanIgnoreCall(call_inst) && !support_function_calls) {
          LLDB_LOGF(log, "Unsupported instruction: %s",
                    PrintValue(&ii).c_str());
          error =
              lldb_private::Status::FromErrorString(unsupported_opcode_error);
          return false;
        }
      } break;
      case Instruction::GetElementPtr:
        break;
      case Instruction::FCmp:
      case Instruction::ICmp: {
        CmpInst *cmp_inst = dyn_cast<CmpInst>(&ii);

        if (!cmp_inst) {
          error =
              lldb_private::Status::FromErrorString(interpreter_internal_error);
          return false;
        }

        switch (cmp_inst->getPredicate()) {
        default: {
          LLDB_LOGF(log, "Unsupported ICmp predicate: %s",
                    PrintValue(&ii).c_str());

          error =
              lldb_private::Status::FromErrorString(unsupported_opcode_error);
          return false;
        }
        case CmpInst::FCMP_OEQ:
        case CmpInst::ICMP_EQ:
        case CmpInst::FCMP_UNE:
        case CmpInst::ICMP_NE:
        case CmpInst::FCMP_OGT:
        case CmpInst::ICMP_UGT:
        case CmpInst::FCMP_OGE:
        case CmpInst::ICMP_UGE:
        case CmpInst::FCMP_OLT:
        case CmpInst::ICMP_ULT:
        case CmpInst::FCMP_OLE:
        case CmpInst::ICMP_ULE:
        case CmpInst::ICMP_SGT:
        case CmpInst::ICMP_SGE:
        case CmpInst::ICMP_SLT:
        case CmpInst::ICMP_SLE:
          break;
        }
      } break;
      case Instruction::And:
      case Instruction::AShr:
      case Instruction::IntToPtr:
      case Instruction::PtrToInt:
      case Instruction::Load:
      case Instruction::LShr:
      case Instruction::Mul:
      case Instruction::Or:
      case Instruction::Ret:
      case Instruction::SDiv:
      case Instruction::SExt:
      case Instruction::Shl:
      case Instruction::SRem:
      case Instruction::Store:
      case Instruction::Sub:
      case Instruction::Trunc:
      case Instruction::UDiv:
      case Instruction::URem:
      case Instruction::Xor:
      case Instruction::ZExt:
        break;
      case Instruction::FAdd:
      case Instruction::FSub:
      case Instruction::FMul:
      case Instruction::FDiv:
        break;
      }

      for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) {
        Value *operand = ii.getOperand(oi);
        Type *operand_type = operand->getType();

        switch (operand_type->getTypeID()) {
        default:
          break;
        case Type::FixedVectorTyID:
        case Type::ScalableVectorTyID: {
          LLDB_LOGF(log, "Unsupported operand type: %s",
                    PrintType(operand_type).c_str());
          error =
              lldb_private::Status::FromErrorString(unsupported_operand_error);
          return false;
        }
        }

        // The IR interpreter currently doesn't know about
        // 128-bit integers. As they're not that frequent,
        // we can just fall back to the JIT rather than
        // choking.
        if (operand_type->getPrimitiveSizeInBits() > 64) {
          LLDB_LOGF(log, "Unsupported operand type: %s",
                    PrintType(operand_type).c_str());
          error =
              lldb_private::Status::FromErrorString(unsupported_operand_error);
          return false;
        }

        if (Constant *constant = llvm::dyn_cast<Constant>(operand)) {
          if (!CanResolveConstant(constant)) {
            LLDB_LOGF(log, "Unsupported constant: %s",
                      PrintValue(constant).c_str());
            error = lldb_private::Status::FromErrorString(
                unsupported_operand_error);
            return false;
          }
        }
      }
    }
  }

  return true;
}

bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
                              llvm::ArrayRef<lldb::addr_t> args,
                              lldb_private::IRExecutionUnit &execution_unit,
                              lldb_private::Status &error,
                              lldb::addr_t stack_frame_bottom,
                              lldb::addr_t stack_frame_top,
                              lldb_private::ExecutionContext &exe_ctx,
                              lldb_private::Timeout<std::micro> timeout) {
  lldb_private::Log *log(GetLog(LLDBLog::Expressions));

  if (log) {
    std::string s;
    raw_string_ostream oss(s);

    module.print(oss, nullptr);

    LLDB_LOGF(log, "Module as passed in to IRInterpreter::Interpret: \n\"%s\"",
              s.c_str());
  }

  const DataLayout &data_layout = module.getDataLayout();

  InterpreterStackFrame frame(data_layout, execution_unit, stack_frame_bottom,
                              stack_frame_top);

  if (frame.m_frame_process_address == LLDB_INVALID_ADDRESS) {
    error =
        lldb_private::Status::FromErrorString("Couldn't allocate stack frame");
  }

  int arg_index = 0;

  for (llvm::Function::arg_iterator ai = function.arg_begin(),
                                    ae = function.arg_end();
       ai != ae; ++ai, ++arg_index) {
    if (args.size() <= static_cast<size_t>(arg_index)) {
      error = lldb_private::Status::FromErrorString(
          "Not enough arguments passed in to function");
      return false;
    }

    lldb::addr_t ptr = args[arg_index];

    frame.MakeArgument(&*ai, ptr);
  }

  frame.Jump(&function.front());

  lldb_private::Process *process = exe_ctx.GetProcessPtr();
  lldb_private::Target *target = exe_ctx.GetTargetPtr();

  using clock = std::chrono::steady_clock;

  // Compute the time at which the timeout has been exceeded.
  std::optional<clock::time_point> end_time;
  if (timeout && timeout->count() > 0)
    end_time = clock::now() + *timeout;

  while (frame.m_ii != frame.m_ie) {
    // Timeout reached: stop interpreting.
    if (end_time && clock::now() >= *end_time) {
      error = lldb_private::Status::FromErrorString(timeout_error);
      return false;
    }

    // If we have access to the debugger we can honor an interrupt request.
    if (target) {
      if (INTERRUPT_REQUESTED(target->GetDebugger(),
                              "Interrupted in IR interpreting.")) {
        error = lldb_private::Status::FromErrorString(interrupt_error);
        return false;
      }
    }

    const Instruction *inst = &*frame.m_ii;

    LLDB_LOGF(log, "Interpreting %s", PrintValue(inst).c_str());

    switch (inst->getOpcode()) {
    default:
      break;

    case Instruction::Add:
    case Instruction::Sub:
    case Instruction::Mul:
    case Instruction::SDiv:
    case Instruction::UDiv:
    case Instruction::SRem:
    case Instruction::URem:
    case Instruction::Shl:
    case Instruction::LShr:
    case Instruction::AShr:
    case Instruction::And:
    case Instruction::Or:
    case Instruction::Xor:
    case Instruction::FAdd:
    case Instruction::FSub:
    case Instruction::FMul:
    case Instruction::FDiv: {
      const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);

      if (!bin_op) {
        LLDB_LOGF(
            log,
            "getOpcode() returns %s, but instruction is not a BinaryOperator",
            inst->getOpcodeName());
        error =
            lldb_private::Status::FromErrorString(interpreter_internal_error);
        return false;
      }

      Value *lhs = inst->getOperand(0);
      Value *rhs = inst->getOperand(1);

      lldb_private::Scalar L;
      lldb_private::Scalar R;

      if (!frame.EvaluateValue(L, lhs, module)) {
        LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str());
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      if (!frame.EvaluateValue(R, rhs, module)) {
        LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str());
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      lldb_private::Scalar result;

      switch (inst->getOpcode()) {
      default:
        break;
      case Instruction::Add:
      case Instruction::FAdd:
        result = L + R;
        break;
      case Instruction::Mul:
      case Instruction::FMul:
        result = L * R;
        break;
      case Instruction::Sub:
      case Instruction::FSub:
        result = L - R;
        break;
      case Instruction::SDiv:
        L.MakeSigned();
        R.MakeSigned();
        result = L / R;
        break;
      case Instruction::UDiv:
        L.MakeUnsigned();
        R.MakeUnsigned();
        result = L / R;
        break;
      case Instruction::FDiv:
        result = L / R;
        break;
      case Instruction::SRem:
        L.MakeSigned();
        R.MakeSigned();
        result = L % R;
        break;
      case Instruction::URem:
        L.MakeUnsigned();
        R.MakeUnsigned();
        result = L % R;
        break;
      case Instruction::Shl:
        result = L << R;
        break;
      case Instruction::AShr:
        result = L >> R;
        break;
      case Instruction::LShr:
        result = L;
        result.ShiftRightLogical(R);
        break;
      case Instruction::And:
        result = L & R;
        break;
      case Instruction::Or:
        result = L | R;
        break;
      case Instruction::Xor:
        result = L ^ R;
        break;
      }

      frame.AssignValue(inst, result, module);

      if (log) {
        LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
        LLDB_LOGF(log, "  L : %s", frame.SummarizeValue(lhs).c_str());
        LLDB_LOGF(log, "  R : %s", frame.SummarizeValue(rhs).c_str());
        LLDB_LOGF(log, "  = : %s", frame.SummarizeValue(inst).c_str());
      }
    } break;
    case Instruction::Alloca: {
      const AllocaInst *alloca_inst = cast<AllocaInst>(inst);

      if (alloca_inst->isArrayAllocation()) {
        LLDB_LOGF(log,
                  "AllocaInsts are not handled if isArrayAllocation() is true");
        error = lldb_private::Status::FromErrorString(unsupported_opcode_error);
        return false;
      }

      // The semantics of Alloca are:
      //   Create a region R of virtual memory of type T, backed by a data
      //   buffer
      //   Create a region P of virtual memory of type T*, backed by a data
      //   buffer
      //   Write the virtual address of R into P

      Type *T = alloca_inst->getAllocatedType();
      Type *Tptr = alloca_inst->getType();

      lldb::addr_t R = frame.Malloc(T);

      if (R == LLDB_INVALID_ADDRESS) {
        LLDB_LOGF(log, "Couldn't allocate memory for an AllocaInst");
        error = lldb_private::Status::FromErrorString(memory_allocation_error);
        return false;
      }

      lldb::addr_t P = frame.Malloc(Tptr);

      if (P == LLDB_INVALID_ADDRESS) {
        LLDB_LOGF(log,
                  "Couldn't allocate the result pointer for an AllocaInst");
        error = lldb_private::Status::FromErrorString(memory_allocation_error);
        return false;
      }

      lldb_private::Status write_error;

      execution_unit.WritePointerToMemory(P, R, write_error);

      if (!write_error.Success()) {
        LLDB_LOGF(log, "Couldn't write the result pointer for an AllocaInst");
        error = lldb_private::Status::FromErrorString(memory_write_error);
        lldb_private::Status free_error;
        execution_unit.Free(P, free_error);
        execution_unit.Free(R, free_error);
        return false;
      }

      frame.m_values[alloca_inst] = P;

      if (log) {
        LLDB_LOGF(log, "Interpreted an AllocaInst");
        LLDB_LOGF(log, "  R : 0x%" PRIx64, R);
        LLDB_LOGF(log, "  P : 0x%" PRIx64, P);
      }
    } break;
    case Instruction::BitCast:
    case Instruction::ZExt: {
      const CastInst *cast_inst = cast<CastInst>(inst);

      Value *source = cast_inst->getOperand(0);

      lldb_private::Scalar S;

      if (!frame.EvaluateValue(S, source, module)) {
        LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str());
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      frame.AssignValue(inst, S, module);
    } break;
    case Instruction::SExt: {
      const CastInst *cast_inst = cast<CastInst>(inst);

      Value *source = cast_inst->getOperand(0);

      lldb_private::Scalar S;

      if (!frame.EvaluateValue(S, source, module)) {
        LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str());
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      S.MakeSigned();

      lldb_private::Scalar S_signextend(S.SLongLong());

      frame.AssignValue(inst, S_signextend, module);
    } break;
    case Instruction::Br: {
      const BranchInst *br_inst = cast<BranchInst>(inst);

      if (br_inst->isConditional()) {
        Value *condition = br_inst->getCondition();

        lldb_private::Scalar C;

        if (!frame.EvaluateValue(C, condition, module)) {
          LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(condition).c_str());
          error = lldb_private::Status::FromErrorString(bad_value_error);
          return false;
        }

        if (!C.IsZero())
          frame.Jump(br_inst->getSuccessor(0));
        else
          frame.Jump(br_inst->getSuccessor(1));

        if (log) {
          LLDB_LOGF(log, "Interpreted a BrInst with a condition");
          LLDB_LOGF(log, "  cond : %s",
                    frame.SummarizeValue(condition).c_str());
        }
      } else {
        frame.Jump(br_inst->getSuccessor(0));

        if (log) {
          LLDB_LOGF(log, "Interpreted a BrInst with no condition");
        }
      }
    }
      continue;
    case Instruction::PHI: {
      const PHINode *phi_inst = cast<PHINode>(inst);
      if (!frame.m_prev_bb) {
        LLDB_LOGF(log,
                  "Encountered PHI node without having jumped from another "
                  "basic block");
        error =
            lldb_private::Status::FromErrorString(interpreter_internal_error);
        return false;
      }

      Value *value = phi_inst->getIncomingValueForBlock(frame.m_prev_bb);
      lldb_private::Scalar result;
      if (!frame.EvaluateValue(result, value, module)) {
        LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(value).c_str());
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }
      frame.AssignValue(inst, result, module);

      if (log) {
        LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
        LLDB_LOGF(log, "  Incoming value : %s",
                  frame.SummarizeValue(value).c_str());
      }
    } break;
    case Instruction::GetElementPtr: {
      const GetElementPtrInst *gep_inst = cast<GetElementPtrInst>(inst);

      const Value *pointer_operand = gep_inst->getPointerOperand();
      Type *src_elem_ty = gep_inst->getSourceElementType();

      lldb_private::Scalar P;

      if (!frame.EvaluateValue(P, pointer_operand, module)) {
        LLDB_LOGF(log, "Couldn't evaluate %s",
                  PrintValue(pointer_operand).c_str());
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      typedef SmallVector<Value *, 8> IndexVector;
      typedef IndexVector::iterator IndexIterator;

      SmallVector<Value *, 8> indices(gep_inst->idx_begin(),
                                      gep_inst->idx_end());

      SmallVector<Value *, 8> const_indices;

      for (IndexIterator ii = indices.begin(), ie = indices.end(); ii != ie;
           ++ii) {
        ConstantInt *constant_index = dyn_cast<ConstantInt>(*ii);

        if (!constant_index) {
          lldb_private::Scalar I;

          if (!frame.EvaluateValue(I, *ii, module)) {
            LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(*ii).c_str());
            error = lldb_private::Status::FromErrorString(bad_value_error);
            return false;
          }

          LLDB_LOGF(log, "Evaluated constant index %s as %llu",
                    PrintValue(*ii).c_str(), I.ULongLong(LLDB_INVALID_ADDRESS));

          constant_index = cast<ConstantInt>(ConstantInt::get(
              (*ii)->getType(), I.ULongLong(LLDB_INVALID_ADDRESS)));
        }

        const_indices.push_back(constant_index);
      }

      uint64_t offset =
          data_layout.getIndexedOffsetInType(src_elem_ty, const_indices);

      lldb_private::Scalar Poffset = P + offset;

      frame.AssignValue(inst, Poffset, module);

      if (log) {
        LLDB_LOGF(log, "Interpreted a GetElementPtrInst");
        LLDB_LOGF(log, "  P       : %s",
                  frame.SummarizeValue(pointer_operand).c_str());
        LLDB_LOGF(log, "  Poffset : %s", frame.SummarizeValue(inst).c_str());
      }
    } break;
    case Instruction::FCmp:
    case Instruction::ICmp: {
      const CmpInst *icmp_inst = cast<CmpInst>(inst);

      CmpInst::Predicate predicate = icmp_inst->getPredicate();

      Value *lhs = inst->getOperand(0);
      Value *rhs = inst->getOperand(1);

      lldb_private::Scalar L;
      lldb_private::Scalar R;

      if (!frame.EvaluateValue(L, lhs, module)) {
        LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str());
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      if (!frame.EvaluateValue(R, rhs, module)) {
        LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str());
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      lldb_private::Scalar result;

      switch (predicate) {
      default:
        return false;
      case CmpInst::ICMP_EQ:
      case CmpInst::FCMP_OEQ:
        result = (L == R);
        break;
      case CmpInst::ICMP_NE:
      case CmpInst::FCMP_UNE:
        result = (L != R);
        break;
      case CmpInst::ICMP_UGT:
        L.MakeUnsigned();
        R.MakeUnsigned();
        result = (L > R);
        break;
      case CmpInst::ICMP_UGE:
        L.MakeUnsigned();
        R.MakeUnsigned();
        result = (L >= R);
        break;
      case CmpInst::FCMP_OGE:
        result = (L >= R);
        break;
      case CmpInst::FCMP_OGT:
        result = (L > R);
        break;
      case CmpInst::ICMP_ULT:
        L.MakeUnsigned();
        R.MakeUnsigned();
        result = (L < R);
        break;
      case CmpInst::FCMP_OLT:
        result = (L < R);
        break;
      case CmpInst::ICMP_ULE:
        L.MakeUnsigned();
        R.MakeUnsigned();
        result = (L <= R);
        break;
      case CmpInst::FCMP_OLE:
        result = (L <= R);
        break;
      case CmpInst::ICMP_SGT:
        L.MakeSigned();
        R.MakeSigned();
        result = (L > R);
        break;
      case CmpInst::ICMP_SGE:
        L.MakeSigned();
        R.MakeSigned();
        result = (L >= R);
        break;
      case CmpInst::ICMP_SLT:
        L.MakeSigned();
        R.MakeSigned();
        result = (L < R);
        break;
      case CmpInst::ICMP_SLE:
        L.MakeSigned();
        R.MakeSigned();
        result = (L <= R);
        break;
      }

      frame.AssignValue(inst, result, module);

      if (log) {
        LLDB_LOGF(log, "Interpreted an ICmpInst");
        LLDB_LOGF(log, "  L : %s", frame.SummarizeValue(lhs).c_str());
        LLDB_LOGF(log, "  R : %s", frame.SummarizeValue(rhs).c_str());
        LLDB_LOGF(log, "  = : %s", frame.SummarizeValue(inst).c_str());
      }
    } break;
    case Instruction::IntToPtr: {
      const IntToPtrInst *int_to_ptr_inst = cast<IntToPtrInst>(inst);

      Value *src_operand = int_to_ptr_inst->getOperand(0);

      lldb_private::Scalar I;

      if (!frame.EvaluateValue(I, src_operand, module)) {
        LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      frame.AssignValue(inst, I, module);

      if (log) {
        LLDB_LOGF(log, "Interpreted an IntToPtr");
        LLDB_LOGF(log, "  Src : %s", frame.SummarizeValue(src_operand).c_str());
        LLDB_LOGF(log, "  =   : %s", frame.SummarizeValue(inst).c_str());
      }
    } break;
    case Instruction::PtrToInt: {
      const PtrToIntInst *ptr_to_int_inst = cast<PtrToIntInst>(inst);

      Value *src_operand = ptr_to_int_inst->getOperand(0);

      lldb_private::Scalar I;

      if (!frame.EvaluateValue(I, src_operand, module)) {
        LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      frame.AssignValue(inst, I, module);

      if (log) {
        LLDB_LOGF(log, "Interpreted a PtrToInt");
        LLDB_LOGF(log, "  Src : %s", frame.SummarizeValue(src_operand).c_str());
        LLDB_LOGF(log, "  =   : %s", frame.SummarizeValue(inst).c_str());
      }
    } break;
    case Instruction::Trunc: {
      const TruncInst *trunc_inst = cast<TruncInst>(inst);

      Value *src_operand = trunc_inst->getOperand(0);

      lldb_private::Scalar I;

      if (!frame.EvaluateValue(I, src_operand, module)) {
        LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      frame.AssignValue(inst, I, module);

      if (log) {
        LLDB_LOGF(log, "Interpreted a Trunc");
        LLDB_LOGF(log, "  Src : %s", frame.SummarizeValue(src_operand).c_str());
        LLDB_LOGF(log, "  =   : %s", frame.SummarizeValue(inst).c_str());
      }
    } break;
    case Instruction::Load: {
      const LoadInst *load_inst = cast<LoadInst>(inst);

      // The semantics of Load are:
      //   Create a region D that will contain the loaded data
      //   Resolve the region P containing a pointer
      //   Dereference P to get the region R that the data should be loaded from
      //   Transfer a unit of type type(D) from R to D

      const Value *pointer_operand = load_inst->getPointerOperand();

      lldb::addr_t D = frame.ResolveValue(load_inst, module);
      lldb::addr_t P = frame.ResolveValue(pointer_operand, module);

      if (D == LLDB_INVALID_ADDRESS) {
        LLDB_LOGF(log, "LoadInst's value doesn't resolve to anything");
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      if (P == LLDB_INVALID_ADDRESS) {
        LLDB_LOGF(log, "LoadInst's pointer doesn't resolve to anything");
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      lldb::addr_t R;
      lldb_private::Status read_error;
      execution_unit.ReadPointerFromMemory(&R, P, read_error);

      if (!read_error.Success()) {
        LLDB_LOGF(log, "Couldn't read the address to be loaded for a LoadInst");
        error = lldb_private::Status::FromErrorString(memory_read_error);
        return false;
      }

      Type *target_ty = load_inst->getType();
      size_t target_size = data_layout.getTypeStoreSize(target_ty);
      lldb_private::DataBufferHeap buffer(target_size, 0);

      read_error.Clear();
      execution_unit.ReadMemory(buffer.GetBytes(), R, buffer.GetByteSize(),
                                read_error);
      if (!read_error.Success()) {
        LLDB_LOGF(log, "Couldn't read from a region on behalf of a LoadInst");
        error = lldb_private::Status::FromErrorString(memory_read_error);
        return false;
      }

      lldb_private::Status write_error;
      execution_unit.WriteMemory(D, buffer.GetBytes(), buffer.GetByteSize(),
                                 write_error);
      if (!write_error.Success()) {
        LLDB_LOGF(log, "Couldn't write to a region on behalf of a LoadInst");
        error = lldb_private::Status::FromErrorString(memory_write_error);
        return false;
      }

      if (log) {
        LLDB_LOGF(log, "Interpreted a LoadInst");
        LLDB_LOGF(log, "  P : 0x%" PRIx64, P);
        LLDB_LOGF(log, "  R : 0x%" PRIx64, R);
        LLDB_LOGF(log, "  D : 0x%" PRIx64, D);
      }
    } break;
    case Instruction::Ret: {
      return true;
    }
    case Instruction::Store: {
      const StoreInst *store_inst = cast<StoreInst>(inst);

      // The semantics of Store are:
      //   Resolve the region D containing the data to be stored
      //   Resolve the region P containing a pointer
      //   Dereference P to get the region R that the data should be stored in
      //   Transfer a unit of type type(D) from D to R

      const Value *value_operand = store_inst->getValueOperand();
      const Value *pointer_operand = store_inst->getPointerOperand();

      lldb::addr_t D = frame.ResolveValue(value_operand, module);
      lldb::addr_t P = frame.ResolveValue(pointer_operand, module);

      if (D == LLDB_INVALID_ADDRESS) {
        LLDB_LOGF(log, "StoreInst's value doesn't resolve to anything");
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      if (P == LLDB_INVALID_ADDRESS) {
        LLDB_LOGF(log, "StoreInst's pointer doesn't resolve to anything");
        error = lldb_private::Status::FromErrorString(bad_value_error);
        return false;
      }

      lldb::addr_t R;
      lldb_private::Status read_error;
      execution_unit.ReadPointerFromMemory(&R, P, read_error);

      if (!read_error.Success()) {
        LLDB_LOGF(log, "Couldn't read the address to be loaded for a LoadInst");
        error = lldb_private::Status::FromErrorString(memory_read_error);
        return false;
      }

      Type *target_ty = value_operand->getType();
      size_t target_size = data_layout.getTypeStoreSize(target_ty);
      lldb_private::DataBufferHeap buffer(target_size, 0);

      read_error.Clear();
      execution_unit.ReadMemory(buffer.GetBytes(), D, buffer.GetByteSize(),
                                read_error);
      if (!read_error.Success()) {
        LLDB_LOGF(log, "Couldn't read from a region on behalf of a StoreInst");
        error = lldb_private::Status::FromErrorString(memory_read_error);
        return false;
      }

      lldb_private::Status write_error;
      execution_unit.WriteMemory(R, buffer.GetBytes(), buffer.GetByteSize(),
                                 write_error);
      if (!write_error.Success()) {
        LLDB_LOGF(log, "Couldn't write to a region on behalf of a StoreInst");
        error = lldb_private::Status::FromErrorString(memory_write_error);
        return false;
      }

      if (log) {
        LLDB_LOGF(log, "Interpreted a StoreInst");
        LLDB_LOGF(log, "  D : 0x%" PRIx64, D);
        LLDB_LOGF(log, "  P : 0x%" PRIx64, P);
        LLDB_LOGF(log, "  R : 0x%" PRIx64, R);
      }
    } break;
    case Instruction::Call: {
      const CallInst *call_inst = cast<CallInst>(inst);

      if (CanIgnoreCall(call_inst))
        break;

      // Get the return type
      llvm::Type *returnType = call_inst->getType();
      if (returnType == nullptr) {
        error = lldb_private::Status::FromErrorString(
            "unable to access return type");
        return false;
      }

      // Work with void, integer and pointer return types
      if (!returnType->isVoidTy() && !returnType->isIntegerTy() &&
          !returnType->isPointerTy()) {
        error = lldb_private::Status::FromErrorString(
            "return type is not supported");
        return false;
      }

      // Check we can actually get a thread
      if (exe_ctx.GetThreadPtr() == nullptr) {
        error =
            lldb_private::Status::FromErrorString("unable to acquire thread");
        return false;
      }

      // Make sure we have a valid process
      if (!process) {
        error =
            lldb_private::Status::FromErrorString("unable to get the process");
        return false;
      }

      // Find the address of the callee function
      lldb_private::Scalar I;
      const llvm::Value *val = call_inst->getCalledOperand();

      if (!frame.EvaluateValue(I, val, module)) {
        error = lldb_private::Status::FromErrorString(
            "unable to get address of function");
        return false;
      }
      lldb_private::Address funcAddr(I.ULongLong(LLDB_INVALID_ADDRESS));

      lldb_private::DiagnosticManager diagnostics;
      lldb_private::EvaluateExpressionOptions options;

      llvm::FunctionType *prototype = call_inst->getFunctionType();

      // Find number of arguments
      const int numArgs = call_inst->arg_size();

      // We work with a fixed array of 16 arguments which is our upper limit
      static lldb_private::ABI::CallArgument rawArgs[16];
      if (numArgs >= 16) {
        error = lldb_private::Status::FromErrorString(
            "function takes too many arguments");
        return false;
      }

      // Push all function arguments to the argument list that will be passed
      // to the call function thread plan
      for (int i = 0; i < numArgs; i++) {
        // Get details of this argument
        llvm::Value *arg_op = call_inst->getArgOperand(i);
        llvm::Type *arg_ty = arg_op->getType();

        // Ensure that this argument is an supported type
        if (!arg_ty->isIntegerTy() && !arg_ty->isPointerTy()) {
          error = lldb_private::Status::FromErrorStringWithFormat(
              "argument %d must be integer type", i);
          return false;
        }

        // Extract the arguments value
        lldb_private::Scalar tmp_op = 0;
        if (!frame.EvaluateValue(tmp_op, arg_op, module)) {
          error = lldb_private::Status::FromErrorStringWithFormat(
              "unable to evaluate argument %d", i);
          return false;
        }

        // Check if this is a string literal or constant string pointer
        if (arg_ty->isPointerTy()) {
          lldb::addr_t addr = tmp_op.ULongLong();
          size_t dataSize = 0;

          bool Success = execution_unit.GetAllocSize(addr, dataSize);
          UNUSED_IF_ASSERT_DISABLED(Success);
          assert(Success &&
                 "unable to locate host data for transfer to device");
          // Create the required buffer
          rawArgs[i].size = dataSize;
          rawArgs[i].data_up.reset(new uint8_t[dataSize + 1]);

          // Read string from host memory
          execution_unit.ReadMemory(rawArgs[i].data_up.get(), addr, dataSize,
                                    error);
          assert(!error.Fail() &&
                 "we have failed to read the string from memory");

          // Add null terminator
          rawArgs[i].data_up[dataSize] = '\0';
          rawArgs[i].type = lldb_private::ABI::CallArgument::HostPointer;
        } else /* if ( arg_ty->isPointerTy() ) */
        {
          rawArgs[i].type = lldb_private::ABI::CallArgument::TargetValue;
          // Get argument size in bytes
          rawArgs[i].size = arg_ty->getIntegerBitWidth() / 8;
          // Push value into argument list for thread plan
          rawArgs[i].value = tmp_op.ULongLong();
        }
      }

      // Pack the arguments into an llvm::array
      llvm::ArrayRef<lldb_private::ABI::CallArgument> args(rawArgs, numArgs);

      // Setup a thread plan to call the target function
      lldb::ThreadPlanSP call_plan_sp(
          new lldb_private::ThreadPlanCallFunctionUsingABI(
              exe_ctx.GetThreadRef(), funcAddr, *prototype, *returnType, args,
              options));

      // Check if the plan is valid
      lldb_private::StreamString ss;
      if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss)) {
        error = lldb_private::Status::FromErrorStringWithFormat(
            "unable to make ThreadPlanCallFunctionUsingABI for 0x%llx",
            I.ULongLong());
        return false;
      }

      process->SetRunningUserExpression(true);

      // Execute the actual function call thread plan
      lldb::ExpressionResults res =
          process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);

      // Check that the thread plan completed successfully
      if (res != lldb::ExpressionResults::eExpressionCompleted) {
        error = lldb_private::Status::FromErrorString(
            "ThreadPlanCallFunctionUsingABI failed");
        return false;
      }

      process->SetRunningUserExpression(false);

      // Void return type
      if (returnType->isVoidTy()) {
        // Cant assign to void types, so we leave the frame untouched
      } else
          // Integer or pointer return type
          if (returnType->isIntegerTy() || returnType->isPointerTy()) {
        // Get the encapsulated return value
        lldb::ValueObjectSP retVal = call_plan_sp.get()->GetReturnValueObject();

        lldb_private::Scalar returnVal = -1;
        lldb_private::ValueObject *vobj = retVal.get();

        // Check if the return value is valid
        if (vobj == nullptr || !retVal) {
          error = lldb_private::Status::FromErrorString(
              "unable to get the return value");
          return false;
        }

        // Extract the return value as a integer
        lldb_private::Value &value = vobj->GetValue();
        returnVal = value.GetScalar();

        // Push the return value as the result
        frame.AssignValue(inst, returnVal, module);
      }
    } break;
    }

    ++frame.m_ii;
  }

  return false;
}
