jameskilton-rice 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (196) hide show
  1. data/COPYING +23 -0
  2. data/Doxyfile +1253 -0
  3. data/Makefile.am +26 -0
  4. data/Makefile.in +749 -0
  5. data/README +879 -0
  6. data/README.mingw +8 -0
  7. data/Rakefile +72 -0
  8. data/aclocal.m4 +891 -0
  9. data/bootstrap +8 -0
  10. data/config.guess +1526 -0
  11. data/config.sub +1658 -0
  12. data/configure +7668 -0
  13. data/configure.ac +52 -0
  14. data/depcomp +589 -0
  15. data/doxygen.ac +314 -0
  16. data/doxygen.am +186 -0
  17. data/extconf.rb +22 -0
  18. data/install-sh +519 -0
  19. data/missing +367 -0
  20. data/post-autoconf.rb +22 -0
  21. data/post-automake.rb +28 -0
  22. data/rice/Address_Registration_Guard.hpp +7 -0
  23. data/rice/Address_Registration_Guard.ipp +34 -0
  24. data/rice/Address_Registration_Guard_defn.hpp +65 -0
  25. data/rice/Allocation_Strategies.hpp +37 -0
  26. data/rice/Arg.hpp +8 -0
  27. data/rice/Arg_impl.hpp +116 -0
  28. data/rice/Arg_operators.cpp +21 -0
  29. data/rice/Arg_operators.hpp +18 -0
  30. data/rice/Array.hpp +220 -0
  31. data/rice/Array.ipp +263 -0
  32. data/rice/Builtin_Object.hpp +8 -0
  33. data/rice/Builtin_Object.ipp +50 -0
  34. data/rice/Builtin_Object_defn.hpp +51 -0
  35. data/rice/Class.cpp +57 -0
  36. data/rice/Class.hpp +8 -0
  37. data/rice/Class.ipp +6 -0
  38. data/rice/Class_defn.hpp +83 -0
  39. data/rice/Constructor.hpp +339 -0
  40. data/rice/Critical_Guard.hpp +40 -0
  41. data/rice/Critical_Guard.ipp +26 -0
  42. data/rice/Data_Object.hpp +8 -0
  43. data/rice/Data_Object.ipp +133 -0
  44. data/rice/Data_Object_defn.hpp +132 -0
  45. data/rice/Data_Type.cpp +21 -0
  46. data/rice/Data_Type.hpp +8 -0
  47. data/rice/Data_Type.ipp +306 -0
  48. data/rice/Data_Type_defn.hpp +219 -0
  49. data/rice/Data_Type_fwd.hpp +12 -0
  50. data/rice/Director.cpp +19 -0
  51. data/rice/Director.hpp +47 -0
  52. data/rice/Enum.hpp +118 -0
  53. data/rice/Enum.ipp +246 -0
  54. data/rice/Exception.cpp +59 -0
  55. data/rice/Exception.hpp +9 -0
  56. data/rice/Exception_Base.hpp +8 -0
  57. data/rice/Exception_Base.ipp +13 -0
  58. data/rice/Exception_Base_defn.hpp +27 -0
  59. data/rice/Exception_defn.hpp +69 -0
  60. data/rice/Hash.hpp +210 -0
  61. data/rice/Hash.ipp +338 -0
  62. data/rice/Identifier.cpp +8 -0
  63. data/rice/Identifier.hpp +50 -0
  64. data/rice/Identifier.ipp +33 -0
  65. data/rice/Jump_Tag.hpp +24 -0
  66. data/rice/Makefile.am +140 -0
  67. data/rice/Makefile.in +740 -0
  68. data/rice/Module.cpp +84 -0
  69. data/rice/Module.hpp +8 -0
  70. data/rice/Module.ipp +6 -0
  71. data/rice/Module_defn.hpp +88 -0
  72. data/rice/Module_impl.hpp +281 -0
  73. data/rice/Module_impl.ipp +348 -0
  74. data/rice/Object.cpp +153 -0
  75. data/rice/Object.hpp +8 -0
  76. data/rice/Object.ipp +19 -0
  77. data/rice/Object_defn.hpp +183 -0
  78. data/rice/Require_Guard.hpp +21 -0
  79. data/rice/String.cpp +94 -0
  80. data/rice/String.hpp +89 -0
  81. data/rice/Struct.cpp +117 -0
  82. data/rice/Struct.hpp +162 -0
  83. data/rice/Struct.ipp +26 -0
  84. data/rice/Symbol.cpp +25 -0
  85. data/rice/Symbol.hpp +66 -0
  86. data/rice/Symbol.ipp +44 -0
  87. data/rice/VM.cpp +92 -0
  88. data/rice/VM.hpp +32 -0
  89. data/rice/config.hpp +44 -0
  90. data/rice/config.hpp.in +43 -0
  91. data/rice/detail/Arguments.hpp +126 -0
  92. data/rice/detail/Auto_Function_Wrapper.hpp +861 -0
  93. data/rice/detail/Auto_Function_Wrapper.ipp +2929 -0
  94. data/rice/detail/Auto_Member_Function_Wrapper.hpp +828 -0
  95. data/rice/detail/Auto_Member_Function_Wrapper.ipp +2326 -0
  96. data/rice/detail/Caster.hpp +63 -0
  97. data/rice/detail/Exception_Handler.hpp +8 -0
  98. data/rice/detail/Exception_Handler.ipp +68 -0
  99. data/rice/detail/Exception_Handler_defn.hpp +96 -0
  100. data/rice/detail/Iterator.hpp +93 -0
  101. data/rice/detail/Not_Copyable.hpp +25 -0
  102. data/rice/detail/Wrapped_Function.hpp +33 -0
  103. data/rice/detail/check_ruby_type.cpp +27 -0
  104. data/rice/detail/check_ruby_type.hpp +23 -0
  105. data/rice/detail/creation_funcs.hpp +37 -0
  106. data/rice/detail/creation_funcs.ipp +36 -0
  107. data/rice/detail/default_allocation_func.hpp +23 -0
  108. data/rice/detail/default_allocation_func.ipp +11 -0
  109. data/rice/detail/define_method_and_auto_wrap.hpp +31 -0
  110. data/rice/detail/define_method_and_auto_wrap.ipp +30 -0
  111. data/rice/detail/demangle.cpp +56 -0
  112. data/rice/detail/demangle.hpp +19 -0
  113. data/rice/detail/env.hpp +19 -0
  114. data/rice/detail/from_ruby.hpp +43 -0
  115. data/rice/detail/from_ruby.ipp +60 -0
  116. data/rice/detail/method_data.cpp +392 -0
  117. data/rice/detail/method_data.cpp.rpp +301 -0
  118. data/rice/detail/method_data.hpp +21 -0
  119. data/rice/detail/mininode.cpp +1220 -0
  120. data/rice/detail/mininode.cpp.rpp +62 -0
  121. data/rice/detail/mininode.hpp +320 -0
  122. data/rice/detail/mininode.hpp.rpp +119 -0
  123. data/rice/detail/node.hpp +13 -0
  124. data/rice/detail/object_call.hpp +85 -0
  125. data/rice/detail/object_call.ipp +147 -0
  126. data/rice/detail/protect.cpp +29 -0
  127. data/rice/detail/protect.hpp +34 -0
  128. data/rice/detail/remove_const.hpp +21 -0
  129. data/rice/detail/ruby.hpp +89 -0
  130. data/rice/detail/ruby_version_code.hpp +6 -0
  131. data/rice/detail/ruby_version_code.hpp.in +6 -0
  132. data/rice/detail/rubysig.hpp +19 -0
  133. data/rice/detail/st.hpp +60 -0
  134. data/rice/detail/to_ruby.hpp +22 -0
  135. data/rice/detail/to_ruby.ipp +37 -0
  136. data/rice/detail/win32.hpp +16 -0
  137. data/rice/detail/wrap_function.hpp +345 -0
  138. data/rice/detail/wrap_function.ipp +531 -0
  139. data/rice/generate_code.rb +1311 -0
  140. data/rice/global_function.hpp +33 -0
  141. data/rice/global_function.ipp +22 -0
  142. data/rice/protect.hpp +91 -0
  143. data/rice/protect.ipp +803 -0
  144. data/rice/ruby_mark.hpp +13 -0
  145. data/rice/ruby_try_catch.hpp +86 -0
  146. data/rice/rubypp.rb +97 -0
  147. data/rice/to_from_ruby.hpp +8 -0
  148. data/rice/to_from_ruby.ipp +299 -0
  149. data/rice/to_from_ruby_defn.hpp +71 -0
  150. data/ruby.ac +150 -0
  151. data/ruby/Makefile.am +1 -0
  152. data/ruby/Makefile.in +497 -0
  153. data/ruby/lib/Makefile.am +3 -0
  154. data/ruby/lib/Makefile.in +374 -0
  155. data/ruby/lib/mkmf-rice.rb.in +209 -0
  156. data/ruby/lib/version.rb +3 -0
  157. data/sample/Makefile.am +47 -0
  158. data/sample/Makefile.in +380 -0
  159. data/sample/enum/extconf.rb +3 -0
  160. data/sample/enum/sample_enum.cpp +54 -0
  161. data/sample/enum/test.rb +8 -0
  162. data/sample/inheritance/animals.cpp +98 -0
  163. data/sample/inheritance/extconf.rb +3 -0
  164. data/sample/inheritance/test.rb +7 -0
  165. data/sample/map/extconf.rb +3 -0
  166. data/sample/map/map.cpp +81 -0
  167. data/sample/map/test.rb +7 -0
  168. data/test/Makefile.am +49 -0
  169. data/test/Makefile.in +603 -0
  170. data/test/test_Address_Registration_Guard.cpp +43 -0
  171. data/test/test_Allocation_Strategies.cpp +77 -0
  172. data/test/test_Array.cpp +241 -0
  173. data/test/test_Builtin_Object.cpp +72 -0
  174. data/test/test_Class.cpp +398 -0
  175. data/test/test_Constructor.cpp +238 -0
  176. data/test/test_Critical_Guard.cpp +51 -0
  177. data/test/test_Data_Object.cpp +275 -0
  178. data/test/test_Data_Type.cpp +121 -0
  179. data/test/test_Director.cpp +225 -0
  180. data/test/test_Enum.cpp +162 -0
  181. data/test/test_Exception.cpp +46 -0
  182. data/test/test_Hash.cpp +195 -0
  183. data/test/test_Identifier.cpp +70 -0
  184. data/test/test_Jump_Tag.cpp +17 -0
  185. data/test/test_Module.cpp +428 -0
  186. data/test/test_Object.cpp +148 -0
  187. data/test/test_String.cpp +94 -0
  188. data/test/test_Struct.cpp +192 -0
  189. data/test/test_Symbol.cpp +63 -0
  190. data/test/test_To_From_Ruby.cpp +263 -0
  191. data/test/test_VM.cpp +26 -0
  192. data/test/test_global_functions.cpp +97 -0
  193. data/test/test_rice.rb +35 -0
  194. data/test/unittest.cpp +136 -0
  195. data/test/unittest.hpp +292 -0
  196. metadata +247 -0
@@ -0,0 +1,37 @@
1
+ #ifndef Rice__detail__creation_funcs__hpp_
2
+ #define Rice__detail__creation_funcs__hpp_
3
+
4
+ namespace Rice
5
+ {
6
+
7
+ class Class;
8
+
9
+ namespace detail
10
+ {
11
+
12
+ //! Like define_alloc_func, but allows the user to define an
13
+ //! "initialize" method too.
14
+ template<typename Initialize_Func_T>
15
+ void define_creation_funcs(
16
+ Class const & klass,
17
+ RUBY_VALUE_FUNC allocate_func,
18
+ Initialize_Func_T initialize_func);
19
+
20
+ //! This is just the opposite of define_alloc_func. It can be
21
+ //! used to create a class that cannot be instantiated by the user.
22
+ void undef_alloc_func(
23
+ Class const & klass);
24
+
25
+ //! This is just the opposite of define_creation_func. It can be
26
+ //! used to create a class that cannot be instantiated by the user.
27
+ void undef_creation_funcs(
28
+ Class const & klass);
29
+
30
+ } // namespace detail
31
+
32
+ } // namespace Rice
33
+
34
+ #include "creation_funcs.ipp"
35
+
36
+ #endif // Rice__detail__creation_funcs__hpp_
37
+
@@ -0,0 +1,36 @@
1
+ #ifndef Rice__detail__creation_funcs__ipp_
2
+ #define Rice__detail__creation_funcs__ipp_
3
+
4
+ namespace Rice
5
+ {
6
+
7
+ namespace detail
8
+ {
9
+
10
+ template<typename Initialize_Func_T>
11
+ inline void define_creation_funcs(
12
+ Class const & klass,
13
+ RUBY_VALUE_FUNC allocate_func,
14
+ Initialize_Func_T initialize_func)
15
+ {
16
+ rb_define_alloc_func(klass, allocate_func);
17
+ klass.define_method("initialize", initialize_func);
18
+ }
19
+
20
+ inline void undef_alloc_func(Class const & klass)
21
+ {
22
+ rb_undef_alloc_func(klass);
23
+ }
24
+
25
+ inline void undef_creation_funcs(Class const & klass)
26
+ {
27
+ undef_alloc_func(klass);
28
+ rb_undef_method(klass, "initialize");
29
+ }
30
+
31
+ } // namespace detail
32
+
33
+ } // namespace Rice
34
+
35
+ #endif // Rice__detail__creation_funcs__ipp_
36
+
@@ -0,0 +1,23 @@
1
+ #ifndef Rice__detail__default_allocation_func__hpp_
2
+ #define Rice__detail__default_allocation_func__hpp_
3
+
4
+ namespace Rice
5
+ {
6
+
7
+ namespace detail
8
+ {
9
+
10
+ //! A default implementation of an allocate_func. This function does no
11
+ //! actual allocation; the initialize_func can later do the real
12
+ //! allocation with: DATA_PTR(self) = new Type(arg1, arg2, ...)
13
+ template<typename T>
14
+ VALUE default_allocation_func(VALUE klass);
15
+
16
+ } // detail
17
+
18
+ } // Rice
19
+
20
+ #include "default_allocation_func.ipp"
21
+
22
+ #endif // Rice__detail__default_allocation_func__hpp_
23
+
@@ -0,0 +1,11 @@
1
+ #include "../Data_Object.hpp"
2
+
3
+ template<typename T>
4
+ VALUE Rice::detail::
5
+ default_allocation_func(VALUE klass)
6
+ {
7
+ Data_Object<T> m(static_cast<T*>(0), klass);
8
+ return m.value();
9
+ }
10
+
11
+
@@ -0,0 +1,31 @@
1
+ #ifndef Rice__detail__define_method_and_auto_wrap__hpp_
2
+ #define Rice__detail__define_method_and_auto_wrap__hpp_
3
+
4
+ #include "ruby.hpp"
5
+ #include "../Data_Object.hpp"
6
+ #include "../Identifier.hpp"
7
+ #include "Arguments.hpp"
8
+
9
+ namespace Rice
10
+ {
11
+
12
+ namespace detail
13
+ {
14
+
15
+ class Exception_Handler;
16
+
17
+ template<typename Fun_T>
18
+ void define_method_and_auto_wrap(
19
+ VALUE klass,
20
+ Identifier name,
21
+ Fun_T function,
22
+ Data_Object<Exception_Handler> handler,
23
+ Arguments* arguments = 0);
24
+
25
+ } // detail
26
+
27
+ } // Rice
28
+
29
+ #include "define_method_and_auto_wrap.ipp"
30
+
31
+ #endif // Rice__detail__define_method_and_auto_wrap__hpp_
@@ -0,0 +1,30 @@
1
+ #ifndef Rice__detail__define_method_and_auto_wrap__ipp_
2
+ #define Rice__detail__define_method_and_auto_wrap__ipp_
3
+
4
+ #include "wrap_function.hpp"
5
+ #include "method_data.hpp"
6
+ #include "Exception_Handler_defn.hpp"
7
+ #include "../protect.hpp"
8
+
9
+ template<typename Fun_T>
10
+ void Rice::detail::
11
+ define_method_and_auto_wrap(
12
+ VALUE klass,
13
+ Identifier name,
14
+ Fun_T function,
15
+ Data_Object<Exception_Handler> handler,
16
+ Arguments* arguments)
17
+ {
18
+ Data_Object<Wrapped_Function> f(
19
+ wrap_function(function, handler, arguments),
20
+ rb_cObject);
21
+ Rice::protect(
22
+ define_method_with_data,
23
+ klass,
24
+ name.id(),
25
+ f->func(),
26
+ -1,
27
+ f);
28
+ }
29
+
30
+ #endif // Rice__detail__define_method_and_auto_wrap__ipp_
@@ -0,0 +1,56 @@
1
+ #include "demangle.hpp"
2
+
3
+ #ifdef __GNUC__
4
+ #include <cxxabi.h>
5
+ #include <cstdlib>
6
+ #include <cstring>
7
+ #endif
8
+
9
+ std::string
10
+ Rice::detail::
11
+ demangle(char const * mangled_name)
12
+ {
13
+ #ifdef __GNUC__
14
+ struct Helper
15
+ {
16
+ Helper(
17
+ char const * mangled_name)
18
+ : name_(0)
19
+ {
20
+ int status = 0;
21
+ name_ = abi::__cxa_demangle(mangled_name, 0, 0, &status);
22
+ }
23
+
24
+ ~Helper()
25
+ {
26
+ std::free(name_);
27
+ }
28
+
29
+ char * name_;
30
+
31
+ private:
32
+ Helper(Helper const &);
33
+ void operator=(Helper const &);
34
+ };
35
+
36
+ Helper helper(mangled_name);
37
+ if(helper.name_)
38
+ {
39
+ return helper.name_;
40
+ }
41
+ else
42
+ {
43
+ return mangled_name;
44
+ }
45
+ #else
46
+ return mangled_name;
47
+ #endif
48
+ }
49
+
50
+
51
+ std::string
52
+ Rice::detail::
53
+ demangle(std::string const & mangled_name)
54
+ {
55
+ return demangle(mangled_name.c_str());
56
+ }
@@ -0,0 +1,19 @@
1
+ #ifndef Rice__detail__demangle__hpp_
2
+ #define Rice__detail__demangle__hpp_
3
+
4
+ #include <string>
5
+
6
+ namespace Rice
7
+ {
8
+
9
+ namespace detail
10
+ {
11
+
12
+ std::string demangle(char const * mangled_name);
13
+ std::string demangle(std::string const & mangled_name);
14
+
15
+ } // detail
16
+
17
+ } // Rice
18
+
19
+ #endif // Rice__detail__demangle__hpp_
@@ -0,0 +1,19 @@
1
+ #ifndef Rice__detail__env__hpp_
2
+ #define Rice__detail__env__hpp_
3
+
4
+ /**
5
+ * Helper header for the env.h ruby include file, which does
6
+ * not have extern "C"
7
+ */
8
+
9
+ // TODO: Won't work on ruby 1.9
10
+
11
+ #include "ruby_version_code.hpp"
12
+
13
+ #if RICE__RUBY_VERSION_CODE < 190
14
+ extern "C" {
15
+ #include "env.h"
16
+ }
17
+ #endif
18
+
19
+ #endif
@@ -0,0 +1,43 @@
1
+ #ifndef Rice__detail__from_ruby__hpp_
2
+ #define Rice__detail__from_ruby__hpp_
3
+
4
+ namespace Rice
5
+ {
6
+ namespace detail
7
+ {
8
+ template<typename T>
9
+ struct from_ruby_
10
+ {
11
+ typedef T Retval_T;
12
+
13
+ static T convert(Rice::Object x);
14
+ };
15
+
16
+ template<typename T>
17
+ struct from_ruby_<T *>
18
+ {
19
+ typedef T * Retval_T;
20
+
21
+ static T * convert(Rice::Object x);
22
+ };
23
+
24
+ template<typename T>
25
+ struct from_ruby_<T const *>
26
+ {
27
+ typedef T const * Retval_T;
28
+
29
+ static T const * convert(Rice::Object x);
30
+ };
31
+
32
+ template<typename T>
33
+ struct from_ruby_<T &>
34
+ {
35
+ typedef T & Retval_T;
36
+
37
+ static T & convert(Rice::Object x);
38
+ };
39
+ } // detail
40
+ } // Rice
41
+
42
+ #endif // Rice__detail__from_ruby__hpp_
43
+
@@ -0,0 +1,60 @@
1
+ #ifndef Rice__detail__from_ruby__ipp_
2
+ #define Rice__detail__from_ruby__ipp_
3
+
4
+ #include "../Data_Type.hpp"
5
+ #include "../String.hpp"
6
+ #include "demangle.hpp"
7
+ #include <typeinfo>
8
+
9
+ template<typename T>
10
+ T Rice::detail::from_ruby_<T>::
11
+ convert(Rice::Object x)
12
+ {
13
+ if(rb_type(x.value()) == T_DATA)
14
+ {
15
+ return *Data_Type<T>::from_ruby(x);
16
+ }
17
+ else
18
+ {
19
+ std::string s("Unable to convert ");
20
+ s += x.class_of().name().c_str();
21
+ s += " to ";
22
+ s += demangle(typeid(T).name());
23
+ throw std::invalid_argument(s.c_str());
24
+ }
25
+ }
26
+
27
+ template<typename T>
28
+ T * Rice::detail::from_ruby_<T *>::
29
+ convert(Rice::Object x)
30
+ {
31
+ if(rb_type(x.value()) == T_DATA)
32
+ {
33
+ return Data_Type<T>::from_ruby(x);
34
+ }
35
+ else
36
+ {
37
+ std::string s("Unable to convert ");
38
+ s += x.class_of().name().c_str();
39
+ s += " to ";
40
+ s += demangle(typeid(T *).name());
41
+ throw std::invalid_argument(s.c_str());
42
+ }
43
+ }
44
+
45
+ template<typename T>
46
+ T const * Rice::detail::from_ruby_<T const *>::
47
+ convert(Rice::Object x)
48
+ {
49
+ return from_ruby<T *>(x);
50
+ }
51
+
52
+ template<typename T>
53
+ T & Rice::detail::from_ruby_<T &>::
54
+ convert(Rice::Object x)
55
+ {
56
+ return *from_ruby<T *>(x);
57
+ }
58
+
59
+ #endif // Rice__detail__from_ruby__ipp_
60
+
@@ -0,0 +1,392 @@
1
+ #include "method_data.hpp"
2
+
3
+ // TODO: This is silly, autoconf...
4
+ #undef PACKAGE_NAME
5
+ #undef PACKAGE_STRING
6
+ #undef PACKAGE_TARNAME
7
+ #undef PACKAGE_VERSION
8
+
9
+ #include "../config.hpp"
10
+
11
+
12
+ #if defined(HAVE_NODE_H)
13
+ /* pre-YARV */
14
+ #include <node.h>
15
+ #elif defined(REALLY_HAVE_RUBY_NODE_H)
16
+ /* YARV */
17
+ #include <ruby/node.h>
18
+ #else
19
+ /* YARV without node.h */
20
+ #include "mininode.hpp"
21
+ using namespace Rice::detail::Mininode;
22
+ #endif
23
+
24
+ #include "env.hpp"
25
+
26
+ #ifdef RUBY_VM
27
+
28
+ /* YARV */
29
+
30
+ namespace
31
+ {
32
+
33
+ struct rb_thread_struct
34
+ {
35
+ VALUE self;
36
+ void *vm;
37
+ VALUE *stack;
38
+ unsigned long stack_size;
39
+ VALUE *cfp;
40
+ /* ... */
41
+ };
42
+
43
+ typedef struct rb_thread_struct rb_thread_t;
44
+
45
+ } // namespace
46
+
47
+ extern "C" rb_thread_t * ruby_current_thread;
48
+
49
+ #endif
50
+
51
+ namespace
52
+ {
53
+
54
+ #ifdef RUBY_VM
55
+
56
+ /* YARV */
57
+
58
+ #define CFP_DATA_MEMO_NODE_AND_PC cfp[0]
59
+ #define CFP_METHOD_CLASS cfp[11]
60
+
61
+ /* On YARV, we store the method data on the stack. We don't have to pop
62
+ * it off the stack, because the stack pointer will be reset to the
63
+ * previous frame's stack pointer when the function returns.
64
+ */
65
+ static void fix_frame()
66
+ {
67
+ do {
68
+ VALUE * cfp = ruby_current_thread->cfp;
69
+ CFP_DATA_MEMO_NODE_AND_PC = RBASIC(CFP_METHOD_CLASS)->klass;
70
+
71
+ if(rb_type(CFP_DATA_MEMO_NODE_AND_PC) != T_NODE)
72
+ {
73
+ /* This can happen for module functions that are created after
74
+ * the stub function */
75
+ rb_raise(
76
+ rb_eRuntimeError,
77
+ "Cannot find method data for module function");
78
+ }
79
+ else
80
+ {
81
+ CFP_METHOD_CLASS = RCLASS_SUPER(CFP_METHOD_CLASS);
82
+ }
83
+ } while(0);
84
+ }
85
+
86
+ #define FIX_FRAME() \
87
+ fix_frame()
88
+
89
+ static NODE * data_memo_node()
90
+ {
91
+ VALUE * cfp = ruby_current_thread->cfp;
92
+ return (NODE *)CFP_DATA_MEMO_NODE_AND_PC;
93
+ }
94
+
95
+ #else
96
+
97
+ /* pre-YARV */
98
+
99
+ /* Okay to not pop this temporary frame, since it will be popped by the
100
+ * caller
101
+ */
102
+ #define FIX_FRAME() \
103
+ struct FRAME _frame = *ruby_frame; \
104
+ _frame.last_class = RCLASS(ruby_frame->last_class)->super; \
105
+ _frame.prev = ruby_frame; \
106
+ ruby_frame = &_frame; \
107
+
108
+ static NODE * data_memo_node()
109
+ {
110
+ return (NODE *)(RBASIC(ruby_frame->prev->last_class)->klass);
111
+ }
112
+
113
+ #endif
114
+
115
+ typedef VALUE (*Method_Func)(ANYARGS);
116
+
117
+ static Method_Func actual_cfunc()
118
+ {
119
+ return data_memo_node()->nd_cfnc;
120
+ }
121
+
122
+ static VALUE data_wrapper_m1(int argc, VALUE * argv, VALUE self)
123
+ {
124
+ VALUE result;
125
+ FIX_FRAME();
126
+ result = (*actual_cfunc())(argc, argv, self);
127
+ return result;
128
+ }
129
+
130
+ static VALUE data_wrapper_0(VALUE self)
131
+ {
132
+ VALUE result;
133
+ FIX_FRAME();
134
+ result = (*actual_cfunc())(self);
135
+ return result;
136
+ }
137
+
138
+ static VALUE data_wrapper_1(VALUE self, VALUE arg1)
139
+ {
140
+ VALUE result;
141
+ FIX_FRAME();
142
+ result = (*actual_cfunc())(self, arg1);
143
+ return result;
144
+ }
145
+ static VALUE data_wrapper_2(VALUE self, VALUE arg1, VALUE arg2)
146
+ {
147
+ VALUE result;
148
+ FIX_FRAME();
149
+ result = (*actual_cfunc())(self, arg1, arg2);
150
+ return result;
151
+ }
152
+ static VALUE data_wrapper_3(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3)
153
+ {
154
+ VALUE result;
155
+ FIX_FRAME();
156
+ result = (*actual_cfunc())(self, arg1, arg2, arg3);
157
+ return result;
158
+ }
159
+ static VALUE data_wrapper_4(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4)
160
+ {
161
+ VALUE result;
162
+ FIX_FRAME();
163
+ result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4);
164
+ return result;
165
+ }
166
+ static VALUE data_wrapper_5(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5)
167
+ {
168
+ VALUE result;
169
+ FIX_FRAME();
170
+ result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5);
171
+ return result;
172
+ }
173
+ static VALUE data_wrapper_6(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6)
174
+ {
175
+ VALUE result;
176
+ FIX_FRAME();
177
+ result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6);
178
+ return result;
179
+ }
180
+ static VALUE data_wrapper_7(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7)
181
+ {
182
+ VALUE result;
183
+ FIX_FRAME();
184
+ result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
185
+ return result;
186
+ }
187
+ static VALUE data_wrapper_8(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8)
188
+ {
189
+ VALUE result;
190
+ FIX_FRAME();
191
+ result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
192
+ return result;
193
+ }
194
+ static VALUE data_wrapper_9(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9)
195
+ {
196
+ VALUE result;
197
+ FIX_FRAME();
198
+ result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
199
+ return result;
200
+ }
201
+ static VALUE data_wrapper_10(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9, VALUE arg10)
202
+ {
203
+ VALUE result;
204
+ FIX_FRAME();
205
+ result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
206
+ return result;
207
+ }
208
+ static VALUE data_wrapper_11(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9, VALUE arg10, VALUE arg11)
209
+ {
210
+ VALUE result;
211
+ FIX_FRAME();
212
+ result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
213
+ return result;
214
+ }
215
+ static VALUE data_wrapper_12(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9, VALUE arg10, VALUE arg11, VALUE arg12)
216
+ {
217
+ VALUE result;
218
+ FIX_FRAME();
219
+ result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
220
+ return result;
221
+ }
222
+ static VALUE data_wrapper_13(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9, VALUE arg10, VALUE arg11, VALUE arg12, VALUE arg13)
223
+ {
224
+ VALUE result;
225
+ FIX_FRAME();
226
+ result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13);
227
+ return result;
228
+ }
229
+ static VALUE data_wrapper_14(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9, VALUE arg10, VALUE arg11, VALUE arg12, VALUE arg13, VALUE arg14)
230
+ {
231
+ VALUE result;
232
+ FIX_FRAME();
233
+ result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14);
234
+ return result;
235
+ }
236
+ static VALUE data_wrapper_15(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9, VALUE arg10, VALUE arg11, VALUE arg12, VALUE arg13, VALUE arg14, VALUE arg15)
237
+ {
238
+ VALUE result;
239
+ FIX_FRAME();
240
+ result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15);
241
+ return result;
242
+ }
243
+
244
+ } // namespace
245
+
246
+ /* Define a method and attach data to it.
247
+ *
248
+ * The method looks to ruby like a normal aliased CFUNC, with a modified
249
+ * origin class:
250
+ *
251
+ * NODE_FBODY
252
+ * |- (u1) orig - origin class
253
+ * | |- basic
254
+ * | | |- flags - origin class flags + FL_SINGLETON
255
+ * | | +- klass - NODE_MEMO
256
+ * | | |- (u1) cfnc - actual C function to call
257
+ * | | |- (u2) rval - stored data
258
+ * | | +- (u3) 0
259
+ * | |- iv_tbl - 0
260
+ * | |- m_tbl - 0
261
+ * | +- super - actual origin class
262
+ * |- (u2) mid - name of the method
263
+ * +- (u3) head - NODE_CFUNC
264
+ * |- (u1) cfnc - wrapper function to call
265
+ * +- (u2) argc - function arity
266
+ *
267
+ * Or, on YARV:
268
+ *
269
+ * NODE_FBODY
270
+ * |- (u1) oid - name of the method
271
+ * +- (u2) body - NODE_METHOD
272
+ * |- (u1) clss - origin class
273
+ * | |- basic
274
+ * | | |- flags - origin class flags + FL_SINGLETON
275
+ * | | +- klass - NODE_MEMO
276
+ * | | |- (u1) cfnc - actual C function to call
277
+ * | | |- (u2) rval - stored data
278
+ * | | +- (u3) 0
279
+ * | |- ptr - rb_classext_t
280
+ * | | |- super - actual origin class
281
+ * | | +- iv_tbl - 0
282
+ * | |- m_tbl - 0
283
+ * | +- iv_index_tbl - 0?
284
+ * |- (u2) body - NODE_CFUNC
285
+ * | |- (u1) cfnc - wrapper function to call
286
+ * | |- (u2) argc - function arity
287
+ * +- (u3) noex - NOEX_PUBLIC
288
+ *
289
+ * When the wrapper function is called, last_class is set to the origin
290
+ * class found in the FBODY node. So that the method data will be
291
+ * accessible, and so last_class will point to klass and not to our MEMO
292
+ * node, it is necessary to "fix" the current frame.
293
+ *
294
+ * Pre-YARV, this means we duplicate the current frame and set last_class:
295
+ *
296
+ * ruby_frame
297
+ * |- last_class - klass
298
+ * |- prev
299
+ * | |- last_class - NODE_MEMO
300
+ * | | |- (u1) cfnc - actual C function to call
301
+ * | | |- (u2) rval - stored data
302
+ * | | +- (u3) 0
303
+ * | |- prev - the real previous frame
304
+ * | +- ...
305
+ * +- ...
306
+ *
307
+ * The method data is then accessible via
308
+ * ruby_frame->prev->last_class->rval.
309
+ *
310
+ * On YARV, the current frame is not duplicated; rather, the method data
311
+ * is placed on the stack and is referenced by one of the unused members
312
+ * of the control frame (the program counter):
313
+ *
314
+ * ruby_current_thread->cfp
315
+ * |- pc - NODE_MEMO
316
+ * | |- (u1) cfnc - actual C function to call
317
+ * | |- (u2) rval - stored data
318
+ * | +- (u3) 0
319
+ * |- method_class - klass
320
+ * +- ...
321
+ *
322
+ */
323
+ VALUE
324
+ Rice::detail::
325
+ define_method_with_data(
326
+ VALUE klass, ID id, VALUE (*cfunc)(ANYARGS), int arity, VALUE data)
327
+ {
328
+ /* TODO: origin should have #to_s and #inspect methods defined */
329
+ #ifdef HAVE_RB_CLASS_BOOT
330
+ VALUE origin = rb_class_boot(klass);
331
+ #else
332
+ VALUE origin = rb_class_new(klass);
333
+ #endif
334
+ NODE * node;
335
+
336
+ VALUE (*data_wrapper)(ANYARGS);
337
+ switch(arity)
338
+ {
339
+ case 0: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_0); break;
340
+ case 1: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_1); break;
341
+ case 2: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_2); break;
342
+ case 3: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_3); break;
343
+ case 4: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_4); break;
344
+ case 5: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_5); break;
345
+ case 6: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_6); break;
346
+ case 7: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_7); break;
347
+ case 8: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_8); break;
348
+ case 9: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_9); break;
349
+ case 10: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_10); break;
350
+ case 11: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_11); break;
351
+ case 12: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_12); break;
352
+ case 13: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_13); break;
353
+ case 14: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_14); break;
354
+ case 15: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_15); break;
355
+ case -1: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_m1); break;
356
+ default: rb_raise(rb_eArgError, "unsupported arity %d", arity);
357
+ }
358
+
359
+ FL_SET(origin, FL_SINGLETON);
360
+ rb_singleton_class_attached(origin, klass);
361
+ rb_name_class(origin, SYM2ID(rb_class_name(klass)));
362
+
363
+ RBASIC(origin)->klass = (VALUE)NEW_NODE(NODE_MEMO, cfunc, data, 0);
364
+
365
+ #ifdef RUBY_VM
366
+ /* YARV */
367
+ node = NEW_FBODY(
368
+ NEW_METHOD(
369
+ NEW_CFUNC(data_wrapper, arity),
370
+ origin,
371
+ NOEX_PUBLIC),
372
+ id);
373
+ st_insert(RCLASS_M_TBL(klass), id, (st_data_t)node);
374
+ #else
375
+ /* pre-YARV */
376
+ node = NEW_FBODY(
377
+ NEW_CFUNC(data_wrapper, arity),
378
+ id,
379
+ origin);
380
+ rb_add_method(klass, id, node, NOEX_PUBLIC);
381
+ #endif
382
+
383
+ return Qnil;
384
+ }
385
+
386
+ VALUE
387
+ Rice::detail::
388
+ method_data()
389
+ {
390
+ return data_memo_node()->nd_rval;
391
+ }
392
+