// Copyright (c) 2019, 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 "vm/compiler/ffi.h"

#include <algorithm>

#include "platform/globals.h"
#include "vm/compiler/backend/locations.h"
#include "vm/compiler/runtime_api.h"
#include "vm/growable_array.h"
#include "vm/stack_frame.h"

namespace dart {

namespace compiler {

namespace ffi {

static const size_t kSizeUnknown = 0;

static const intptr_t kNumElementSizes = kFfiVoidCid - kFfiPointerCid + 1;

static const size_t element_size_table[kNumElementSizes] = {
    target::kWordSize,  // kFfiPointerCid
    kSizeUnknown,       // kFfiNativeFunctionCid
    1,                  // kFfiInt8Cid
    2,                  // kFfiInt16Cid
    4,                  // kFfiInt32Cid
    8,                  // kFfiInt64Cid
    1,                  // kFfiUint8Cid
    2,                  // kFfiUint16Cid
    4,                  // kFfiUint32Cid
    8,                  // kFfiUint64Cid
    target::kWordSize,  // kFfiIntPtrCid
    4,                  // kFfiFloatCid
    8,                  // kFfiDoubleCid
    kSizeUnknown,       // kFfiVoidCid
};

size_t ElementSizeInBytes(intptr_t class_id) {
  ASSERT(class_id != kFfiNativeFunctionCid);
  ASSERT(class_id != kFfiVoidCid);
  if (!RawObject::IsFfiTypeClassId(class_id)) {
    // subtype of Pointer
    class_id = kFfiPointerCid;
  }
  intptr_t index = class_id - kFfiPointerCid;
  return element_size_table[index];
}

#if !defined(DART_PRECOMPILED_RUNTIME)

Representation TypeRepresentation(const AbstractType& result_type) {
  switch (result_type.type_class_id()) {
    case kFfiFloatCid:
      return kUnboxedFloat;
    case kFfiDoubleCid:
      return kUnboxedDouble;
    case kFfiInt8Cid:
    case kFfiInt16Cid:
    case kFfiInt32Cid:
      return kUnboxedInt32;
    case kFfiUint8Cid:
    case kFfiUint16Cid:
    case kFfiUint32Cid:
      return kUnboxedUint32;
    case kFfiInt64Cid:
    case kFfiUint64Cid:
      return kUnboxedInt64;
    case kFfiIntPtrCid:
    case kFfiPointerCid:
    default:  // Subtypes of Pointer.
      return kUnboxedFfiIntPtr;
  }
}

SmallRepresentation TypeSmallRepresentation(const AbstractType& ffi_type) {
  switch (ffi_type.type_class_id()) {
    case kFfiInt8Cid:
      return kSmallUnboxedInt8;
    case kFfiInt16Cid:
      return kSmallUnboxedInt16;
    case kFfiUint8Cid:
      return kSmallUnboxedUint8;
    case kFfiUint16Cid:
      return kSmallUnboxedUint16;
    default:
      return kNoSmallRepresentation;
  }
}

bool NativeTypeIsVoid(const AbstractType& result_type) {
  return result_type.type_class_id() == kFfiVoidCid;
}

bool NativeTypeIsPointer(const AbstractType& result_type) {
  switch (result_type.type_class_id()) {
    case kFfiVoidCid:
    case kFfiFloatCid:
    case kFfiDoubleCid:
    case kFfiInt8Cid:
    case kFfiInt16Cid:
    case kFfiInt32Cid:
    case kFfiUint8Cid:
    case kFfiUint16Cid:
    case kFfiUint32Cid:
    case kFfiInt64Cid:
    case kFfiUint64Cid:
    case kFfiIntPtrCid:
      return false;
    case kFfiPointerCid:
    default:
      return true;
  }
}

// Converts a Ffi [signature] to a list of Representations.
// Note that this ignores first argument (receiver) which is dynamic.
template <class CallingConventions>
ZoneGrowableArray<Representation>* ArgumentRepresentationsBase(
    const Function& signature) {
  intptr_t num_arguments = signature.num_fixed_parameters() - 1;
  auto result = new ZoneGrowableArray<Representation>(num_arguments);
  for (intptr_t i = 0; i < num_arguments; i++) {
    AbstractType& arg_type =
        AbstractType::Handle(signature.ParameterTypeAt(i + 1));
    Representation rep = TypeRepresentation(arg_type);
    // In non simulator mode host::CallingConventions == CallingConventions.
    // In simulator mode convert arguments to host representation.
    if (rep == kUnboxedFloat && CallingConventions::kAbiSoftFP) {
      rep = kUnboxedInt32;
    } else if (rep == kUnboxedDouble && CallingConventions::kAbiSoftFP) {
      rep = kUnboxedInt64;
    }
    result->Add(rep);
  }
  return result;
}

template <class CallingConventions>
Representation ResultRepresentationBase(const Function& signature) {
  AbstractType& arg_type = AbstractType::Handle(signature.result_type());
  Representation rep = TypeRepresentation(arg_type);
  if (rep == kUnboxedFloat && CallingConventions::kAbiSoftFP) {
    rep = kUnboxedInt32;
  } else if (rep == kUnboxedDouble && CallingConventions::kAbiSoftFP) {
    rep = kUnboxedInt64;
  }
  return rep;
}

#if !defined(TARGET_ARCH_DBC)

ZoneGrowableArray<Representation>* ArgumentRepresentations(
    const Function& signature) {
  return ArgumentRepresentationsBase<CallingConventions>(signature);
}

Representation ResultRepresentation(const Function& signature) {
  return ResultRepresentationBase<CallingConventions>(signature);
}

#endif  // !defined(TARGET_ARCH_DBC)

#if defined(USING_SIMULATOR)

ZoneGrowableArray<Representation>* ArgumentHostRepresentations(
    const Function& signature) {
  return ArgumentRepresentationsBase<host::CallingConventions>(signature);
}

Representation ResultHostRepresentation(const Function& signature) {
  return ResultRepresentationBase<host::CallingConventions>(signature);
}

#endif  // defined(USING_SIMULATOR)

// Represents the state of a stack frame going into a call, between allocations
// of argument locations. Acts like a register allocator but for arguments in
// the native ABI.
template <class CallingConventions,
          class Location,
          class Register,
          class FpuRegister>
class ArgumentAllocator : public ValueObject {
 public:
  Location AllocateArgument(Representation rep) {
    switch (rep) {
      case kUnboxedFloat:
      case kUnboxedDouble: {
        Location result = AllocateFpuRegister();
        if (!result.IsUnallocated()) return result;
        break;
      }
      case kUnboxedInt64:
      case kUnboxedUint32:
      case kUnboxedInt32: {
        Location result =
            rep == kUnboxedInt64 && compiler::target::kWordSize == 4
                ? AllocateAlignedRegisterPair()
                : AllocateCpuRegister();
        if (!result.IsUnallocated()) return result;
        break;
      }
      default:
        UNREACHABLE();
    }

    // Argument must be spilled.
    if (rep == kUnboxedInt64 && compiler::target::kWordSize == 4) {
      return AllocateAlignedStackSlots(rep);
    } else if (rep == kUnboxedDouble) {
      // By convention, we always use DoubleStackSlot for doubles, even on
      // 64-bit systems.
      ASSERT(!CallingConventions::kAlignArguments);
      return AllocateDoubleStackSlot();
    } else {
      return AllocateStackSlot();
    }
  }

 private:
  Location AllocateStackSlot() {
    return Location::StackSlot(stack_height_in_slots++,
                               CallingConventions::kStackPointerRegister);
  }

  Location AllocateDoubleStackSlot() {
    const Location result = Location::DoubleStackSlot(
        stack_height_in_slots, CallingConventions::kStackPointerRegister);
    stack_height_in_slots += 8 / compiler::target::kWordSize;
    return result;
  }

  // Allocates a pair of stack slots where the first stack slot is aligned to an
  // 8-byte boundary, if necessary.
  Location AllocateAlignedStackSlots(Representation rep) {
    if (CallingConventions::kAlignArguments &&
        compiler::target::kWordSize == 4) {
      stack_height_in_slots += stack_height_in_slots % 2;
    }

    Location result;
    if (rep == kUnboxedDouble) {
      result = Location::DoubleStackSlot(
          stack_height_in_slots, CallingConventions::kStackPointerRegister);
      stack_height_in_slots += 2;
    } else {
      const Location low = AllocateStackSlot();
      const Location high = AllocateStackSlot();
      result = Location::Pair(low, high);
    }
    return result;
  }

  Location AllocateFpuRegister() {
    if (fpu_regs_used == CallingConventions::kNumFpuArgRegs) {
      return Location::RequiresFpuRegister();
    }

    const Location result = Location::FpuRegisterLocation(
        CallingConventions::FpuArgumentRegisters[fpu_regs_used]);
    fpu_regs_used++;
    if (CallingConventions::kArgumentIntRegXorFpuReg) {
      cpu_regs_used++;
    }
    return result;
  }

  Location AllocateCpuRegister() {
    if (cpu_regs_used == CallingConventions::kNumArgRegs) {
      return Location::RequiresRegister();
    }

    const Location result = Location::RegisterLocation(
        CallingConventions::ArgumentRegisters[cpu_regs_used]);
    cpu_regs_used++;
    if (CallingConventions::kArgumentIntRegXorFpuReg) {
      fpu_regs_used++;
    }
    return result;
  }

  // Allocates a pair of registers where the first register index is even, if
  // necessary.
  Location AllocateAlignedRegisterPair() {
    if (CallingConventions::kAlignArguments) {
      cpu_regs_used += cpu_regs_used % 2;
    }
    if (cpu_regs_used > CallingConventions::kNumArgRegs - 2) {
      return Location::Any();
    }
    return Location::Pair(AllocateCpuRegister(), AllocateCpuRegister());
  }

  intptr_t cpu_regs_used = 0;
  intptr_t fpu_regs_used = 0;
  intptr_t stack_height_in_slots = 0;
};

ZoneGrowableArray<Location>*
CallbackArgumentTranslator::TranslateArgumentLocations(
    const ZoneGrowableArray<Location>& arg_locs) {
  auto& pushed_locs = *(new ZoneGrowableArray<Location>(arg_locs.length()));

  CallbackArgumentTranslator translator;
  for (intptr_t i = 0, n = arg_locs.length(); i < n; i++) {
    translator.AllocateArgument(arg_locs[i]);
  }
  for (intptr_t i = 0, n = arg_locs.length(); i < n; ++i) {
    pushed_locs.Add(translator.TranslateArgument(arg_locs[i]));
  }

  return &pushed_locs;
}

void CallbackArgumentTranslator::AllocateArgument(Location arg) {
  if (arg.IsPairLocation()) {
    AllocateArgument(arg.Component(0));
    AllocateArgument(arg.Component(1));
    return;
  }
  if (arg.HasStackIndex()) return;
  ASSERT(arg.IsRegister() || arg.IsFpuRegister());
  if (arg.IsRegister()) {
    argument_slots_required_++;
  } else {
    argument_slots_required_ += 8 / compiler::target::kWordSize;
  }
}

Location CallbackArgumentTranslator::TranslateArgument(Location arg) {
  if (arg.IsPairLocation()) {
    const Location low = TranslateArgument(arg.Component(0));
    const Location high = TranslateArgument(arg.Component(1));
    return Location::Pair(low, high);
  }

  if (arg.HasStackIndex()) {
    // Add extra slots after the saved arguments for the return address and
    // frame pointer of the dummy arguments frame, which will be between the
    // saved argument registers and stack arguments. Also add slots for the
    // shadow space if present (factored into
    // kCallbackSlotsBeforeSavedArguments).
    FrameRebase rebase(
        /*old_base=*/SPREG, /*new_base=*/SPREG,
        /*stack_delta=*/argument_slots_required_ +
            kCallbackSlotsBeforeSavedArguments);
    return rebase.Rebase(arg);
  }

  if (arg.IsRegister()) {
    return Location::StackSlot(argument_slots_used_++, SPREG);
  }

  ASSERT(arg.IsFpuRegister());
  const Location result =
      Location::DoubleStackSlot(argument_slots_used_, SPREG);
  argument_slots_used_ += 8 / compiler::target::kWordSize;
  return result;
}

// Takes a list of argument representations, and converts it to a list of
// argument locations based on calling convention.
template <class CallingConventions,
          class Location,
          class Register,
          class FpuRegister>
ZoneGrowableArray<Location>* ArgumentLocationsBase(
    const ZoneGrowableArray<Representation>& arg_reps) {
  intptr_t num_arguments = arg_reps.length();
  auto result = new ZoneGrowableArray<Location>(num_arguments);

  // Loop through all arguments and assign a register or a stack location.
  ArgumentAllocator<CallingConventions, Location, Register, FpuRegister>
      frame_state;
  for (intptr_t i = 0; i < num_arguments; i++) {
    Representation rep = arg_reps[i];
    result->Add(frame_state.AllocateArgument(rep));
  }
  return result;
}

ZoneGrowableArray<Location>* ArgumentLocations(
    const ZoneGrowableArray<Representation>& arg_reps) {
#if !defined(TARGET_ARCH_DBC)
  return ArgumentLocationsBase<dart::CallingConventions, Location,
                               dart::Register, dart::FpuRegister>(arg_reps);
#else
  intptr_t next_free_register = compiler::ffi::kFirstArgumentRegister;
  intptr_t num_arguments = arg_reps.length();
  auto result = new ZoneGrowableArray<Location>(num_arguments);
  for (intptr_t i = 0; i < num_arguments; i++) {
    // TODO(dacoharkes): In 32 bits, use pair locations.
    result->Add(Location::RegisterLocation(next_free_register));
    next_free_register++;
  }
  return result;
#endif
}

#if defined(TARGET_ARCH_DBC)
ZoneGrowableArray<HostLocation>* HostArgumentLocations(
    const ZoneGrowableArray<Representation>& arg_reps) {
  return ArgumentLocationsBase<dart::host::CallingConventions, HostLocation,
                               dart::host::Register, dart::host::FpuRegister>(
      arg_reps);
}
#endif

Location ResultLocation(Representation result_rep) {
#ifndef TARGET_ARCH_DBC
  switch (result_rep) {
    case kUnboxedFloat:
    case kUnboxedDouble:
#if defined(TARGET_ARCH_IA32)
      // The result is returned in ST0, but we don't allocate ST registers, so
      // the FFI trampoline will move it to XMM0.
      return Location::FpuRegisterLocation(XMM0);
#else
      return Location::FpuRegisterLocation(CallingConventions::kReturnFpuReg);
#endif
    case kUnboxedInt32:
    case kUnboxedUint32:
      return Location::RegisterLocation(CallingConventions::kReturnReg);
    case kUnboxedInt64:
      if (compiler::target::kWordSize == 4) {
        return Location::Pair(
            Location::RegisterLocation(CallingConventions::kReturnReg),
            Location::RegisterLocation(CallingConventions::kSecondReturnReg));
      } else {
        return Location::RegisterLocation(CallingConventions::kReturnReg);
      }
    default:
      UNREACHABLE();
  }
#else
  // TODO(dacoharkes): Support 64 bit result values on 32 bit DBC.
  return Location::RegisterLocation(0);
#endif
}

// Accounts for alignment, where some stack slots are used as padding.
template <class Location>
intptr_t TemplateNumStackSlots(const ZoneGrowableArray<Location>& locations) {
  intptr_t num_arguments = locations.length();
  intptr_t max_height_in_slots = 0;
  for (intptr_t i = 0; i < num_arguments; i++) {
    intptr_t height = 0;
    if (locations.At(i).IsStackSlot()) {
      height = locations.At(i).stack_index() + 1;
    } else if (locations.At(i).IsDoubleStackSlot()) {
      height = locations.At(i).stack_index() + 8 / compiler::target::kWordSize;
    } else if (locations.At(i).IsPairLocation()) {
      const Location first = locations.At(i).AsPairLocation()->At(0);
      const Location second = locations.At(i).AsPairLocation()->At(1);
      height = std::max(first.IsStackSlot() ? first.stack_index() + 1 : 0,
                        second.IsStackSlot() ? second.stack_index() + 1 : 0);
    }
    max_height_in_slots = std::max(height, max_height_in_slots);
  }
  return max_height_in_slots;
}

intptr_t NumStackSlots(const ZoneGrowableArray<Location>& locations) {
  return TemplateNumStackSlots(locations);
}

#if defined(TARGET_ARCH_DBC)

static RawTypedData* typed_data_new_uintptr(intptr_t length) {
#if defined(ARCH_IS_32_BIT)
  return TypedData::New(kTypedDataUint32ArrayCid, length);
#else
  return TypedData::New(kTypedDataUint64ArrayCid, length);
#endif
}

static void typed_data_set_uintptr(const TypedData& typed_data,
                                   intptr_t index,
                                   uintptr_t value) {
#if defined(ARCH_IS_32_BIT)
  typed_data.SetUint32(target::kWordSize * index, value);
#else
  typed_data.SetUint64(target::kWordSize * index, value);
#endif
}

static uintptr_t typed_data_get_uintptr(const TypedData& typed_data,
                                        intptr_t index) {
#if defined(ARCH_IS_32_BIT)
  return typed_data.GetUint32(target::kWordSize * index);
#else
  return typed_data.GetUint64(target::kWordSize * index);
#endif
}

// Number of host stack slots used in 'locations'.
static intptr_t HostNumStackSlots(
    const ZoneGrowableArray<HostLocation>& locations) {
  return TemplateNumStackSlots(locations);
}

RawTypedData* FfiSignatureDescriptor::New(
    const ZoneGrowableArray<HostLocation>& arg_host_locations,
    const Representation result_representation) {
  const uintptr_t num_arguments = arg_host_locations.length();
  const uintptr_t num_stack_slots = HostNumStackSlots(arg_host_locations);

  const TypedData& result = TypedData::Handle(
      typed_data_new_uintptr(kOffsetArgumentLocations + num_arguments));

  typed_data_set_uintptr(result, kOffsetNumArguments, num_arguments);
  typed_data_set_uintptr(result, kOffsetNumStackSlots, num_stack_slots);
  typed_data_set_uintptr(result, kOffsetResultRepresentation,
                         result_representation);

  for (uintptr_t i = 0; i < num_arguments; i++) {
    typed_data_set_uintptr(result, kOffsetArgumentLocations + i,
                           arg_host_locations.At(i).write());
  }

  return result.raw();
}

intptr_t FfiSignatureDescriptor::length() const {
  return typed_data_get_uintptr(typed_data_, kOffsetNumArguments);
}

intptr_t FfiSignatureDescriptor::num_stack_slots() const {
  return typed_data_get_uintptr(typed_data_, kOffsetNumStackSlots);
}

HostLocation FfiSignatureDescriptor::LocationAt(intptr_t index) const {
  return HostLocation::read(
      typed_data_get_uintptr(typed_data_, kOffsetArgumentLocations + index));
}

Representation FfiSignatureDescriptor::ResultRepresentation() const {
  uintptr_t result_int =
      typed_data_get_uintptr(typed_data_, kOffsetResultRepresentation);
  ASSERT(result_int < kNumRepresentations);
  return static_cast<Representation>(result_int);
}

#endif  // defined(TARGET_ARCH_DBC)

#endif  // !defined(DART_PRECOMPILED_RUNTIME)

}  // namespace ffi

}  // namespace compiler

}  // namespace dart
