extpp 0.0.6 → 0.1.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/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/Rakefile +1 -28
- data/doc/text/news.md +43 -0
- data/include/ruby/cast.hpp +4 -4
- data/include/ruby/class.hpp +190 -13
- data/{ext/extpp → include/ruby}/function.hpp +20 -7
- data/include/ruby/object.hpp +44 -5
- data/include/ruby/protect.hpp +12 -5
- data/lib/extpp/compiler.rb +17 -10
- data/lib/extpp/setup.rb +0 -0
- data/lib/extpp/version.rb +1 -1
- data/lib/extpp.rb +0 -12
- data/sample/hello/Rakefile +6 -1
- metadata +7 -74
- data/ext/extpp/class.cpp +0 -277
- data/ext/extpp/extconf.rb +0 -110
- data/ext/extpp/function.cpp +0 -28
- data/ext/extpp/object.cpp +0 -48
- data/ext/extpp/protect.cpp +0 -12
- data/lib/extpp/platform.rb +0 -14
- data/test/fixtures/cast/Makefile +0 -269
- data/test/fixtures/cast/cast.cpp +0 -39
- data/test/fixtures/cast/cast.o +0 -0
- data/test/fixtures/cast/cast.so +0 -0
- data/test/fixtures/cast/extconf.rb +0 -4
- data/test/fixtures/cast/mkmf.log +0 -140
- data/test/fixtures/class/Makefile +0 -269
- data/test/fixtures/class/class.cpp +0 -46
- data/test/fixtures/class/class.o +0 -0
- data/test/fixtures/class/class.so +0 -0
- data/test/fixtures/class/extconf.rb +0 -4
- data/test/fixtures/class/mkmf.log +0 -140
- data/test/fixtures/object/Makefile +0 -269
- data/test/fixtures/object/extconf.rb +0 -4
- data/test/fixtures/object/mkmf.log +0 -140
- data/test/fixtures/object/object.cpp +0 -102
- data/test/fixtures/object/object.o +0 -0
- data/test/fixtures/object/object.so +0 -0
- data/test/fixtures/protect/Makefile +0 -269
- data/test/fixtures/protect/extconf.rb +0 -4
- data/test/fixtures/protect/mkmf.log +0 -140
- data/test/fixtures/protect/protect.cpp +0 -70
- data/test/fixtures/protect/protect.o +0 -0
- data/test/fixtures/protect/protect.so +0 -0
- data/test/helper.rb +0 -9
- data/test/run-test.rb +0 -23
- data/test/test-cast.rb +0 -46
- data/test/test-class.rb +0 -47
- data/test/test-object.rb +0 -68
- data/test/test-protect.rb +0 -54
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d99eab03d29814512bdae39c7be899d60794464e05b361f7cb6b612ba08d36b5
|
|
4
|
+
data.tar.gz: 73d755c8c3c52ddc2e2eb9474637735b1ed5f02a8b08fce1524522bcb3590bcc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: adbe4fc358aa20367f56703424366e5401c8c4c26af831b751e534fec5c853f64e0fb1a87fe68340a33ad1d50ce7808cf8d410e6cc5391f994403b57795a0702
|
|
7
|
+
data.tar.gz: 7fdc84981a093e94b5aeec3f1cbf58b9f986368e03f923f01ea9d6411f31d8c57f0e68dab1c054cc1a8315031a8596a586afd9064318b9ed406cb5e7b709a760
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
data/Rakefile
CHANGED
|
@@ -13,36 +13,9 @@ end
|
|
|
13
13
|
|
|
14
14
|
helper.install
|
|
15
15
|
|
|
16
|
-
def run_extconf(*arguments)
|
|
17
|
-
cd("ext/extpp") do
|
|
18
|
-
ruby("extconf.rb", *arguments)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
desc "Configure"
|
|
23
|
-
task :configure do
|
|
24
|
-
run_extconf
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
namespace :configure do
|
|
28
|
-
desc "Configure for debug"
|
|
29
|
-
task :debug do
|
|
30
|
-
run_extconf("--enable-debug-build")
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
task :clean do
|
|
35
|
-
makefile = "ext/extpp/Makefile"
|
|
36
|
-
if File.exists?(makefile)
|
|
37
|
-
cd(File.dirname(makefile)) do
|
|
38
|
-
sh("make", "clean")
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
16
|
desc "Run tests"
|
|
44
17
|
task :test do
|
|
45
18
|
ruby("test/run-test.rb")
|
|
46
19
|
end
|
|
47
20
|
|
|
48
|
-
task default:
|
|
21
|
+
task default: :test
|
data/doc/text/news.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# News
|
|
2
2
|
|
|
3
|
+
## 0.1.0 - 2021-10-03
|
|
4
|
+
|
|
5
|
+
### Improvements
|
|
6
|
+
|
|
7
|
+
* Implemented as header only library.
|
|
8
|
+
|
|
9
|
+
## 0.0.9 - 2020-11-03
|
|
10
|
+
|
|
11
|
+
### Improvements
|
|
12
|
+
|
|
13
|
+
* Improved `clang++` version detection.
|
|
14
|
+
[GitHub#10][Patch by Alex Neill]
|
|
15
|
+
|
|
16
|
+
* Improved `g++` version detection.
|
|
17
|
+
|
|
18
|
+
### Thanks
|
|
19
|
+
|
|
20
|
+
* Alex Neill
|
|
21
|
+
|
|
22
|
+
## 0.0.8 - 2019-09-25
|
|
23
|
+
|
|
24
|
+
### Improvements
|
|
25
|
+
|
|
26
|
+
* Changed to use `RbConfig::CONFIG["SOEXT"]`.
|
|
27
|
+
[Suggested by Nobuyoshi Nakada]
|
|
28
|
+
|
|
29
|
+
* Added `ExtpPP::Platform#shared_library_extension`.
|
|
30
|
+
|
|
31
|
+
* Added support for macOS Majave.
|
|
32
|
+
[GitHub#8][Patch by Josh Huckabee]
|
|
33
|
+
|
|
34
|
+
### Thanks
|
|
35
|
+
|
|
36
|
+
* Nobuyoshi Nakada
|
|
37
|
+
|
|
38
|
+
* Josh Huckabee
|
|
39
|
+
|
|
40
|
+
## 0.0.7 - 2019-03-21
|
|
41
|
+
|
|
42
|
+
### Improvements
|
|
43
|
+
|
|
44
|
+
* Added support for Windows.
|
|
45
|
+
|
|
3
46
|
## 0.0.6 - 2019-02-25
|
|
4
47
|
|
|
5
48
|
### Improvements
|
data/include/ruby/cast.hpp
CHANGED
|
@@ -36,12 +36,12 @@ namespace rb {
|
|
|
36
36
|
|
|
37
37
|
template <>
|
|
38
38
|
inline int64_t cast<int64_t, Object>(const Object& rb_object) {
|
|
39
|
-
return
|
|
39
|
+
return NUM2LL(rb_object);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
template <>
|
|
43
43
|
inline Object cast<Object, int64_t>(const int64_t& n) {
|
|
44
|
-
return Object(
|
|
44
|
+
return Object(LL2NUM(n));
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
|
|
@@ -58,12 +58,12 @@ namespace rb {
|
|
|
58
58
|
|
|
59
59
|
template <>
|
|
60
60
|
inline uint64_t cast<uint64_t, Object>(const Object& rb_object) {
|
|
61
|
-
return
|
|
61
|
+
return NUM2ULL(rb_object);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
template <>
|
|
65
65
|
inline Object cast<Object, uint64_t>(const uint64_t& n) {
|
|
66
|
-
return Object(
|
|
66
|
+
return Object(ULL2NUM(n));
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
|
data/include/ruby/class.hpp
CHANGED
|
@@ -1,26 +1,203 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#include <ruby/function.hpp>
|
|
3
4
|
#include <ruby/object.hpp>
|
|
4
5
|
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <unordered_map>
|
|
8
|
+
#include <vector>
|
|
9
|
+
|
|
5
10
|
namespace rb {
|
|
11
|
+
using MethodTable = std::unordered_map<ID, Function *>;
|
|
12
|
+
|
|
13
|
+
struct MethodDefinition {
|
|
14
|
+
MethodDefinition(std::string name_, Function *function_) :
|
|
15
|
+
name(name_),
|
|
16
|
+
function(function_) {
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
std::string name;
|
|
20
|
+
Function *function;
|
|
21
|
+
};
|
|
22
|
+
using MethodDefinitions = std::vector<MethodDefinition>;
|
|
23
|
+
|
|
24
|
+
namespace {
|
|
25
|
+
inline MethodTable *method_table_from_ruby(VALUE rb_method_table) {
|
|
26
|
+
return reinterpret_cast<MethodTable *>(NUM2ULL(rb_method_table));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
inline VALUE method_table_to_ruby(MethodTable *method_table) {
|
|
30
|
+
return ULL2NUM(reinterpret_cast<uintptr_t>(method_table));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
inline MethodDefinitions *
|
|
34
|
+
method_definitions_from_ruby(VALUE rb_definitions) {
|
|
35
|
+
return reinterpret_cast<MethodDefinitions *>(NUM2ULL(rb_definitions));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
inline VALUE method_definitions_to_ruby(MethodDefinitions *definitions) {
|
|
39
|
+
return ULL2NUM(reinterpret_cast<uintptr_t>(definitions));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
inline VALUE call_func(int argc, VALUE *argv, VALUE self) {
|
|
43
|
+
auto rb_method_table =
|
|
44
|
+
rb_ivar_get(rb_obj_class(self), rb_intern("__method_table__"));
|
|
45
|
+
auto method_table = method_table_from_ruby(rb_method_table);
|
|
46
|
+
auto method_name_symbol = rb_funcall(self, rb_intern("__method__"), 0);
|
|
47
|
+
auto function = (*method_table)[rb_sym2id(method_name_symbol)];
|
|
48
|
+
return function->call(self, argc, argv);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
inline bool flush_method_definitions(VALUE klass) {
|
|
52
|
+
ID id_method_definitions = rb_intern("__method_definitions__");
|
|
53
|
+
auto rb_definitions = rb_ivar_get(klass, id_method_definitions);
|
|
54
|
+
if (NIL_P(rb_definitions)) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
auto definitions = method_definitions_from_ruby(rb_definitions);
|
|
59
|
+
auto rb_method_table = rb_ivar_get(klass, rb_intern("__method_table__"));
|
|
60
|
+
auto method_table = method_table_from_ruby(rb_method_table);
|
|
61
|
+
for (const auto &definition : *definitions) {
|
|
62
|
+
ID name_id = rb_intern(definition.name.c_str());
|
|
63
|
+
(*method_table)[name_id] = definition.function;
|
|
64
|
+
rb_define_method(klass,
|
|
65
|
+
definition.name.c_str(),
|
|
66
|
+
reinterpret_cast<rb::RawMethod>(call_func),
|
|
67
|
+
-1);
|
|
68
|
+
}
|
|
69
|
+
rb_ivar_set(klass, id_method_definitions, Qnil);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
inline VALUE method_missing(int argc, VALUE *argv, VALUE self) {
|
|
74
|
+
auto klass = rb_obj_class(self);
|
|
75
|
+
|
|
76
|
+
if (flush_method_definitions(klass)) {
|
|
77
|
+
auto rb_method_table = rb_ivar_get(klass, rb_intern("__method_table__"));
|
|
78
|
+
auto method_table = method_table_from_ruby(rb_method_table);
|
|
79
|
+
|
|
80
|
+
VALUE rb_name_symbol;
|
|
81
|
+
VALUE rb_args;
|
|
82
|
+
rb_scan_args(argc, argv, "1*", &rb_name_symbol, &rb_args);
|
|
83
|
+
auto function = (*method_table)[rb_sym2id(rb_name_symbol)];
|
|
84
|
+
if (function) {
|
|
85
|
+
return function->call(self,
|
|
86
|
+
static_cast<int>(RARRAY_LEN(rb_args)),
|
|
87
|
+
RARRAY_PTR(rb_args));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return rb_call_super(argc, argv);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
inline VALUE respond_to_missing_p(VALUE self,
|
|
95
|
+
VALUE rb_name_symbol,
|
|
96
|
+
VALUE rb_include_private) {
|
|
97
|
+
auto klass = rb_obj_class(self);
|
|
98
|
+
|
|
99
|
+
if (flush_method_definitions(klass)) {
|
|
100
|
+
auto rb_method_table = rb_ivar_get(klass, rb_intern("__method_table__"));
|
|
101
|
+
auto method_table = method_table_from_ruby(rb_method_table);
|
|
102
|
+
|
|
103
|
+
auto function = (*method_table)[rb_sym2id(rb_name_symbol)];
|
|
104
|
+
if (function) {
|
|
105
|
+
return Qtrue;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
VALUE rb_args[] = {rb_name_symbol, rb_include_private};
|
|
110
|
+
return rb_call_super(2, rb_args);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
6
114
|
class Class: public Object {
|
|
7
115
|
public:
|
|
8
|
-
Class(const char *name)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
116
|
+
Class(const char *name) :
|
|
117
|
+
Class(RTEST(rb_funcall(rb_cObject,
|
|
118
|
+
rb_intern("const_defined?"),
|
|
119
|
+
1,
|
|
120
|
+
rb_str_new_static(name, strlen(name)))) ?
|
|
121
|
+
rb_funcall(rb_cObject,
|
|
122
|
+
rb_intern("const_get"),
|
|
123
|
+
1,
|
|
124
|
+
rb_str_new_static(name, strlen(name))) :
|
|
125
|
+
rb_define_class(name, rb_cObject)) {
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
Class(const char *name, VALUE parent) :
|
|
129
|
+
Class(rb_define_class(name, parent)) {
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
Class(VALUE klass) :
|
|
133
|
+
Object(klass),
|
|
134
|
+
class_(klass),
|
|
135
|
+
method_table_(new MethodTable()),
|
|
136
|
+
lazy_define_method_(false),
|
|
137
|
+
method_definitions_(nullptr) {
|
|
138
|
+
rb_iv_set(class_,
|
|
139
|
+
"__method_table__",
|
|
140
|
+
method_table_to_ruby(method_table_));
|
|
141
|
+
rb_iv_set(class_, "__method_definitions__", Qnil);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
inline Class &define_method(const char *name,
|
|
145
|
+
MethodWithoutArguments body) {
|
|
146
|
+
auto function = new FunctionWithoutArgument(body);
|
|
147
|
+
return define_method(name, function);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
inline Class &define_method(const char *name,
|
|
151
|
+
MethodWithArguments body) {
|
|
152
|
+
auto function = new FunctionWithArguments(body);
|
|
153
|
+
return define_method(name, function);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
inline Class &define_method(const char *name,
|
|
157
|
+
MethodWithArgumentsCompatible body) {
|
|
158
|
+
auto function = new FunctionWithArgumentsCompatible(body);
|
|
159
|
+
return define_method(name, function);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
inline Class &define_method(const char *name, Function *function) {
|
|
163
|
+
if (lazy_define_method_) {
|
|
164
|
+
method_definitions_->emplace_back(name, function);
|
|
165
|
+
} else {
|
|
166
|
+
ID name_id = rb_intern(name);
|
|
167
|
+
(*method_table_)[name_id] = function;
|
|
168
|
+
rb_define_method(class_,
|
|
169
|
+
name,
|
|
170
|
+
reinterpret_cast<RawMethod>(call_func),
|
|
171
|
+
-1);
|
|
172
|
+
}
|
|
173
|
+
return (Class &)*this;
|
|
174
|
+
}
|
|
12
175
|
|
|
13
|
-
Class &
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Class &define_method(const char *name,
|
|
18
|
-
MethodWithArgumentsCompatible body);
|
|
176
|
+
inline Class &enable_lazy_define_method() {
|
|
177
|
+
if (lazy_define_method_) {
|
|
178
|
+
return (Class &)*this;
|
|
179
|
+
}
|
|
19
180
|
|
|
20
|
-
|
|
181
|
+
lazy_define_method_ = true;
|
|
182
|
+
method_definitions_ = new MethodDefinitions();
|
|
183
|
+
rb_iv_set(class_,
|
|
184
|
+
"__method_definitions__",
|
|
185
|
+
method_definitions_to_ruby(method_definitions_));
|
|
186
|
+
rb_define_method(class_,
|
|
187
|
+
"method_missing",
|
|
188
|
+
reinterpret_cast<RawMethod>(method_missing),
|
|
189
|
+
-1);
|
|
190
|
+
rb_define_method(class_,
|
|
191
|
+
"respond_to_missing?",
|
|
192
|
+
reinterpret_cast<RawMethod>(respond_to_missing_p),
|
|
193
|
+
-1);
|
|
194
|
+
return (Class &)*this;
|
|
195
|
+
}
|
|
21
196
|
|
|
22
197
|
private:
|
|
23
|
-
|
|
24
|
-
|
|
198
|
+
VALUE class_;
|
|
199
|
+
MethodTable *method_table_;
|
|
200
|
+
bool lazy_define_method_;
|
|
201
|
+
MethodDefinitions *method_definitions_;
|
|
25
202
|
};
|
|
26
203
|
}
|
|
@@ -13,9 +13,13 @@ namespace rb {
|
|
|
13
13
|
|
|
14
14
|
class FunctionWithoutArgument : public Function {
|
|
15
15
|
public:
|
|
16
|
-
FunctionWithoutArgument(const MethodWithoutArguments &function)
|
|
16
|
+
FunctionWithoutArgument(const MethodWithoutArguments &function) :
|
|
17
|
+
function_(function) {
|
|
18
|
+
}
|
|
17
19
|
|
|
18
|
-
VALUE call(VALUE self, int argc, VALUE *argv) override
|
|
20
|
+
inline VALUE call(VALUE self, int argc, VALUE *argv) override {
|
|
21
|
+
return function_(self);
|
|
22
|
+
}
|
|
19
23
|
|
|
20
24
|
private:
|
|
21
25
|
MethodWithoutArguments function_;
|
|
@@ -23,9 +27,13 @@ namespace rb {
|
|
|
23
27
|
|
|
24
28
|
class FunctionWithArguments : public Function {
|
|
25
29
|
public:
|
|
26
|
-
FunctionWithArguments(const MethodWithArguments &function)
|
|
30
|
+
FunctionWithArguments(const MethodWithArguments &function) :
|
|
31
|
+
function_(function) {
|
|
32
|
+
}
|
|
27
33
|
|
|
28
|
-
VALUE call(VALUE self, int argc, VALUE *argv) override
|
|
34
|
+
inline VALUE call(VALUE self, int argc, VALUE *argv) override {
|
|
35
|
+
return function_(self, argc, argv);
|
|
36
|
+
}
|
|
29
37
|
|
|
30
38
|
private:
|
|
31
39
|
MethodWithArguments function_;
|
|
@@ -33,9 +41,14 @@ namespace rb {
|
|
|
33
41
|
|
|
34
42
|
class FunctionWithArgumentsCompatible : public Function {
|
|
35
43
|
public:
|
|
36
|
-
FunctionWithArgumentsCompatible(
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
FunctionWithArgumentsCompatible(
|
|
45
|
+
const MethodWithArgumentsCompatible &function) :
|
|
46
|
+
function_(function) {
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
inline VALUE call(VALUE self, int argc, VALUE *argv) override {
|
|
50
|
+
return function_(argc, argv, self);
|
|
51
|
+
}
|
|
39
52
|
|
|
40
53
|
private:
|
|
41
54
|
MethodWithArgumentsCompatible function_;
|
data/include/ruby/object.hpp
CHANGED
|
@@ -56,7 +56,10 @@ namespace rb {
|
|
|
56
56
|
rb_gc_register_address(&rb_object_);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
Object send(ID name_id)
|
|
59
|
+
inline Object send(ID name_id) {
|
|
60
|
+
VALUE rb_result = rb_funcall(rb_object_, name_id, 0);
|
|
61
|
+
return Object(rb_result);
|
|
62
|
+
}
|
|
60
63
|
|
|
61
64
|
inline Object send(const char *name) {
|
|
62
65
|
return send(rb_intern(name));
|
|
@@ -66,7 +69,19 @@ namespace rb {
|
|
|
66
69
|
return send(rb_intern_str(name));
|
|
67
70
|
}
|
|
68
71
|
|
|
69
|
-
Object send(ID name_id, std::initializer_list<VALUE> args)
|
|
72
|
+
inline Object send(ID name_id, std::initializer_list<VALUE> args) {
|
|
73
|
+
auto n = args.size();
|
|
74
|
+
VALUE rb_args[n];
|
|
75
|
+
int i = 0;
|
|
76
|
+
for (auto arg : args) {
|
|
77
|
+
rb_args[i++] = arg;
|
|
78
|
+
}
|
|
79
|
+
VALUE rb_result = rb_funcallv(rb_object_,
|
|
80
|
+
name_id,
|
|
81
|
+
static_cast<int>(n),
|
|
82
|
+
rb_args);
|
|
83
|
+
return Object(rb_result);
|
|
84
|
+
}
|
|
70
85
|
|
|
71
86
|
inline Object send(const char *name, std::initializer_list<VALUE> args) {
|
|
72
87
|
return send(rb_intern(name), args);
|
|
@@ -76,9 +91,33 @@ namespace rb {
|
|
|
76
91
|
return send(rb_intern_str(name), args);
|
|
77
92
|
}
|
|
78
93
|
|
|
79
|
-
Object send(ID name_id,
|
|
80
|
-
|
|
81
|
-
|
|
94
|
+
inline Object send(ID name_id,
|
|
95
|
+
std::initializer_list<VALUE> args,
|
|
96
|
+
MethodWithoutArguments block) {
|
|
97
|
+
auto n = args.size();
|
|
98
|
+
VALUE rb_args[n];
|
|
99
|
+
int i = 0;
|
|
100
|
+
for (auto arg : args) {
|
|
101
|
+
rb_args[i++] = arg;
|
|
102
|
+
}
|
|
103
|
+
auto call_block = [](RB_BLOCK_CALL_FUNC_ARGLIST(rb_data, rb_block)) {
|
|
104
|
+
auto block = reinterpret_cast<rb::MethodWithoutArguments>(rb_block);
|
|
105
|
+
return block(rb_data);
|
|
106
|
+
};
|
|
107
|
+
#ifdef RUBY_BACKWARD_CXXANYARGS_HPP
|
|
108
|
+
# define CAST_CALLER(caller) caller
|
|
109
|
+
#else
|
|
110
|
+
# define CAST_CALLER(caller) reinterpret_cast<RawMethod>(+caller)
|
|
111
|
+
#endif
|
|
112
|
+
auto rb_result = rb_block_call(rb_object_,
|
|
113
|
+
name_id,
|
|
114
|
+
static_cast<int>(n),
|
|
115
|
+
rb_args,
|
|
116
|
+
CAST_CALLER(call_block),
|
|
117
|
+
reinterpret_cast<VALUE>(block));
|
|
118
|
+
#undef CAST_CALLER
|
|
119
|
+
return Object(rb_result);
|
|
120
|
+
}
|
|
82
121
|
|
|
83
122
|
inline Object send(const char *name,
|
|
84
123
|
std::initializer_list<VALUE> args,
|
data/include/ruby/protect.hpp
CHANGED
|
@@ -17,15 +17,22 @@ namespace rb {
|
|
|
17
17
|
int state_;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
VALUE protect(RawCallback callback, VALUE callback_data)
|
|
20
|
+
inline VALUE protect(RawCallback callback, VALUE callback_data) {
|
|
21
|
+
int state = 0;
|
|
22
|
+
auto result = rb_protect(callback, callback_data, &state);
|
|
23
|
+
if (state != 0) {
|
|
24
|
+
throw State(state);
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
21
28
|
|
|
22
|
-
template <typename
|
|
23
|
-
VALUE protect(const
|
|
29
|
+
template <typename NoArgumentCallback>
|
|
30
|
+
VALUE protect(const NoArgumentCallback& callback) {
|
|
24
31
|
struct Data {
|
|
25
|
-
Data(const
|
|
32
|
+
Data(const NoArgumentCallback& callback) :
|
|
26
33
|
callback_(callback) {
|
|
27
34
|
}
|
|
28
|
-
const
|
|
35
|
+
const NoArgumentCallback& callback_;
|
|
29
36
|
} data(callback);
|
|
30
37
|
auto callback_data = reinterpret_cast<VALUE>(&data);
|
|
31
38
|
return protect([](VALUE callback_data) -> VALUE {
|
data/lib/extpp/compiler.rb
CHANGED
|
@@ -60,23 +60,16 @@ module ExtPP
|
|
|
60
60
|
std = nil
|
|
61
61
|
|
|
62
62
|
case `#{RbConfig.expand("$(CXX) --version")}`
|
|
63
|
-
when
|
|
63
|
+
when /g\+\+.+ (\d+\.\d+)\.\d/
|
|
64
64
|
version = Float($1)
|
|
65
65
|
if version < 5.1
|
|
66
66
|
std = "gnu++11"
|
|
67
67
|
elsif version < 6.1
|
|
68
68
|
std = "gnu++14"
|
|
69
|
-
end
|
|
70
|
-
when /\A.+ clang version (\d\.\d)\.\d/
|
|
71
|
-
version = Float($1)
|
|
72
|
-
if version < 3.5
|
|
73
|
-
std = "gnu++11"
|
|
74
|
-
elsif version < 5
|
|
75
|
-
std = "gnu++14"
|
|
76
69
|
else
|
|
77
70
|
std = "gnu++17"
|
|
78
71
|
end
|
|
79
|
-
when /\AApple LLVM version (\d+\.\d+)\.\d/
|
|
72
|
+
when /\AApple (?:LLVM|clang) version (\d+\.\d+)\.\d/
|
|
80
73
|
version = Float($1)
|
|
81
74
|
# TODO: Is it right?
|
|
82
75
|
if version < 9.0
|
|
@@ -87,6 +80,15 @@ module ExtPP
|
|
|
87
80
|
std = "gnu++17"
|
|
88
81
|
end
|
|
89
82
|
cxx_flags = "-Wno-deprecated-register"
|
|
83
|
+
when /clang version (\d+\.\d+)\.\d/
|
|
84
|
+
version = Float($1)
|
|
85
|
+
if version < 3.5
|
|
86
|
+
std = "gnu++11"
|
|
87
|
+
elsif version < 5
|
|
88
|
+
std = "gnu++14"
|
|
89
|
+
else
|
|
90
|
+
std = "gnu++17"
|
|
91
|
+
end
|
|
90
92
|
end
|
|
91
93
|
|
|
92
94
|
if std
|
|
@@ -135,7 +137,12 @@ module ExtPP
|
|
|
135
137
|
flags << warning_flag
|
|
136
138
|
end
|
|
137
139
|
end
|
|
138
|
-
|
|
140
|
+
case RUBY_PLATFORM
|
|
141
|
+
when /windows/, /mingw/
|
|
142
|
+
@cxx_flags = flags.join(" ")
|
|
143
|
+
else
|
|
144
|
+
@cxx_flags = Shellwords.join(flags)
|
|
145
|
+
end
|
|
139
146
|
end
|
|
140
147
|
end
|
|
141
148
|
end
|
data/lib/extpp/setup.rb
ADDED
|
File without changes
|
data/lib/extpp/version.rb
CHANGED
data/lib/extpp.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require "extpp/compiler"
|
|
2
|
-
require "extpp/platform"
|
|
3
2
|
|
|
4
3
|
compiler = ExtPP::Compiler.new(RbConfig.expand($CXXFLAGS))
|
|
5
4
|
compiler.check
|
|
@@ -26,14 +25,3 @@ $(OBJS): $(extpp_headers)
|
|
|
26
25
|
end
|
|
27
26
|
end
|
|
28
27
|
extend(header_files_dependency_injector)
|
|
29
|
-
|
|
30
|
-
platform = ExtPP::Platform.new
|
|
31
|
-
|
|
32
|
-
[
|
|
33
|
-
File.join(__dir__, "..", "ext", "extpp"),
|
|
34
|
-
__dir__,
|
|
35
|
-
].each do |candidate_dir|
|
|
36
|
-
so_name = "libruby-extpp.#{platform.dynamic_library_extension}"
|
|
37
|
-
lib_path = File.expand_path(File.join(candidate_dir, so_name))
|
|
38
|
-
$LIBS += " #{lib_path.quote}" if File.exist?(lib_path)
|
|
39
|
-
end
|