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
@@ -2,34 +2,21 @@
|
|
2
2
|
#include <functional>
|
3
3
|
#include <type_traits>
|
4
4
|
|
5
|
-
#include "cpp_protect.hpp"
|
6
|
-
#include "NativeRegistry.hpp"
|
7
|
-
|
8
5
|
namespace Rice::detail
|
9
6
|
{
|
10
7
|
template <typename T, typename Iterator_Func_T>
|
11
8
|
inline void NativeIterator<T, Iterator_Func_T>::define(VALUE klass, std::string method_name, Iterator_Func_T begin, Iterator_Func_T end)
|
12
9
|
{
|
13
|
-
// Tell Ruby to invoke the static method
|
14
|
-
detail::protect(rb_define_method, klass, method_name.c_str(), (RUBY_METHOD_FUNC)&
|
15
|
-
|
16
|
-
// Now create a NativeIterator instance and save it to the natives registry keyed on
|
17
|
-
// Ruby klass and method id. There may be multiple NativeIterator instances
|
18
|
-
// because the same C++ method could be mapped to multiple Ruby methods.
|
19
|
-
NativeIterator_T* native = new NativeIterator_T(klass, method_name, begin, end);
|
20
|
-
detail::Registries::instance.natives.add(klass, Identifier(method_name).id(), native);
|
21
|
-
}
|
10
|
+
// Tell Ruby to invoke the resolveIterator static method defined in Native super class.
|
11
|
+
detail::protect(rb_define_method, klass, method_name.c_str(), (RUBY_METHOD_FUNC)&Native::resolve, -1);
|
22
12
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
NativeIterator_T* nativeIterator = detail::Registries::instance.natives.lookup<NativeIterator_T*>();
|
13
|
+
// Create a NativeIterator instance and save it to the NativeRegistry. There may be multiple
|
14
|
+
// NativeFunction instances for a specific method because C++ supports method overloading.
|
15
|
+
NativeIterator_T* nativeIterator = new NativeIterator_T(klass, method_name, begin, end);
|
16
|
+
std::unique_ptr<Native> native(nativeIterator);
|
28
17
|
|
29
|
-
|
30
|
-
|
31
|
-
return nativeIterator->operator()(self);
|
32
|
-
});
|
18
|
+
Identifier identifier(method_name);
|
19
|
+
detail::Registries::instance.natives.add(klass, identifier.id(), native);
|
33
20
|
}
|
34
21
|
|
35
22
|
template <typename T, typename Iterator_Func_T>
|
@@ -38,6 +25,12 @@ namespace Rice::detail
|
|
38
25
|
{
|
39
26
|
}
|
40
27
|
|
28
|
+
template<typename T, typename Iterator_Func_T>
|
29
|
+
inline Resolved NativeIterator<T, Iterator_Func_T>::matches(size_t argc, const VALUE* argv, VALUE self)
|
30
|
+
{
|
31
|
+
return Resolved{ Convertible::Exact, 1.0, this };
|
32
|
+
}
|
33
|
+
|
41
34
|
template<typename T, typename Iterator_Func_T>
|
42
35
|
inline VALUE NativeIterator<T, Iterator_Func_T>::createRubyEnumerator(VALUE self)
|
43
36
|
{
|
@@ -48,12 +41,13 @@ namespace Rice::detail
|
|
48
41
|
return cpp_protect([&]
|
49
42
|
{
|
50
43
|
// Get the iterator instance
|
51
|
-
using Iter_T = NativeIterator<T, Iterator_Func_T>;
|
52
44
|
// Class is easy
|
53
45
|
VALUE klass = protect(rb_class_of, recv);
|
54
46
|
// Read the method_id from an attribute we added to the enumerator instance
|
55
|
-
|
56
|
-
|
47
|
+
Identifier identifier = protect(rb_ivar_get, eobj, rb_intern("rice_method"));
|
48
|
+
|
49
|
+
const std::vector<std::unique_ptr<Native>>& natives = detail::Registries::instance.natives.lookup(klass, identifier.id());
|
50
|
+
NativeIterator_T* iterator = static_cast<NativeIterator_T*>(natives.back().get());
|
57
51
|
|
58
52
|
// Get the wrapped C++ instance
|
59
53
|
T* receiver = detail::From_Ruby<T*>().convert(recv);
|
@@ -67,19 +61,18 @@ namespace Rice::detail
|
|
67
61
|
});
|
68
62
|
};
|
69
63
|
|
70
|
-
|
71
|
-
VALUE enumerator = protect(rb_enumeratorize_with_size, self,
|
64
|
+
Identifier identifier(this->method_name_);
|
65
|
+
VALUE enumerator = protect(rb_enumeratorize_with_size, self, identifier.to_sym(), 0, nullptr, rb_size_function);
|
72
66
|
|
73
67
|
// Hack the enumerator object by storing name_ on the enumerator object so
|
74
68
|
// the rb_size_function above has access to it
|
75
|
-
|
76
|
-
protect(rb_ivar_set, enumerator, rb_intern("rice_method"), method_id);
|
69
|
+
protect(rb_ivar_set, enumerator, rb_intern("rice_method"), identifier.id());
|
77
70
|
|
78
71
|
return enumerator;
|
79
72
|
}
|
80
73
|
|
81
74
|
template<typename T, typename Iterator_Func_T>
|
82
|
-
inline VALUE NativeIterator<T, Iterator_Func_T>::operator()(VALUE self)
|
75
|
+
inline VALUE NativeIterator<T, Iterator_Func_T>::operator()(size_t argc, const VALUE* argv, VALUE self)
|
83
76
|
{
|
84
77
|
if (!protect(rb_block_given_p))
|
85
78
|
{
|
@@ -87,16 +80,25 @@ namespace Rice::detail
|
|
87
80
|
}
|
88
81
|
else
|
89
82
|
{
|
90
|
-
|
83
|
+
detail::From_Ruby<T*> fromRuby;
|
84
|
+
T* receiver = fromRuby.convert(self);
|
85
|
+
|
91
86
|
Iterator_T it = std::invoke(this->begin_, *receiver);
|
92
87
|
Iterator_T end = std::invoke(this->end_, *receiver);
|
93
88
|
|
89
|
+
detail::To_Ruby<To_Ruby_T> toRuby;
|
94
90
|
for (; it != end; ++it)
|
95
91
|
{
|
96
|
-
protect(rb_yield,
|
92
|
+
protect(rb_yield, toRuby.convert(*it));
|
97
93
|
}
|
98
94
|
|
99
95
|
return self;
|
100
96
|
}
|
101
97
|
}
|
98
|
+
|
99
|
+
template<typename T, typename Iterator_Func_T>
|
100
|
+
inline std::string NativeIterator<T, Iterator_Func_T>::toString()
|
101
|
+
{
|
102
|
+
return "";
|
103
|
+
}
|
102
104
|
}
|
@@ -1,30 +1,39 @@
|
|
1
1
|
#ifndef Rice__detail__NativeRegistry__hpp
|
2
2
|
#define Rice__detail__NativeRegistry__hpp
|
3
3
|
|
4
|
-
#include <
|
5
|
-
#include <
|
6
|
-
|
7
|
-
#include "ruby.hpp"
|
4
|
+
#include <map>
|
5
|
+
#include <memory>
|
6
|
+
#include <utility>
|
8
7
|
|
8
|
+
/* The Native Registry tracks C++ instance that are used to invoke C++ methods for Ruby.
|
9
|
+
These objects include instances of the NativeFunction, NativeIterator, NativeAttributeGet
|
10
|
+
and NativeAttributeSet Each instance is specialized to call a specific C++ function, method
|
11
|
+
or attribute that is exposed to Ruby.
|
12
|
+
|
13
|
+
The registry stores these C++ instances using a map of vectors. The map is keyed on the
|
14
|
+
the Ruby class (VALUE) and method id (ID). The value is a vector of Native pointers stored
|
15
|
+
in a std::unique_ptr. Thus the registry takes ownership of the pointers when calling
|
16
|
+
code adds them to the registry. The value is a vector to support C++ method overloading.
|
17
|
+
|
18
|
+
Note - when an existing Ruby class is redefined using rb_define_class, its VALUE stays the same
|
19
|
+
but all its methods and fields are reset. Thus any call to rb_define_class must be followed
|
20
|
+
by calling the reset method on the registry. Although redefinition shouldn't happen in
|
21
|
+
production code it happens in many places in the unit tests. */
|
22
|
+
|
9
23
|
namespace Rice::detail
|
10
24
|
{
|
11
25
|
class NativeRegistry
|
12
26
|
{
|
13
27
|
public:
|
14
|
-
|
15
|
-
void
|
16
|
-
|
17
|
-
// Returns the Rice data for the currently active Ruby method
|
18
|
-
template <typename Return_T>
|
19
|
-
Return_T lookup();
|
20
|
-
|
21
|
-
template <typename Return_T>
|
22
|
-
Return_T lookup(VALUE klass, ID method_id);
|
28
|
+
void add(VALUE klass, ID methodId, std::unique_ptr<Native>& native);
|
29
|
+
void reset(VALUE klass);
|
30
|
+
const std::vector<std::unique_ptr<Native>>& lookup(VALUE klass, ID methodId);
|
23
31
|
|
24
32
|
private:
|
25
|
-
|
33
|
+
// Key - Ruby klass/method
|
34
|
+
// Value - Vector of Native pointers owned by the registry (thus wrapped in std::unique_ptr)
|
35
|
+
std::map<std::pair<VALUE, ID>, std::vector<std::unique_ptr<Native>>> natives_ = {};
|
26
36
|
};
|
27
37
|
}
|
28
|
-
#include "NativeRegistry.ipp"
|
29
38
|
|
30
39
|
#endif // Rice__detail__NativeRegistry__hpp
|
@@ -1,74 +1,49 @@
|
|
1
1
|
|
2
|
-
// Ruby 2.7 now includes a similarly named macro that uses templates to
|
3
|
-
// pick the right overload for the underlying function. That doesn't work
|
4
|
-
// for our cases because we are using this method dynamically and get a
|
5
|
-
// compilation error otherwise. This removes the macro and lets us fall
|
6
|
-
// back to the C-API underneath again.
|
7
|
-
#undef rb_define_method_id
|
8
|
-
|
9
|
-
#include "RubyFunction.hpp"
|
10
|
-
|
11
2
|
namespace Rice::detail
|
12
3
|
{
|
13
|
-
inline void NativeRegistry::add(VALUE klass, ID
|
4
|
+
inline void NativeRegistry::add(VALUE klass, ID methodId, std::unique_ptr<Native>& native)
|
14
5
|
{
|
15
6
|
if (rb_type(klass) == T_ICLASS)
|
16
7
|
{
|
17
8
|
klass = detail::protect(rb_class_of, klass);
|
18
9
|
}
|
19
10
|
|
20
|
-
|
21
|
-
|
22
|
-
{
|
23
|
-
const auto [k, d] = it->second;
|
11
|
+
// Create the key
|
12
|
+
std::pair<VALUE, ID> key = std::make_pair(klass, methodId);
|
24
13
|
|
25
|
-
|
26
|
-
|
27
|
-
std::get<1>(it->second) = callable;
|
28
|
-
return;
|
29
|
-
}
|
30
|
-
}
|
14
|
+
// Lookup items for method
|
15
|
+
std::vector<std::unique_ptr<Native>>& natives = this->natives_[key];
|
31
16
|
|
32
|
-
|
17
|
+
natives.push_back(std::move(native));
|
33
18
|
}
|
34
19
|
|
35
|
-
|
36
|
-
inline Return_T NativeRegistry::lookup()
|
20
|
+
inline void NativeRegistry::reset(VALUE klass)
|
37
21
|
{
|
38
|
-
|
39
|
-
VALUE klass;
|
40
|
-
if (!rb_frame_method_id_and_class(&method_id, &klass))
|
22
|
+
for (auto iter = this->natives_.begin(); iter != this->natives_.end();)
|
41
23
|
{
|
42
|
-
|
24
|
+
// Iter points to a std::pair<std::pair<VALUE, ID>, std::vector<NativeRegistryItem>
|
25
|
+
if (iter->first.first == klass)
|
26
|
+
{
|
27
|
+
iter = this->natives_.erase(iter);
|
28
|
+
}
|
29
|
+
else
|
30
|
+
{
|
31
|
+
++iter;
|
32
|
+
}
|
43
33
|
}
|
44
|
-
|
45
|
-
return this->lookup<Return_T>(klass, method_id);
|
46
34
|
}
|
47
|
-
|
48
|
-
|
49
|
-
inline Return_T NativeRegistry::lookup(VALUE klass, ID method_id)
|
35
|
+
|
36
|
+
inline const std::vector<std::unique_ptr<Native>>& NativeRegistry::lookup(VALUE klass, ID methodId)
|
50
37
|
{
|
51
38
|
if (rb_type(klass) == T_ICLASS)
|
52
39
|
{
|
53
40
|
klass = detail::protect(rb_class_of, klass);
|
54
41
|
}
|
55
42
|
|
56
|
-
|
57
|
-
|
58
|
-
{
|
59
|
-
const auto [k, d] = it->second;
|
60
|
-
|
61
|
-
if (k == klass)
|
62
|
-
{
|
63
|
-
auto* ptr = std::any_cast<Return_T>(&d);
|
64
|
-
if (!ptr)
|
65
|
-
{
|
66
|
-
rb_raise(rb_eRuntimeError, "Unexpected return type for %s#%s", rb_class2name(klass), rb_id2name(method_id));
|
67
|
-
}
|
68
|
-
return *ptr;
|
69
|
-
}
|
70
|
-
}
|
43
|
+
// Create the key
|
44
|
+
std::pair<VALUE, ID> key = std::make_pair(klass, methodId);
|
71
45
|
|
72
|
-
|
46
|
+
// Lookup items for method
|
47
|
+
return this->natives_[key];
|
73
48
|
}
|
74
49
|
}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
namespace Rice::detail
|
2
|
+
{
|
3
|
+
// Note Return_T(Arg_Ts...) is intentional versus Return_T(*)(Arg_Ts...). That is
|
4
|
+
// because the Type machinery strips all pointers/references/const/val etc to avoid
|
5
|
+
// having an explosion of Type definitions
|
6
|
+
template<typename Return_T, typename ...Arg_Ts>
|
7
|
+
struct Type<Return_T(Arg_Ts...)>
|
8
|
+
{
|
9
|
+
static bool verify()
|
10
|
+
{
|
11
|
+
return true;
|
12
|
+
}
|
13
|
+
};
|
14
|
+
|
15
|
+
// Wraps a C++ function as a Ruby proc
|
16
|
+
template<typename Return_T, typename ...Arg_Ts>
|
17
|
+
class To_Ruby<Return_T(*)(Arg_Ts...)>
|
18
|
+
{
|
19
|
+
public:
|
20
|
+
using Proc_T = Return_T(*)(Arg_Ts...);
|
21
|
+
|
22
|
+
VALUE convert(Proc_T proc)
|
23
|
+
{
|
24
|
+
using NativeFunction_T = NativeFunction<void, Proc_T, false>;
|
25
|
+
auto native = new NativeFunction_T(proc);
|
26
|
+
VALUE result = rb_proc_new(NativeFunction_T::procEntry, (VALUE)native);
|
27
|
+
|
28
|
+
// Tie the lifetime of the NativeCallback C++ instance to the lifetime of the Ruby proc object
|
29
|
+
VALUE finalizer = rb_proc_new(NativeFunction_T::finalizerCallback, (VALUE)native);
|
30
|
+
rb_define_finalizer(result, finalizer);
|
31
|
+
|
32
|
+
return result;
|
33
|
+
}
|
34
|
+
};
|
35
|
+
|
36
|
+
// Makes a Ruby proc callable as C callback
|
37
|
+
template<typename Return_T, typename ...Arg_Ts>
|
38
|
+
class From_Ruby<Return_T(*)(Arg_Ts...)>
|
39
|
+
{
|
40
|
+
public:
|
41
|
+
using Callback_T = Return_T(*)(Arg_Ts...);
|
42
|
+
|
43
|
+
From_Ruby() = default;
|
44
|
+
|
45
|
+
explicit From_Ruby(Arg* arg) : arg_(arg)
|
46
|
+
{
|
47
|
+
}
|
48
|
+
|
49
|
+
Convertible is_convertible(VALUE value)
|
50
|
+
{
|
51
|
+
if (protect(rb_obj_is_proc, value) == Qtrue || protect(rb_proc_lambda_p, value))
|
52
|
+
{
|
53
|
+
return Convertible::Exact;
|
54
|
+
}
|
55
|
+
else
|
56
|
+
{
|
57
|
+
return Convertible::None;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
#ifdef HAVE_LIBFFI
|
62
|
+
Callback_T convert(VALUE value)
|
63
|
+
{
|
64
|
+
using NativeCallback_T = NativeCallbackFFI<Return_T(*)(Arg_Ts...)>;
|
65
|
+
NativeCallback_T* nativeCallback = new NativeCallback_T(value);
|
66
|
+
|
67
|
+
// Tie the lifetime of the NativeCallback C++ instance to the lifetime of the Ruby proc object
|
68
|
+
VALUE finalizer = rb_proc_new(NativeCallback_T::finalizerCallback, (VALUE)nativeCallback);
|
69
|
+
rb_define_finalizer(value, finalizer);
|
70
|
+
|
71
|
+
return nativeCallback->callback();
|
72
|
+
}
|
73
|
+
#else
|
74
|
+
Callback_T convert(VALUE value)
|
75
|
+
{
|
76
|
+
using NativeCallback_T = NativeCallbackSimple<Return_T(*)(Arg_Ts...)>;
|
77
|
+
NativeCallback_T::proc = value;
|
78
|
+
return &NativeCallback_T::callback;
|
79
|
+
}
|
80
|
+
#endif
|
81
|
+
|
82
|
+
private:
|
83
|
+
Arg* arg_ = nullptr;
|
84
|
+
};
|
85
|
+
}
|
data/rice/detail/Registries.hpp
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
#ifndef Rice__Registries__hpp_
|
2
2
|
#define Rice__Registries__hpp_
|
3
3
|
|
4
|
-
#include "HandlerRegistry.hpp"
|
5
|
-
#include "InstanceRegistry.hpp"
|
6
|
-
#include "NativeRegistry.hpp"
|
7
|
-
#include "TypeRegistry.hpp"
|
8
|
-
|
9
4
|
namespace Rice::detail
|
10
5
|
{
|
11
6
|
class Registries
|
@@ -21,6 +16,4 @@ namespace Rice::detail
|
|
21
16
|
};
|
22
17
|
}
|
23
18
|
|
24
|
-
#include "Registries.ipp"
|
25
|
-
|
26
19
|
#endif // Rice__Registries__hpp_
|
data/rice/detail/Registries.ipp
CHANGED
@@ -2,22 +2,4 @@ namespace Rice::detail
|
|
2
2
|
{
|
3
3
|
//Initialize static variables here.
|
4
4
|
inline Registries Registries::instance;
|
5
|
-
|
6
|
-
// TODO - Big hack here but this code is dependent on internals
|
7
|
-
template<typename T>
|
8
|
-
bool Type<T>::verify()
|
9
|
-
{
|
10
|
-
// Use intrinsic_type so that we don't have to define specializations
|
11
|
-
// for pointers, references, const, etc.
|
12
|
-
using Intrinsic_T = intrinsic_type<T>;
|
13
|
-
|
14
|
-
if constexpr (std::is_fundamental_v<Intrinsic_T>)
|
15
|
-
{
|
16
|
-
return true;
|
17
|
-
}
|
18
|
-
else
|
19
|
-
{
|
20
|
-
return Registries::instance.types.verifyDefined<Intrinsic_T>();
|
21
|
-
}
|
22
|
-
}
|
23
5
|
}
|
@@ -1,8 +1,6 @@
|
|
1
1
|
#ifndef Rice__detail__ruby_function__hpp_
|
2
2
|
#define Rice__detail__ruby_function__hpp_
|
3
3
|
|
4
|
-
#include "ruby.hpp"
|
5
|
-
|
6
4
|
namespace Rice::detail
|
7
5
|
{
|
8
6
|
/* This is functor class that wraps calls to a Ruby C API method. It is needed because
|
@@ -29,6 +27,5 @@ namespace Rice::detail
|
|
29
27
|
template<typename Function_T, typename ...Arg_Ts>
|
30
28
|
auto protect(Function_T func, Arg_Ts...args);
|
31
29
|
}
|
32
|
-
#include "RubyFunction.ipp"
|
33
30
|
|
34
31
|
#endif // Rice__detail__ruby_function__hpp_
|
@@ -1,5 +1,3 @@
|
|
1
|
-
#include "Jump_Tag.hpp"
|
2
|
-
#include "../Exception_defn.hpp"
|
3
1
|
|
4
2
|
#include <any>
|
5
3
|
|
@@ -14,9 +12,6 @@ namespace Rice::detail
|
|
14
12
|
template<typename Function_T, typename...Arg_Ts>
|
15
13
|
inline typename RubyFunction<Function_T, Arg_Ts...>::Return_T RubyFunction<Function_T, Arg_Ts...>::operator()()
|
16
14
|
{
|
17
|
-
const int TAG_RAISE = 0x6; // From Ruby header files
|
18
|
-
int state = 0;
|
19
|
-
|
20
15
|
// Setup a thread local variable to capture the result of the Ruby function call.
|
21
16
|
// We use thread_local because the lambda has to be captureless so it can
|
22
17
|
// be converted to a function pointer callable by C.
|
@@ -45,10 +40,11 @@ namespace Rice::detail
|
|
45
40
|
};
|
46
41
|
|
47
42
|
// Now call rb_protect which will invoke the callback lambda above
|
43
|
+
int state = (int)JumpException::RUBY_TAG_NONE;
|
48
44
|
rb_protect(callback, (VALUE)this, &state);
|
49
45
|
|
50
46
|
// Did anything go wrong?
|
51
|
-
if (state ==
|
47
|
+
if (state == JumpException::RUBY_TAG_NONE)
|
52
48
|
{
|
53
49
|
if constexpr (!std::is_same_v<Return_T, void>)
|
54
50
|
{
|
@@ -58,14 +54,14 @@ namespace Rice::detail
|
|
58
54
|
else
|
59
55
|
{
|
60
56
|
VALUE err = rb_errinfo();
|
61
|
-
if (state ==
|
57
|
+
if (state == JumpException::RUBY_TAG_RAISE && RB_TEST(err))
|
62
58
|
{
|
63
59
|
rb_set_errinfo(Qnil);
|
64
60
|
throw Rice::Exception(err);
|
65
61
|
}
|
66
62
|
else
|
67
63
|
{
|
68
|
-
throw
|
64
|
+
throw Rice::JumpException((Rice::JumpException::ruby_tag_type)state);
|
69
65
|
}
|
70
66
|
}
|
71
67
|
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#ifndef Rice__detail__ruby__type__hpp_
|
2
|
+
#define Rice__detail__ruby__type__hpp_
|
3
|
+
|
4
|
+
#include <set>
|
5
|
+
|
6
|
+
namespace Rice::detail
|
7
|
+
{
|
8
|
+
template <typename T>
|
9
|
+
class RubyType
|
10
|
+
{
|
11
|
+
};
|
12
|
+
|
13
|
+
void define_ruby_types();
|
14
|
+
}
|
15
|
+
|
16
|
+
#endif // Rice__detail__ruby__type__hpp_
|