// Copyright 2020 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 "iree/vm/native_module.h"

#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

#include "iree/vm/stack.h"

// Native module implementation allocated for all modules.
typedef struct iree_vm_native_module_t {
  // Interface containing default function pointers.
  // base_interface.self will be the self pointer to iree_vm_native_module_t.
  //
  // Must be first in the struct as we dereference the interface to find our
  // members below.
  iree_vm_module_t base_interface;

  // Interface with optional user-provided function pointers.
  iree_vm_module_t user_interface;

  // The self passed to user_interface functions. Will either be the value of
  // user_interface.self when initialized and the base pointer of the base
  // native module otherwise.
  void* self;

  // Allocator this module was allocated with and must be freed with.
  iree_allocator_t allocator;

  // Module descriptor used for reflection.
  const iree_vm_native_module_descriptor_t* descriptor;
} iree_vm_native_module_t;

IREE_API_EXPORT iree_host_size_t iree_vm_native_module_size(void) {
  return sizeof(iree_vm_native_module_t);
}

#if defined(NDEBUG)
static iree_status_t iree_vm_native_module_verify_descriptor(
    const iree_vm_native_module_descriptor_t* module_descriptor) {
  return iree_ok_status();
}
#else
static iree_status_t iree_vm_native_module_verify_descriptor(
    const iree_vm_native_module_descriptor_t* module_descriptor) {
  // Verify the export table is sorted by name. This will help catch issues with
  // people appending to tables instead of inserting in the proper order.
  for (iree_host_size_t i = 1; i < module_descriptor->export_count; ++i) {
    iree_string_view_t prev_export_name =
        module_descriptor->exports[i - 1].local_name;
    iree_string_view_t export_name = module_descriptor->exports[i].local_name;
    int cmp = iree_string_view_compare(prev_export_name, export_name);
    if (IREE_UNLIKELY(cmp >= 0)) {
      return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                              "module export table is not sorted by name "
                              "(export %zu ('%.*s') >= %zu ('%.*s'))",
                              i - 1, (int)prev_export_name.size,
                              prev_export_name.data, i, (int)export_name.size,
                              export_name.data);
    }
  }
  return iree_ok_status();
}
#endif  // NDEBUG

static void IREE_API_PTR iree_vm_native_module_destroy(void* self) {
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)self;
  iree_allocator_t allocator = module->allocator;

  // Destroy the optional user-provided self.
  if (module->user_interface.destroy) {
    module->user_interface.destroy(module->self);
  }

  iree_allocator_free(allocator, module);
}

static iree_string_view_t IREE_API_PTR iree_vm_native_module_name(void* self) {
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)self;
  if (module->user_interface.name) {
    return module->user_interface.name(module->self);
  }
  return module->descriptor->module_name;
}

static iree_vm_module_signature_t IREE_API_PTR
iree_vm_native_module_signature(void* self) {
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)self;
  if (module->user_interface.signature) {
    return module->user_interface.signature(module->self);
  }
  iree_vm_module_signature_t signature;
  memset(&signature, 0, sizeof(signature));
  signature.import_function_count = module->descriptor->import_count;
  signature.export_function_count = module->descriptor->export_count;
  signature.internal_function_count = 0;  // unused
  return signature;
}

static iree_status_t IREE_API_PTR iree_vm_native_module_get_import_function(
    iree_vm_native_module_t* module, iree_host_size_t ordinal,
    iree_vm_function_t* out_function, iree_string_view_t* out_name,
    iree_vm_function_signature_t* out_signature) {
  if (IREE_UNLIKELY(ordinal >= module->descriptor->import_count)) {
    return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                            "import ordinal out of range (0 < %zu < %zu)",
                            ordinal, module->descriptor->import_count);
  }
  const iree_vm_native_import_descriptor_t* import_descriptor =
      &module->descriptor->imports[ordinal];
  if (out_function) {
    out_function->module = &module->base_interface;
    out_function->linkage = IREE_VM_FUNCTION_LINKAGE_IMPORT;
    out_function->ordinal = (uint16_t)ordinal;
  }
  if (out_name) {
    *out_name = import_descriptor->full_name;
  }
  // TODO(#1979): signature queries when info is useful.
  return iree_ok_status();
}

static iree_status_t IREE_API_PTR iree_vm_native_module_get_export_function(
    iree_vm_native_module_t* module, iree_host_size_t ordinal,
    iree_vm_function_t* out_function, iree_string_view_t* out_name,
    iree_vm_function_signature_t* out_signature) {
  if (IREE_UNLIKELY(ordinal >= module->descriptor->export_count)) {
    return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                            "export ordinal out of range (0 < %zu < %zu)",
                            ordinal, module->descriptor->export_count);
  }
  if (out_function) {
    out_function->module = &module->base_interface;
    out_function->linkage = IREE_VM_FUNCTION_LINKAGE_EXPORT;
    out_function->ordinal = (uint16_t)ordinal;
  }
  const iree_vm_native_export_descriptor_t* export_descriptor =
      &module->descriptor->exports[ordinal];
  if (out_name) {
    *out_name = export_descriptor->local_name;
  }
  if (out_signature) {
    out_signature->calling_convention = export_descriptor->calling_convention;
  }
  return iree_ok_status();
}

static iree_status_t IREE_API_PTR iree_vm_native_module_get_function(
    void* self, iree_vm_function_linkage_t linkage, iree_host_size_t ordinal,
    iree_vm_function_t* out_function, iree_string_view_t* out_name,
    iree_vm_function_signature_t* out_signature) {
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)self;
  if (out_function) memset(out_function, 0, sizeof(*out_function));
  if (out_name) memset(out_name, 0, sizeof(*out_name));
  if (out_signature) memset(out_signature, 0, sizeof(*out_signature));
  if (module->user_interface.get_function) {
    return module->user_interface.get_function(
        module->self, linkage, ordinal, out_function, out_name, out_signature);
  }
  switch (linkage) {
    case IREE_VM_FUNCTION_LINKAGE_IMPORT:
      return iree_vm_native_module_get_import_function(
          module, ordinal, out_function, out_name, out_signature);
    case IREE_VM_FUNCTION_LINKAGE_EXPORT:
      return iree_vm_native_module_get_export_function(
          module, ordinal, out_function, out_name, out_signature);
    default:
      return iree_make_status(
          IREE_STATUS_UNIMPLEMENTED,
          "native modules do not support internal function queries");
  }
}

static iree_status_t IREE_API_PTR
iree_vm_native_module_get_function_reflection_attr(
    void* self, iree_vm_function_linkage_t linkage, iree_host_size_t ordinal,
    iree_host_size_t index, iree_string_view_t* key,
    iree_string_view_t* value) {
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)self;
  if (module->user_interface.get_function_reflection_attr) {
    return module->user_interface.get_function_reflection_attr(
        module->self, linkage, ordinal, index, key, value);
  }
  // TODO(benvanik): implement native module reflection.
  return iree_make_status(IREE_STATUS_UNIMPLEMENTED,
                          "reflection not yet implemented");
}

static iree_status_t IREE_API_PTR iree_vm_native_module_lookup_function(
    void* self, iree_vm_function_linkage_t linkage, iree_string_view_t name,
    iree_vm_function_t* out_function) {
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)self;
  memset(out_function, 0, sizeof(*out_function));
  if (module->user_interface.lookup_function) {
    return module->user_interface.lookup_function(module->self, linkage, name,
                                                  out_function);
  }

  if (IREE_UNLIKELY(linkage != IREE_VM_FUNCTION_LINKAGE_EXPORT)) {
    // NOTE: we could support imports if required.
    return iree_make_status(
        IREE_STATUS_UNIMPLEMENTED,
        "native modules do not support import/internal function queries");
  }

  // Binary search through the export descriptors.
  ptrdiff_t min_ordinal = 0;
  ptrdiff_t max_ordinal = module->descriptor->export_count - 1;
  const iree_vm_native_export_descriptor_t* exports =
      module->descriptor->exports;
  while (min_ordinal <= max_ordinal) {
    ptrdiff_t ordinal = (min_ordinal + max_ordinal) / 2;
    int cmp = iree_string_view_compare(exports[ordinal].local_name, name);
    if (cmp == 0) {
      return iree_vm_native_module_get_function(self, linkage, ordinal,
                                                out_function, NULL, NULL);
    } else if (cmp < 0) {
      min_ordinal = ordinal + 1;
    } else {
      max_ordinal = ordinal - 1;
    }
  }
  return iree_make_status(
      IREE_STATUS_NOT_FOUND, "no function %.*s.%.*s exported by module",
      (int)module->descriptor->module_name.size,
      module->descriptor->module_name.data, (int)name.size, name.data);
}

static iree_status_t IREE_API_PTR
iree_vm_native_module_alloc_state(void* self, iree_allocator_t allocator,
                                  iree_vm_module_state_t** out_module_state) {
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)self;
  *out_module_state = NULL;
  if (module->user_interface.alloc_state) {
    return module->user_interface.alloc_state(module->self, allocator,
                                              out_module_state);
  }
  // Default to no state.
  return iree_ok_status();
}

static void IREE_API_PTR iree_vm_native_module_free_state(
    void* self, iree_vm_module_state_t* module_state) {
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)self;
  if (module->user_interface.free_state) {
    module->user_interface.free_state(module->self, module_state);
    return;
  }
  // No-op in the default implementation.
  // TODO(#2843): IREE_DCHECK_EQ(NULL, module_state);
  assert(!module_state);
}

static iree_status_t IREE_API_PTR iree_vm_native_module_resolve_import(
    void* self, iree_vm_module_state_t* module_state, iree_host_size_t ordinal,
    const iree_vm_function_t* function,
    const iree_vm_function_signature_t* signature) {
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)self;
  if (module->user_interface.resolve_import) {
    return module->user_interface.resolve_import(module->self, module_state,
                                                 ordinal, function, signature);
  }
  return iree_make_status(IREE_STATUS_UNIMPLEMENTED,
                          "native module does not support imports");
}

static iree_status_t IREE_API_PTR iree_vm_native_module_notify(
    void* self, iree_vm_module_state_t* module_state, iree_vm_signal_t signal) {
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)self;
  if (module->user_interface.notify) {
    return module->user_interface.notify(module->self, module_state, signal);
  }
  return iree_ok_status();
}

static iree_status_t IREE_API_PTR iree_vm_native_module_begin_call(
    void* self, iree_vm_stack_t* stack, const iree_vm_function_call_t* call,
    iree_vm_execution_result_t* out_result) {
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)self;
  if (IREE_UNLIKELY(call->function.linkage !=
                    IREE_VM_FUNCTION_LINKAGE_EXPORT) ||
      IREE_UNLIKELY(call->function.ordinal >=
                    module->descriptor->export_count)) {
    return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                            "function ordinal out of bounds: 0 < %u < %zu",
                            call->function.ordinal,
                            module->descriptor->export_count);
  }
  if (module->user_interface.begin_call) {
    return module->user_interface.begin_call(module->self, stack, call,
                                             out_result);
  }

  // NOTE: VM stack is currently unused. We could stash things here for the
  // debugger or use it for coroutine state.
  iree_host_size_t frame_size = 0;

  iree_vm_stack_frame_t* callee_frame = NULL;
  IREE_RETURN_IF_ERROR(iree_vm_stack_function_enter(
      stack, &call->function, IREE_VM_STACK_FRAME_NATIVE, frame_size,
      /*frame_cleanup_fn=*/NULL, &callee_frame));

  // Call the target function using the shim.
  const iree_vm_native_function_ptr_t* function_ptr =
      &module->descriptor->functions[call->function.ordinal];
  iree_vm_module_state_t* module_state = callee_frame->module_state;
  iree_status_t status = function_ptr->shim(stack, call, function_ptr->target,
                                            module, module_state, out_result);
  if (IREE_UNLIKELY(!iree_status_is_ok(status))) {
#if IREE_STATUS_FEATURES & IREE_STATUS_FEATURE_ANNOTATIONS
    iree_string_view_t module_name IREE_ATTRIBUTE_UNUSED =
        iree_vm_native_module_name(module);
    iree_string_view_t function_name IREE_ATTRIBUTE_UNUSED =
        iree_string_view_empty();
    iree_status_ignore(iree_vm_native_module_get_export_function(
        module, call->function.ordinal, NULL, &function_name, NULL));
    return iree_status_annotate_f(status,
                                  "while invoking native function %.*s.%.*s",
                                  (int)module_name.size, module_name.data,
                                  (int)function_name.size, function_name.data);
#else
    return status;
#endif  // IREE_STATUS_FEATURES & IREE_STATUS_FEATURE_ANNOTATIONS
  }

  return iree_vm_stack_function_leave(stack);
}

static iree_status_t IREE_API_PTR
iree_vm_native_module_resume_call(void* self, iree_vm_stack_t* stack,
                                  iree_vm_execution_result_t* out_result) {
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)self;
  if (module->user_interface.resume_call) {
    return module->user_interface.resume_call(module->self, stack, out_result);
  }
  return iree_make_status(IREE_STATUS_UNIMPLEMENTED,
                          "native module does not support resume");
}

IREE_API_EXPORT iree_status_t iree_vm_native_module_create(
    const iree_vm_module_t* interface,
    const iree_vm_native_module_descriptor_t* module_descriptor,
    iree_allocator_t allocator, iree_vm_module_t** out_module) {
  IREE_ASSERT_ARGUMENT(out_module);
  *out_module = NULL;

  if (IREE_UNLIKELY(!interface->begin_call) &&
      IREE_UNLIKELY(!module_descriptor->functions)) {
    return iree_make_status(
        IREE_STATUS_INVALID_ARGUMENT,
        "native modules must provide call support or function pointers");
  } else if (IREE_UNLIKELY(!interface->begin_call) &&
             IREE_UNLIKELY(module_descriptor->export_count !=
                           module_descriptor->function_count)) {
    return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                            "native modules using the default call support "
                            "must have 1:1 exports:function pointers");
  }

  // Perform some optional debug-only verification of the descriptor.
  // Since native modules are designed to be compiled in we don't need to do
  // this in release builds.
  IREE_RETURN_IF_ERROR(
      iree_vm_native_module_verify_descriptor(module_descriptor));

  // TODO(benvanik): invert allocation such that caller allocates and we init.
  // This would avoid the need for any dynamic memory allocation in the common
  // case as the outer user module interface could nest us. Note that we'd need
  // to expose this via a query_size function so that we could adjust the size
  // of our storage independent of the definition of the user module.
  iree_vm_native_module_t* module = NULL;
  IREE_RETURN_IF_ERROR(
      iree_allocator_malloc(allocator, sizeof(*module), (void**)&module));

  iree_status_t status = iree_vm_native_module_initialize(
      interface, module_descriptor, allocator, (iree_vm_module_t*)module);
  if (!iree_status_is_ok(status)) {
    iree_allocator_free(allocator, module);
    return status;
  }

  *out_module = &module->base_interface;
  return iree_ok_status();
}

IREE_API_EXPORT iree_status_t iree_vm_native_module_initialize(
    const iree_vm_module_t* interface,
    const iree_vm_native_module_descriptor_t* module_descriptor,
    iree_allocator_t allocator, iree_vm_module_t* base_module) {
  IREE_ASSERT_ARGUMENT(interface);
  IREE_ASSERT_ARGUMENT(module_descriptor);
  IREE_ASSERT_ARGUMENT(base_module);
  iree_vm_native_module_t* module = (iree_vm_native_module_t*)base_module;

  if (IREE_UNLIKELY(!interface->begin_call) &&
      IREE_UNLIKELY(!module_descriptor->functions)) {
    return iree_make_status(
        IREE_STATUS_INVALID_ARGUMENT,
        "native modules must provide call support or function pointers");
  } else if (IREE_UNLIKELY(!interface->begin_call) &&
             IREE_UNLIKELY(module_descriptor->export_count !=
                           module_descriptor->function_count)) {
    return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                            "native modules using the default call support "
                            "must have 1:1 exports:function pointers");
  }

  // Perform some optional debug-only verification of the descriptor.
  // Since native modules are designed to be compiled in we don't need to do
  // this in release builds.
  IREE_RETURN_IF_ERROR(
      iree_vm_native_module_verify_descriptor(module_descriptor));
  module->allocator = allocator;
  module->descriptor = module_descriptor;

  // TODO(benvanik): version interface and copy only valid bytes.
  memcpy(&module->user_interface, interface, sizeof(*interface));
  module->self =
      module->user_interface.self ? module->user_interface.self : module;

  // Base interface that routes through our thunks.
  iree_vm_module_initialize(&module->base_interface, module);
  module->base_interface.destroy = iree_vm_native_module_destroy;
  module->base_interface.name = iree_vm_native_module_name;
  module->base_interface.signature = iree_vm_native_module_signature;
  module->base_interface.get_function = iree_vm_native_module_get_function;
  module->base_interface.get_function_reflection_attr =
      iree_vm_native_module_get_function_reflection_attr;
  module->base_interface.lookup_function =
      iree_vm_native_module_lookup_function;
  module->base_interface.alloc_state = iree_vm_native_module_alloc_state;
  module->base_interface.free_state = iree_vm_native_module_free_state;
  module->base_interface.resolve_import = iree_vm_native_module_resolve_import;
  module->base_interface.notify = iree_vm_native_module_notify;
  module->base_interface.begin_call = iree_vm_native_module_begin_call;
  module->base_interface.resume_call = iree_vm_native_module_resume_call;

  return iree_ok_status();
}
