// 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 "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);
}

// 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 / compiler::ffi::ElementSizeInBytes(type_cid);
  CheckRange(argCount, 1, max_count, "count");

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

  RawPointer* result =
      Pointer::New(type_arg, Integer::Handle(zone, Integer::New(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));

  // TODO(dacoharkes): should this return NULL if address is 0?
  // https://github.com/dart-lang/sdk/issues/35756

  RawPointer* result =
      Pointer::New(native_type, arg_ptr, 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(zone, pointer.type_argument());
  CheckSized(pointer_type_arg);

  classid_t class_id = pointer_type_arg.type_class_id();
  Integer& address = Integer::Handle(zone, pointer.GetCMemoryAddress());
  address = Integer::New(address.AsInt64Value() +
                         index.AsInt64Value() *
                             compiler::ffi::ElementSizeInBytes(class_id));
  RawPointer* result = Pointer::New(pointer_type_arg, address);
  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());

  intptr_t address =
      Integer::Handle(zone, pointer.GetCMemoryAddress()).AsInt64Value() +
      offset.AsInt64Value();
  RawPointer* result = Pointer::New(
      pointer_type_arg, Integer::Handle(zone, Integer::New(address)));
  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);

  const Integer& address = Integer::Handle(zone, 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));

  const Integer& address = Integer::Handle(zone, pointer.GetCMemoryAddress());
  free(reinterpret_cast<void*>(address.AsInt64Value()));
  pointer.SetCMemoryAddress(Integer::Handle(zone, Integer::New(0)));
  return Object::null();
}

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

static RawInstance* BoxLoadPointer(Zone* zone,
                                   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 == nullptr) {
    return Instance::null();
  }
  AbstractType& type_arg =
      AbstractType::Handle(TypeArguments::Handle(instance_type_arg.arguments())
                               .TypeAt(Pointer::kNativeTypeArgPos));
  return Pointer::New(
      type_arg,
      Integer::Handle(zone, Integer::New(reinterpret_cast<intptr_t>(address))),
      type_cid);
}

static RawInstance* LoadValue(Zone* zone,
                              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(zone, *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 = reinterpret_cast<uint8_t*>(
      Integer::Handle(pointer.GetCMemoryAddress()).AsInt64Value());
  return LoadValue(zone, address, pointer_type_arg);
}

static void StoreValue(Zone* zone,
                       const Pointer& pointer,
                       classid_t type_cid,
                       const Instance& new_value) {
  uint8_t* address = reinterpret_cast<uint8_t*>(
      Integer::Handle(pointer.GetCMemoryAddress()).AsInt64Value());
  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));
      intptr_t new_value_unwrapped = 0;
      if (!new_value.IsNull()) {
        ASSERT(new_value.IsPointer());
        new_value_unwrapped =
            Integer::Handle(AsPointer(new_value).GetCMemoryAddress())
                .AsInt64Value();
        // TODO(dacoharkes): should this return NULL if addres is 0?
        // https://github.com/dart-lang/sdk/issues/35756
      }
      *reinterpret_cast<intptr_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(zone, 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(compiler::ffi::ElementSizeInBytes(type_cid));
}

// 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();
  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::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
                                           /*is_static=*/true,
                                           /*is_const=*/false,
                                           /*is_abstract=*/false,
                                           /*is_external=*/false,
                                           /*is_native=*/false, owner_class,
                                           TokenPosition::kMinSource));
  function.set_is_debuggable(false);
  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()));

  // The signature function won't have any names for the parameters. We need to
  // assign unique names for scope building and error messages.
  const intptr_t num_params = dart_signature.num_fixed_parameters();
  const Array& parameter_names = Array::Handle(Array::New(num_params));
  for (intptr_t i = 0; i < num_params; ++i) {
    if (i == 0) {
      name = Symbols::ClosureParameter().raw();
    } else {
      name = Symbols::NewFormatted(thread, ":ffiParam%" Pd, i);
    }
    parameter_names.SetAt(i, name);
  }
  function.set_parameter_names(parameter_names);
  function.SetFfiCSignature(c_signature);

  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, Integer::Handle(zone, 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) &&                \
    !defined(TARGET_OS_WINDOWS)
  // https://github.com/dart-lang/sdk/issues/35760 Arm32 && Android
  // https://github.com/dart-lang/sdk/issues/35772 Arm64
  // https://github.com/dart-lang/sdk/issues/35773 DBC
  UNREACHABLE();
#else

  // TODO(dacoharkes): Implement this.
  // https://github.com/dart-lang/sdk/issues/35761
  // Look at StubCode::GenerateInvokeDartCodeStub.
  UNREACHABLE();
#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());

  intptr_t address = reinterpret_cast<intptr_t>(
      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, Integer::Handle(zone, Integer::New(address))));

  return result.raw();
}

}  // namespace dart
