//===-- runtime/temporary-stack.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
//
//===----------------------------------------------------------------------===//

// Implements std::vector like storage for a dynamically resizable number of
// temporaries. For use in HLFIR lowering.

#include "flang/Runtime/temporary-stack.h"
#include "terminator.h"
#include "flang/ISO_Fortran_binding_wrapper.h"
#include "flang/Runtime/assign.h"
#include "flang/Runtime/descriptor.h"
#include "flang/Runtime/memory.h"

namespace {

using namespace Fortran::runtime;

// the number of elements to allocate when first creating the vector
constexpr size_t INITIAL_ALLOC = 8;

/// To store C style data. Does not run constructors/destructors.
/// Not using std::vector to avoid linking the runtime library to stdc++
template <bool COPY_VALUES> class DescriptorStorage final {
  using size_type = uint64_t; // see checkedMultiply()

  size_type capacity_{0};
  size_type size_{0};
  Descriptor **data_{nullptr};
  Terminator terminator_;

  // return true on overflow
  static bool checkedMultiply(size_type x, size_type y, size_type &res);

  void resize(size_type newCapacity);

  Descriptor *cloneDescriptor(const Descriptor &source);

public:
  DescriptorStorage(const char *sourceFile, int line);
  ~DescriptorStorage();

  // `new` but using the runtime allocation API
  static inline DescriptorStorage *allocate(const char *sourceFile, int line) {
    Terminator term{sourceFile, line};
    void *ptr = AllocateMemoryOrCrash(term, sizeof(DescriptorStorage));
    return new (ptr) DescriptorStorage{sourceFile, line};
  }

  // `delete` but using the runtime allocation API
  static inline void destroy(DescriptorStorage *instance) {
    instance->~DescriptorStorage();
    FreeMemory(instance);
  }

  // clones a descriptor into this storage
  void push(const Descriptor &source);

  // out must be big enough to hold a descriptor of the right rank and addendum
  void pop(Descriptor &out);

  // out must be big enough to hold a descriptor of the right rank and addendum
  void at(size_type i, Descriptor &out);
};

using ValueStack = DescriptorStorage</*COPY_VALUES=*/true>;
using DescriptorStack = DescriptorStorage</*COPY_VALUES=*/false>;
} // namespace

template <bool COPY_VALUES>
bool DescriptorStorage<COPY_VALUES>::checkedMultiply(
    size_type x, size_type y, size_type &res) {
  // TODO: c++20 [[unlikely]]
  if (x > UINT64_MAX / y) {
    return true;
  }
  res = x * y;
  return false;
}

template <bool COPY_VALUES>
void DescriptorStorage<COPY_VALUES>::resize(size_type newCapacity) {
  if (newCapacity <= capacity_) {
    return;
  }
  size_type bytes;
  if (checkedMultiply(newCapacity, sizeof(Descriptor *), bytes)) {
    terminator_.Crash("temporary-stack: out of memory");
  }
  Descriptor **newData =
      static_cast<Descriptor **>(AllocateMemoryOrCrash(terminator_, bytes));
  // "memcpy" in glibc has a "nonnull" attribute on the source pointer.
  // Avoid passing a null pointer, since it would result in an undefined
  // behavior.
  if (data_ != nullptr) {
    memcpy(newData, data_, capacity_ * sizeof(Descriptor *));
    FreeMemory(data_);
  }
  data_ = newData;
  capacity_ = newCapacity;
}

template <bool COPY_VALUES>
Descriptor *DescriptorStorage<COPY_VALUES>::cloneDescriptor(
    const Descriptor &source) {
  const std::size_t bytes = source.SizeInBytes();
  void *memory = AllocateMemoryOrCrash(terminator_, bytes);
  Descriptor *desc = new (memory) Descriptor{source};
  return desc;
}

template <bool COPY_VALUES>
DescriptorStorage<COPY_VALUES>::DescriptorStorage(
    const char *sourceFile, int line)
    : terminator_{sourceFile, line} {
  resize(INITIAL_ALLOC);
}

template <bool COPY_VALUES>
DescriptorStorage<COPY_VALUES>::~DescriptorStorage() {
  for (size_type i = 0; i < size_; ++i) {
    Descriptor *element = data_[i];
    if constexpr (COPY_VALUES) {
      element->Destroy(false, true);
    }
    FreeMemory(element);
  }
  FreeMemory(data_);
}

template <bool COPY_VALUES>
void DescriptorStorage<COPY_VALUES>::push(const Descriptor &source) {
  if (size_ == capacity_) {
    size_type newSize;
    if (checkedMultiply(capacity_, 2, newSize)) {
      terminator_.Crash("temporary-stack: out of address space");
    }
    resize(newSize);
  }
  data_[size_] = cloneDescriptor(source);
  Descriptor &box = *data_[size_];
  size_ += 1;

  if constexpr (COPY_VALUES) {
    // copy the data pointed to by the box
    box.set_base_addr(nullptr);
    box.Allocate();
    RTNAME(AssignTemporary)
    (box, source, terminator_.sourceFileName(), terminator_.sourceLine());
  }
}

template <bool COPY_VALUES>
void DescriptorStorage<COPY_VALUES>::pop(Descriptor &out) {
  if (size_ == 0) {
    terminator_.Crash("temporary-stack: pop empty storage");
  }
  size_ -= 1;
  Descriptor *ptr = data_[size_];
  out = *ptr; // Descriptor::operator= handles the different sizes
  FreeMemory(ptr);
}

template <bool COPY_VALUES>
void DescriptorStorage<COPY_VALUES>::at(size_type i, Descriptor &out) {
  if (i >= size_) {
    terminator_.Crash("temporary-stack: out of bounds access");
  }
  Descriptor *ptr = data_[i];
  out = *ptr; // Descriptor::operator= handles the different sizes
}

inline static ValueStack *getValueStorage(void *opaquePtr) {
  return static_cast<ValueStack *>(opaquePtr);
}
inline static DescriptorStack *getDescriptorStorage(void *opaquePtr) {
  return static_cast<DescriptorStack *>(opaquePtr);
}

namespace Fortran::runtime {
extern "C" {
void *RTNAME(CreateValueStack)(const char *sourceFile, int line) {
  return ValueStack::allocate(sourceFile, line);
}

void RTNAME(PushValue)(void *opaquePtr, const Descriptor &value) {
  getValueStorage(opaquePtr)->push(value);
}

void RTNAME(PopValue)(void *opaquePtr, Descriptor &value) {
  getValueStorage(opaquePtr)->pop(value);
}

void RTNAME(ValueAt)(void *opaquePtr, uint64_t i, Descriptor &value) {
  getValueStorage(opaquePtr)->at(i, value);
}

void RTNAME(DestroyValueStack)(void *opaquePtr) {
  ValueStack::destroy(getValueStorage(opaquePtr));
}

void *RTNAME(CreateDescriptorStack)(const char *sourceFile, int line) {
  return DescriptorStack::allocate(sourceFile, line);
}

void RTNAME(PushDescriptor)(void *opaquePtr, const Descriptor &value) {
  getDescriptorStorage(opaquePtr)->push(value);
}

void RTNAME(PopDescriptor)(void *opaquePtr, Descriptor &value) {
  getDescriptorStorage(opaquePtr)->pop(value);
}

void RTNAME(DescriptorAt)(void *opaquePtr, uint64_t i, Descriptor &value) {
  getValueStorage(opaquePtr)->at(i, value);
}

void RTNAME(DestroyDescriptorStack)(void *opaquePtr) {
  DescriptorStack::destroy(getDescriptorStorage(opaquePtr));
}

} // extern "C"
} // namespace Fortran::runtime
