keyme-rice 1.5.1.keyme
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 +15 -0
- data/COPYING +23 -0
- data/Doxyfile +1253 -0
- data/Makefile.am +26 -0
- data/Makefile.in +853 -0
- data/README +1124 -0
- data/README.mingw +8 -0
- data/Rakefile +34 -0
- data/aclocal.m4 +971 -0
- data/bootstrap +8 -0
- data/config.guess +1530 -0
- data/config.sub +1773 -0
- data/configure +7121 -0
- data/configure.ac +52 -0
- data/depcomp +688 -0
- data/doxygen.ac +314 -0
- data/doxygen.am +186 -0
- data/extconf.rb +51 -0
- data/install-sh +527 -0
- data/missing +331 -0
- data/post-autoconf.rb +22 -0
- data/post-automake.rb +28 -0
- data/rice/Address_Registration_Guard.cpp +22 -0
- data/rice/Address_Registration_Guard.hpp +7 -0
- data/rice/Address_Registration_Guard.ipp +37 -0
- data/rice/Address_Registration_Guard_defn.hpp +75 -0
- data/rice/Arg.hpp +8 -0
- data/rice/Arg_impl.hpp +127 -0
- data/rice/Arg_operators.cpp +21 -0
- data/rice/Arg_operators.hpp +19 -0
- data/rice/Array.hpp +220 -0
- data/rice/Array.ipp +263 -0
- data/rice/Builtin_Object.hpp +8 -0
- data/rice/Builtin_Object.ipp +50 -0
- data/rice/Builtin_Object_defn.hpp +50 -0
- data/rice/Class.cpp +57 -0
- data/rice/Class.hpp +8 -0
- data/rice/Class.ipp +6 -0
- data/rice/Class_defn.hpp +83 -0
- data/rice/Constructor.hpp +368 -0
- data/rice/Critical_Guard.hpp +40 -0
- data/rice/Critical_Guard.ipp +26 -0
- data/rice/Data_Object.hpp +8 -0
- data/rice/Data_Object.ipp +133 -0
- data/rice/Data_Object_defn.hpp +138 -0
- data/rice/Data_Type.cpp +54 -0
- data/rice/Data_Type.hpp +8 -0
- data/rice/Data_Type.ipp +365 -0
- data/rice/Data_Type_defn.hpp +261 -0
- data/rice/Data_Type_fwd.hpp +12 -0
- data/rice/Director.cpp +13 -0
- data/rice/Director.hpp +39 -0
- data/rice/Enum.hpp +117 -0
- data/rice/Enum.ipp +246 -0
- data/rice/Exception.cpp +59 -0
- data/rice/Exception.hpp +9 -0
- data/rice/Exception_Base.hpp +8 -0
- data/rice/Exception_Base.ipp +13 -0
- data/rice/Exception_Base_defn.hpp +27 -0
- data/rice/Exception_defn.hpp +69 -0
- data/rice/Hash.hpp +227 -0
- data/rice/Hash.ipp +330 -0
- data/rice/Identifier.cpp +8 -0
- data/rice/Identifier.hpp +50 -0
- data/rice/Identifier.ipp +33 -0
- data/rice/Jump_Tag.hpp +24 -0
- data/rice/Makefile.am +129 -0
- data/rice/Makefile.in +769 -0
- data/rice/Module.cpp +84 -0
- data/rice/Module.hpp +8 -0
- data/rice/Module.ipp +6 -0
- data/rice/Module_defn.hpp +88 -0
- data/rice/Module_impl.hpp +281 -0
- data/rice/Module_impl.ipp +348 -0
- data/rice/Object.cpp +160 -0
- data/rice/Object.hpp +8 -0
- data/rice/Object.ipp +19 -0
- data/rice/Object_defn.hpp +191 -0
- data/rice/Require_Guard.hpp +21 -0
- data/rice/String.cpp +94 -0
- data/rice/String.hpp +89 -0
- data/rice/Struct.cpp +117 -0
- data/rice/Struct.hpp +162 -0
- data/rice/Struct.ipp +26 -0
- data/rice/Symbol.cpp +25 -0
- data/rice/Symbol.hpp +66 -0
- data/rice/Symbol.ipp +44 -0
- data/rice/VM.cpp +82 -0
- data/rice/VM.hpp +32 -0
- data/rice/config.hpp +44 -0
- data/rice/config.hpp.in +43 -0
- data/rice/detail/Arguments.hpp +118 -0
- data/rice/detail/Auto_Function_Wrapper.hpp +898 -0
- data/rice/detail/Auto_Function_Wrapper.ipp +3694 -0
- data/rice/detail/Auto_Member_Function_Wrapper.hpp +897 -0
- data/rice/detail/Auto_Member_Function_Wrapper.ipp +2774 -0
- data/rice/detail/Caster.hpp +103 -0
- data/rice/detail/Exception_Handler.hpp +8 -0
- data/rice/detail/Exception_Handler.ipp +68 -0
- data/rice/detail/Exception_Handler_defn.hpp +96 -0
- data/rice/detail/Iterator.hpp +93 -0
- data/rice/detail/Not_Copyable.hpp +25 -0
- data/rice/detail/Wrapped_Function.hpp +33 -0
- data/rice/detail/cfp.hpp +24 -0
- data/rice/detail/cfp.ipp +51 -0
- data/rice/detail/check_ruby_type.cpp +27 -0
- data/rice/detail/check_ruby_type.hpp +23 -0
- data/rice/detail/creation_funcs.hpp +37 -0
- data/rice/detail/creation_funcs.ipp +36 -0
- data/rice/detail/default_allocation_func.hpp +23 -0
- data/rice/detail/default_allocation_func.ipp +11 -0
- data/rice/detail/define_method_and_auto_wrap.hpp +31 -0
- data/rice/detail/define_method_and_auto_wrap.ipp +30 -0
- data/rice/detail/demangle.cpp +56 -0
- data/rice/detail/demangle.hpp +19 -0
- data/rice/detail/env.hpp +19 -0
- data/rice/detail/from_ruby.hpp +43 -0
- data/rice/detail/from_ruby.ipp +60 -0
- data/rice/detail/method_data.cpp +159 -0
- data/rice/detail/method_data.hpp +21 -0
- data/rice/detail/mininode.cpp +1220 -0
- data/rice/detail/mininode.hpp +320 -0
- data/rice/detail/node.hpp +13 -0
- data/rice/detail/object_call.hpp +69 -0
- data/rice/detail/object_call.ipp +131 -0
- data/rice/detail/protect.cpp +29 -0
- data/rice/detail/protect.hpp +34 -0
- data/rice/detail/ruby.hpp +84 -0
- data/rice/detail/ruby_version_code.hpp +6 -0
- data/rice/detail/ruby_version_code.hpp.in +6 -0
- data/rice/detail/rubysig.hpp +19 -0
- data/rice/detail/st.hpp +22 -0
- data/rice/detail/to_ruby.hpp +22 -0
- data/rice/detail/to_ruby.ipp +36 -0
- data/rice/detail/traits.hpp +43 -0
- data/rice/detail/win32.hpp +16 -0
- data/rice/detail/wrap_function.hpp +341 -0
- data/rice/detail/wrap_function.ipp +514 -0
- data/rice/global_function.hpp +33 -0
- data/rice/global_function.ipp +22 -0
- data/rice/protect.hpp +92 -0
- data/rice/protect.ipp +1134 -0
- data/rice/ruby_mark.hpp +13 -0
- data/rice/ruby_try_catch.hpp +86 -0
- data/rice/rubypp.rb +97 -0
- data/rice/to_from_ruby.hpp +8 -0
- data/rice/to_from_ruby.ipp +294 -0
- data/rice/to_from_ruby_defn.hpp +71 -0
- data/ruby/Makefile.am +1 -0
- data/ruby/Makefile.in +569 -0
- data/ruby/lib/Makefile.am +3 -0
- data/ruby/lib/Makefile.in +423 -0
- data/ruby/lib/mkmf-rice.rb.in +213 -0
- data/ruby/lib/version.rb +3 -0
- data/ruby.ac +136 -0
- data/sample/Makefile.am +47 -0
- data/sample/Makefile.in +408 -0
- data/sample/enum/extconf.rb +3 -0
- data/sample/enum/sample_enum.cpp +54 -0
- data/sample/enum/test.rb +8 -0
- data/sample/inheritance/animals.cpp +98 -0
- data/sample/inheritance/extconf.rb +3 -0
- data/sample/inheritance/test.rb +7 -0
- data/sample/map/extconf.rb +3 -0
- data/sample/map/map.cpp +81 -0
- data/sample/map/test.rb +7 -0
- data/test/Makefile.am +77 -0
- data/test/Makefile.in +820 -0
- data/test/ext/Makefile.am +43 -0
- data/test/ext/Makefile.in +404 -0
- data/test/ext/t1/Foo.hpp +10 -0
- data/test/ext/t1/extconf.rb +2 -0
- data/test/ext/t1/t1.cpp +15 -0
- data/test/ext/t2/extconf.rb +2 -0
- data/test/ext/t2/t2.cpp +11 -0
- data/test/test_Address_Registration_Guard.cpp +43 -0
- data/test/test_Array.cpp +241 -0
- data/test/test_Builtin_Object.cpp +72 -0
- data/test/test_Class.cpp +498 -0
- data/test/test_Constructor.cpp +128 -0
- data/test/test_Critical_Guard.cpp +51 -0
- data/test/test_Data_Object.cpp +275 -0
- data/test/test_Data_Type.cpp +348 -0
- data/test/test_Director.cpp +303 -0
- data/test/test_Enum.cpp +195 -0
- data/test/test_Exception.cpp +46 -0
- data/test/test_Hash.cpp +198 -0
- data/test/test_Identifier.cpp +70 -0
- data/test/test_Jump_Tag.cpp +17 -0
- data/test/test_Memory_Management.cpp +50 -0
- data/test/test_Module.cpp +497 -0
- data/test/test_Object.cpp +148 -0
- data/test/test_String.cpp +94 -0
- data/test/test_Struct.cpp +192 -0
- data/test/test_Symbol.cpp +63 -0
- data/test/test_To_From_Ruby.cpp +321 -0
- data/test/test_VM.cpp +26 -0
- data/test/test_global_functions.cpp +114 -0
- data/test/test_rice.rb +43 -0
- data/test/unittest.cpp +136 -0
- data/test/unittest.hpp +294 -0
- metadata +259 -0
|
@@ -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_
|
data/rice/detail/env.hpp
ADDED
|
@@ -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,159 @@
|
|
|
1
|
+
#include "method_data.hpp"
|
|
2
|
+
#include "ruby.hpp"
|
|
3
|
+
|
|
4
|
+
// TODO: This is silly, autoconf...
|
|
5
|
+
#undef PACKAGE_NAME
|
|
6
|
+
#undef PACKAGE_STRING
|
|
7
|
+
#undef PACKAGE_TARNAME
|
|
8
|
+
#undef PACKAGE_VERSION
|
|
9
|
+
#include "../config.hpp"
|
|
10
|
+
|
|
11
|
+
#ifndef RUBY_VM
|
|
12
|
+
/* pre-YARV */
|
|
13
|
+
#include <node.h>
|
|
14
|
+
#include "env.hpp"
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
/* 1.8.6 compatibility */
|
|
18
|
+
#ifndef RCLASS_M_TBL
|
|
19
|
+
#define RCLASS_M_TBL(x) (RCLASS(x)->m_tbl)
|
|
20
|
+
#endif
|
|
21
|
+
|
|
22
|
+
namespace
|
|
23
|
+
{
|
|
24
|
+
|
|
25
|
+
VALUE DATA_MAGIC = rb_fix_new(0xDA7A);
|
|
26
|
+
|
|
27
|
+
} // namespace
|
|
28
|
+
|
|
29
|
+
#ifdef RUBY_VM
|
|
30
|
+
|
|
31
|
+
VALUE
|
|
32
|
+
Rice::detail::
|
|
33
|
+
method_data()
|
|
34
|
+
{
|
|
35
|
+
ID id;
|
|
36
|
+
VALUE origin;
|
|
37
|
+
if (!rb_frame_method_id_and_class(&id, &origin))
|
|
38
|
+
{
|
|
39
|
+
rb_raise(
|
|
40
|
+
rb_eRuntimeError,
|
|
41
|
+
"Cannot get method id and class for function");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
VALUE memo = rb_ivar_get(origin, 0);
|
|
45
|
+
|
|
46
|
+
if(rb_type(memo) != T_ARRAY && RARRAY_PTR(memo)[0] != DATA_MAGIC)
|
|
47
|
+
{
|
|
48
|
+
/* This can happen for module functions that are created after
|
|
49
|
+
* the stub function */
|
|
50
|
+
rb_raise(
|
|
51
|
+
rb_eRuntimeError,
|
|
52
|
+
"Cannot find method data for module function");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return RARRAY_PTR(memo)[1];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#else
|
|
59
|
+
|
|
60
|
+
/* pre-YARV */
|
|
61
|
+
|
|
62
|
+
VALUE
|
|
63
|
+
Rice::detail::
|
|
64
|
+
method_data()
|
|
65
|
+
{
|
|
66
|
+
VALUE origin = ruby_frame->last_class;
|
|
67
|
+
VALUE memo = rb_ivar_get(origin, 0);
|
|
68
|
+
return RARRAY_PTR(memo)[1];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#endif
|
|
72
|
+
|
|
73
|
+
// Define a method and attach data to it.
|
|
74
|
+
// The method looks to ruby like a normal aliased CFUNC, with a modified
|
|
75
|
+
// origin class.
|
|
76
|
+
//
|
|
77
|
+
// How this works:
|
|
78
|
+
//
|
|
79
|
+
// To store method data and have it registered with the GC, we need a
|
|
80
|
+
// "slot" to put it in. This "slot" must be recognized and marked by
|
|
81
|
+
// the garbage collector. There happens to be such a place we can put
|
|
82
|
+
// data, and it has to do with aliased methods. When Ruby creates an
|
|
83
|
+
// alias for a method, it stores a reference to the original class in
|
|
84
|
+
// the method entry. The form of the method entry differs from ruby
|
|
85
|
+
// version to ruby version, but the concept is the same across all of
|
|
86
|
+
// them.
|
|
87
|
+
//
|
|
88
|
+
// In Rice, we make use of this by defining a method on a dummy class,
|
|
89
|
+
// then attaching that method to our real class. The method is a real
|
|
90
|
+
// method in our class, but its origin class is our dummy class.
|
|
91
|
+
//
|
|
92
|
+
// When Ruby makes a method call, it stores the origin class in the
|
|
93
|
+
// current stack frame. When Ruby calls into Rice, we grab the origin
|
|
94
|
+
// class from the stack frame, then pull the data out of the origin
|
|
95
|
+
// class. The data item is then used to determine how to convert
|
|
96
|
+
// arguments and return type, how to handle exceptions, etc.
|
|
97
|
+
//
|
|
98
|
+
// It used to be the case that Rice would "fix" the call frame so that
|
|
99
|
+
// the modified origin class was not visible to the called function (it
|
|
100
|
+
// would appear to the callee that the origin class was the same as the
|
|
101
|
+
// class it was defined on). However, this required modifying the call
|
|
102
|
+
// frame directly, and the layout of that frame varies from version to
|
|
103
|
+
// version. To keep things simple (and as a side effect improve
|
|
104
|
+
// performance), Rice no longer hides the modified origin class this way.
|
|
105
|
+
//
|
|
106
|
+
// Functions that make use of "last_class" (1.8) or
|
|
107
|
+
// "rb_frame_method_id_and_class" (1.9) will therefore not get the
|
|
108
|
+
// results they expect.
|
|
109
|
+
VALUE
|
|
110
|
+
Rice::detail::
|
|
111
|
+
define_method_with_data(
|
|
112
|
+
VALUE klass, ID id, VALUE (*cfunc)(ANYARGS), int arity, VALUE data)
|
|
113
|
+
{
|
|
114
|
+
VALUE origin = rb_class_boot(klass);
|
|
115
|
+
|
|
116
|
+
// Create the memo object with a magic number so we can detect if
|
|
117
|
+
// we're getting the origin class we expect (this can happen if the
|
|
118
|
+
// module_function method is called on a Rice function on ruby 1.9).
|
|
119
|
+
VALUE memo = rb_assoc_new(DATA_MAGIC, data);
|
|
120
|
+
|
|
121
|
+
// Set the class name of our modified origin class to something
|
|
122
|
+
// obvious in case someone tries to inspect it.
|
|
123
|
+
VALUE real_class_name = rb_class_name(klass);
|
|
124
|
+
VALUE origin_class_name = rb_str_plus(
|
|
125
|
+
real_class_name,
|
|
126
|
+
rb_str_new2("<data wrapper>"));
|
|
127
|
+
|
|
128
|
+
// Create the modified origin class
|
|
129
|
+
FL_SET(origin, FL_SINGLETON);
|
|
130
|
+
rb_singleton_class_attached(origin, klass);
|
|
131
|
+
rb_name_class(origin, SYM2ID(rb_str_intern(origin_class_name)));
|
|
132
|
+
|
|
133
|
+
// Attach our "memo" to the origin class
|
|
134
|
+
rb_ivar_set(origin, 0, memo);
|
|
135
|
+
|
|
136
|
+
// Create the aliased method on the origin class
|
|
137
|
+
rb_define_method(
|
|
138
|
+
origin,
|
|
139
|
+
rb_id2name(id),
|
|
140
|
+
cfunc,
|
|
141
|
+
arity);
|
|
142
|
+
|
|
143
|
+
// Alias the method in the origin class so we can copy it to another
|
|
144
|
+
// class with the origin class intact as part of the method entry
|
|
145
|
+
rb_alias(
|
|
146
|
+
origin,
|
|
147
|
+
rb_intern("dummy"),
|
|
148
|
+
id);
|
|
149
|
+
|
|
150
|
+
// Copy the method entry to the real class
|
|
151
|
+
st_data_t dummy_entry;
|
|
152
|
+
st_lookup(RCLASS_M_TBL(origin), rb_intern("dummy"), &dummy_entry);
|
|
153
|
+
st_insert(RCLASS_M_TBL(klass), id, dummy_entry);
|
|
154
|
+
|
|
155
|
+
// Clear the table so we don't try to double-free the method entry
|
|
156
|
+
RCLASS_M_TBL(origin) = st_init_numtable();
|
|
157
|
+
|
|
158
|
+
return Qnil;
|
|
159
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#ifndef Rice__detail__method_data__hpp
|
|
2
|
+
#define Rice__detail__method_data__hpp
|
|
3
|
+
|
|
4
|
+
#include "ruby.hpp"
|
|
5
|
+
|
|
6
|
+
namespace Rice
|
|
7
|
+
{
|
|
8
|
+
|
|
9
|
+
namespace detail
|
|
10
|
+
{
|
|
11
|
+
|
|
12
|
+
VALUE define_method_with_data(
|
|
13
|
+
VALUE klass, ID id, VALUE (*cfunc)(ANYARGS), int arity, VALUE data);
|
|
14
|
+
|
|
15
|
+
VALUE method_data();
|
|
16
|
+
|
|
17
|
+
} // namespace detail
|
|
18
|
+
|
|
19
|
+
} // namespace Rice
|
|
20
|
+
|
|
21
|
+
#endif // Rice__detail__method_data__hpp
|