// Copyright (c) 2020, 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/call.h"

#include "vm/class_finalizer.h"
#include "vm/symbols.h"

namespace dart {

namespace compiler {

namespace ffi {

// TODO(dartbug.com/36607): Cache the trampolines.
FunctionPtr TrampolineFunction(const FunctionType& dart_signature,
                               const FunctionType& c_signature,
                               bool is_leaf,
                               const String& function_name) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  String& name =
      String::Handle(zone, Symbols::NewFormatted(thread, "FfiTrampoline_%s",
                                                 function_name.ToCString()));
  const Library& lib = Library::Handle(zone, Library::FfiLibrary());
  const Class& owner_class = Class::Handle(zone, lib.toplevel_class());
  FunctionType& signature = FunctionType::Handle(zone, FunctionType::New());
  Function& function = Function::Handle(
      zone, Function::New(signature, name, UntaggedFunction::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);
  // Trampolines have no optional arguments.
  const intptr_t num_fixed = dart_signature.num_fixed_parameters();
  signature.set_num_fixed_parameters(num_fixed);
  signature.set_result_type(
      AbstractType::Handle(zone, dart_signature.result_type()));
  signature.set_parameter_types(
      Array::Handle(zone, dart_signature.parameter_types()));

  // Create unique names for the parameters, as they are used in scope building
  // and error messages.
  if (num_fixed > 0) {
    function.CreateNameArray();
    function.SetParameterNameAt(0, Symbols::ClosureParameter());
    for (intptr_t i = 1; i < num_fixed; i++) {
      name = Symbols::NewFormatted(thread, ":ffi_param%" Pd, i);
      function.SetParameterNameAt(i, name);
    }
  }
  function.SetFfiCSignature(c_signature);
  signature ^= ClassFinalizer::FinalizeType(signature);
  function.SetSignature(signature);

  function.SetFfiIsLeaf(is_leaf);

  return function.ptr();
}

}  // namespace ffi

}  // namespace compiler

}  // namespace dart
