rice 4.3.3 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +86 -26
- data/CMakeLists.txt +31 -0
- data/CMakePresets.json +75 -0
- data/COPYING +3 -2
- data/FindRuby.cmake +437 -0
- data/README.md +7 -2
- data/Rakefile +12 -5
- data/include/rice/rice.hpp +9522 -4426
- data/include/rice/stl.hpp +2831 -1198
- data/lib/make_rice_headers.rb +79 -0
- data/lib/mkmf-rice.rb +40 -94
- data/lib/rice/version.rb +3 -0
- data/lib/rice.rb +1 -0
- data/lib/rubygems/builder.rb +11 -0
- data/lib/rubygems/cmake_builder.rb +113 -0
- data/lib/rubygems_plugin.rb +9 -0
- data/rice/Address_Registration_Guard.hpp +72 -3
- data/rice/Arg.hpp +26 -6
- data/rice/Arg.ipp +35 -2
- data/rice/Buffer.hpp +123 -0
- data/rice/Buffer.ipp +599 -0
- data/rice/Callback.hpp +21 -0
- data/rice/Callback.ipp +13 -0
- data/rice/Constructor.hpp +4 -27
- data/rice/Constructor.ipp +79 -0
- data/rice/Data_Object.hpp +73 -3
- data/rice/Data_Object.ipp +388 -96
- data/rice/Data_Type.hpp +214 -3
- data/rice/Data_Type.ipp +144 -67
- data/rice/Director.hpp +0 -2
- data/rice/Enum.hpp +4 -7
- data/rice/Enum.ipp +102 -55
- data/rice/Exception.hpp +62 -2
- data/rice/Exception.ipp +7 -12
- data/rice/Init.hpp +8 -0
- data/rice/Init.ipp +8 -0
- data/rice/JumpException.hpp +44 -0
- data/rice/JumpException.ipp +48 -0
- data/rice/MemoryView.hpp +11 -0
- data/rice/MemoryView.ipp +3 -0
- data/rice/Return.hpp +7 -27
- data/rice/Return.ipp +13 -13
- data/rice/cpp_api/Array.hpp +209 -0
- data/rice/cpp_api/Array.ipp +304 -0
- data/rice/cpp_api/Builtin_Object.hpp +31 -0
- data/rice/cpp_api/Builtin_Object.ipp +37 -0
- data/rice/cpp_api/Class.hpp +70 -0
- data/rice/cpp_api/Class.ipp +97 -0
- data/rice/cpp_api/Encoding.hpp +32 -0
- data/rice/cpp_api/Encoding.ipp +59 -0
- data/rice/cpp_api/Hash.hpp +194 -0
- data/rice/cpp_api/Hash.ipp +257 -0
- data/rice/{Identifier.hpp → cpp_api/Identifier.hpp} +2 -6
- data/rice/{Identifier.ipp → cpp_api/Identifier.ipp} +4 -2
- data/rice/cpp_api/Module.hpp +72 -0
- data/rice/cpp_api/Module.ipp +101 -0
- data/rice/cpp_api/Object.hpp +272 -0
- data/rice/cpp_api/Object.ipp +235 -0
- data/rice/cpp_api/String.hpp +74 -0
- data/rice/cpp_api/String.ipp +120 -0
- data/rice/cpp_api/Struct.hpp +113 -0
- data/rice/cpp_api/Struct.ipp +92 -0
- data/rice/cpp_api/Symbol.hpp +46 -0
- data/rice/cpp_api/Symbol.ipp +93 -0
- data/rice/cpp_api/shared_methods.hpp +134 -0
- data/rice/detail/DefaultHandler.hpp +12 -0
- data/rice/detail/DefaultHandler.ipp +8 -0
- data/rice/detail/HandlerRegistry.hpp +5 -35
- data/rice/detail/HandlerRegistry.ipp +7 -11
- data/rice/detail/InstanceRegistry.hpp +1 -4
- data/rice/detail/MethodInfo.hpp +12 -10
- data/rice/detail/MethodInfo.ipp +26 -21
- data/rice/detail/Native.hpp +33 -0
- data/rice/detail/Native.ipp +157 -0
- data/rice/detail/NativeAttributeGet.hpp +52 -0
- data/rice/detail/NativeAttributeGet.ipp +57 -0
- data/rice/detail/NativeAttributeSet.hpp +44 -0
- data/rice/detail/NativeAttributeSet.ipp +88 -0
- data/rice/detail/NativeCallbackFFI.hpp +55 -0
- data/rice/detail/NativeCallbackFFI.ipp +151 -0
- data/rice/detail/NativeCallbackSimple.hpp +30 -0
- data/rice/detail/NativeCallbackSimple.ipp +29 -0
- data/rice/detail/NativeFunction.hpp +33 -23
- data/rice/detail/NativeFunction.ipp +309 -70
- data/rice/detail/NativeIterator.hpp +9 -11
- data/rice/detail/NativeIterator.ipp +33 -31
- data/rice/detail/NativeRegistry.hpp +24 -15
- data/rice/detail/NativeRegistry.ipp +23 -48
- data/rice/detail/Proc.hpp +4 -0
- data/rice/detail/Proc.ipp +85 -0
- data/rice/detail/Registries.hpp +0 -7
- data/rice/detail/Registries.ipp +0 -18
- data/rice/detail/RubyFunction.hpp +0 -3
- data/rice/detail/RubyFunction.ipp +4 -8
- data/rice/detail/RubyType.hpp +16 -0
- data/rice/detail/RubyType.ipp +232 -0
- data/rice/detail/Type.hpp +7 -6
- data/rice/detail/Type.ipp +192 -45
- data/rice/detail/TypeRegistry.hpp +15 -7
- data/rice/detail/TypeRegistry.ipp +105 -12
- data/rice/detail/Wrapper.hpp +68 -32
- data/rice/detail/Wrapper.ipp +121 -109
- data/rice/detail/cpp_protect.hpp +5 -6
- data/rice/detail/default_allocation_func.ipp +0 -2
- data/rice/detail/from_ruby.hpp +38 -3
- data/rice/detail/from_ruby.ipp +1321 -492
- data/rice/detail/ruby.hpp +18 -0
- data/rice/detail/to_ruby.hpp +41 -3
- data/rice/detail/to_ruby.ipp +1424 -194
- data/rice/global_function.hpp +0 -4
- data/rice/global_function.ipp +0 -1
- data/rice/libc/file.hpp +11 -0
- data/rice/libc/file.ipp +32 -0
- data/rice/rice.hpp +116 -26
- data/rice/ruby_mark.hpp +4 -3
- data/rice/stl/complex.hpp +6 -0
- data/rice/stl/complex.ipp +93 -0
- data/rice/stl/exception.hpp +11 -0
- data/rice/stl/exception.ipp +29 -0
- data/rice/stl/exception_ptr.hpp +6 -0
- data/rice/stl/exception_ptr.ipp +27 -0
- data/rice/stl/map.hpp +12 -0
- data/rice/stl/map.ipp +469 -0
- data/rice/stl/monostate.hpp +6 -0
- data/rice/stl/monostate.ipp +80 -0
- data/rice/stl/multimap.hpp +14 -0
- data/rice/stl/multimap.ipp +448 -0
- data/rice/stl/optional.hpp +6 -0
- data/rice/stl/optional.ipp +118 -0
- data/rice/stl/pair.hpp +13 -0
- data/rice/stl/pair.ipp +155 -0
- data/rice/stl/reference_wrapper.hpp +6 -0
- data/rice/stl/reference_wrapper.ipp +41 -0
- data/rice/stl/set.hpp +12 -0
- data/rice/stl/set.ipp +495 -0
- data/rice/stl/shared_ptr.hpp +28 -0
- data/rice/stl/shared_ptr.ipp +224 -0
- data/rice/stl/string.hpp +6 -0
- data/rice/stl/string.ipp +158 -0
- data/rice/stl/string_view.hpp +6 -0
- data/rice/stl/string_view.ipp +65 -0
- data/rice/stl/tuple.hpp +6 -0
- data/rice/stl/tuple.ipp +128 -0
- data/rice/stl/type_index.hpp +6 -0
- data/rice/stl/type_index.ipp +30 -0
- data/rice/stl/type_info.hpp +6 -0
- data/rice/stl/type_info.ipp +29 -0
- data/rice/stl/unique_ptr.hpp +22 -0
- data/rice/stl/unique_ptr.ipp +139 -0
- data/rice/stl/unordered_map.hpp +12 -0
- data/rice/stl/unordered_map.ipp +469 -0
- data/rice/stl/variant.hpp +6 -0
- data/rice/stl/variant.ipp +242 -0
- data/rice/stl/vector.hpp +12 -0
- data/rice/stl/vector.ipp +590 -0
- data/rice/stl.hpp +11 -3
- data/rice/traits/attribute_traits.hpp +26 -0
- data/rice/traits/function_traits.hpp +95 -0
- data/rice/traits/method_traits.hpp +47 -0
- data/rice/traits/rice_traits.hpp +160 -0
- data/rice.gemspec +85 -0
- data/test/embed_ruby.cpp +7 -1
- data/test/extconf.rb +2 -0
- data/test/test_Address_Registration_Guard.cpp +5 -0
- data/test/test_Array.cpp +18 -4
- data/test/test_Attribute.cpp +136 -21
- data/test/test_Buffer.cpp +285 -0
- data/test/test_Builtin_Object.cpp +5 -0
- data/test/test_Callback.cpp +230 -0
- data/test/test_Class.cpp +5 -31
- data/test/test_Constructor.cpp +69 -6
- data/test/test_Data_Object.cpp +97 -38
- data/test/test_Data_Type.cpp +470 -65
- data/test/test_Director.cpp +17 -8
- data/test/test_Enum.cpp +155 -40
- data/test/test_Exception.cpp +235 -0
- data/test/test_File.cpp +70 -0
- data/test/test_From_Ruby.cpp +609 -0
- data/test/test_Hash.cpp +5 -0
- data/test/test_Identifier.cpp +5 -0
- data/test/test_Inheritance.cpp +6 -1
- data/test/test_Iterator.cpp +6 -1
- data/test/test_Jump_Exception.cpp +23 -0
- data/test/test_Keep_Alive.cpp +13 -19
- data/test/test_Keep_Alive_No_Wrapper.cpp +5 -1
- data/test/test_Memory_Management.cpp +5 -0
- data/test/test_Module.cpp +128 -67
- data/test/test_Native_Registry.cpp +2 -34
- data/test/test_Object.cpp +5 -0
- data/test/test_Overloads.cpp +806 -0
- data/test/test_Ownership.cpp +160 -54
- data/test/test_Proc.cpp +44 -0
- data/test/test_Self.cpp +9 -4
- data/test/test_Stl_Exception.cpp +109 -0
- data/test/test_Stl_Map.cpp +54 -42
- data/test/test_Stl_Multimap.cpp +693 -0
- data/test/test_Stl_Optional.cpp +5 -0
- data/test/test_Stl_Pair.cpp +14 -9
- data/test/test_Stl_Reference_Wrapper.cpp +9 -2
- data/test/test_Stl_Set.cpp +790 -0
- data/test/test_Stl_SharedPtr.cpp +458 -0
- data/test/test_Stl_String.cpp +5 -0
- data/test/test_Stl_String_View.cpp +5 -0
- data/test/test_Stl_Tuple.cpp +116 -0
- data/test/test_Stl_Type.cpp +147 -0
- data/test/test_Stl_UniquePtr.cpp +202 -0
- data/test/test_Stl_Unordered_Map.cpp +43 -38
- data/test/test_Stl_Variant.cpp +217 -84
- data/test/test_Stl_Vector.cpp +306 -58
- data/test/test_String.cpp +5 -0
- data/test/test_Struct.cpp +5 -0
- data/test/test_Symbol.cpp +5 -0
- data/test/test_Template.cpp +192 -0
- data/test/test_To_Ruby.cpp +524 -0
- data/test/test_Tracking.cpp +1 -0
- data/test/test_Type.cpp +171 -0
- data/test/test_global_functions.cpp +67 -7
- data/test/unittest.cpp +8 -0
- metadata +127 -26
- data/lib/version.rb +0 -3
- data/rice/Address_Registration_Guard_defn.hpp +0 -79
- data/rice/Data_Object_defn.hpp +0 -84
- data/rice/Data_Type_defn.hpp +0 -190
- data/rice/Exception_defn.hpp +0 -68
- data/rice/HandlerRegistration.hpp +0 -15
- data/rice/detail/ExceptionHandler.hpp +0 -8
- data/rice/detail/ExceptionHandler.ipp +0 -28
- data/rice/detail/ExceptionHandler_defn.hpp +0 -77
- data/rice/detail/Jump_Tag.hpp +0 -21
- data/rice/detail/NativeAttribute.hpp +0 -64
- data/rice/detail/NativeAttribute.ipp +0 -112
- data/rice/detail/from_ruby_defn.hpp +0 -38
- data/rice/detail/to_ruby_defn.hpp +0 -48
- data/test/test_Jump_Tag.cpp +0 -17
- data/test/test_Stl_SmartPointer.cpp +0 -283
- data/test/test_To_From_Ruby.cpp +0 -399
@@ -0,0 +1,55 @@
|
|
1
|
+
#ifndef Rice__detail__Native_Callback_Ffi_hpp_
|
2
|
+
#define Rice__detail__Native_Callback_Ffi_hpp_
|
3
|
+
|
4
|
+
#ifdef HAVE_LIBFFI
|
5
|
+
|
6
|
+
#include <ffi.h>
|
7
|
+
|
8
|
+
namespace Rice::detail
|
9
|
+
{
|
10
|
+
template<typename Callback_T>
|
11
|
+
class NativeCallbackFFI;
|
12
|
+
|
13
|
+
template<typename Return_T, typename ...Arg_Ts>
|
14
|
+
class NativeCallbackFFI<Return_T(*)(Arg_Ts...)>
|
15
|
+
{
|
16
|
+
public:
|
17
|
+
using Callback_T = Return_T(Arg_Ts...);
|
18
|
+
using Tuple_T = std::tuple<Arg_Ts...>;
|
19
|
+
static void ffiCallback(ffi_cif* cif, void* ret, void* args[], void* instance);
|
20
|
+
static VALUE finalizerCallback(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg);
|
21
|
+
static void setMethodInfo(MethodInfo* methodInfo);
|
22
|
+
|
23
|
+
public:
|
24
|
+
NativeCallbackFFI(VALUE proc);
|
25
|
+
~NativeCallbackFFI();
|
26
|
+
NativeCallbackFFI(const NativeCallbackFFI&) = delete;
|
27
|
+
NativeCallbackFFI(NativeCallbackFFI&&) = delete;
|
28
|
+
void operator=(const NativeCallbackFFI&) = delete;
|
29
|
+
void operator=(NativeCallbackFFI&&) = delete;
|
30
|
+
|
31
|
+
Return_T operator()(Arg_Ts...args);
|
32
|
+
Callback_T* callback();
|
33
|
+
|
34
|
+
private:
|
35
|
+
template <typename Arg_T>
|
36
|
+
static ffi_type* ffiType();
|
37
|
+
|
38
|
+
template<std::size_t... I>
|
39
|
+
static Tuple_T convertArgsToTuple(void* args[], std::index_sequence<I...>& indices);
|
40
|
+
|
41
|
+
static inline std::array<ffi_type*, sizeof...(Arg_Ts)> args_ = { ffiType<Arg_Ts>()... };
|
42
|
+
static inline ffi_cif cif_;
|
43
|
+
static inline ffi_closure* closure_ = nullptr;
|
44
|
+
static inline Callback_T* callback_ = nullptr;
|
45
|
+
static inline std::unique_ptr<MethodInfo> methodInfo_ = std::make_unique<MethodInfo>();
|
46
|
+
|
47
|
+
template<std::size_t... I>
|
48
|
+
Return_T callRuby(std::index_sequence<I...>& indices, Arg_Ts...args);
|
49
|
+
private:
|
50
|
+
VALUE proc_;
|
51
|
+
};
|
52
|
+
}
|
53
|
+
#endif // HAVE_LIBFFI
|
54
|
+
|
55
|
+
#endif // Rice__detail__Native_Callback_Ffi_hpp_
|
@@ -0,0 +1,151 @@
|
|
1
|
+
#ifdef HAVE_LIBFFI
|
2
|
+
#include <ffi.h>
|
3
|
+
|
4
|
+
namespace Rice::detail
|
5
|
+
{
|
6
|
+
template<typename Return_T, typename ...Arg_Ts>
|
7
|
+
template<typename Arg_T>
|
8
|
+
ffi_type* NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::ffiType()
|
9
|
+
{
|
10
|
+
std::map<std::type_index, ffi_type*> nativeToFfiMapping = {
|
11
|
+
{std::type_index(typeid(bool)), &ffi_type_uint8},
|
12
|
+
{std::type_index(typeid(bool)), &ffi_type_uint8},
|
13
|
+
{std::type_index(typeid(char)), &ffi_type_schar},
|
14
|
+
{std::type_index(typeid(unsigned char)), &ffi_type_uchar},
|
15
|
+
{std::type_index(typeid(signed char)), &ffi_type_schar},
|
16
|
+
{std::type_index(typeid(uint8_t)), &ffi_type_uint8},
|
17
|
+
{std::type_index(typeid(unsigned short)), &ffi_type_uint8},
|
18
|
+
{std::type_index(typeid(int8_t)), &ffi_type_sint8},
|
19
|
+
{std::type_index(typeid(short)), &ffi_type_sint8},
|
20
|
+
{std::type_index(typeid(uint16_t)), &ffi_type_uint16},
|
21
|
+
{std::type_index(typeid(int16_t)), &ffi_type_sint16},
|
22
|
+
{std::type_index(typeid(uint32_t)), &ffi_type_uint32},
|
23
|
+
{std::type_index(typeid(unsigned int)), &ffi_type_uint32},
|
24
|
+
{std::type_index(typeid(signed int)), &ffi_type_uint32},
|
25
|
+
{std::type_index(typeid(int32_t)), &ffi_type_sint32},
|
26
|
+
{std::type_index(typeid(uint64_t)), &ffi_type_uint64},
|
27
|
+
{std::type_index(typeid(unsigned long long)), &ffi_type_uint64},
|
28
|
+
{std::type_index(typeid(int64_t)), &ffi_type_sint64},
|
29
|
+
{std::type_index(typeid(signed long long)), &ffi_type_sint64},
|
30
|
+
{std::type_index(typeid(float)), &ffi_type_float},
|
31
|
+
{std::type_index(typeid(double)), &ffi_type_double},
|
32
|
+
{std::type_index(typeid(void)), &ffi_type_pointer},
|
33
|
+
{std::type_index(typeid(long double)), &ffi_type_longdouble}
|
34
|
+
};
|
35
|
+
|
36
|
+
if (sizeof(long) == 32)
|
37
|
+
{
|
38
|
+
nativeToFfiMapping[std::type_index(typeid(unsigned long))] = &ffi_type_uint32;
|
39
|
+
nativeToFfiMapping[std::type_index(typeid(long))] = &ffi_type_sint32;
|
40
|
+
}
|
41
|
+
else if (sizeof(long) == 64)
|
42
|
+
{
|
43
|
+
nativeToFfiMapping[std::type_index(typeid(unsigned long))] = &ffi_type_uint64;
|
44
|
+
nativeToFfiMapping[std::type_index(typeid(long))] = &ffi_type_sint64;
|
45
|
+
}
|
46
|
+
|
47
|
+
if (std::is_pointer_v<Arg_T>)
|
48
|
+
{
|
49
|
+
return &ffi_type_pointer;
|
50
|
+
}
|
51
|
+
else
|
52
|
+
{
|
53
|
+
const std::type_index& key = std::type_index(typeid(Arg_T));
|
54
|
+
return nativeToFfiMapping[key];
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
template<typename Return_T, typename ...Arg_Ts>
|
59
|
+
template<std::size_t... I>
|
60
|
+
typename NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::Tuple_T NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::convertArgsToTuple(void* args[], std::index_sequence<I...>& indices)
|
61
|
+
{
|
62
|
+
/* Loop over each value returned from Ruby and convert it to the appropriate C++ type based
|
63
|
+
on the arguments (Arg_Ts) required by the C++ function. Arg_T may have const/volatile while
|
64
|
+
the associated From_Ruby<T> template parameter will not. Thus From_Ruby produces non-const values
|
65
|
+
which we let the compiler convert to const values as needed. This works except for
|
66
|
+
T** -> const T**, see comment in getNativeValue method. */
|
67
|
+
return std::forward_as_tuple(*(std::tuple_element_t<I, Tuple_T>*)(args[I])...);
|
68
|
+
}
|
69
|
+
|
70
|
+
template<typename Return_T, typename ...Arg_Ts>
|
71
|
+
void NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::ffiCallback(ffi_cif* cif, void* ret, void* args[], void* instance)
|
72
|
+
{
|
73
|
+
using Self_T = NativeCallbackFFI<Return_T(*)(Arg_Ts...)>;
|
74
|
+
Self_T* self = (Self_T*)instance;
|
75
|
+
|
76
|
+
auto indices = std::make_index_sequence<sizeof...(Arg_Ts)>{};
|
77
|
+
|
78
|
+
if constexpr (sizeof...(Arg_Ts) == 0)
|
79
|
+
{
|
80
|
+
*(Return_T*)ret = self->operator()();
|
81
|
+
}
|
82
|
+
else
|
83
|
+
{
|
84
|
+
std::tuple<Arg_Ts...> tuple = convertArgsToTuple(args, indices);
|
85
|
+
*(Return_T*)ret = std::apply(*self, tuple);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
template<typename Return_T, typename ...Arg_Ts>
|
90
|
+
void NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::setMethodInfo(MethodInfo* methodInfo)
|
91
|
+
{
|
92
|
+
methodInfo_.reset(methodInfo);
|
93
|
+
}
|
94
|
+
|
95
|
+
template<typename Return_T, typename ...Arg_Ts>
|
96
|
+
NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::~NativeCallbackFFI()
|
97
|
+
{
|
98
|
+
this->proc_ = Qnil;
|
99
|
+
}
|
100
|
+
|
101
|
+
template<typename Return_T, typename ...Arg_Ts>
|
102
|
+
VALUE NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::finalizerCallback(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg)
|
103
|
+
{
|
104
|
+
using NativeCallback_T = NativeCallbackFFI<Return_T(*)(Arg_Ts...)>;
|
105
|
+
NativeCallback_T* nativeCallback = (NativeCallback_T*)callback_arg;
|
106
|
+
delete nativeCallback;
|
107
|
+
return Qnil;
|
108
|
+
}
|
109
|
+
|
110
|
+
template<typename Return_T, typename ...Arg_Ts>
|
111
|
+
NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::NativeCallbackFFI(VALUE proc) : proc_(proc)
|
112
|
+
{
|
113
|
+
// First setup desccription of callback
|
114
|
+
if (cif_.bytes == 0)
|
115
|
+
{
|
116
|
+
ffi_prep_cif(&cif_, FFI_DEFAULT_ABI, sizeof...(Arg_Ts), &ffi_type_pointer, args_.data());
|
117
|
+
}
|
118
|
+
|
119
|
+
// Create FFI closure
|
120
|
+
this->closure_ = (ffi_closure *)ffi_closure_alloc(sizeof(ffi_closure) + sizeof(void*), (void**)(&this->callback_));
|
121
|
+
ffi_prep_closure_loc(this->closure_, &cif_, ffiCallback, (void*)this, (void*)this->callback_);
|
122
|
+
}
|
123
|
+
|
124
|
+
template<typename Return_T, typename ...Arg_Ts>
|
125
|
+
typename NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::Callback_T* NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::callback()
|
126
|
+
{
|
127
|
+
return (Callback_T*)this->callback_;
|
128
|
+
}
|
129
|
+
|
130
|
+
template<typename Return_T, typename ...Arg_Ts>
|
131
|
+
template<std::size_t... I>
|
132
|
+
Return_T NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::callRuby(std::index_sequence<I...>& indices, Arg_Ts...args)
|
133
|
+
{
|
134
|
+
static Identifier id("call");
|
135
|
+
std::array<VALUE, sizeof...(Arg_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Arg_Ts>>(methodInfo_->arg(I)).convert(args)... };
|
136
|
+
VALUE result = detail::protect(rb_funcallv, this->proc_, id.id(), (int)sizeof...(Arg_Ts), values.data());
|
137
|
+
if constexpr (!std::is_void_v<Return_T>)
|
138
|
+
{
|
139
|
+
static From_Ruby<Return_T> fromRuby(dynamic_cast<Arg*>(&methodInfo_->returnInfo));
|
140
|
+
return fromRuby.convert(result);
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
template<typename Return_T, typename ...Arg_Ts>
|
145
|
+
Return_T NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::operator()(Arg_Ts...args)
|
146
|
+
{
|
147
|
+
auto indices = std::make_index_sequence<sizeof...(Arg_Ts)>{};
|
148
|
+
return NativeCallbackFFI<Return_T(*)(Arg_Ts...)>::callRuby(indices, args...);
|
149
|
+
}
|
150
|
+
}
|
151
|
+
#endif // HAVE_LIBFFI
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#ifndef Rice__detail__Native_Callback_Simple_hpp_
|
2
|
+
#define Rice__detail__Native_Callback_Simple_hpp_
|
3
|
+
|
4
|
+
namespace Rice::detail
|
5
|
+
{
|
6
|
+
template<typename Callback_T>
|
7
|
+
class NativeCallbackSimple;
|
8
|
+
|
9
|
+
template<typename Return_T, typename ...Arg_Ts>
|
10
|
+
class NativeCallbackSimple<Return_T(*)(Arg_Ts...)>
|
11
|
+
{
|
12
|
+
public:
|
13
|
+
static Return_T callback(Arg_Ts...args);
|
14
|
+
static inline VALUE proc = Qnil;
|
15
|
+
static void setMethodInfo(MethodInfo* methodInfo);
|
16
|
+
|
17
|
+
public:
|
18
|
+
NativeCallbackSimple() = delete;
|
19
|
+
NativeCallbackSimple(const NativeCallbackSimple&) = delete;
|
20
|
+
NativeCallbackSimple(NativeCallbackSimple&&) = delete;
|
21
|
+
void operator=(const NativeCallbackSimple&) = delete;
|
22
|
+
void operator=(NativeCallbackSimple&&) = delete;
|
23
|
+
|
24
|
+
private:
|
25
|
+
template<std::size_t... I>
|
26
|
+
static Return_T callRuby(std::index_sequence<I...>& indices, Arg_Ts...args);
|
27
|
+
static inline std::unique_ptr<MethodInfo> methodInfo_ = std::make_unique<MethodInfo>();
|
28
|
+
};
|
29
|
+
}
|
30
|
+
#endif // Rice__detail__Native_Callback_Simple_hpp_
|
@@ -0,0 +1,29 @@
|
|
1
|
+
namespace Rice::detail
|
2
|
+
{
|
3
|
+
template<typename Return_T, typename ...Arg_Ts>
|
4
|
+
void NativeCallbackSimple<Return_T(*)(Arg_Ts...)>::setMethodInfo(MethodInfo* methodInfo)
|
5
|
+
{
|
6
|
+
methodInfo_.reset(methodInfo);
|
7
|
+
}
|
8
|
+
|
9
|
+
template<typename Return_T, typename ...Arg_Ts>
|
10
|
+
template<std::size_t... I>
|
11
|
+
Return_T NativeCallbackSimple<Return_T(*)(Arg_Ts...)>::callRuby(std::index_sequence<I...>& indices, Arg_Ts...args)
|
12
|
+
{
|
13
|
+
static Identifier id("call");
|
14
|
+
std::array<VALUE, sizeof...(Arg_Ts)> values = { detail::To_Ruby<detail::remove_cv_recursive_t<Arg_Ts>>(methodInfo_->arg(I)).convert(args)... };
|
15
|
+
VALUE result = detail::protect(rb_funcallv, proc, id.id(), (int)sizeof...(Arg_Ts), values.data());
|
16
|
+
if constexpr (!std::is_void_v<Return_T>)
|
17
|
+
{
|
18
|
+
static From_Ruby<Return_T> fromRuby(dynamic_cast<Arg*>(&methodInfo_->returnInfo));
|
19
|
+
return fromRuby.convert(result);
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
template<typename Return_T, typename ...Arg_Ts>
|
24
|
+
Return_T NativeCallbackSimple<Return_T(*)(Arg_Ts...)>::callback(Arg_Ts...args)
|
25
|
+
{
|
26
|
+
auto indices = std::make_index_sequence<sizeof...(Arg_Ts)>{};
|
27
|
+
return NativeCallbackSimple<Return_T(*)(Arg_Ts...)>::callRuby(indices, args...);
|
28
|
+
}
|
29
|
+
}
|
@@ -1,13 +1,6 @@
|
|
1
1
|
#ifndef Rice__detail__Native_Function__hpp_
|
2
2
|
#define Rice__detail__Native_Function__hpp_
|
3
3
|
|
4
|
-
#include "ruby.hpp"
|
5
|
-
#include "ExceptionHandler_defn.hpp"
|
6
|
-
#include "MethodInfo.hpp"
|
7
|
-
#include "../traits/function_traits.hpp"
|
8
|
-
#include "../traits/method_traits.hpp"
|
9
|
-
#include "from_ruby.hpp"
|
10
|
-
|
11
4
|
namespace Rice::detail
|
12
5
|
{
|
13
6
|
//! The NativeFunction class calls C++ functions/methods/lambdas on behalf of Ruby
|
@@ -43,24 +36,26 @@ namespace Rice::detail
|
|
43
36
|
*/
|
44
37
|
|
45
38
|
template<typename Class_T, typename Function_T, bool IsMethod>
|
46
|
-
class NativeFunction
|
39
|
+
class NativeFunction: Native
|
47
40
|
{
|
48
41
|
public:
|
49
42
|
using NativeFunction_T = NativeFunction<Class_T, Function_T, IsMethod>;
|
50
43
|
|
51
44
|
// We remove const to avoid an explosion of To_Ruby specializations and Ruby doesn't
|
52
45
|
// have the concept of constants anyways
|
53
|
-
using Return_T =
|
46
|
+
using Return_T = typename function_traits<Function_T>::return_type;
|
54
47
|
using Receiver_T = typename method_traits<Function_T, IsMethod>::Class_T;
|
55
48
|
using Arg_Ts = typename method_traits<Function_T, IsMethod>::Arg_Ts;
|
49
|
+
static constexpr std::size_t arity = method_traits<Function_T, IsMethod>::arity;
|
56
50
|
using From_Ruby_Args_Ts = typename tuple_map<From_Ruby, Arg_Ts>::type;
|
51
|
+
using To_Ruby_T = remove_cv_recursive_t<Return_T>;
|
57
52
|
|
58
53
|
// Register function with Ruby
|
59
54
|
static void define(VALUE klass, std::string method_name, Function_T function, MethodInfo* methodInfo);
|
60
55
|
|
61
|
-
//
|
62
|
-
static VALUE
|
63
|
-
|
56
|
+
// Proc entry
|
57
|
+
static VALUE procEntry(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg);
|
58
|
+
static VALUE finalizerCallback(VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE* argv, VALUE blockarg);
|
64
59
|
public:
|
65
60
|
// Disallow creating/copying/moving
|
66
61
|
NativeFunction() = delete;
|
@@ -69,13 +64,25 @@ namespace Rice::detail
|
|
69
64
|
void operator=(const NativeFunction_T&) = delete;
|
70
65
|
void operator=(NativeFunction_T&&) = delete;
|
71
66
|
|
72
|
-
|
73
|
-
VALUE operator()(
|
67
|
+
Resolved matches(size_t argc, const VALUE* argv, VALUE self) override;
|
68
|
+
VALUE operator()(size_t argc, const VALUE* argv, VALUE self) override;
|
69
|
+
std::string toString() override;
|
74
70
|
|
75
|
-
|
71
|
+
NativeFunction(Function_T function);
|
76
72
|
NativeFunction(VALUE klass, std::string method_name, Function_T function, MethodInfo* methodInfo);
|
77
73
|
|
74
|
+
protected:
|
75
|
+
|
78
76
|
private:
|
77
|
+
template<int I>
|
78
|
+
Convertible matchParameter(std::vector<std::optional<VALUE>>& value);
|
79
|
+
|
80
|
+
template<std::size_t...I>
|
81
|
+
Convertible matchParameters(std::vector<std::optional<VALUE>>& values, std::index_sequence<I...>& indices);
|
82
|
+
|
83
|
+
template<std::size_t...I>
|
84
|
+
std::vector<std::string> argTypeNames(std::ostringstream& stream, std::index_sequence<I...>& indices);
|
85
|
+
|
79
86
|
template<typename T, std::size_t I>
|
80
87
|
From_Ruby<T> createFromRuby();
|
81
88
|
|
@@ -83,14 +90,18 @@ namespace Rice::detail
|
|
83
90
|
template<std::size_t...I>
|
84
91
|
From_Ruby_Args_Ts createFromRuby(std::index_sequence<I...>& indices);
|
85
92
|
|
86
|
-
|
93
|
+
// Convert C++ value to Ruby
|
94
|
+
To_Ruby<To_Ruby_T> createToRuby();
|
87
95
|
|
88
96
|
// Convert Ruby argv pointer to Ruby values
|
89
|
-
std::vector<VALUE
|
97
|
+
std::vector<std::optional<VALUE>> getRubyValues(size_t argc, const VALUE* argv, bool validate);
|
98
|
+
|
99
|
+
template<typename Arg_T, int I>
|
100
|
+
Arg_T getNativeValue(std::vector<std::optional<VALUE>>& values);
|
90
101
|
|
91
102
|
// Convert Ruby values to C++ values
|
92
103
|
template<typename std::size_t...I>
|
93
|
-
Arg_Ts getNativeValues(std::vector<VALUE
|
104
|
+
Arg_Ts getNativeValues(std::vector<std::optional<VALUE>>& values, std::index_sequence<I...>& indices);
|
94
105
|
|
95
106
|
// Figure out what self is
|
96
107
|
Receiver_T getReceiver(VALUE self);
|
@@ -99,21 +110,20 @@ namespace Rice::detail
|
|
99
110
|
[[noreturn]] void noWrapper(const VALUE klass, const std::string& wrapper);
|
100
111
|
|
101
112
|
// Do we need to keep alive any arguments?
|
102
|
-
void checkKeepAlive(VALUE self, VALUE returnValue, std::vector<VALUE
|
113
|
+
void checkKeepAlive(VALUE self, VALUE returnValue, std::vector<std::optional<VALUE>>& rubyValues);
|
103
114
|
|
104
115
|
// Call the underlying C++ function
|
105
|
-
VALUE invokeNativeFunction(
|
106
|
-
VALUE invokeNativeMethod(VALUE self,
|
116
|
+
VALUE invokeNativeFunction(Arg_Ts&& nativeArgs);
|
117
|
+
VALUE invokeNativeMethod(VALUE self, Arg_Ts&& nativeArgs);
|
107
118
|
|
108
119
|
private:
|
109
120
|
VALUE klass_;
|
110
121
|
std::string method_name_;
|
111
122
|
Function_T function_;
|
112
123
|
From_Ruby_Args_Ts fromRubys_;
|
113
|
-
To_Ruby<
|
124
|
+
To_Ruby<To_Ruby_T> toRuby_;
|
114
125
|
std::unique_ptr<MethodInfo> methodInfo_;
|
115
126
|
};
|
116
127
|
}
|
117
|
-
#include "NativeFunction.ipp"
|
118
128
|
|
119
129
|
#endif // Rice__detail__Native_Function__hpp_
|