| 1 | // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file |
| 2 | // for details. All rights reserved. Use of this source code is governed by a |
| 3 | // BSD-style license that can be found in the LICENSE file. |
| 4 | |
| 5 | #include "vm/compiler/ffi/call.h" |
| 6 | |
| 7 | #include "vm/symbols.h" |
| 8 | |
| 9 | namespace dart { |
| 10 | |
| 11 | namespace compiler { |
| 12 | |
| 13 | namespace ffi { |
| 14 | |
| 15 | // TODO(dartbug.com/36607): Cache the trampolines. |
| 16 | FunctionPtr TrampolineFunction(const Function& dart_signature, |
| 17 | const Function& c_signature) { |
| 18 | Thread* thread = Thread::Current(); |
| 19 | Zone* zone = thread->zone(); |
| 20 | String& name = String::Handle(zone, Symbols::New(thread, "FfiTrampoline" )); |
| 21 | const Library& lib = Library::Handle(zone, Library::FfiLibrary()); |
| 22 | const Class& owner_class = Class::Handle(zone, lib.toplevel_class()); |
| 23 | Function& function = |
| 24 | Function::Handle(zone, Function::New(name, FunctionLayout::kFfiTrampoline, |
| 25 | /*is_static=*/true, |
| 26 | /*is_const=*/false, |
| 27 | /*is_abstract=*/false, |
| 28 | /*is_external=*/false, |
| 29 | /*is_native=*/false, owner_class, |
| 30 | TokenPosition::kMinSource)); |
| 31 | function.set_is_debuggable(false); |
| 32 | function.set_num_fixed_parameters(dart_signature.num_fixed_parameters()); |
| 33 | function.set_result_type( |
| 34 | AbstractType::Handle(zone, dart_signature.result_type())); |
| 35 | function.set_parameter_types( |
| 36 | Array::Handle(zone, dart_signature.parameter_types())); |
| 37 | |
| 38 | // The signature function won't have any names for the parameters. We need to |
| 39 | // assign unique names for scope building and error messages. |
| 40 | const intptr_t num_params = dart_signature.num_fixed_parameters(); |
| 41 | const Array& parameter_names = Array::Handle(zone, Array::New(num_params)); |
| 42 | for (intptr_t i = 0; i < num_params; ++i) { |
| 43 | if (i == 0) { |
| 44 | name = Symbols::ClosureParameter().raw(); |
| 45 | } else { |
| 46 | name = Symbols::NewFormatted(thread, ":ffi_param%" Pd, i); |
| 47 | } |
| 48 | parameter_names.SetAt(i, name); |
| 49 | } |
| 50 | function.set_parameter_names(parameter_names); |
| 51 | function.SetFfiCSignature(c_signature); |
| 52 | |
| 53 | return function.raw(); |
| 54 | } |
| 55 | |
| 56 | } // namespace ffi |
| 57 | |
| 58 | } // namespace compiler |
| 59 | |
| 60 | } // namespace dart |
| 61 | |