extpp 0.0.9 → 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.
Files changed (50) 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 +6 -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/setup.rb +0 -4
  12. data/lib/extpp/version.rb +1 -1
  13. data/lib/extpp.rb +0 -12
  14. metadata +6 -73
  15. data/ext/extpp/class.cpp +0 -277
  16. data/ext/extpp/extconf.rb +0 -110
  17. data/ext/extpp/function.cpp +0 -28
  18. data/ext/extpp/object.cpp +0 -48
  19. data/ext/extpp/protect.cpp +0 -12
  20. data/lib/extpp/platform.rb +0 -8
  21. data/test/fixtures/cast/Makefile +0 -269
  22. data/test/fixtures/cast/cast.cpp +0 -39
  23. data/test/fixtures/cast/cast.o +0 -0
  24. data/test/fixtures/cast/cast.so +0 -0
  25. data/test/fixtures/cast/extconf.rb +0 -4
  26. data/test/fixtures/cast/mkmf.log +0 -144
  27. data/test/fixtures/class/Makefile +0 -269
  28. data/test/fixtures/class/class.cpp +0 -46
  29. data/test/fixtures/class/class.o +0 -0
  30. data/test/fixtures/class/class.so +0 -0
  31. data/test/fixtures/class/extconf.rb +0 -4
  32. data/test/fixtures/class/mkmf.log +0 -144
  33. data/test/fixtures/object/Makefile +0 -269
  34. data/test/fixtures/object/extconf.rb +0 -4
  35. data/test/fixtures/object/mkmf.log +0 -144
  36. data/test/fixtures/object/object.cpp +0 -102
  37. data/test/fixtures/object/object.o +0 -0
  38. data/test/fixtures/object/object.so +0 -0
  39. data/test/fixtures/protect/Makefile +0 -269
  40. data/test/fixtures/protect/extconf.rb +0 -4
  41. data/test/fixtures/protect/mkmf.log +0 -144
  42. data/test/fixtures/protect/protect.cpp +0 -70
  43. data/test/fixtures/protect/protect.o +0 -0
  44. data/test/fixtures/protect/protect.so +0 -0
  45. data/test/helper.rb +0 -11
  46. data/test/run-test.rb +0 -31
  47. data/test/test-cast.rb +0 -46
  48. data/test/test-class.rb +0 -47
  49. data/test/test-object.rb +0 -68
  50. 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