extpp 0.0.9 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/Rakefile +1 -28
  5. data/doc/text/news.md +12 -0
  6. data/include/ruby/class.hpp +191 -14
  7. data/{ext/extpp → include/ruby}/function.hpp +20 -7
  8. data/include/ruby/object.hpp +45 -6
  9. data/include/ruby/protect.hpp +9 -2
  10. data/include/ruby.hpp +0 -10
  11. data/lib/extpp/compiler.rb +0 -6
  12. data/lib/extpp/setup.rb +0 -4
  13. data/lib/extpp/version.rb +1 -1
  14. data/lib/extpp.rb +0 -12
  15. metadata +9 -76
  16. data/ext/extpp/class.cpp +0 -277
  17. data/ext/extpp/extconf.rb +0 -110
  18. data/ext/extpp/function.cpp +0 -28
  19. data/ext/extpp/object.cpp +0 -48
  20. data/ext/extpp/protect.cpp +0 -12
  21. data/lib/extpp/platform.rb +0 -8
  22. data/test/fixtures/cast/Makefile +0 -269
  23. data/test/fixtures/cast/cast.cpp +0 -39
  24. data/test/fixtures/cast/cast.o +0 -0
  25. data/test/fixtures/cast/cast.so +0 -0
  26. data/test/fixtures/cast/extconf.rb +0 -4
  27. data/test/fixtures/cast/mkmf.log +0 -144
  28. data/test/fixtures/class/Makefile +0 -269
  29. data/test/fixtures/class/class.cpp +0 -46
  30. data/test/fixtures/class/class.o +0 -0
  31. data/test/fixtures/class/class.so +0 -0
  32. data/test/fixtures/class/extconf.rb +0 -4
  33. data/test/fixtures/class/mkmf.log +0 -144
  34. data/test/fixtures/object/Makefile +0 -269
  35. data/test/fixtures/object/extconf.rb +0 -4
  36. data/test/fixtures/object/mkmf.log +0 -144
  37. data/test/fixtures/object/object.cpp +0 -102
  38. data/test/fixtures/object/object.o +0 -0
  39. data/test/fixtures/object/object.so +0 -0
  40. data/test/fixtures/protect/Makefile +0 -269
  41. data/test/fixtures/protect/extconf.rb +0 -4
  42. data/test/fixtures/protect/mkmf.log +0 -144
  43. data/test/fixtures/protect/protect.cpp +0 -70
  44. data/test/fixtures/protect/protect.o +0 -0
  45. data/test/fixtures/protect/protect.so +0 -0
  46. data/test/helper.rb +0 -11
  47. data/test/run-test.rb +0 -31
  48. data/test/test-cast.rb +0 -46
  49. data/test/test-class.rb +0 -47
  50. data/test/test-object.rb +0 -68
  51. data/test/test-protect.rb +0 -54
data/ext/extpp/class.cpp DELETED
@@ -1,277 +0,0 @@
1
- #include "function.hpp"
2
-
3
- #include <string>
4
- #include <unordered_map>
5
- #include <vector>
6
-
7
- namespace rb {
8
- using MethodTable = std::unordered_map<ID, Function *>;
9
-
10
- struct MethodDefinition {
11
- MethodDefinition(std::string name_, Function *function_) :
12
- name(name_),
13
- function(function_) {
14
- }
15
-
16
- std::string name;
17
- Function *function;
18
- };
19
- using MethodDefinitions = std::vector<MethodDefinition>;
20
- }
21
-
22
- namespace {
23
- VALUE MethodTable = Qnil;
24
-
25
- void free_method_table(void *data) {
26
- auto method_table = static_cast<rb::MethodTable *>(data);
27
- delete method_table;
28
- }
29
-
30
- const rb_data_type_t MethodTableType = {
31
- "MethodTable",
32
- {nullptr, free_method_table, nullptr,},
33
- nullptr,
34
- nullptr,
35
- RUBY_TYPED_FREE_IMMEDIATELY,
36
- };
37
-
38
- rb::MethodTable *method_table_from_ruby(VALUE rb_method_table) {
39
- rb::MethodTable *method_table;
40
- TypedData_Get_Struct(rb_method_table,
41
- rb::MethodTable,
42
- &MethodTableType,
43
- method_table);
44
- return method_table;
45
- }
46
-
47
- VALUE method_table_to_ruby(rb::MethodTable *method_table) {
48
- if (NIL_P(MethodTable)) {
49
- MethodTable = rb_define_class("MethodTable", rb_cData);
50
- }
51
- return TypedData_Wrap_Struct(MethodTable, &MethodTableType, method_table);
52
- }
53
-
54
- VALUE MethodDefinitions = Qnil;
55
-
56
- void free_method_definitions(void *data) {
57
- auto method_definitions = static_cast<rb::MethodDefinitions *>(data);
58
- delete method_definitions;
59
- }
60
-
61
- const rb_data_type_t MethodDefinitionsType = {
62
- "MethodDefinitions",
63
- {nullptr, free_method_definitions, nullptr,},
64
- nullptr,
65
- nullptr,
66
- RUBY_TYPED_FREE_IMMEDIATELY,
67
- };
68
-
69
- rb::MethodDefinitions *method_definitions_from_ruby(VALUE rb_definitions) {
70
- rb::MethodDefinitions *definitions;
71
- TypedData_Get_Struct(rb_definitions,
72
- rb::MethodDefinitions,
73
- &MethodDefinitionsType,
74
- definitions);
75
- return definitions;
76
- }
77
-
78
- VALUE method_definitions_to_ruby(rb::MethodDefinitions *definitions) {
79
- if (NIL_P(MethodDefinitions)) {
80
- MethodDefinitions = rb_define_class("MethodDefinitions", rb_cData);
81
- }
82
- return TypedData_Wrap_Struct(MethodDefinitions,
83
- &MethodDefinitionsType,
84
- definitions);
85
- }
86
-
87
- VALUE call_func(int argc, VALUE *argv, VALUE self) {
88
- auto rb_method_table =
89
- rb_ivar_get(rb_obj_class(self), rb_intern("__method_table__"));
90
- auto method_table = method_table_from_ruby(rb_method_table);
91
- auto method_name_symbol = rb_funcall(self, rb_intern("__method__"), 0);
92
- auto function = (*method_table)[rb_sym2id(method_name_symbol)];
93
- return function->call(self, argc, argv);
94
- }
95
-
96
- bool flush_method_definitions(VALUE klass) {
97
- ID id_method_definitions = rb_intern("__method_definitions__");
98
- auto rb_definitions = rb_ivar_get(klass, id_method_definitions);
99
- if (NIL_P(rb_definitions)) {
100
- return false;
101
- }
102
-
103
- auto definitions = method_definitions_from_ruby(rb_definitions);
104
- auto rb_method_table = rb_ivar_get(klass, rb_intern("__method_table__"));
105
- auto method_table = method_table_from_ruby(rb_method_table);
106
- for (const auto &definition : *definitions) {
107
- ID name_id = rb_intern(definition.name.c_str());
108
- (*method_table)[name_id] = definition.function;
109
- rb_define_method(klass,
110
- definition.name.c_str(),
111
- reinterpret_cast<rb::RawMethod>(call_func),
112
- -1);
113
- }
114
- rb_ivar_set(klass, id_method_definitions, Qnil);
115
- return true;
116
- }
117
-
118
- VALUE method_missing(int argc, VALUE *argv, VALUE self) {
119
- auto klass = rb_obj_class(self);
120
-
121
- if (flush_method_definitions(klass)) {
122
- auto rb_method_table = rb_ivar_get(klass, rb_intern("__method_table__"));
123
- auto method_table = method_table_from_ruby(rb_method_table);
124
-
125
- VALUE rb_name_symbol;
126
- VALUE rb_args;
127
- rb_scan_args(argc, argv, "1*", &rb_name_symbol, &rb_args);
128
- auto function = (*method_table)[rb_sym2id(rb_name_symbol)];
129
- if (function) {
130
- return function->call(self,
131
- static_cast<int>(RARRAY_LEN(rb_args)),
132
- RARRAY_PTR(rb_args));
133
- }
134
- }
135
-
136
- return rb_call_super(argc, argv);
137
- }
138
-
139
- VALUE respond_to_missing_p(VALUE self,
140
- VALUE rb_name_symbol,
141
- VALUE rb_include_private) {
142
- auto klass = rb_obj_class(self);
143
-
144
- if (flush_method_definitions(klass)) {
145
- auto rb_method_table = rb_ivar_get(klass, rb_intern("__method_table__"));
146
- auto method_table = method_table_from_ruby(rb_method_table);
147
-
148
- auto function = (*method_table)[rb_sym2id(rb_name_symbol)];
149
- if (function) {
150
- return Qtrue;
151
- }
152
- }
153
-
154
- VALUE rb_args[] = {rb_name_symbol, rb_include_private};
155
- return rb_call_super(2, rb_args);
156
- }
157
- }
158
-
159
- namespace rb {
160
- class Class::ClassImpl {
161
- public:
162
- ClassImpl(VALUE klass) :
163
- class_(klass),
164
- method_table_(new MethodTable()),
165
- lazy_define_method_(false),
166
- method_definitions_(nullptr) {
167
- rb_iv_set(class_, "__method_table__", method_table_to_ruby(method_table_));
168
- rb_iv_set(class_, "__method_definitions__", Qnil);
169
- }
170
-
171
- void enable_lazy_define_method() {
172
- if (lazy_define_method_) {
173
- return;
174
- }
175
-
176
- lazy_define_method_ = true;
177
- method_definitions_ = new MethodDefinitions();
178
- rb_iv_set(class_, "__method_definitions__",
179
- method_definitions_to_ruby(method_definitions_));
180
- rb_define_method(class_,
181
- "method_missing",
182
- reinterpret_cast<RawMethod>(method_missing),
183
- -1);
184
- rb_define_method(class_,
185
- "respond_to_missing?",
186
- reinterpret_cast<RawMethod>(respond_to_missing_p),
187
- -1);
188
- }
189
-
190
- void define_method(const char *name, VALUE (*body)(VALUE self)) {
191
- rb_define_method(class_,
192
- name,
193
- reinterpret_cast<RawMethod>(body),
194
- 0);
195
- }
196
-
197
- void define_method(const char *name,
198
- VALUE (*body)(int argc, VALUE *argv, VALUE self)) {
199
- rb_define_method(class_,
200
- name,
201
- reinterpret_cast<RawMethod>(body),
202
- -1);
203
- }
204
-
205
- void define_method(const char *name, Function *function) {
206
- if (lazy_define_method_) {
207
- method_definitions_->emplace_back(name, function);
208
- } else {
209
- ID name_id = rb_intern(name);
210
- (*method_table_)[name_id] = function;
211
- rb_define_method(class_,
212
- name,
213
- reinterpret_cast<RawMethod>(call_func),
214
- -1);
215
- }
216
- }
217
-
218
- private:
219
- VALUE class_;
220
- MethodTable *method_table_;
221
- bool lazy_define_method_;
222
- MethodDefinitions *method_definitions_;
223
- };
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
-
238
- Class::Class(const char *name, VALUE parent) :
239
- Object(rb_define_class(name, parent)),
240
- impl_(new ClassImpl(this->to_ruby())) {
241
- }
242
-
243
- Class::Class(VALUE klass) :
244
- Object(klass),
245
- impl_(new ClassImpl(this->to_ruby())) {
246
- }
247
-
248
- Class::~Class() {
249
- delete impl_;
250
- }
251
-
252
- Class &Class::define_method(const char *name,
253
- MethodWithoutArguments body) {
254
- auto function = new FunctionWithoutArgument(body);
255
- impl_->define_method(name, function);
256
- return (Class &)*this;
257
- }
258
-
259
- Class &Class::define_method(const char *name,
260
- MethodWithArguments body) {
261
- auto function = new FunctionWithArguments(body);
262
- impl_->define_method(name, function);
263
- return (Class &)*this;
264
- }
265
-
266
- Class &Class::define_method(const char *name,
267
- MethodWithArgumentsCompatible body) {
268
- auto function = new FunctionWithArgumentsCompatible(body);
269
- impl_->define_method(name, function);
270
- return (Class &)*this;
271
- }
272
-
273
- Class &Class::enable_lazy_define_method() {
274
- impl_->enable_lazy_define_method();
275
- return (Class &)*this;
276
- }
277
- }
data/ext/extpp/extconf.rb DELETED
@@ -1,110 +0,0 @@
1
- require_relative "../../lib/extpp/compiler"
2
- require_relative "../../lib/extpp/platform"
3
-
4
- cxxflags = RbConfig.expand("$(CXXFLAGS)")
5
- compiler = ExtPP::Compiler.new(cxxflags)
6
- compiler.check
7
- cxxflags = compiler.cxx_flags
8
-
9
- sources = Dir.chdir(__dir__) do
10
- Dir.glob("*.cpp").collect do |cpp_source|
11
- File.join(__dir__, cpp_source)
12
- end
13
- end
14
- objects = sources.collect do |source|
15
- source.gsub(/\.cpp\z/, ".o")
16
- end
17
-
18
- def collect_headers(dir)
19
- Dir.chdir(dir) do
20
- Dir.glob("**/*.hpp").collect do |header|
21
- File.join(dir, header)
22
- end
23
- end
24
- end
25
-
26
- include_dir = File.expand_path(File.join(__dir__, "..", "..", "include"))
27
- public_headers = collect_headers(include_dir)
28
- private_headers = collect_headers(__dir__)
29
- headers = public_headers + private_headers
30
-
31
- platform = ExtPP::Platform.new
32
- case RUBY_PLATFORM
33
- when /darwin/
34
- ldsharedxx = RbConfig::CONFIG["LDSHAREDXX"]
35
- ldsharedxx = ldsharedxx.gsub(/ (?:-dynamic|-bundle)/, "") + " -shared"
36
- ldsharedxx += " -install_name #{Dir.pwd.quote}/$(LIBRARY)"
37
- else
38
- ldsharedxx = RbConfig::CONFIG["LDSHAREDXX"]
39
- end
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
-
46
- File.open("Makefile", "w") do |makefile|
47
- makefile.puts(<<-MAKEFILE)
48
- LIBRARY = libruby-extpp.#{platform.dynamic_library_extension}
49
-
50
- SOURCES = #{sources.collect(&:quote).join(" ")}
51
- OBJECTS = #{objects.collect(&:quote).join(" ")}
52
- HEADERS = #{headers.collect(&:quote).join(" ")}
53
-
54
- INCLUDE_DIR = #{include_dir.quote}
55
-
56
- CXX = #{RbConfig.expand("$(CXX)")}
57
-
58
- RUBY = #{RbConfig.ruby.quote}
59
- RUBY_HEADER_DIR = #{RbConfig::CONFIG["rubyhdrdir"].quote}
60
- RUBY_ARCH_HEADER_DIR = #{RbConfig::CONFIG["rubyarchhdrdir"].quote}
61
-
62
- libdir = #{RbConfig::CONFIG["libdir"].quote}
63
- sitearchdir = #{RbConfig::CONFIG["sitearchdir"].quote}
64
- sitelibdir = #{RbConfig::CONFIG["sitelibdir"].quote}
65
-
66
- LIBRUBYARG_SHARED = #{librubyarg_shared}
67
- ARCH_FLAG = #{RbConfig::CONFIG["ARCH_FLAG"]}
68
- LDFLAGS = #{RbConfig::CONFIG["LDFLAGS"]}
69
- DLDFLAGS = #{RbConfig::CONFIG["DLDFLAGS"]}
70
- EXTDLDFLAGS = #{RbConfig::CONFIG["EXTDLDFLAGS"]}
71
- LDSHAREDXX = #{ldsharedxx}
72
- CCDLFLAGS = #{RbConfig::CONFIG["CCDLFLAGS"]}
73
-
74
- INCLUDEFLAGS = \
75
- -I$(INCLUDE_DIR) \
76
- -I$(RUBY_HEADER_DIR) \
77
- -I$(RUBY_ARCH_HEADER_DIR)
78
- CPPFLAGS = #{RbConfig::CONFIG["CPPFLAGS"]} -DRB_EXTPP_COMPILATION
79
- CXXFLAGS = $(CCDLFLAGS) #{cxxflags}
80
-
81
- all: $(LIBRARY)
82
-
83
- clean:
84
- rm -rf $(OBJECTS) $(LIBRARY)
85
-
86
- dist-clean:
87
- $(MAKE) clean
88
- rm -rf Makefile
89
-
90
- install: install-so
91
-
92
- install-so: $(LIBRARY)
93
- "$(RUBY)" -run -e install -- $(LIBRARY) $(sitearchdir)
94
-
95
- $(LIBRARY): $(OBJECTS) Makefile
96
- $(LDSHAREDXX) \\
97
- -o $@ \\
98
- $(OBJECTS) \\
99
- $(LDFLAGS) \\
100
- $(DLDFLAGS) \\
101
- $(EXTDLDFLAGS) \\
102
- $(ARCH_FLAG) \\
103
- $(LIBRUBYARG_SHARED)
104
-
105
- .cpp.o:
106
- $(CXX) $(INCLUDEFLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
107
-
108
- $(OBJECTS): $(HEADERS)
109
- MAKEFILE
110
- end
@@ -1,28 +0,0 @@
1
- #include "function.hpp"
2
-
3
- namespace rb {
4
- FunctionWithoutArgument::FunctionWithoutArgument(const MethodWithoutArguments &function) :
5
- function_(function) {
6
- }
7
-
8
- VALUE FunctionWithoutArgument::call(VALUE self, int argc, VALUE *argv) {
9
- return function_(self);
10
- };
11
-
12
-
13
- FunctionWithArguments::FunctionWithArguments(const MethodWithArguments &function) :
14
- function_(function) {
15
- }
16
-
17
- VALUE FunctionWithArguments::call(VALUE self, int argc, VALUE *argv) {
18
- return function_(self, argc, argv);
19
- };
20
-
21
- FunctionWithArgumentsCompatible::FunctionWithArgumentsCompatible(const MethodWithArgumentsCompatible &function) :
22
- function_(function) {
23
- }
24
-
25
- VALUE FunctionWithArgumentsCompatible::call(VALUE self, int argc, VALUE *argv) {
26
- return function_(argc, argv, self);
27
- };
28
- }
data/ext/extpp/object.cpp DELETED
@@ -1,48 +0,0 @@
1
- #include <ruby.hpp>
2
-
3
- namespace {
4
- VALUE call_block(RB_BLOCK_CALL_FUNC_ARGLIST(rb_data, rb_block)) {
5
- auto block = reinterpret_cast<rb::MethodWithoutArguments>(rb_block);
6
- return block(rb_data);
7
- }
8
- }
9
-
10
- namespace rb {
11
- Object Object::send(ID name_id) {
12
- VALUE rb_result = rb_funcall(rb_object_, name_id, 0);
13
- return Object(rb_result);
14
- }
15
-
16
- Object Object::send(ID name_id,
17
- std::initializer_list<VALUE> args) {
18
- auto n = args.size();
19
- VALUE rb_args[n];
20
- int i = 0;
21
- for (auto arg : args) {
22
- rb_args[i++] = arg;
23
- }
24
- VALUE rb_result = rb_funcallv(rb_object_,
25
- name_id,
26
- static_cast<int>(n),
27
- rb_args);
28
- return Object(rb_result);
29
- }
30
-
31
- Object Object::send(ID name_id,
32
- std::initializer_list<VALUE> args,
33
- MethodWithoutArguments block) {
34
- auto n = args.size();
35
- VALUE rb_args[n];
36
- int i = 0;
37
- for (auto arg : args) {
38
- rb_args[i++] = arg;
39
- }
40
- VALUE rb_result = rb_block_call(rb_object_,
41
- name_id,
42
- static_cast<int>(n),
43
- rb_args,
44
- reinterpret_cast<RawMethod>(call_block),
45
- reinterpret_cast<VALUE>(block));
46
- return Object(rb_result);
47
- }
48
- }
@@ -1,12 +0,0 @@
1
- #include <ruby.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
- }
@@ -1,8 +0,0 @@
1
- module ExtPP
2
- class Platform
3
- def dynamic_library_extension
4
- RbConfig::CONFIG["SOEXT"]
5
- end
6
- alias_method :shared_library_extension, :dynamic_library_extension
7
- end
8
- end