// Copyright 2019 The IREE Authors
//
// Licensed 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 "./vm.h"

#include <ios>
#include <sstream>
#include <unordered_set>

#include "./buffer_interop.h"
#include "./status_utils.h"
#include "iree/base/api.h"

// TODO: We shouldn't need the HAL API but it is used for direct printing
// summaries of HAL objects in lists. We should have a better way of doing this
// dynamically vs hard depending on a type switch here.
#include "iree/modules/hal/module.h"
#include "iree/tooling/modules/resolver.h"
#include "iree/vm/api.h"

using namespace nanobind::literals;

namespace iree {
namespace python {

namespace {

static const char kFromBufferDocstring[] =
    R"(Creates a Vmmodule from a Python buffer.

This is intended as a quick and dirty way to instantiate a VmModule from
a binary blob. It will implicitly make a copy if alignment is not sufficient.

It is recommended to use one of the other construction methods for maximum
determinism and efficiency:

* `mmap` : To memory map from a file.
* `wrap_buffer` : To directly wrap a Python buffer that is known to be
  aligned properly.
* `copy_buffer` : To always make a copy of a Python buffer such that it is
  aligned properly.

This was historically called `from_flatbuffer`. It is recommended that new
code use `flat_buffer`.

Args:
  instance: A VmInstance.
  buffer: An object implementing the Python buffer protocol. Typically a
    bytes, bytearray, memoryview, etc.
  warn_if_copy: Raises a warning if alignment is not sufficient to use the
    buffer directly, resulting in a copy. Defaults to True.
)";

static const char kCopyBufferDocstring[] =
    R"(Creates a VmModule by making a copy of a Python buffer.

Args:
  instance: A VmInstance.
  buffer: An object implementing the Python buffer protocol. Typically a
    bytes, bytearray, memoryview, etc.
)";

static const char kWrapBufferDocstring[] =
    R"(Creates a VmModule by directly using the backing memory of a Python buffer.

Args:
  instance: A VmInstance.
  buffer: An object implementing the Python buffer protocol. Typically a
    bytes, bytearray, memoryview, etc.
  destroy_callback: A no-argument callback that is invoked when the backing
    buffer is no longer in use.
  close_buffer: Whether to call the `close` method on the `buffer` (prior to
    invoking `destroy_callback`). Defaults to False.

Raises:
  ValueError if alignment is not satisfied.
)";

static const char kMMapDocstring[] =
    R"(Create a VmModule by mmap'ing a file.

When backed by a file, this is generally the most effective way to create a
VmModule. Especially for large modules, this will result in the fewest
copies and the most effective use of the system cache across invocations.

Note that mmap behavior differs between Posix and Windows. Whereas the former
will allow the backing file to be open before an mmap call and deleted
immediately after, Windows generally allows neither. For compatibility,
make sure that the backing file is not open for writing before calling this
method and that if it needs to be deleted when done, that is done in a
`destroy_callback`.

Args:
  instance: A VmInstance.
  filepath: Path to the file on the file system.
  destroy_callback: A no-argument callback that is invoked when the backing
    buffer is no longer in use.
)";

// RAII wrapper for a Py_buffer which calls PyBuffer_Release when it goes
// out of scope.
class PyBufferReleaser {
 public:
  PyBufferReleaser(Py_buffer& b) : b_(b) {}
  ~PyBufferReleaser() { PyBuffer_Release(&b_); }

 private:
  Py_buffer& b_;
};

py::dict GetFunctionReflectionDict(iree_vm_function_t& f) {
  py::dict attrs;
  for (iree_host_size_t i = 0;; ++i) {
    iree_string_pair_t attr;
    auto status = iree_vm_function_get_attr(f, i, &attr);
    if (iree_status_is_out_of_range(status)) {
      iree_status_ignore(status);
      break;
    }
    CheckApiStatus(status, "Error getting reflection attr");
    py::str key_str(attr.key.data, attr.key.size);
    py::str value_str(attr.value.data, attr.value.size);
    attrs[std::move(key_str)] = std::move(value_str);
  }
  return attrs;
}

}  // namespace

//------------------------------------------------------------------------------
// VmBuffer
//------------------------------------------------------------------------------

int VmBuffer::HandleBufferProtocol(Py_buffer* view, int flags) {
  view->buf = raw_ptr()->data.data;
  view->len = raw_ptr()->data.data_length;
  view->readonly = !(raw_ptr()->access & IREE_VM_BUFFER_ACCESS_MUTABLE);
  view->itemsize = 1;
  view->format = (char*)"B";  // Byte
  view->ndim = 1;
  view->shape = nullptr;
  view->strides = nullptr;
  view->suboffsets = nullptr;
  view->internal = nullptr;
  return 0;
}

//------------------------------------------------------------------------------
// VmInstance
//------------------------------------------------------------------------------

VmInstance VmInstance::Create() {
  IREE_TRACE_SCOPE_NAMED("VmInstance::Create");

  iree_vm_instance_t* instance = NULL;
  auto status = iree_vm_instance_create(IREE_VM_TYPE_CAPACITY_DEFAULT,
                                        iree_allocator_system(), &instance);
  CheckApiStatus(status, "Error creating instance");

  // The python bindings assume the HAL is always available for use.
  // We register the types here so modules can be loaded using the HAL types
  // in any order.
  CheckApiStatus(iree_hal_module_register_all_types(instance),
                 "registering HAL types");

  return VmInstance::StealFromRawPtr(instance);
}

//------------------------------------------------------------------------------
// VmContext
//------------------------------------------------------------------------------

VmContext VmContext::Create(VmInstance* instance,
                            std::optional<std::vector<VmModule*>>& modules) {
  IREE_TRACE_SCOPE_NAMED("VmContext::Create");
  iree_vm_context_t* context;
  if (!modules) {
    // Simple create with open allowed modules.
    auto status =
        iree_vm_context_create(instance->raw_ptr(), IREE_VM_CONTEXT_FLAG_NONE,
                               iree_allocator_system(), &context);
    CheckApiStatus(status, "Error creating vm context");
  } else {
    // Closed set of modules.
    std::vector<iree_vm_module_t*> module_handles;
    module_handles.resize(modules->size());
    for (size_t i = 0, e = module_handles.size(); i < e; ++i) {
      module_handles[i] = (*modules)[i]->raw_ptr();
    }
    auto status = iree_vm_context_create_with_modules(
        instance->raw_ptr(), IREE_VM_CONTEXT_FLAG_NONE, module_handles.size(),
        module_handles.data(), iree_allocator_system(), &context);
    CheckApiStatus(status, "Error creating vm context with modules");
  }

  IREE_ASSERT(context);
  return VmContext::StealFromRawPtr(context);
}

void VmContext::RegisterModules(std::vector<VmModule*> modules) {
  std::vector<iree_vm_module_t*> module_handles;
  module_handles.resize(modules.size());
  for (size_t i = 0, e = module_handles.size(); i < e; ++i) {
    module_handles[i] = modules[i]->raw_ptr();
  }
  auto status = iree_vm_context_register_modules(
      raw_ptr(), module_handles.size(), &module_handles[0]);
  CheckApiStatus(status, "Error registering modules");
}

void VmContext::Invoke(iree_vm_function_t f, VmVariantList& inputs,
                       VmVariantList& outputs) {
  iree_status_t status;
  {
    py::gil_scoped_release release;
    status = iree_vm_invoke(raw_ptr(), f, IREE_VM_INVOCATION_FLAG_NONE, nullptr,
                            inputs.raw_ptr(), outputs.raw_ptr(),
                            iree_allocator_system());
  }
  CheckApiStatus(status, "Error invoking function");
}

//------------------------------------------------------------------------------
// VmModule
//------------------------------------------------------------------------------

VmModule VmModule::ResolveModuleDependency(VmInstance* instance,
                                           const std::string& name,
                                           uint32_t minimum_version) {
  IREE_TRACE_SCOPE_NAMED("VmModule::ResolveModuleDependency");
  iree_vm_module_t* module = nullptr;

  iree_vm_module_dependency_t dependency = {
      iree_make_cstring_view(name.c_str()), minimum_version,
      IREE_VM_MODULE_DEPENDENCY_FLAG_REQUIRED};

  auto status = iree_tooling_resolve_module_dependency(
      instance->raw_ptr(), &dependency, iree_allocator_system(), &module);

  assert(module != nullptr);

  CheckApiStatus(status, "Error resolving module dependency");
  auto py_module = VmModule::StealFromRawPtr(module);
  return py_module;
}

VmModule VmModule::MMap(VmInstance* instance, std::string filepath,
                        py::object destroy_callback) {
  IREE_TRACE_SCOPE_NAMED("VmModule::MMap");
  auto mmap_module = py::module_::import_("mmap");
  auto open_func = py::module_::import_("io").attr("open");
  auto file_obj = open_func(filepath, "r+b");
  // The signature of mmap is different on Windows vs others. On others,
  // we use explicit flags and protection attributes for better control,
  // triggering off of the presence of the MAP_SHARED flag constant (which
  // is not present on Windows).
  py::object mapped_file;
  if (py::hasattr(mmap_module, "MAP_SHARED")) {
    // Posix mmap signature.
    auto flags = py::cast<int64_t>(mmap_module.attr("MAP_SHARED"));
    // MAP_POPULATE isn't available on all versions/platforms.
    if (py::hasattr(mmap_module, "MAP_POPULATE")) {
      flags |= py::cast<int64_t>(mmap_module.attr("MAP_POPULATE"));
    }
    auto prot = py::cast<int64_t>(mmap_module.attr("PROT_READ"));
    mapped_file = mmap_module.attr("mmap")(file_obj.attr("fileno")(), 0,
                                           "flags"_a = flags, "prot"_a = prot);
  } else {
    // Windows mmap signature.
    mapped_file =
        mmap_module.attr("mmap")(file_obj.attr("fileno")(), 0,
                                 "access"_a = mmap_module.attr("ACCESS_READ"));
  }
  // Backing file can be closed after a successful mmap call.
  file_obj.attr("close")();

  // MADV_RANDOM is not available on Windows (and possibly others?).
  if (py::hasattr(mmap_module, "MADV_RANDOM")) {
    mapped_file.attr("madvise")(mmap_module.attr("MADV_RANDOM"));
  }
  return WrapBuffer(instance, std::move(mapped_file),
                    std::move(destroy_callback),
                    /*close_buffer=*/true);
}

VmModule VmModule::WrapBuffer(VmInstance* instance, py::object buffer_obj,
                              py::object destroy_callback, bool close_buffer) {
  IREE_TRACE_SCOPE_NAMED("VmModule::FromAlignedMemory");
  // State object that is retained for the life of the module.
  // It is responsible for keeping the backing resources alive and
  // holding the user-level destroy callback.
  // Note that the original buffer_obj is not captured explicitly but
  // is available as part of the Py_buffer underlying the PyBufferRequest.
  // Aside from being more efficient, avoiding redundant capture removes
  // destruction race potential.
  struct BufferState {
    BufferState(py::object buffer_obj, py::object destroy_callback,
                bool close_buffer)
        : buffer_info(buffer_obj, PyBUF_SIMPLE),
          destroy_callback(std::move(destroy_callback)),
          close_buffer(close_buffer) {}
    PyBufferRequest buffer_info;
    py::object destroy_callback;
    bool close_buffer;

    py::handle get_buffer() { return py::handle(buffer_info.view().obj); }
  };
  BufferState* state =
      new BufferState(buffer_obj, destroy_callback, close_buffer);
  PyBufferRequest& buffer_info = state->buffer_info;
  if (!iree_host_size_has_alignment((uintptr_t)buffer_info.view().buf,
                                    IREE_HAL_HEAP_BUFFER_ALIGNMENT)) {
    std::stringstream err;
    err << "VmModule.from_aligned_memory received an unaligned buffer. ";
    err << "Got 0x" << (void*)buffer_info.view().buf << ", expected alignment ";
    err << IREE_HAL_HEAP_BUFFER_ALIGNMENT;
    throw std::invalid_argument(err.str());
  }

  iree_vm_module_t* module = nullptr;
  auto ctl_fn = +([](void* self, iree_allocator_command_t command,
                     const void* params, void** inout_ptr) {
    py::gil_scoped_acquire gil;
    assert(command == IREE_ALLOCATOR_COMMAND_FREE);
    try {
      // Destruction sequencing is tricky. We must have released the
      // PyBufferRequest before calling close, so we first get what we
      // need out of the state into local variables, then delete the state
      // (releasing the PyBufferRequest), then closing and issuing the
      // destroy callback. Getting the order wrong will result in an
      // unrecoverable exception indicating the the buffer cannot be closed
      // with outstanding mappings.
      BufferState* state = static_cast<BufferState*>(self);
      py::object destroy_callback = std::move(state->destroy_callback);
      py::object buffer_to_close;
      if (state->close_buffer) {
        buffer_to_close = py::borrow(state->get_buffer());
      }
      delete state;

      if (buffer_to_close) {
        buffer_to_close.attr("close")();
      }

      if (!destroy_callback.is_none()) {
        destroy_callback();
      }
    } catch (std::exception& e) {
      // There are many situations where deallocation exceptions can be
      // swallowed, so carp loudly. This is almost always a critical issue
      // that needs to be visible.
      fprintf(
          stderr,
          "error: exception raised while deallocating storage for an "
          "iree.runtime.VmModule. This is unrecoverable and likely indicates a "
          "serious problem, minimally resulting in memory leaks: %s",
          e.what());
      return iree_make_status(
          IREE_STATUS_UNKNOWN,
          "exception raised while deallocating storage for an "
          "iree.runtime.VmModule. This is unrecoverable and likely indicates a "
          "serious problem, minimally resulting in memory leaks: %s",
          e.what());
    }
    return iree_ok_status();
  });
  iree_allocator_t deallocator{/*self=*/state, /*ctl=*/ctl_fn};

  auto status = iree_vm_bytecode_module_create(
      instance->raw_ptr(),
      {static_cast<const uint8_t*>(buffer_info.view().buf),
       static_cast<iree_host_size_t>(buffer_info.view().len)},
      deallocator, iree_allocator_system(), &module);
  if (!iree_status_is_ok(status)) {
    delete state;
  }

  CheckApiStatus(status, "Error creating vm module from aligned memory");
  auto py_module = VmModule::StealFromRawPtr(module);
  // Stash a reference to the flatbuffer at the Python instance level. This
  // is exposed to the tracing API, allowing it to get at the backing contents.
  py_module.stashed_flatbuffer_blob = buffer_obj;
  return py_module;
}

VmModule VmModule::CopyBuffer(VmInstance* instance, py::object buffer_obj) {
  IREE_TRACE_SCOPE_NAMED("VmModule::CopyBuffer");
  auto alignment =
      py::cast<uintptr_t>(py::module_::import_("mmap").attr("PAGESIZE"));
  auto bytearray_ctor = py::module_::import_("builtins").attr("bytearray");
  PyBufferRequest src_buffer_info(buffer_obj, PyBUF_SIMPLE);
  auto src_buffer_size = src_buffer_info.view().len;

  // Need to allocate an extra page because there is no control at the Python
  // level for the alignment it may have.
  auto dst_buffer = bytearray_ctor(src_buffer_size + alignment);
  PyBufferRequest dst_buffer_info(dst_buffer, PyBUF_SIMPLE);
  void* dst_aligned =
      (void*)iree_host_align((uintptr_t)dst_buffer_info.view().buf, alignment);
  uintptr_t dst_offset =
      (uintptr_t)dst_aligned - (uintptr_t)dst_buffer_info.view().buf;

  // Now create a memoryview over the unaligned bytearray and slice into that
  // to get the aligned Python buffer.
  auto dst_slice =
      py::slice(py::cast(dst_offset), py::cast(dst_offset + src_buffer_size),
                py::cast(1));

  py::object dst_view = py::steal<py::object>(
      PyMemoryView_GetContiguous(dst_buffer.ptr(), PyBUF_READ, 'C'));
  py::object dst_view_aligned = dst_view[dst_slice];

  // If any of the indexing math was wrong, Python exceptions will be raised
  // above, so this is implicitly guarding the memcpy if it is done last.
  std::memcpy(dst_aligned, src_buffer_info.view().buf, src_buffer_size);
  return WrapBuffer(instance, std::move(dst_view_aligned),
                    /*destroy_callback=*/py::none(),
                    /*close_buffer=*/false);
}

VmModule VmModule::FromBuffer(VmInstance* instance, py::object buffer_obj,
                              bool warn_if_copy) {
  IREE_TRACE_SCOPE_NAMED("VmModule::FromBuffer");
  PyBufferRequest buffer_info(buffer_obj, PyBUF_SIMPLE);

  if (iree_host_size_has_alignment((uintptr_t)buffer_info.view().buf,
                                   IREE_HAL_HEAP_BUFFER_ALIGNMENT)) {
    return WrapBuffer(instance, std::move(buffer_obj),
                      /*destroy_callback=*/py::none(), /*close_buffer=*/false);
  } else {
    if (warn_if_copy) {
      py::module_::import_("warnings")
          .attr("warn")(
              "Making copy of unaligned VmModule buffer. It is recommended to "
              "make this deterministic by calling `copy_buffer` to always make "
              "a copy or `mmap` to efficiently load from a file. This warning "
              "can be silenced by adding `warn_if_copy=False` to "
              "`from_buffer`");
    }
    return CopyBuffer(instance, std::move(buffer_obj));
  }
}

std::optional<iree_vm_function_t> VmModule::LookupFunction(
    const std::string& name, iree_vm_function_linkage_t linkage) {
  iree_vm_function_t f;
  auto status = iree_vm_module_lookup_function_by_name(
      raw_ptr(), linkage,
      {name.data(), static_cast<iree_host_size_t>(name.size())}, &f);
  if (iree_status_is_not_found(status)) {
    iree_status_ignore(status);
    return std::nullopt;
  }
  CheckApiStatus(status, "Error looking up function");
  return f;
}

//------------------------------------------------------------------------------
// VmRef
//------------------------------------------------------------------------------

const char* const VmRef::kRefAttr = "__iree_vm_ref__";
const char* const VmRef::kCastAttr = "__iree_vm_cast__";
const char* const VmRef::kTypeAttr = "__iree_vm_type__";

py::object VmRef::Deref(py::object ref_object_class, bool optional) {
  py::object casted = ref_object_class.attr(kCastAttr)(this);
  if (!optional && casted.is_none()) {
    throw py::type_error("Cannot dereference to specific type");
  }
  return casted;
}

bool VmRef::IsInstance(py::object ref_object_class) {
  auto type = py::cast<iree_vm_ref_type_t>(ref_object_class.attr(kTypeAttr)());
  return type == ref_.type;
}

std::string VmRef::ToString() {
  if (!ref_.ptr) {
    return "<VmRef NULL>";
  }
  iree_string_view_t type_name = iree_vm_ref_type_name(ref_.type);
  std::stringstream ss;
  ss << "<VmRef ";
  ss.write(type_name.data, type_name.size);
  ss << " at " << std::hex << "0x" << reinterpret_cast<uintptr_t>(ref_.ptr)
     << ">";
  return ss.str();
}

//------------------------------------------------------------------------------
// VmVariantList
//------------------------------------------------------------------------------

void VmVariantList::PushFloat(double fvalue) {
  // Note that Python floats are f64.
  iree_vm_value_t value = iree_vm_value_make_f64(fvalue);
  CheckApiStatus(iree_vm_list_push_value(raw_ptr(), &value),
                 "Could not push float");
}

void VmVariantList::PushInt(int64_t ivalue) {
  // Note that Python ints are unbounded, so just use the largest type we
  // have.
  iree_vm_value_t value = iree_vm_value_make_i64(ivalue);
  CheckApiStatus(iree_vm_list_push_value(raw_ptr(), &value),
                 "Could not push int");
}

void VmVariantList::PushList(VmVariantList& other) {
  iree_vm_ref_t retained = iree_vm_list_retain_ref(other.raw_ptr());
  iree_vm_list_push_ref_move(raw_ptr(), &retained);
}

void VmVariantList::PushRef(py::handle ref_or_object) {
  py::object py_ref = ref_or_object.attr(VmRef::kRefAttr);
  VmRef& ref = py::cast<VmRef&>(py_ref);
  CheckApiStatus(iree_vm_list_push_ref_retain(raw_ptr(), &ref.ref()),
                 "Failed to push ref");
}

py::object VmVariantList::GetAsList(int index) {
  iree_vm_ref_t ref = {0};
  CheckApiStatus(iree_vm_list_get_ref_assign(raw_ptr(), index, &ref),
                 "Could not access list element");
  iree_vm_list_t* sub_list = NULL;
  CheckApiStatus(iree_vm_list_check_deref(ref, &sub_list),
                 "Could not deref list (wrong type?)");
  iree_vm_list_retain(sub_list);
  return py::cast(VmVariantList::StealFromRawPtr(sub_list));
}

py::object VmVariantList::GetVariant(int index) {
  iree_vm_variant_t v = iree_vm_variant_empty();
  CheckApiStatus(iree_vm_list_get_variant_assign(raw_ptr(), index, &v),
                 "Could not access list element");
  if (iree_vm_variant_is_empty(v)) {
    return py::none();
  } else if (iree_vm_variant_is_value(v)) {
    // Convert a value type.
    switch (iree_vm_type_def_as_value(v.type)) {
      case IREE_VM_VALUE_TYPE_I8:
        return py::cast(v.i8);
      case IREE_VM_VALUE_TYPE_I16:
        return py::cast(v.i16);
      case IREE_VM_VALUE_TYPE_I32:
        return py::cast(v.i32);
      case IREE_VM_VALUE_TYPE_I64:
        return py::cast(v.i64);
      case IREE_VM_VALUE_TYPE_F32:
        return py::cast(v.f32);
      case IREE_VM_VALUE_TYPE_F64:
        return py::cast(v.f64);
      default:
        throw RaiseValueError("Unsupported VM value type conversion");
    }
  } else if (iree_vm_variant_is_ref(v)) {
    VmRef ref;
    iree_vm_ref_retain(&v.ref, &ref.ref());
    return py::cast(ref, py::rv_policy::move);
  }

  throw RaiseValueError("Unsupported VM to Python Type Conversion");
}

py::object VmVariantList::GetAsSerializedTraceValue(int index) {
  iree_vm_variant_t v = iree_vm_variant_empty();
  CheckApiStatus(iree_vm_list_get_variant_assign(raw_ptr(), index, &v),
                 "Could not access list element");
  if (iree_vm_variant_is_empty(v)) {
    py::dict record;
    record["type"] = "null";
    return std::move(record);
  } else if (iree_vm_variant_is_value(v)) {
    // Convert a value type.
    py::dict record;
    switch (iree_vm_type_def_as_value(v.type)) {
      case IREE_VM_VALUE_TYPE_I8:
        record["i8"] = py::cast(v.i8);
        break;
      case IREE_VM_VALUE_TYPE_I16:
        record["i16"] = py::cast(v.i16);
        break;
      case IREE_VM_VALUE_TYPE_I32:
        record["i32"] = py::cast(v.i32);
        break;
      case IREE_VM_VALUE_TYPE_I64:
        record["i64"] = py::cast(v.i64);
        break;
      case IREE_VM_VALUE_TYPE_F32:
        record["f32"] = py::cast(v.f32);
        break;
      case IREE_VM_VALUE_TYPE_F64:
        record["f64"] = py::cast(v.f64);
        break;
      default:
        throw RaiseValueError("Unsupported VM value type conversion");
    }
    record["type"] = py::cast("value");
    return std::move(record);
  } else if (iree_vm_variant_is_ref(v)) {
    // Convert reference type.
    if (iree_vm_list_isa(v.ref)) {
      py::dict record;
      record["type"] = "vm.list";
      py::list items;
      iree_vm_list_t* sub_list = NULL;
      CheckApiStatus(iree_vm_list_check_deref(v.ref, &sub_list),
                     "Could not deref list (wrong type?)");
      iree_vm_list_retain(sub_list);
      VmVariantList sub_list_object = VmVariantList::StealFromRawPtr(sub_list);
      for (int i = 0, e = sub_list_object.size(); i < e; ++i) {
        items.append(sub_list_object.GetAsSerializedTraceValue(i));
      }
      record["items"] = std::move(items);
      return std::move(record);
    } else if (iree_hal_buffer_view_isa(v.ref)) {
      py::dict record;
      record["type"] = "hal.buffer_view";
      iree_hal_buffer_view_t* buffer_view = iree_hal_buffer_view_deref(v.ref);
      if (!buffer_view) {
        throw RaiseValueError(
            "Could not deref result buffer view (wrong type?)");
      }
      iree_hal_buffer_t* raw_buffer = iree_hal_buffer_view_buffer(buffer_view);
      if (!raw_buffer) {
        throw RaiseValueError("Could not deref result buffer (wrong type?)");
      }

      // Extract dims from the buffer view.
      iree_host_size_t rank = 0;
      std::vector<iree_hal_dim_t> dims(6);
      iree_status_t status = iree_hal_buffer_view_shape(
          buffer_view, dims.capacity(), dims.data(), &rank);
      if (iree_status_is_out_of_range(status)) {
        dims.resize(rank);
        status = iree_hal_buffer_view_shape(buffer_view, dims.capacity(),
                                            dims.data(), &rank);
      }
      CheckApiStatus(status, "Error extracting shape");
      dims.resize(rank);
      record["shape"] = py::cast(std::move(dims));

      // Element type.
      iree_hal_element_type_t element_type =
          iree_hal_buffer_view_element_type(buffer_view);
      char element_type_str[64] = {0};
      iree_host_size_t element_type_length = 0;
      CheckApiStatus(
          iree_hal_format_element_type(element_type, sizeof(element_type_str),
                                       element_type_str, &element_type_length),
          "Formatting element type");
      record["element_type"] =
          std::string(element_type_str, element_type_length);

      // Map memory.
      iree_device_size_t byte_length = iree_hal_buffer_byte_length(raw_buffer);
      iree_hal_buffer_mapping_t mapped_memory = {{0}};
      CheckApiStatus(iree_hal_buffer_map_range(
                         raw_buffer, IREE_HAL_MAPPING_MODE_SCOPED,
                         IREE_HAL_MEMORY_ACCESS_READ, 0 /* element_offset */,
                         byte_length, &mapped_memory),
                     "Could not map memory");
      record["contents"] =
          py::bytes(reinterpret_cast<const char*>(mapped_memory.contents.data),
                    mapped_memory.contents.data_length);
      iree_hal_buffer_unmap_range(&mapped_memory);

      return std::move(record);
    }
  }

  throw RaiseValueError("Unsupported VM to Python Type Conversion");
}

py::object VmVariantList::GetAsRef(int index) {
  iree_vm_variant_t v = iree_vm_variant_empty();
  CheckApiStatus(iree_vm_list_get_variant_assign(raw_ptr(), index, &v),
                 "Could not access list element");
  if (!iree_vm_variant_is_ref(v)) {
    throw std::invalid_argument("list element is not a ref");
  }
  VmRef ref;
  iree_vm_ref_retain(&v.ref, &ref.ref());
  return py::cast(ref, py::rv_policy::move);
}

py::object VmVariantList::GetAsObject(int index, py::object clazz) {
  return clazz.attr(VmRef::kCastAttr)(GetAsRef(index));
}

namespace {

static std::string ToHexString(const uint8_t* data, size_t length) {
  static constexpr char kHexChars[] = {'0', '1', '2', '3', '4', '5', '6', '7',
                                       '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
  std::string s(length * 2, ' ');
  for (size_t i = 0; i < length; ++i) {
    s[2 * i + 0] = kHexChars[(data[i] & 0xF0) >> 4];
    s[2 * i + 1] = kHexChars[(data[i] & 0x0F) >> 0];
  }
  return s;
}
static std::string ToHexString(uint32_t value) {
  return ToHexString((const uint8_t*)&value, sizeof(value));
}

void AppendListContents(std::string& out, iree_vm_list_t* list,
                        std::unordered_set<iree_vm_list_t*>& visited) {
  for (iree_host_size_t i = 0, e = iree_vm_list_size(list); i < e; ++i) {
    iree_vm_variant_t variant = iree_vm_variant_empty();
    iree_status_t status = iree_vm_list_get_variant_assign(list, i, &variant);
    if (!iree_status_is_ok(status)) {
      iree_status_ignore(status);
      out.append("Error");
      continue;
    }
    if (i > 0) out.append(", ");

    if (iree_vm_variant_is_value(variant)) {
      // Convert a value type to a string.
      switch (iree_vm_type_def_as_value(variant.type)) {
        case IREE_VM_VALUE_TYPE_I8: {
          out += std::to_string(variant.i8);
          break;
        }
        case IREE_VM_VALUE_TYPE_I16: {
          out += std::to_string(variant.i16);
          break;
        }
        case IREE_VM_VALUE_TYPE_I32: {
          out += std::to_string(variant.i32);
          break;
        }
        case IREE_VM_VALUE_TYPE_I64: {
          out += std::to_string(variant.i64);
          break;
        }
        case IREE_VM_VALUE_TYPE_F32: {
          out += std::to_string(variant.f32);
          break;
        }
        case IREE_VM_VALUE_TYPE_F64: {
          out += std::to_string(variant.f64);
          break;
        }
        default:
          throw RaiseValueError("Unsupported VM value type to string");
      }
    } else if (iree_vm_variant_is_ref(variant)) {
      // Pretty print a subset of ABI impacting known types.
      if (iree_hal_buffer_isa(variant.ref)) {
        auto* hal_buffer = iree_hal_buffer_deref(variant.ref);
        assert(hal_buffer);
        out += std::string("HalBuffer(") +
               std::to_string(iree_hal_buffer_byte_length(hal_buffer)) + ")";
      } else if (iree_hal_buffer_view_isa(variant.ref)) {
        auto hal_bv = iree_hal_buffer_view_deref(variant.ref);
        out += "HalBufferView(";
        std::vector<iree_hal_dim_t> shape(
            iree_hal_buffer_view_shape_rank(hal_bv));
        iree_hal_buffer_view_shape(hal_bv, shape.size(), shape.data(), nullptr);
        for (size_t i = 0; i < shape.size(); ++i) {
          if (i > 0) out += 'x';
          out += std::to_string(shape[i]);
        }
        out += ":0x" +
               ToHexString(static_cast<uint32_t>(
                   iree_hal_buffer_view_element_type(hal_bv))) +
               ")";
      } else if (iree_vm_list_isa(variant.ref)) {
        out.append("List[");
        iree_vm_list_t* sub_list = iree_vm_list_deref(variant.ref);
        if (visited.insert(sub_list).second) {
          AppendListContents(out, sub_list, visited);
        } else {
          out.append("...circular...");
        }
        out.append("]");
      } else if (iree_hal_fence_isa(variant.ref)) {
        out.append("fence(");
        auto* hal_fence = iree_hal_fence_deref(variant.ref);
        iree_host_size_t timepoint_count =
            iree_hal_fence_timepoint_count(hal_fence);
        out.append(std::to_string(timepoint_count) + ")");
      } else {
        out += "Unknown(" +
               std::to_string(iree_vm_type_def_as_ref(variant.type)) + ")";
      }
    } else {
      out.append("None");
    }
  }
}

}  // namespace

std::string VmVariantList::DebugString() const {
  // The variant list API requires mutability, so we const cast to it internally
  // so we can maintain a const DebugString() for callers.
  auto mutable_this = const_cast<VmVariantList*>(this);
  std::string s =
      std::string("<VmVariantList(") + std::to_string(size()) + "): [";
  iree_vm_list_t* list = mutable_this->raw_ptr();
  std::unordered_set<iree_vm_list_t*> visited;
  visited.insert(list);
  AppendListContents(s, list, visited);
  s.append("]>");
  return s;
}

void SetupVmBindings(nanobind::module_ m) {
  py::enum_<enum iree_vm_function_linkage_e>(m, "Linkage")
      .value("INTERNAL", IREE_VM_FUNCTION_LINKAGE_INTERNAL)
      .value("IMPORT", IREE_VM_FUNCTION_LINKAGE_IMPORT)
      .value("IMPORT_OPTIONAL", IREE_VM_FUNCTION_LINKAGE_IMPORT_OPTIONAL)
      .value("EXPORT", IREE_VM_FUNCTION_LINKAGE_EXPORT)
      .value("EXPORT_OPTIONAL", IREE_VM_FUNCTION_LINKAGE_EXPORT_OPTIONAL)
      .export_values();

  auto vm_buffer = py::class_<VmBuffer>(m, "VmBuffer");
  VmRef::BindRefProtocol(vm_buffer, iree_vm_buffer_type,
                         iree_vm_buffer_retain_ref, iree_vm_buffer_deref,
                         iree_vm_buffer_isa);
  BindBufferProtocol<VmBuffer>(vm_buffer);
  vm_buffer
      .def(
          "__init__",
          [](VmBuffer* self, iree_host_size_t length,
             iree_host_size_t alignment, bool is_mutable) {
            iree_vm_buffer_access_t access = 0;
            if (is_mutable) {
              access |= IREE_VM_BUFFER_ACCESS_MUTABLE;
            }
            iree_vm_buffer_t* raw_buffer;
            CheckApiStatus(
                iree_vm_buffer_create(access, length, alignment,
                                      iree_allocator_system(), &raw_buffer),
                "Error creating buffer");

            new (self) VmBuffer();
            *self = VmBuffer::StealFromRawPtr(raw_buffer);
          },
          py::arg("length"), py::arg("alignment") = 0,
          py::arg("mutable") = true)
      .def("__repr__", [](VmBuffer& self) {
        std::stringstream ss;
        ss << "<VmBuffer size " << self.raw_ptr()->data.data_length << " at 0x"
           << std::hex << reinterpret_cast<uintptr_t>(self.raw_ptr()->data.data)
           << ">";
        return ss.str();
      });

  // Mutation and inspection of the variant list is mostly opaque to python.
  auto vm_list = py::class_<VmVariantList>(m, "VmVariantList");
  VmRef::BindRefProtocol(vm_list, iree_vm_list_type, iree_vm_list_retain_ref,
                         iree_vm_list_deref, iree_vm_list_isa);
  vm_list
      // User Methods.
      .def(
          "__init__",
          [](VmVariantList* self, iree_host_size_t capacity) {
            new (self) VmVariantList();
            *self = VmVariantList::Create(capacity);
          },
          py::arg("capacity"))
      .def_prop_ro("size", &VmVariantList::size)
      .def("__len__", &VmVariantList::size)
      .def("get_as_ref", &VmVariantList::GetAsRef)
      .def("get_as_object", &VmVariantList::GetAsObject)
      .def("get_as_list", &VmVariantList::GetAsList)
      .def("get_variant", &VmVariantList::GetVariant)
      .def("get_serialized_trace_value",
           &VmVariantList::GetAsSerializedTraceValue)
      .def("push_float", &VmVariantList::PushFloat)
      .def("push_int", &VmVariantList::PushInt)
      .def("push_list", &VmVariantList::PushList)
      .def("push_ref", &VmVariantList::PushRef)
      .def("__repr__", &VmVariantList::DebugString);

  py::class_<iree_vm_function_t>(m, "VmFunction")
      .def_ro("linkage", &iree_vm_function_t::linkage)
      .def_ro("ordinal", &iree_vm_function_t::ordinal)
      .def_prop_ro("name",
                   [](iree_vm_function_t& self) {
                     iree_string_view_t name = iree_vm_function_name(&self);
                     return py::str(name.data, name.size);
                   })
      .def_prop_ro("module_name",
                   [](iree_vm_function_t& self) {
                     iree_string_view_t name = iree_vm_module_name(self.module);
                     return py::str(name.data, name.size);
                   })
      .def_prop_ro("reflection",
                   [](iree_vm_function_t& self) {
                     return GetFunctionReflectionDict(self);
                   })
      .def("__repr__", [](iree_vm_function_t& self) {
        iree_string_view_t name = iree_vm_function_name(&self);
        std::string repr("<VmFunction ");
        repr.append(name.data, name.size);

        iree_vm_function_signature_t sig = iree_vm_function_signature(&self);
        repr.append("(");
        repr.append(sig.calling_convention.data, sig.calling_convention.size);
        repr.append("), reflection = ");
        py::dict reflection = GetFunctionReflectionDict(self);
        repr.append(py::cast<std::string>(py::repr(reflection)));
        repr.append(">");
        return repr;
      });

  py::class_<VmInstance>(m, "VmInstance").def("__init__", [](VmInstance* self) {
    new (self) VmInstance();
    *self = VmInstance::Create();
  });
  py::class_<VmContext>(m, "VmContext")
      .def(
          "__init__",
          [](VmContext* self, VmInstance* instance,
             std::optional<std::vector<VmModule*>> modules) {
            new (self) VmContext();
            *self = VmContext::Create(instance, modules);
          },
          py::arg("instance"),
          py::arg("modules") = std::optional<std::vector<VmModule*>>())
      .def("register_modules", &VmContext::RegisterModules)
      .def_prop_ro("context_id", &VmContext::context_id)
      .def("invoke", &VmContext::Invoke);

  py::class_<VmModule>(m, "VmModule")
      .def_static("resolve_module_dependency",
                  &VmModule::ResolveModuleDependency)
      .def_static("from_flatbuffer", &VmModule::FromBuffer, py::arg("instance"),
                  py::arg("buffer"), py::arg("warn_if_copy") = true,
                  kFromBufferDocstring)
      .def_static("from_buffer", &VmModule::FromBuffer, py::arg("instance"),
                  py::arg("buffer"), py::arg("warn_if_copy") = true,
                  kFromBufferDocstring)
      .def_static("copy_buffer", &VmModule::CopyBuffer, py::arg("instance"),
                  py::arg("buffer"), kCopyBufferDocstring)
      .def_static("wrap_buffer", &VmModule::WrapBuffer, py::arg("instance"),
                  py::arg("buffer"), py::arg("destroy_callback") = py::none(),
                  py::arg("close_buffer") = false, kWrapBufferDocstring)
      .def_static("mmap", &VmModule::MMap, py::arg("instance"),
                  py::arg("filepath"), py::arg("destroy_callback") = py::none(),
                  kMMapDocstring)
      .def_prop_ro("name", &VmModule::name)
      .def_prop_ro("version",
                   [](VmModule& self) {
                     iree_vm_module_signature_t sig =
                         iree_vm_module_signature(self.raw_ptr());
                     return sig.version;
                   })
      .def("lookup_function", &VmModule::LookupFunction, py::arg("name"),
           py::arg("linkage") = IREE_VM_FUNCTION_LINKAGE_EXPORT)
      .def_prop_ro(
          "stashed_flatbuffer_blob",
          [](VmModule& self) { return self.get_stashed_flatbuffer_blob(); })
      .def_prop_ro("function_names",
                   [](VmModule& self) {
                     py::list names;
                     iree_vm_module_signature_t sig =
                         iree_vm_module_signature(self.raw_ptr());
                     for (size_t ordinal = 0;
                          ordinal < sig.export_function_count; ++ordinal) {
                       iree_vm_function_t f;
                       auto status = iree_vm_module_lookup_function_by_ordinal(
                           self.raw_ptr(), IREE_VM_FUNCTION_LINKAGE_EXPORT,
                           ordinal, &f);
                       if (iree_status_is_not_found(status)) {
                         iree_status_ignore(status);
                         break;
                       }
                       CheckApiStatus(status, "Error enumerating module");
                       iree_string_view_t fname = iree_vm_function_name(&f);
                       py::str name(fname.data, fname.size);
                       names.append(name);
                     }
                     return names;
                   })
      .def("__repr__", [](VmModule& self) {
        std::string repr("<VmModule ");
        iree_string_view_t name = iree_vm_module_name(self.raw_ptr());
        repr.append(name.data, name.size);

        iree_vm_module_signature_t sig =
            iree_vm_module_signature(self.raw_ptr());
        repr.append(" : [");
        for (size_t ordinal = 0; ordinal < sig.export_function_count;
             ++ordinal) {
          iree_vm_function_t f;
          auto status = iree_vm_module_lookup_function_by_ordinal(
              self.raw_ptr(), IREE_VM_FUNCTION_LINKAGE_EXPORT, ordinal, &f);
          if (iree_status_is_not_found(status)) {
            iree_status_ignore(status);
            break;
          }
          CheckApiStatus(status, "Error enumerating module");
          iree_string_view_t fname = iree_vm_function_name(&f);
          if (ordinal > 0) {
            repr.append(", ");
          }
          repr.append(fname.data, fname.size);
        }
        repr.append("]");
        repr.append(">");
        return repr;
      });

  py::class_<VmRef>(m, "VmRef")
      .def("isinstance", &VmRef::IsInstance)
      .def("deref", &VmRef::Deref, py::arg("value"),
           py::arg("optional") = false)
      .def("__repr__", &VmRef::ToString)
      .def_prop_ro(VmRef::kRefAttr, [](py::object self) { return self; })
      .def("__eq__",
           [](VmRef& self, VmRef& other) {
             return self.ref().ptr == other.ref().ptr;
           })
      .def("__eq__", [](VmRef& self, py::object& other) { return false; });
}

}  // namespace python
}  // namespace iree
