// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/utils.h"

#include "platform/allocation.h"
#include "platform/globals.h"

#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS) ||              \
    defined(DART_HOST_OS_ANDROID)
#include <dlfcn.h>
#include <libgen.h>
#elif defined(DART_HOST_OS_FUCHSIA)
#include <dlfcn.h>
#include <fuchsia/io/cpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/io.h>
#include <zircon/dlfcn.h>
#include <zircon/status.h>
#endif

namespace dart {

uint64_t Utils::ReverseBits64(uint64_t x) {
  x = ((x >> 32) & 0x00000000ffffffff) | (x << 32);
  x = ((x >> 16) & 0x0000ffff0000ffff) | ((x & 0x0000ffff0000ffff) << 16);
  x = ((x >> 8) & 0x00ff00ff00ff00ff) | ((x & 0x00ff00ff00ff00ff) << 8);
  x = ((x >> 4) & 0x0f0f0f0f0f0f0f0f) | ((x & 0x0f0f0f0f0f0f0f0f) << 4);
  x = ((x >> 2) & 0x3333333333333333) | ((x & 0x3333333333333333) << 2);
  x = ((x >> 1) & 0x5555555555555555) | ((x & 0x5555555555555555) << 1);
  return x;
}

uint32_t Utils::ReverseBits32(uint32_t x) {
  x = ((x >> 16) & 0x0000ffff) | ((x & 0x0000ffff) << 16);
  x = ((x >> 8) & 0x00ff00ff) | ((x & 0x00ff00ff) << 8);
  x = ((x >> 4) & 0x0f0f0f0f) | ((x & 0x0f0f0f0f) << 4);
  x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
  x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
  return x;
}

// Implementation according to H.S.Warren's "Hacker's Delight"
// (Addison Wesley, 2002) Chapter 10 and T.Grablund, P.L.Montgomery's
// "Division by Invariant Integers Using Multiplication" (PLDI 1994).
void Utils::CalculateMagicAndShiftForDivRem(int64_t divisor,
                                            int64_t* magic,
                                            int64_t* shift) {
  ASSERT(divisor <= -2 || divisor >= 2);
  /* The magic number M and shift S can be calculated in the following way:
   * Let nc be the most positive value of numerator(n) such that nc = kd - 1,
   * where divisor(d) >= 2.
   * Let nc be the most negative value of numerator(n) such that nc = kd + 1,
   * where divisor(d) <= -2.
   * Thus nc can be calculated like:
   * nc =  exp + exp       % d - 1, where d >= 2 and exp = 2^63.
   * nc = -exp + (exp + 1) % d,     where d >= 2 and exp = 2^63.
   *
   * So the shift p is the smallest p satisfying
   * 2^p > nc * (d - 2^p % d), where d >= 2
   * 2^p > nc * (d + 2^p % d), where d <= -2.
   *
   * The magic number M is calculated by
   * M = (2^p + d - 2^p % d) / d, where d >= 2
   * M = (2^p - d - 2^p % d) / d, where d <= -2.
   */
  int64_t p = 63;
  const uint64_t exp = 1LL << 63;

  // Initialize the computations.
  uint64_t abs_d = (divisor >= 0) ? divisor : -static_cast<uint64_t>(divisor);
  uint64_t sign_bit = static_cast<uint64_t>(divisor) >> 63;
  uint64_t tmp = exp + sign_bit;
  uint64_t abs_nc = tmp - 1 - (tmp % abs_d);
  uint64_t quotient1 = exp / abs_nc;
  uint64_t remainder1 = exp % abs_nc;
  uint64_t quotient2 = exp / abs_d;
  uint64_t remainder2 = exp % abs_d;

  // To avoid handling both positive and negative divisor,
  // "Hacker's Delight" introduces a method to handle these
  // two cases together to avoid duplication.
  uint64_t delta;
  do {
    p++;
    quotient1 = 2 * quotient1;
    remainder1 = 2 * remainder1;
    if (remainder1 >= abs_nc) {
      quotient1++;
      remainder1 = remainder1 - abs_nc;
    }
    quotient2 = 2 * quotient2;
    remainder2 = 2 * remainder2;
    if (remainder2 >= abs_d) {
      quotient2++;
      remainder2 = remainder2 - abs_d;
    }
    delta = abs_d - remainder2;
  } while (quotient1 < delta || (quotient1 == delta && remainder1 == 0));

  *magic = (divisor > 0) ? (quotient2 + 1) : (-quotient2 - 1);
  *shift = p - 64;
}

// This implementation is based on the public domain MurmurHash
// version 2.0. The constants M and R have been determined
// to work well experimentally.
static constexpr uint32_t kStringHashM = 0x5bd1e995;
static constexpr int kStringHashR = 24;

// hash and part must be lvalues.
#define MIX(hash, part)                                                        \
  {                                                                            \
    (part) *= kStringHashM;                                                    \
    (part) ^= (part) >> kStringHashR;                                          \
    (part) *= kStringHashM;                                                    \
    (hash) *= kStringHashM;                                                    \
    (hash) ^= (part);                                                          \
  }

uint32_t Utils::StringHash(const void* data, int length) {
  int size = length;
  uint32_t hash = size;

  auto cursor = reinterpret_cast<const uint8_t*>(data);

  if (size >= kInt32Size) {
    const intptr_t misalignment =
        reinterpret_cast<intptr_t>(cursor) % kInt32Size;
    if (misalignment > 0) {
      // Stores 4-byte values starting from the start of the string to mimic
      // the algorithm on aligned data.
      uint32_t data_window = 0;

      // Shift sizes for adjusting the data window when adding the next aligned
      // piece of data.
      const uint32_t sr = misalignment * kBitsPerByte;
      const uint32_t sl = kBitsPerInt32 - sr;

      const intptr_t pre_alignment_length = kInt32Size - misalignment;
      switch (pre_alignment_length) {
        case 3:
          data_window |= cursor[2] << 16;
          FALL_THROUGH;
        case 2:
          data_window |= cursor[1] << 8;
          FALL_THROUGH;
        case 1:
          data_window |= cursor[0];
      }
      cursor += pre_alignment_length;
      size -= pre_alignment_length;

      // Mix four bytes at a time now that we're at an aligned spot.
      for (; size >= kInt32Size; cursor += kInt32Size, size -= kInt32Size) {
        uint32_t aligned_part = *reinterpret_cast<const uint32_t*>(cursor);
        data_window |= (aligned_part << sl);
        MIX(hash, data_window);
        data_window = aligned_part >> sr;
      }

      if (size >= misalignment) {
        // There's one more full window in the data. We'll let the normal tail
        // code handle any partial window.
        switch (misalignment) {
          case 3:
            data_window |= cursor[2] << (16 + sl);
            FALL_THROUGH;
          case 2:
            data_window |= cursor[1] << (8 + sl);
            FALL_THROUGH;
          case 1:
            data_window |= cursor[0] << sl;
        }
        MIX(hash, data_window);
        cursor += misalignment;
        size -= misalignment;
      } else {
        // This is a partial window, so just xor and multiply by M.
        switch (size) {
          case 2:
            data_window |= cursor[1] << (8 + sl);
            FALL_THROUGH;
          case 1:
            data_window |= cursor[0] << sl;
        }
        hash ^= data_window;
        hash *= kStringHashM;
        cursor += size;
        size = 0;
      }
    } else {
      // Mix four bytes at a time into the hash.
      for (; size >= kInt32Size; size -= kInt32Size, cursor += kInt32Size) {
        uint32_t part = *reinterpret_cast<const uint32_t*>(cursor);
        MIX(hash, part);
      }
    }
  }

  // Handle the last few bytes of the string if any.
  switch (size) {
    case 3:
      hash ^= cursor[2] << 16;
      FALL_THROUGH;
    case 2:
      hash ^= cursor[1] << 8;
      FALL_THROUGH;
    case 1:
      hash ^= cursor[0];
      hash *= kStringHashM;
  }

  // Do a few final mixes of the hash to ensure the last few bytes are
  // well-incorporated.
  hash ^= hash >> 13;
  hash *= kStringHashM;
  hash ^= hash >> 15;
  return hash;
}

#undef MIX

uint32_t Utils::WordHash(intptr_t key) {
  // TODO(iposva): Need to check hash spreading.
  // This example is from http://www.concentric.net/~Ttwang/tech/inthash.htm
  // via. http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
  uword a = static_cast<uword>(key);
  a = (a + 0x7ed55d16) + (a << 12);
  a = (a ^ 0xc761c23c) ^ (a >> 19);
  a = (a + 0x165667b1) + (a << 5);
  a = (a + 0xd3a2646c) ^ (a << 9);
  a = (a + 0xfd7046c5) + (a << 3);
  a = (a ^ 0xb55a4f09) ^ (a >> 16);
  return static_cast<uint32_t>(a);
}

char* Utils::SCreate(const char* format, ...) {
  va_list args;
  va_start(args, format);
  char* buffer = VSCreate(format, args);
  va_end(args);
  return buffer;
}

char* Utils::VSCreate(const char* format, va_list args) {
  // Measure.
  va_list measure_args;
  va_copy(measure_args, args);
  intptr_t len = VSNPrint(nullptr, 0, format, measure_args);
  va_end(measure_args);

  char* buffer = reinterpret_cast<char*>(malloc(len + 1));
  ASSERT(buffer != nullptr);

  // Print.
  va_list print_args;
  va_copy(print_args, args);
  VSNPrint(buffer, len + 1, format, print_args);
  va_end(print_args);
  return buffer;
}

static void GetLastErrorAsString(char** error) {
  if (error == nullptr) return;  // Nothing to do.

#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS) ||              \
    defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA)
  const char* status = dlerror();
  *error = status != nullptr ? strdup(status) : nullptr;
#elif defined(DART_HOST_OS_WINDOWS)
  const int status = GetLastError();
  if (status != 0) {
    char* description = nullptr;
    int length = FormatMessageA(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
        nullptr, status, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
        reinterpret_cast<char*>(&description), 0, nullptr);
    if (length == 0) {
      // Seems like there is no message for this error code.
      *error = Utils::SCreate("error code %i", status);
    } else {
      *error = Utils::SCreate("%s (error code: %i)", description, status);
    }

    LocalFree(description);
  } else {
    *error = nullptr;
  }
#else
  *error = Utils::StrDup("loading dynamic libraries is not supported");
#endif
}

void* Utils::LoadDynamicLibrary(const char* library_path,
                                bool search_dll_load_dir,
                                char** error) {
  void* handle = nullptr;

#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS) ||              \
    defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA)
  handle = dlopen(library_path, RTLD_LAZY);
#if defined(DART_HOST_OS_FUCHSIA)
  if (handle == nullptr) {
    // Fuchsia's search path is different.
    // https://fuchsia.dev/fuchsia-src/concepts/process/program_loading#zircons_standard_elf_dynamic_linker
    constexpr fuchsia::io::Flags kFlags =
        fuchsia::io::PERM_READABLE | fuchsia::io::PERM_EXECUTABLE;
    int fd = -1;
    zx_status_t status = fdio_open3_fd(library_path, uint64_t{kFlags}, &fd);
    if (status != ZX_OK) {
      *error = strdup(zx_status_get_string(status));
      return nullptr;
    }
    zx_handle_t vmo = ZX_HANDLE_INVALID;
    status = fdio_get_vmo_exec(fd, &vmo);
    close(fd);
    if (status != ZX_OK) {
      *error = strdup(zx_status_get_string(status));
      return nullptr;
    }
    handle = dlopen_vmo(vmo, RTLD_LAZY);
  }
#endif  // defined(DART_HOST_OS_FUCHSIA)
#elif defined(DART_HOST_OS_WINDOWS)
  SetLastError(0);  // Clear any errors.

  if (library_path == nullptr) {
    handle = GetModuleHandle(nullptr);
  } else {
    // Convert to wchar_t string.
    const int name_len = MultiByteToWideChar(
        CP_UTF8, /*dwFlags=*/0, library_path, /*cbMultiByte=*/-1, nullptr, 0);
    if (name_len != 0) {
      std::unique_ptr<wchar_t[]> name(new wchar_t[name_len]);
      const int written_len =
          MultiByteToWideChar(CP_UTF8, /*dwFlags=*/0, library_path,
                              /*cbMultiByte=*/-1, name.get(), name_len);
      RELEASE_ASSERT(written_len == name_len);
      if (search_dll_load_dir) {
        handle =
            LoadLibraryExW(name.get(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
      } else {
        handle = LoadLibraryW(name.get());
      }
    }
  }
#endif

  if (handle == nullptr) {
    GetLastErrorAsString(error);
  }

  return handle;
}

void* Utils::ResolveSymbolInDynamicLibrary(void* library_handle,
                                           const char* symbol,
                                           char** error) {
#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS) ||              \
    defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA)
  dlerror();  // Clear any errors.
  void* result = dlsym(library_handle, symbol);
  // Note: nullptr might be a valid return from dlsym. Must call dlerror
  // to differentiate.
  GetLastErrorAsString(error);
  return result;
#elif defined(DART_HOST_OS_WINDOWS)
  SetLastError(0);
  void* result = reinterpret_cast<void*>(
      GetProcAddress(reinterpret_cast<HMODULE>(library_handle), symbol));
  if (result == nullptr) {
    GetLastErrorAsString(error);
  }
  return result;
#endif
}

void Utils::UnloadDynamicLibrary(void* library_handle, char** error) {
  bool ok = false;

#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS) ||              \
    defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA)
  ok = dlclose(library_handle) == 0;
#elif defined(DART_HOST_OS_WINDOWS)
  SetLastError(0);  // Clear any errors.

  ok = FreeLibrary(reinterpret_cast<HMODULE>(library_handle));
#endif

  if (!ok) {
    GetLastErrorAsString(error);
  }
}

char* Utils::Basename(const char* path) {
#if defined(DART_HOST_OS_FUCHSIA) || defined(DART_HOST_OS_WINDOWS)
  // Not handled for these operating systems.
  return nullptr;
#else
  if (path == nullptr) return nullptr;
  char* const path_copy = Utils::StrDup(path);
  char* result = basename(path_copy);
  // The result may be in statically allocated memory, so copy.
  result = Utils::StrDup(result);
  // The result may point to a portion of the passed in string, so
  // only free the copy after duplicating the result.
  free(path_copy);
  return result;
#endif
}

}  // namespace dart
