extpp 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Rakefile +10 -10
- data/doc/text/news.md +14 -0
- data/ext/extpp/class.cpp +19 -6
- data/ext/extpp/extconf.rb +8 -2
- data/ext/extpp/object.cpp +1 -1
- data/ext/extpp/protect.cpp +12 -0
- data/include/ruby.hpp +1 -0
- data/include/ruby/cast.hpp +37 -13
- data/include/ruby/class.hpp +2 -1
- data/include/ruby/object.hpp +4 -1
- data/include/ruby/protect.hpp +37 -0
- data/include/ruby/type.hpp +3 -1
- data/lib/extpp.rb +1 -1
- data/lib/extpp/compiler.rb +44 -10
- data/lib/extpp/version.rb +1 -1
- data/test/fixtures/cast/Makefile +15 -13
- data/test/fixtures/cast/cast.cpp +7 -0
- data/test/fixtures/cast/cast.o +0 -0
- data/test/fixtures/cast/cast.so +0 -0
- data/test/fixtures/cast/mkmf.log +133 -1
- data/test/fixtures/class/Makefile +15 -13
- data/test/fixtures/class/class.o +0 -0
- data/test/fixtures/class/class.so +0 -0
- data/test/fixtures/class/mkmf.log +133 -1
- data/test/fixtures/object/Makefile +15 -13
- data/test/fixtures/object/mkmf.log +133 -1
- data/test/fixtures/object/object.o +0 -0
- data/test/fixtures/object/object.so +0 -0
- data/test/fixtures/protect/Makefile +269 -0
- data/test/fixtures/protect/extconf.rb +4 -0
- data/test/fixtures/protect/mkmf.log +140 -0
- data/test/fixtures/protect/protect.cpp +70 -0
- data/test/fixtures/protect/protect.o +0 -0
- data/test/fixtures/protect/protect.so +0 -0
- data/test/test-cast.rb +4 -0
- data/test/test-protect.rb +54 -0
- metadata +19 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1c37906ea8ea871e171e387ce61d68bc162cdc7d45aa94c85e9a080c1565b4a1
|
4
|
+
data.tar.gz: c1f54dea942fa0329b8e275bdb296e880d1b1731ec16eff59ef663509bad2fbc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0dd33cc753814d03f1d2f1177a4ff74138a1c52808ee4bccfd3f4d8c52f8667e35f310d7d9afd3b64c3f0233d6549e2e0977b80a8d6947f3297f4188b4c5f089
|
7
|
+
data.tar.gz: 92f0058fb4af4f2da3702a0af37a4afb3095cb7fc3e5891b7500e29458a3fe21f4a7cf4c17c82553a916603643eb871fd921df3cf354336fb903d0ddf184756f
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require "rubygems"
|
4
4
|
require "bundler/gem_helper"
|
5
|
-
require "
|
5
|
+
require "rake/clean"
|
6
6
|
|
7
7
|
base_dir = File.join(File.dirname(__FILE__))
|
8
8
|
|
@@ -12,15 +12,6 @@ def helper.version_tag
|
|
12
12
|
end
|
13
13
|
|
14
14
|
helper.install
|
15
|
-
spec = helper.gemspec
|
16
|
-
|
17
|
-
Packnga::DocumentTask.new(spec) do |task|
|
18
|
-
task.original_language = "en"
|
19
|
-
task.translate_language = "ja"
|
20
|
-
end
|
21
|
-
|
22
|
-
Packnga::ReleaseTask.new(spec) do
|
23
|
-
end
|
24
15
|
|
25
16
|
def run_extconf(*arguments)
|
26
17
|
cd("ext/extpp") do
|
@@ -40,6 +31,15 @@ namespace :configure do
|
|
40
31
|
end
|
41
32
|
end
|
42
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
43
|
desc "Run tests"
|
44
44
|
task :test do
|
45
45
|
ruby("test/run-test.rb")
|
data/doc/text/news.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# News
|
2
2
|
|
3
|
+
## 0.0.4 - 2019-02-16
|
4
|
+
|
5
|
+
### Improvements
|
6
|
+
|
7
|
+
* `rb::Class(const char *name)`: Added.
|
8
|
+
|
9
|
+
* `rb::protect()`: Added.
|
10
|
+
|
11
|
+
* `rb::cast<std::string>(rb::Object)`: Added.
|
12
|
+
|
13
|
+
* `rb::cast<rb::Object(std::string)`: Added.
|
14
|
+
|
15
|
+
* Added support for auto needless C++ compiler warning flags remove.
|
16
|
+
|
3
17
|
## 0.0.3 - 2018-02-18
|
4
18
|
|
5
19
|
### Improvements
|
data/ext/extpp/class.cpp
CHANGED
@@ -108,7 +108,7 @@ namespace {
|
|
108
108
|
(*method_table)[name_id] = definition.function;
|
109
109
|
rb_define_method(klass,
|
110
110
|
definition.name.c_str(),
|
111
|
-
reinterpret_cast<rb::
|
111
|
+
reinterpret_cast<rb::RawMethod>(call_func),
|
112
112
|
-1);
|
113
113
|
}
|
114
114
|
rb_ivar_set(klass, id_method_definitions, Qnil);
|
@@ -179,18 +179,18 @@ namespace rb {
|
|
179
179
|
method_definitions_to_ruby(method_definitions_));
|
180
180
|
rb_define_method(class_,
|
181
181
|
"method_missing",
|
182
|
-
reinterpret_cast<
|
182
|
+
reinterpret_cast<RawMethod>(method_missing),
|
183
183
|
-1);
|
184
184
|
rb_define_method(class_,
|
185
185
|
"respond_to_missing?",
|
186
|
-
reinterpret_cast<
|
186
|
+
reinterpret_cast<RawMethod>(respond_to_missing_p),
|
187
187
|
-1);
|
188
188
|
}
|
189
189
|
|
190
190
|
void define_method(const char *name, VALUE (*body)(VALUE self)) {
|
191
191
|
rb_define_method(class_,
|
192
192
|
name,
|
193
|
-
reinterpret_cast<
|
193
|
+
reinterpret_cast<RawMethod>(body),
|
194
194
|
0);
|
195
195
|
}
|
196
196
|
|
@@ -198,7 +198,7 @@ namespace rb {
|
|
198
198
|
VALUE (*body)(int argc, VALUE *argv, VALUE self)) {
|
199
199
|
rb_define_method(class_,
|
200
200
|
name,
|
201
|
-
reinterpret_cast<
|
201
|
+
reinterpret_cast<RawMethod>(body),
|
202
202
|
-1);
|
203
203
|
}
|
204
204
|
|
@@ -210,7 +210,7 @@ namespace rb {
|
|
210
210
|
(*method_table_)[name_id] = function;
|
211
211
|
rb_define_method(class_,
|
212
212
|
name,
|
213
|
-
reinterpret_cast<
|
213
|
+
reinterpret_cast<RawMethod>(call_func),
|
214
214
|
-1);
|
215
215
|
}
|
216
216
|
}
|
@@ -222,6 +222,19 @@ namespace rb {
|
|
222
222
|
MethodDefinitions *method_definitions_;
|
223
223
|
};
|
224
224
|
|
225
|
+
Class::Class(const char *name) :
|
226
|
+
Object(RTEST(rb_funcall(rb_cObject,
|
227
|
+
rb_intern("const_defined?"),
|
228
|
+
1,
|
229
|
+
rb_str_new_static(name, strlen(name)))) ?
|
230
|
+
rb_funcall(rb_cObject,
|
231
|
+
rb_intern("const_get"),
|
232
|
+
1,
|
233
|
+
rb_str_new_static(name, strlen(name))) :
|
234
|
+
rb_define_class(name, rb_cObject)),
|
235
|
+
impl_(new ClassImpl(this->to_ruby())) {
|
236
|
+
}
|
237
|
+
|
225
238
|
Class::Class(const char *name, VALUE parent) :
|
226
239
|
Object(rb_define_class(name, parent)),
|
227
240
|
impl_(new ClassImpl(this->to_ruby())) {
|
data/ext/extpp/extconf.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative "../../lib/extpp/compiler"
|
2
2
|
require_relative "../../lib/extpp/platform"
|
3
3
|
|
4
|
-
cxxflags = RbConfig
|
4
|
+
cxxflags = RbConfig.expand("$(CXXFLAGS)")
|
5
5
|
compiler = ExtPP::Compiler.new(cxxflags)
|
6
6
|
compiler.check
|
7
7
|
cxxflags = compiler.cxx_flags
|
@@ -38,6 +38,11 @@ else
|
|
38
38
|
ldsharedxx = RbConfig::CONFIG["LDSHAREDXX"]
|
39
39
|
end
|
40
40
|
|
41
|
+
librubyarg_shared = RbConfig::CONFIG["LIBRUBYARG_SHARED"]
|
42
|
+
if compiler.gcc? and !librubyarg_shared.include?("-L")
|
43
|
+
librubyarg_shared += " -L$(libdir)"
|
44
|
+
end
|
45
|
+
|
41
46
|
File.open("Makefile", "w") do |makefile|
|
42
47
|
makefile.puts(<<-MAKEFILE)
|
43
48
|
LIBRARY = libruby-extpp.#{platform.dynamic_library_extension}
|
@@ -54,10 +59,11 @@ RUBY = #{RbConfig.ruby.quote}
|
|
54
59
|
RUBY_HEADER_DIR = #{RbConfig::CONFIG["rubyhdrdir"].quote}
|
55
60
|
RUBY_ARCH_HEADER_DIR = #{RbConfig::CONFIG["rubyarchhdrdir"].quote}
|
56
61
|
|
62
|
+
libdir = #{RbConfig::CONFIG["libdir"].quote}
|
57
63
|
sitearchdir = #{RbConfig::CONFIG["sitearchdir"].quote}
|
58
64
|
sitelibdir = #{RbConfig::CONFIG["sitelibdir"].quote}
|
59
65
|
|
60
|
-
LIBRUBYARG_SHARED = #{
|
66
|
+
LIBRUBYARG_SHARED = #{librubyarg_shared}
|
61
67
|
ARCH_FLAG = #{RbConfig::CONFIG["ARCH_FLAG"]}
|
62
68
|
LDFLAGS = #{RbConfig::CONFIG["LDFLAGS"]}
|
63
69
|
DLDFLAGS = #{RbConfig::CONFIG["DLDFLAGS"]}
|
data/ext/extpp/object.cpp
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
#include <ruby/protect.hpp>
|
2
|
+
|
3
|
+
namespace rb {
|
4
|
+
VALUE protect(RawCallback callback, VALUE callback_data) {
|
5
|
+
int state = 0;
|
6
|
+
auto result = rb_protect(callback, callback_data, &state);
|
7
|
+
if (state != 0) {
|
8
|
+
throw State(state);
|
9
|
+
}
|
10
|
+
return result;
|
11
|
+
}
|
12
|
+
}
|
data/include/ruby.hpp
CHANGED
data/include/ruby/cast.hpp
CHANGED
@@ -1,74 +1,98 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
|
+
#include <string>
|
4
|
+
|
3
5
|
#include <ruby/object.hpp>
|
4
6
|
|
5
7
|
namespace rb {
|
6
8
|
template <typename RETURN_TYPE, typename ARGUMENT_TYPE>
|
7
|
-
inline RETURN_TYPE cast(ARGUMENT_TYPE object);
|
9
|
+
inline RETURN_TYPE cast(const ARGUMENT_TYPE& object);
|
10
|
+
|
11
|
+
template <typename RETURN_TYPE, typename ARGUMENT_TYPE>
|
12
|
+
inline RETURN_TYPE cast(const ARGUMENT_TYPE *object);
|
13
|
+
|
14
|
+
template <typename RETURN_TYPE,
|
15
|
+
typename ARGUMENT_TYPE,
|
16
|
+
typename ADDTIONAL_DATA_TYPE1>
|
17
|
+
inline RETURN_TYPE cast(const ARGUMENT_TYPE& object,
|
18
|
+
ADDTIONAL_DATA_TYPE1 data1);
|
8
19
|
|
9
20
|
template <typename RETURN_TYPE,
|
10
21
|
typename ARGUMENT_TYPE,
|
11
22
|
typename ADDTIONAL_DATA_TYPE1>
|
12
|
-
inline RETURN_TYPE cast(ARGUMENT_TYPE object,
|
23
|
+
inline RETURN_TYPE cast(const ARGUMENT_TYPE *object,
|
13
24
|
ADDTIONAL_DATA_TYPE1 data1);
|
14
25
|
|
15
26
|
template <>
|
16
|
-
inline int32_t cast<int32_t, Object>(Object rb_object) {
|
27
|
+
inline int32_t cast<int32_t, Object>(const Object& rb_object) {
|
17
28
|
return NUM2INT(rb_object);
|
18
29
|
}
|
19
30
|
|
20
31
|
template <>
|
21
|
-
inline Object cast<Object, int32_t>(int32_t n) {
|
32
|
+
inline Object cast<Object, int32_t>(const int32_t& n) {
|
22
33
|
return Object(INT2NUM(n));
|
23
34
|
}
|
24
35
|
|
25
36
|
|
26
37
|
template <>
|
27
|
-
inline int64_t cast<int64_t, Object>(Object rb_object) {
|
38
|
+
inline int64_t cast<int64_t, Object>(const Object& rb_object) {
|
28
39
|
return NUM2LONG(rb_object);
|
29
40
|
}
|
30
41
|
|
31
42
|
template <>
|
32
|
-
inline Object cast<Object, int64_t>(int64_t n) {
|
43
|
+
inline Object cast<Object, int64_t>(const int64_t& n) {
|
33
44
|
return Object(LONG2NUM(n));
|
34
45
|
}
|
35
46
|
|
36
47
|
|
37
48
|
template <>
|
38
|
-
inline uint32_t cast<uint32_t, Object>(Object rb_object) {
|
49
|
+
inline uint32_t cast<uint32_t, Object>(const Object& rb_object) {
|
39
50
|
return NUM2UINT(rb_object);
|
40
51
|
}
|
41
52
|
|
42
53
|
template <>
|
43
|
-
inline Object cast<Object, uint32_t>(uint32_t n) {
|
54
|
+
inline Object cast<Object, uint32_t>(const uint32_t& n) {
|
44
55
|
return Object(UINT2NUM(n));
|
45
56
|
}
|
46
57
|
|
47
58
|
|
48
59
|
template <>
|
49
|
-
inline uint64_t cast<uint64_t, Object>(Object rb_object) {
|
60
|
+
inline uint64_t cast<uint64_t, Object>(const Object& rb_object) {
|
50
61
|
return NUM2ULONG(rb_object);
|
51
62
|
}
|
52
63
|
|
53
64
|
template <>
|
54
|
-
inline Object cast<Object, uint64_t>(uint64_t n) {
|
65
|
+
inline Object cast<Object, uint64_t>(const uint64_t& n) {
|
55
66
|
return Object(ULONG2NUM(n));
|
56
67
|
}
|
57
68
|
|
58
69
|
|
59
70
|
template <>
|
60
|
-
inline const char *cast<const char *, Object>(Object rb_object) {
|
71
|
+
inline const char *cast<const char *, Object>(const Object& rb_object) {
|
61
72
|
VALUE rb_object_raw = rb_object;
|
62
73
|
return StringValueCStr(rb_object_raw);
|
63
74
|
}
|
64
75
|
|
65
76
|
template <>
|
66
|
-
inline Object cast<Object,
|
77
|
+
inline Object cast<Object, char>(const char *c_string) {
|
67
78
|
return Object(rb_str_new_cstr(c_string));
|
68
79
|
}
|
69
80
|
|
70
81
|
template <>
|
71
|
-
inline Object cast<Object,
|
82
|
+
inline Object cast<Object, char, long>(const char *data, long size) {
|
72
83
|
return Object(rb_str_new(data, size));
|
73
84
|
}
|
85
|
+
|
86
|
+
|
87
|
+
template <>
|
88
|
+
inline std::string cast<std::string, Object>(const Object& rb_object) {
|
89
|
+
VALUE rb_object_raw = rb_object;
|
90
|
+
return std::string(RSTRING_PTR(rb_object_raw),
|
91
|
+
RSTRING_LEN(rb_object_raw));
|
92
|
+
}
|
93
|
+
|
94
|
+
template <>
|
95
|
+
inline Object cast<Object, std::string>(const std::string& string) {
|
96
|
+
return Object(rb_str_new(string.data(), string.size()));
|
97
|
+
}
|
74
98
|
}
|
data/include/ruby/class.hpp
CHANGED
data/include/ruby/object.hpp
CHANGED
@@ -13,7 +13,10 @@ namespace rb {
|
|
13
13
|
}
|
14
14
|
|
15
15
|
explicit Object(const char *name) :
|
16
|
-
rb_object_(
|
16
|
+
rb_object_(rb_funcall(rb_cObject,
|
17
|
+
rb_intern("const_get"),
|
18
|
+
1,
|
19
|
+
rb_str_new_static(name, strlen(name)))),
|
17
20
|
is_gc_guarding_(false) {
|
18
21
|
}
|
19
22
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <ruby/type.hpp>
|
4
|
+
|
5
|
+
namespace rb {
|
6
|
+
class State {
|
7
|
+
public:
|
8
|
+
explicit State(int state) :
|
9
|
+
state_(state) {
|
10
|
+
}
|
11
|
+
|
12
|
+
inline void jump() {
|
13
|
+
rb_jump_tag(state_);
|
14
|
+
}
|
15
|
+
|
16
|
+
private:
|
17
|
+
int state_;
|
18
|
+
};
|
19
|
+
|
20
|
+
VALUE protect(RawCallback callback, VALUE callback_data);
|
21
|
+
|
22
|
+
template <typename CALLBACK>
|
23
|
+
VALUE protect(const CALLBACK& callback) {
|
24
|
+
struct Data {
|
25
|
+
Data(const CALLBACK& callback) :
|
26
|
+
callback_(callback) {
|
27
|
+
}
|
28
|
+
const CALLBACK& callback_;
|
29
|
+
} data(callback);
|
30
|
+
auto callback_data = reinterpret_cast<VALUE>(&data);
|
31
|
+
return protect([](VALUE callback_data) -> VALUE {
|
32
|
+
auto data = reinterpret_cast<Data *>(callback_data);
|
33
|
+
return data->callback_();
|
34
|
+
},
|
35
|
+
callback_data);
|
36
|
+
};
|
37
|
+
}
|
data/include/ruby/type.hpp
CHANGED
@@ -3,10 +3,12 @@
|
|
3
3
|
#include <ruby.h>
|
4
4
|
|
5
5
|
namespace rb {
|
6
|
-
using
|
6
|
+
using RawMethod = VALUE (*)(ANYARGS);
|
7
7
|
|
8
8
|
using MethodWithoutArguments = VALUE (*)(VALUE self);
|
9
9
|
using MethodWithArguments = VALUE (*)(VALUE self, int argc, VALUE *argv);
|
10
10
|
using MethodWithArgumentsCompatible =
|
11
11
|
VALUE (*)(int argc, VALUE *argv, VALUE self);
|
12
|
+
|
13
|
+
using RawCallback = VALUE (*)(VALUE user_data);
|
12
14
|
}
|
data/lib/extpp.rb
CHANGED
data/lib/extpp/compiler.rb
CHANGED
@@ -14,6 +14,7 @@ module ExtPP
|
|
14
14
|
def check
|
15
15
|
check_debug_build
|
16
16
|
check_version
|
17
|
+
check_warning_flags
|
17
18
|
end
|
18
19
|
|
19
20
|
private
|
@@ -28,6 +29,22 @@ module ExtPP
|
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
32
|
+
def disable_optimization_build_flag(flags)
|
33
|
+
if gcc?
|
34
|
+
flags.gsub(/(^|\s)-O\d(\s|$)/, '\\1-O0\\2')
|
35
|
+
else
|
36
|
+
flags
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def enable_debug_build_flag(flags)
|
41
|
+
if gcc?
|
42
|
+
flags.gsub(/(^|\s)(?:-g|-g\d|-ggdb\d?)(\s|$)/, '\\1-g3\\2')
|
43
|
+
else
|
44
|
+
flags
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
31
48
|
def check_version
|
32
49
|
return unless gcc?
|
33
50
|
|
@@ -73,20 +90,37 @@ module ExtPP
|
|
73
90
|
end
|
74
91
|
end
|
75
92
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
93
|
+
def try_cxx_warning_flag(warning_flag)
|
94
|
+
conftest_cxx = "#{CONFTEST}.cpp"
|
95
|
+
begin
|
96
|
+
source = "int main(void) {return 0;}"
|
97
|
+
open(conftest_cxx, "wb") do |cxx_file|
|
98
|
+
cxx_file.print(source)
|
99
|
+
end
|
100
|
+
flags = "-Werror #{warning_flag}"
|
101
|
+
xsystem(RbConfig.expand("$(CXX) #{flags} -c #{conftest_cxx}"))
|
102
|
+
ensure
|
103
|
+
log_src(source)
|
104
|
+
MakeMakefile.rm_f(conftest_cxx)
|
81
105
|
end
|
82
106
|
end
|
83
107
|
|
84
|
-
def
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
108
|
+
def check_warning_flags
|
109
|
+
flags = []
|
110
|
+
warning_flags = []
|
111
|
+
Shellwords.split(@cxx_flags).each do |flag|
|
112
|
+
if flag.start_with?("-W")
|
113
|
+
warning_flags << flag
|
114
|
+
else
|
115
|
+
flags << flag
|
116
|
+
end
|
117
|
+
end
|
118
|
+
warning_flags.each do |warning_flag|
|
119
|
+
if try_cxx_warning_flag(warning_flag.gsub(/\A-Wno-/, "-W"))
|
120
|
+
flags << warning_flag
|
121
|
+
end
|
89
122
|
end
|
123
|
+
@cxx_flags = Shellwords.join(flags)
|
90
124
|
end
|
91
125
|
end
|
92
126
|
end
|