// 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 "include/dart_api.h"
#include "vm/bootstrap_natives.h"
#include "vm/class_finalizer.h"
#include "vm/compiler/assembler/assembler.h"
#include "vm/exceptions.h"
#include "vm/log.h"
#include "vm/native_arguments.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/symbols.h"

namespace dart {

// The following functions are runtime checks on type arguments.
// Some checks are also performed in kernel transformation, these are asserts.
// Some checks are only performed at runtime to allow for generic code, these
// throw ArgumentExceptions.

static void ThrowTypeArgumentError(const AbstractType& type_arg,
                                   const char* expected) {
  const String& error = String::Handle(String::NewFormatted(
      "Type argument (%s) should be a %s",
      String::Handle(type_arg.UserVisibleName()).ToCString(), expected));
  Exceptions::ThrowArgumentError(error);
}

static bool IsPointerType(const AbstractType& type) {
  // Do a fast check for predefined types.
  classid_t type_cid = type.type_class_id();
  if (RawObject::IsFfiPointerClassId(type_cid)) {
    return true;
  }

  // Do a slow check for subtyping.
  const Class& pointer_class =
      Class::Handle(Isolate::Current()->object_store()->ffi_pointer_class());
  AbstractType& pointer_type =
      AbstractType::Handle(pointer_class.DeclarationType());
  pointer_type ^= pointer_type.InstantiateFrom(Object::null_type_arguments(),
                                               Object::null_type_arguments(),
                                               kNoneFree, NULL, Heap::kNew);
  ASSERT(pointer_type.IsInstantiated());
  ASSERT(type.IsInstantiated());
  return type.IsSubtypeOf(pointer_type, Heap::kNew);
}

static bool IsConcreteNativeType(const AbstractType& type) {
  // Do a fast check for predefined types.
  classid_t type_cid = type.type_class_id();
  if (RawObject::IsFfiNativeTypeTypeClassId(type_cid)) {
    return false;
  }
  if (RawObject::IsFfiTypeClassId(type_cid)) {
    return true;
  }

  // Do a slow check for subtyping.
  const Class& native_type_class = Class::Handle(
      Isolate::Current()->object_store()->ffi_native_type_class());
  AbstractType& native_type_type =
      AbstractType::Handle(native_type_class.DeclarationType());
  return type.IsSubtypeOf(native_type_type, Heap::kNew);
}

static void CheckIsConcreteNativeType(const AbstractType& type) {
  if (!IsConcreteNativeType(type)) {
    ThrowTypeArgumentError(type, "concrete sub type of NativeType");
  }
}

static bool IsNativeFunction(const AbstractType& type_arg) {
  classid_t type_cid = type_arg.type_class_id();
  return RawObject::IsFfiTypeNativeFunctionClassId(type_cid);
}

static void CheckSized(const AbstractType& type_arg) {
  classid_t type_cid = type_arg.type_class_id();
  if (RawObject::IsFfiTypeVoidClassId(type_cid) ||
      RawObject::IsFfiTypeNativeFunctionClassId(type_cid)) {
    const String& error = String::Handle(String::NewFormatted(
        "%s does not have a predefined size (@unsized). "
        "Unsized NativeTypes do not support [sizeOf] because their size "
        "is unknown. "
        "Consequently, [allocate], [Pointer.load], [Pointer.store], and "
        "[Pointer.elementAt] are not available.",
        String::Handle(type_arg.UserVisibleName()).ToCString()));
    Exceptions::ThrowArgumentError(error);
  }
}

// Checks that a dart type correspond to a [NativeType].
// Because this is checked already in a kernel transformation, it does not throw
// an ArgumentException but a boolean which should be asserted.
//
// [Int8]                               -> [int]
// [Int16]                              -> [int]
// [Int32]                              -> [int]
// [Int64]                              -> [int]
// [Uint8]                              -> [int]
// [Uint16]                             -> [int]
// [Uint32]                             -> [int]
// [Uint64]                             -> [int]
// [IntPtr]                             -> [int]
// [Double]                             -> [double]
// [Float]                              -> [double]
// [Pointer]<T>                         -> [Pointer]<T>
// T extends [Pointer]                  -> T
// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
//    where DartRepresentationOf(Tn) -> Sn
static bool DartAndCTypeCorrespond(const AbstractType& native_type,
                                   const AbstractType& dart_type) {
  classid_t native_type_cid = native_type.type_class_id();
  if (RawObject::IsFfiTypeIntClassId(native_type_cid)) {
    return dart_type.IsSubtypeOf(AbstractType::Handle(Type::IntType()),
                                 Heap::kNew);
  }
  if (RawObject::IsFfiTypeDoubleClassId(native_type_cid)) {
    return dart_type.IsSubtypeOf(AbstractType::Handle(Type::Double()),
                                 Heap::kNew);
  }
  if (RawObject::IsFfiPointerClassId(native_type_cid)) {
    return native_type.Equals(dart_type) || dart_type.IsNullType();
  }
  if (RawObject::IsFfiTypeNativeFunctionClassId(native_type_cid)) {
    if (!dart_type.IsFunctionType()) {
      return false;
    }
    TypeArguments& nativefunction_type_args =
        TypeArguments::Handle(native_type.arguments());
    AbstractType& nativefunction_type_arg =
        AbstractType::Handle(nativefunction_type_args.TypeAt(0));
    if (!nativefunction_type_arg.IsFunctionType()) {
      return false;
    }
    Function& dart_function = Function::Handle(((Type&)dart_type).signature());
    if (dart_function.NumTypeParameters() != 0 ||
        dart_function.HasOptionalPositionalParameters() ||
        dart_function.HasOptionalNamedParameters()) {
      return false;
    }
    Function& nativefunction_function =
        Function::Handle(((Type&)nativefunction_type_arg).signature());
    if (nativefunction_function.NumTypeParameters() != 0 ||
        nativefunction_function.HasOptionalPositionalParameters() ||
        nativefunction_function.HasOptionalNamedParameters()) {
      return false;
    }
    if (!(dart_function.NumParameters() ==
          nativefunction_function.NumParameters())) {
      return false;
    }
    if (!DartAndCTypeCorrespond(
            AbstractType::Handle(nativefunction_function.result_type()),
            AbstractType::Handle(dart_function.result_type()))) {
      return false;
    }
    for (intptr_t i = 0; i < dart_function.NumParameters(); i++) {
      if (!DartAndCTypeCorrespond(
              AbstractType::Handle(nativefunction_function.ParameterTypeAt(i)),
              AbstractType::Handle(dart_function.ParameterTypeAt(i)))) {
        return false;
      }
    }
  }
  return true;
}

// The following functions are runtime checks on arguments.

// Note that expected_from and expected_to are inclusive.
static void CheckRange(const Integer& argument_value,
                       intptr_t expected_from,
                       intptr_t expected_to,
                       const char* argument_name) {
  int64_t value = argument_value.AsInt64Value();
  if (value < expected_from || expected_to < value) {
    Exceptions::ThrowRangeError(argument_name, argument_value, expected_from,
                                expected_to);
  }
}

static const Pointer& AsPointer(const Instance& instance) {
  if (!instance.IsPointer()) {
    const String& error = String::Handle(String::NewFormatted(
        "Expected a Pointer object but found %s", instance.ToCString()));
    Exceptions::ThrowArgumentError(error);
  }
  return Pointer::Cast(instance);
}

static const Integer& AsInteger(const Instance& instance) {
  if (!instance.IsInteger()) {
    const String& error = String::Handle(String::NewFormatted(
        "Expected an int but found %s", instance.ToCString()));
    Exceptions::ThrowArgumentError(error);
  }
  return Integer::Cast(instance);
}

static const Double& AsDouble(const Instance& instance) {
  if (!instance.IsDouble()) {
    const String& error = String::Handle(String::NewFormatted(
        "Expected a double but found %s", instance.ToCString()));
    Exceptions::ThrowArgumentError(error);
  }
  return Double::Cast(instance);
}

// Native data types sizes in bytes

static const size_t kSizeUnknown = 0;

static const intptr_t kNumElementSizes = kFfiVoidCid - kFfiPointerCid + 1;

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

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

// The remainder of this file implements the dart:ffi native methods.

DEFINE_NATIVE_ENTRY(Ffi_allocate, 1, 1) {
  // TODO(dacoharkes): When we have a way of determining the size of structs in
  // the VM, change the signature so we can allocate structs, subtype of
  // Pointer. https://github.com/dart-lang/sdk/issues/35782
  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));

  CheckIsConcreteNativeType(type_arg);
  CheckSized(type_arg);

  GET_NON_NULL_NATIVE_ARGUMENT(Integer, argCount, arguments->NativeArgAt(0));
  int64_t count = argCount.AsInt64Value();
  classid_t type_cid = type_arg.type_class_id();
  int64_t max_count = INTPTR_MAX / ElementSizeInBytes(type_cid);
  CheckRange(argCount, 1, max_count, "count");

  size_t size = ElementSizeInBytes(type_cid) * count;
  uint8_t* memory = reinterpret_cast<uint8_t*>(malloc(size));
  if (memory == NULL) {
    const String& error = String::Handle(String::NewFormatted(
        "allocating (%" Pd ") bytes of memory failed", size));
    Exceptions::ThrowArgumentError(error);
  }

  RawPointer* result = Pointer::New(type_arg, memory);
  return result;
}

DEFINE_NATIVE_ENTRY(Ffi_fromAddress, 1, 1) {
  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
  TypeArguments& type_args = TypeArguments::Handle(type_arg.arguments());
  AbstractType& native_type = AbstractType::Handle(
      type_args.TypeAtNullSafe(Pointer::kNativeTypeArgPos));
  CheckIsConcreteNativeType(native_type);
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, arg_ptr, arguments->NativeArgAt(0));

  uint8_t* address = reinterpret_cast<uint8_t*>(arg_ptr.AsInt64Value());
  // TODO(dacoharkes): should this return NULL if addres is 0?
  // https://github.com/dart-lang/sdk/issues/35756

  RawPointer* result =
      Pointer::New(native_type, address, type_arg.type_class_id());
  return result;
}

DEFINE_NATIVE_ENTRY(Ffi_elementAt, 0, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, index, arguments->NativeArgAt(1));
  AbstractType& pointer_type_arg =
      AbstractType::Handle(pointer.type_argument());
  CheckSized(pointer_type_arg);

  classid_t class_id = pointer_type_arg.type_class_id();
  uint8_t* address = pointer.GetCMemoryAddress();
  uint8_t* address_new =
      address + index.AsInt64Value() * ElementSizeInBytes(class_id);
  RawPointer* result = Pointer::New(pointer_type_arg, address_new);
  return result;
}

DEFINE_NATIVE_ENTRY(Ffi_offsetBy, 0, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, offset, arguments->NativeArgAt(1));
  AbstractType& pointer_type_arg =
      AbstractType::Handle(pointer.type_argument());

  uint8_t* address = pointer.GetCMemoryAddress();
  uint8_t* address_new = address + offset.AsInt64Value();
  RawPointer* result = Pointer::New(pointer_type_arg, address_new);
  return result;
}

DEFINE_NATIVE_ENTRY(Ffi_cast, 1, 1) {
  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
  TypeArguments& type_args = TypeArguments::Handle(type_arg.arguments());
  AbstractType& native_type = AbstractType::Handle(
      type_args.TypeAtNullSafe(Pointer::kNativeTypeArgPos));
  CheckIsConcreteNativeType(native_type);

  uint8_t* address = pointer.GetCMemoryAddress();
  RawPointer* result =
      Pointer::New(native_type, address, type_arg.type_class_id());
  return result;
}

DEFINE_NATIVE_ENTRY(Ffi_free, 0, 1) {
  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));

  uint8_t* address = pointer.GetCMemoryAddress();
  free(address);
  pointer.SetCMemoryAddress(0);
  return Object::null();
}

DEFINE_NATIVE_ENTRY(Ffi_address, 0, 1) {
  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));

  uint8_t* address = pointer.GetCMemoryAddress();
  intptr_t int_ptr = reinterpret_cast<intptr_t>(address);
  return Integer::NewFromUint64(int_ptr);
}

static RawInstance* BoxLoadPointer(uint8_t* address,
                                   const AbstractType& instance_type_arg,
                                   intptr_t type_cid) {
  // TODO(dacoharkes): should this return NULL if addres is 0?
  // https://github.com/dart-lang/sdk/issues/35756
  if (address == 0) {  // 0 is the c++ null pointer
    return Instance::null();
  }
  AbstractType& type_arg =
      AbstractType::Handle(TypeArguments::Handle(instance_type_arg.arguments())
                               .TypeAt(Pointer::kNativeTypeArgPos));
  return Pointer::New(type_arg, address, type_cid);
}

static RawInstance* LoadValue(uint8_t* address,
                              const AbstractType& instance_type_arg) {
  classid_t type_cid = instance_type_arg.type_class_id();
  switch (type_cid) {
    case kFfiInt8Cid:
      return Integer::New(*reinterpret_cast<int8_t*>(address));
    case kFfiInt16Cid:
      return Integer::New(*reinterpret_cast<int16_t*>(address));
    case kFfiInt32Cid:
      return Integer::New(*reinterpret_cast<int32_t*>(address));
    case kFfiInt64Cid:
      return Integer::New(*reinterpret_cast<int64_t*>(address));
    case kFfiUint8Cid:
      return Integer::NewFromUint64(*reinterpret_cast<uint8_t*>(address));
    case kFfiUint16Cid:
      return Integer::NewFromUint64(*reinterpret_cast<uint16_t*>(address));
    case kFfiUint32Cid:
      return Integer::NewFromUint64(*reinterpret_cast<uint32_t*>(address));
    case kFfiUint64Cid:
      return Integer::NewFromUint64(*reinterpret_cast<uint64_t*>(address));
    case kFfiIntPtrCid:
      return Integer::New(*reinterpret_cast<intptr_t*>(address));
    case kFfiFloatCid:
      return Double::New(*reinterpret_cast<float_t*>(address));
    case kFfiDoubleCid:
      return Double::New(*reinterpret_cast<double_t*>(address));
    case kFfiPointerCid:
    default:
      ASSERT(IsPointerType(instance_type_arg));
      return BoxLoadPointer(*reinterpret_cast<uint8_t**>(address),
                            instance_type_arg, type_cid);
  }
}

DEFINE_NATIVE_ENTRY(Ffi_load, 1, 1) {
  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
  AbstractType& pointer_type_arg =
      AbstractType::Handle(pointer.type_argument());
  CheckSized(pointer_type_arg);
  ASSERT(DartAndCTypeCorrespond(pointer_type_arg, type_arg));

  uint8_t* address = pointer.GetCMemoryAddress();
  return LoadValue(address, pointer_type_arg);
}

static void StoreValue(const Pointer& pointer,
                       classid_t type_cid,
                       const Instance& new_value) {
  uint8_t* address = pointer.GetCMemoryAddress();
  AbstractType& pointer_type_arg =
      AbstractType::Handle(pointer.type_argument());
  switch (type_cid) {
    case kFfiInt8Cid:
      *reinterpret_cast<int8_t*>(address) = AsInteger(new_value).AsInt64Value();
      break;
    case kFfiInt16Cid:
      *reinterpret_cast<int16_t*>(address) =
          AsInteger(new_value).AsInt64Value();
      break;
    case kFfiInt32Cid:
      *reinterpret_cast<int32_t*>(address) =
          AsInteger(new_value).AsInt64Value();
      break;
    case kFfiInt64Cid:
      *reinterpret_cast<int64_t*>(address) =
          AsInteger(new_value).AsInt64Value();
      break;
    case kFfiUint8Cid:
      *reinterpret_cast<uint8_t*>(address) =
          AsInteger(new_value).AsInt64Value();
      break;
    case kFfiUint16Cid:
      *reinterpret_cast<uint16_t*>(address) =
          AsInteger(new_value).AsInt64Value();
      break;
    case kFfiUint32Cid:
      *reinterpret_cast<uint32_t*>(address) =
          AsInteger(new_value).AsInt64Value();
      break;
    case kFfiUint64Cid:
      *reinterpret_cast<uint64_t*>(address) =
          AsInteger(new_value).AsInt64Value();
      break;
    case kFfiIntPtrCid:
      *reinterpret_cast<intptr_t*>(address) =
          AsInteger(new_value).AsInt64Value();
      break;
    case kFfiFloatCid:
      *reinterpret_cast<float*>(address) = AsDouble(new_value).value();
      break;
    case kFfiDoubleCid:
      *reinterpret_cast<double*>(address) = AsDouble(new_value).value();
      break;
    case kFfiPointerCid:
    default: {
      ASSERT(IsPointerType(pointer_type_arg));
      uint8_t* new_value_unwrapped = nullptr;
      if (!new_value.IsNull()) {
        ASSERT(new_value.IsPointer());
        new_value_unwrapped = AsPointer(new_value).GetCMemoryAddress();
        // TODO(dacoharkes): should this return NULL if addres is 0?
        // https://github.com/dart-lang/sdk/issues/35756
      }
      *reinterpret_cast<uint8_t**>(address) = new_value_unwrapped;
    } break;
  }
}

DEFINE_NATIVE_ENTRY(Ffi_store, 0, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
  GET_NATIVE_ARGUMENT(Instance, new_value, arguments->NativeArgAt(1));
  AbstractType& arg_type = AbstractType::Handle(new_value.GetType(Heap::kNew));
  AbstractType& pointer_type_arg =
      AbstractType::Handle(pointer.type_argument());
  CheckSized(pointer_type_arg);
  ASSERT(DartAndCTypeCorrespond(pointer_type_arg, arg_type));

  classid_t type_cid = pointer_type_arg.type_class_id();
  StoreValue(pointer, type_cid, new_value);
  return Object::null();
}

DEFINE_NATIVE_ENTRY(Ffi_sizeOf, 1, 0) {
  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
  CheckIsConcreteNativeType(type_arg);
  CheckSized(type_arg);

  classid_t type_cid = type_arg.type_class_id();
  return Smi::New(ElementSizeInBytes(type_cid));
}

// Generates assembly to trampoline from Dart into C++.
//
// Attaches assembly code to the function with the folling features:
// - unboxes arguments
// - puts the arguments on the c stack
// - invokes the c function
// - reads the the result
// - boxes the result and returns it.
//
// It inspects the signature to know what to box/unbox
// Parameter `function` has the Dart types in its signature
// Parameter `c_signature` has the C++ types in its signature
static RawCode* TrampolineCode(const Function& function,
                               const Function& c_signature) {
#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
  // Currently we generate the trampoline when calling asFunction(), this means
  // the ffi cannot be used in AOT.
  // In order make it work in AOT we need to:
  // - collect all asFunction signatures ahead of time
  // - generate trampolines for those
  // - store these in the object store
  // - and read these from the object store when calling asFunction()
  // https://github.com/dart-lang/sdk/issues/35765
  UNREACHABLE();
#elif !defined(TARGET_ARCH_X64)
  // https://github.com/dart-lang/sdk/issues/35774
  UNREACHABLE();
#elif !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS)
  // https://github.com/dart-lang/sdk/issues/35760 Arm32 && Android
  // https://github.com/dart-lang/sdk/issues/35771 Windows
  // https://github.com/dart-lang/sdk/issues/35772 Arm64
  // https://github.com/dart-lang/sdk/issues/35773 DBC
  UNREACHABLE();
#else
  extern void GenerateFfiTrampoline(Assembler * assembler,
                                    const Function& signature);
  ObjectPoolBuilder object_pool_builder;
  Assembler assembler(&object_pool_builder);
  GenerateFfiTrampoline(&assembler, c_signature);
  const Code& code = Code::Handle(Code::FinalizeCode(
      function, nullptr, &assembler, Code::PoolAttachment::kAttachPool));
  code.set_exception_handlers(
      ExceptionHandlers::Handle(ExceptionHandlers::New(0)));
  return code.raw();
#endif
}

// TODO(dacoharkes): Cache the trampolines.
// We can possibly address simultaniously with 'precaching' in AOT.
static RawFunction* TrampolineFunction(const Function& dart_signature,
                                       const Function& c_signature) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  const String& name =
      String::ZoneHandle(Symbols::New(Thread::Current(), "FfiTrampoline"));
  const Library& lib = Library::Handle(Library::FfiLibrary());
  const Class& owner_class = Class::Handle(lib.toplevel_class());
  Function& function = Function::ZoneHandle(
      zone, Function::New(name, RawFunction::kFfiTrampoline,
                          true,   // is_static
                          false,  // is_const
                          false,  // is_abstract
                          false,  // is_external
                          true,   // is_native
                          owner_class, TokenPosition::kMinSource));

  function.set_num_fixed_parameters(dart_signature.num_fixed_parameters());
  function.set_result_type(AbstractType::Handle(dart_signature.result_type()));
  function.set_parameter_types(Array::Handle(dart_signature.parameter_types()));

  const Code& code = Code::Handle(TrampolineCode(function, c_signature));
  function.AttachCode(code);

  return function.raw();
}

DEFINE_NATIVE_ENTRY(Ffi_asFunction, 1, 1) {
  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
  AbstractType& pointer_type_arg =
      AbstractType::Handle(pointer.type_argument());
  ASSERT(IsNativeFunction(pointer_type_arg));
  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
  ASSERT(DartAndCTypeCorrespond(pointer_type_arg, type_arg));

  Function& dart_signature = Function::Handle(Type::Cast(type_arg).signature());
  TypeArguments& nativefunction_type_args =
      TypeArguments::Handle(pointer_type_arg.arguments());
  AbstractType& nativefunction_type_arg =
      AbstractType::Handle(nativefunction_type_args.TypeAt(0));
  Function& c_signature =
      Function::Handle(Type::Cast(nativefunction_type_arg).signature());
  Function& function =
      Function::Handle(TrampolineFunction(dart_signature, c_signature));

  // Set the c function pointer in the context of the closure rather than in
  // the function so that we can reuse the function for each c function with
  // the same signature.
  Context& context = Context::Handle(Context::New(1));
  context.SetAt(0,
                Object::Handle(Integer::NewFromUint64(
                    reinterpret_cast<intptr_t>(pointer.GetCMemoryAddress()))));

  RawClosure* raw_closure =
      Closure::New(Object::null_type_arguments(), Object::null_type_arguments(),
                   function, context, Heap::kOld);

  return raw_closure;
}

// Generates assembly to trampoline from C++ back into Dart.
static void* GenerateFfiInverseTrampoline(const Function& signature,
                                          void* dart_entry_point) {
#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
  UNREACHABLE();
#elif !defined(TARGET_ARCH_X64)
  // https://github.com/dart-lang/sdk/issues/35774
  UNREACHABLE();
#elif !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS)
  // https://github.com/dart-lang/sdk/issues/35760 Arm32 && Android
  // https://github.com/dart-lang/sdk/issues/35771 Windows
  // https://github.com/dart-lang/sdk/issues/35772 Arm64
  // https://github.com/dart-lang/sdk/issues/35773 DBC
  UNREACHABLE();
#else
  extern void GenerateFfiInverseTrampoline(
      Assembler * assembler, const Function& signature, void* dart_entry_point);
  ObjectPoolBuilder object_pool_builder;
  Assembler assembler(&object_pool_builder);
  GenerateFfiInverseTrampoline(&assembler, signature, dart_entry_point);
  const Code& code = Code::Handle(
      Code::FinalizeCode("inverse trampoline", nullptr, &assembler,
                         Code::PoolAttachment::kAttachPool, false));

  uword entryPoint = code.EntryPoint();

  return reinterpret_cast<void*>(entryPoint);
#endif
}

// TODO(dacoharkes): Implement this feature.
// https://github.com/dart-lang/sdk/issues/35761
// For now, it always returns Pointer with address 0.
DEFINE_NATIVE_ENTRY(Ffi_fromFunction, 1, 1) {
  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Closure, closure, arguments->NativeArgAt(0));

  Function& c_signature = Function::Handle(((Type&)type_arg).signature());

  Function& func = Function::Handle(closure.function());
  Code& code = Code::Handle(func.EnsureHasCode());
  void* entryPoint = reinterpret_cast<void*>(code.EntryPoint());

  THR_Print("Ffi_fromFunction: %s\n", type_arg.ToCString());
  THR_Print("Ffi_fromFunction: %s\n", c_signature.ToCString());
  THR_Print("Ffi_fromFunction: %s\n", closure.ToCString());
  THR_Print("Ffi_fromFunction: %s\n", func.ToCString());
  THR_Print("Ffi_fromFunction: %s\n", code.ToCString());
  THR_Print("Ffi_fromFunction: %p\n", entryPoint);
  THR_Print("Ffi_fromFunction: %" Pd "\n", code.Size());

  void* address = GenerateFfiInverseTrampoline(c_signature, entryPoint);

  TypeArguments& type_args = TypeArguments::Handle(zone);
  type_args = TypeArguments::New(1);
  type_args.SetTypeAt(Pointer::kNativeTypeArgPos, type_arg);
  type_args ^= type_args.Canonicalize();

  Class& native_function_class = Class::Handle(
      Isolate::Current()->class_table()->At(kFfiNativeFunctionCid));
  native_function_class.EnsureIsFinalized(Thread::Current());

  Type& native_function_type = Type::Handle(
      Type::New(native_function_class, type_args, TokenPosition::kNoSource));
  native_function_type ^=
      ClassFinalizer::FinalizeType(Class::Handle(), native_function_type);
  native_function_type ^= native_function_type.Canonicalize();

  address = 0;  // https://github.com/dart-lang/sdk/issues/35761

  Pointer& result = Pointer::Handle(
      Pointer::New(native_function_type, reinterpret_cast<uint8_t*>(address)));

  return result.raw();
}

}  // namespace dart
