fiddle 1.0.9 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 05f04e2fc988a1635621c537e5836231c2ae496ed45990523be623b44c8557be
4
- data.tar.gz: b81aec1d67a6a08413245b483c6aed84052df7f5b907e8111bf1b8a47c2e69bd
3
+ metadata.gz: 53ccf1d87df1a91951377a4baf37bf13519b15a05dd4ae6f18789027ffa69a44
4
+ data.tar.gz: 59c667cd8a70043e46e517b77700565e481d0ea69c8f7e85a5a27f98914ed357
5
5
  SHA512:
6
- metadata.gz: 7b1c8640fb5a93f6b8c36eb3062f7b795cc10160176fe6d8e3f1370c5ce4ffd2e3036581ed4a3842a8eeb6d595219e8ee370c9c0d996e6213dfcb400fea10c58
7
- data.tar.gz: fcd3f9cf4d08f760065770d2529f95c17dc8c95f889d691824f98bad1cb03fbeee20dcf005493b4bc9b66850b7fecdf022b13aaa6c359949a2266696a313619f
6
+ metadata.gz: a10f7c91bde1fe0b9d9c1cc57a0b0ea1c0001e59301496cb676893f0fc948bbae570a8c78ac523a84c43b977db17ff9c2c101e7154ece15ac2b66eb4cf561618
7
+ data.tar.gz: 41be31921c03c6a153f24bfda7753c706ad0d68602fc6b59f8fe2ebe4d54282e3c0e029ff327ac2aa17bca9e66ccb593d133b6534bd677169b1a99d16ad8bfc8
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Fiddle
2
2
 
3
- [![Build Status](https://travis-ci.org/ruby/fiddle.svg?branch=master)](https://travis-ci.org/ruby/fiddle)
3
+ [![CI](https://github.com/ruby/fiddle/actions/workflows/ci.yml/badge.svg)](https://github.com/ruby/fiddle/actions/workflows/ci.yml)
4
4
 
5
5
  A libffi wrapper for Ruby.
6
6
 
data/Rakefile CHANGED
@@ -5,6 +5,18 @@ task :test do
5
5
  ruby("test/run.rb")
6
6
  end
7
7
 
8
+ namespace :version do
9
+ desc "Bump version"
10
+ task :bump do
11
+ version_rb_path = "lib/fiddle/version.rb"
12
+ version_rb = File.read(version_rb_path).gsub(/VERSION = "(.+?)"/) do
13
+ version = $1
14
+ "VERSION = \"#{version.succ}\""
15
+ end
16
+ File.write(version_rb_path, version_rb)
17
+ end
18
+ end
19
+
8
20
  require 'rake/extensiontask'
9
21
  Rake::ExtensionTask.new("fiddle")
10
22
  Rake::ExtensionTask.new("-test-/memory_view")
@@ -187,6 +187,7 @@ else
187
187
  end
188
188
 
189
189
  have_header 'sys/mman.h'
190
+ have_header 'link.h'
190
191
 
191
192
  if have_header "dlfcn.h"
192
193
  have_library "dl"
@@ -196,8 +197,10 @@ if have_header "dlfcn.h"
196
197
  end
197
198
 
198
199
  have_func "dlerror"
200
+ have_func "dlinfo"
201
+ have_const("RTLD_DI_LINKMAP", "dlfcn.h")
199
202
  elsif have_header "windows.h"
200
- %w{ LoadLibrary FreeLibrary GetProcAddress }.each do |func|
203
+ %w{ LoadLibrary FreeLibrary GetProcAddress GetModuleFileName }.each do |func|
201
204
  abort "missing function #{func}" unless have_func(func)
202
205
  end
203
206
 
@@ -222,10 +225,6 @@ types.each do |type, signed|
222
225
  end
223
226
  end
224
227
 
225
- if have_header("ruby/memory_view.h")
226
- have_type("rb_memory_view_t", ["ruby/memory_view.h"])
227
- end
228
-
229
228
  if libffi
230
229
  $LOCAL_LIBS.prepend("./#{libffi.a} ").strip! # to exts.mk
231
230
  $INCFLAGS.gsub!(/-I#{libffi.dir}/, '-I$(LIBFFI_DIR)')
data/ext/fiddle/fiddle.c CHANGED
@@ -7,7 +7,7 @@ VALUE rb_eFiddleError;
7
7
  void Init_fiddle_pointer(void);
8
8
  void Init_fiddle_pinned(void);
9
9
 
10
- #ifdef FIDDLE_MEMORY_VIEW
10
+ #ifdef HAVE_RUBY_MEMORY_VIEW_H
11
11
  void Init_fiddle_memory_view(void);
12
12
  #endif
13
13
 
@@ -546,7 +546,7 @@ Init_fiddle(void)
546
546
  Init_fiddle_pointer();
547
547
  Init_fiddle_pinned();
548
548
 
549
- #ifdef FIDDLE_MEMORY_VIEW
549
+ #ifdef HAVE_RUBY_MEMORY_VIEW_H
550
550
  Init_fiddle_memory_view();
551
551
  #endif
552
552
  }
data/ext/fiddle/fiddle.h CHANGED
@@ -12,6 +12,10 @@
12
12
  #include <sys/mman.h>
13
13
  #endif
14
14
 
15
+ #if defined(HAVE_LINK_H)
16
+ # include <link.h>
17
+ #endif
18
+
15
19
  #if defined(HAVE_DLFCN_H)
16
20
  # include <dlfcn.h>
17
21
  # /* some stranger systems may not define all of these */
@@ -189,14 +193,13 @@
189
193
  #define ALIGN_INT32_T ALIGN_OF(int32_t)
190
194
  #define ALIGN_INT64_T ALIGN_OF(int64_t)
191
195
 
192
- #ifdef HAVE_TYPE_RB_MEMORY_VIEW_T
193
- # define FIDDLE_MEMORY_VIEW
194
- #endif
195
-
196
196
  extern VALUE mFiddle;
197
197
  extern VALUE rb_eFiddleDLError;
198
198
 
199
199
  VALUE rb_fiddle_new_function(VALUE address, VALUE arg_types, VALUE ret_type);
200
200
 
201
+ typedef void (*rb_fiddle_freefunc_t)(void*);
202
+ VALUE rb_fiddle_ptr_new_wrap(void *ptr, long size, rb_fiddle_freefunc_t func, VALUE wrap0, VALUE wrap1);
203
+
201
204
  #endif
202
205
  /* vim: set noet sws=4 sw=4: */
data/ext/fiddle/handle.c CHANGED
@@ -259,7 +259,21 @@ rb_fiddle_handle_to_i(VALUE self)
259
259
  struct dl_handle *fiddle_handle;
260
260
 
261
261
  TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
262
- return PTR2NUM(fiddle_handle);
262
+ return PTR2NUM(fiddle_handle->ptr);
263
+ }
264
+
265
+ /*
266
+ * call-seq: to_ptr
267
+ *
268
+ * Returns the Fiddle::Pointer of this handle.
269
+ */
270
+ static VALUE
271
+ rb_fiddle_handle_to_ptr(VALUE self)
272
+ {
273
+ struct dl_handle *fiddle_handle;
274
+
275
+ TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
276
+ return rb_fiddle_ptr_new_wrap(fiddle_handle->ptr, 0, 0, self, 0);
263
277
  }
264
278
 
265
279
  static VALUE fiddle_handle_sym(void *handle, VALUE symbol);
@@ -372,6 +386,48 @@ fiddle_handle_sym(void *handle, VALUE symbol)
372
386
  return PTR2NUM(func);
373
387
  }
374
388
 
389
+ /*
390
+ * call-seq: file_name
391
+ *
392
+ * Returns the file name of this handle.
393
+ */
394
+ static VALUE
395
+ rb_fiddle_handle_file_name(VALUE self)
396
+ {
397
+ struct dl_handle *fiddle_handle;
398
+
399
+ TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
400
+
401
+ #if defined(HAVE_DLINFO) && defined(HAVE_CONST_RTLD_DI_LINKMAP)
402
+ {
403
+ struct link_map *lm = NULL;
404
+ int res = dlinfo(fiddle_handle->ptr, RTLD_DI_LINKMAP, &lm);
405
+ if (res == 0 && lm != NULL) {
406
+ return rb_str_new_cstr(lm->l_name);
407
+ }
408
+ else {
409
+ #if defined(HAVE_DLERROR)
410
+ rb_raise(rb_eFiddleDLError, "could not get handle file name: %s", dlerror());
411
+ #else
412
+ rb_raise(rb_eFiddleDLError, "could not get handle file name");
413
+ #endif
414
+ }
415
+ }
416
+ #elif defined(HAVE_GETMODULEFILENAME)
417
+ {
418
+ char filename[MAX_PATH];
419
+ DWORD res = GetModuleFileName(fiddle_handle->ptr, filename, MAX_PATH);
420
+ if (res == 0) {
421
+ rb_raise(rb_eFiddleDLError, "could not get handle file name: %s", dlerror());
422
+ }
423
+ return rb_str_new_cstr(filename);
424
+ }
425
+ #else
426
+ (void)fiddle_handle;
427
+ return Qnil;
428
+ #endif
429
+ }
430
+
375
431
  void
376
432
  Init_fiddle_handle(void)
377
433
  {
@@ -466,9 +522,11 @@ Init_fiddle_handle(void)
466
522
 
467
523
  rb_define_method(rb_cHandle, "initialize", rb_fiddle_handle_initialize, -1);
468
524
  rb_define_method(rb_cHandle, "to_i", rb_fiddle_handle_to_i, 0);
525
+ rb_define_method(rb_cHandle, "to_ptr", rb_fiddle_handle_to_ptr, 0);
469
526
  rb_define_method(rb_cHandle, "close", rb_fiddle_handle_close, 0);
470
527
  rb_define_method(rb_cHandle, "sym", rb_fiddle_handle_sym, 1);
471
528
  rb_define_method(rb_cHandle, "[]", rb_fiddle_handle_sym, 1);
529
+ rb_define_method(rb_cHandle, "file_name", rb_fiddle_handle_file_name, 0);
472
530
  rb_define_method(rb_cHandle, "disable_close", rb_fiddle_handle_disable_close, 0);
473
531
  rb_define_method(rb_cHandle, "enable_close", rb_fiddle_handle_enable_close, 0);
474
532
  rb_define_method(rb_cHandle, "close_enabled?", rb_fiddle_handle_close_enabled_p, 0);
@@ -1,10 +1,11 @@
1
+ #include <fiddle.h>
2
+
3
+ #ifdef HAVE_RUBY_MEMORY_VIEW_H
4
+
1
5
  #include <stdbool.h>
2
6
  #include <ruby/ruby.h>
3
7
  #include <ruby/encoding.h>
4
-
5
- #ifdef HAVE_RUBY_MEMORY_VIEW_H
6
- # include <ruby/memory_view.h>
7
- #endif
8
+ #include <ruby/memory_view.h>
8
9
 
9
10
  #if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
10
11
  # define INTPTR2NUM LL2NUM
@@ -17,9 +18,6 @@
17
18
  # define UINTPTR2NUM UINT2NUM
18
19
  #endif
19
20
 
20
- #include <fiddle.h>
21
-
22
- #ifdef FIDDLE_MEMORY_VIEW
23
21
  VALUE rb_cMemoryView = Qnil;
24
22
 
25
23
  struct memview_data {
@@ -320,4 +318,4 @@ Init_fiddle_memory_view(void)
320
318
  rb_define_method(rb_cMemoryView, "to_s", rb_fiddle_memview_to_s, 0);
321
319
  }
322
320
 
323
- #endif /* FIDDLE_MEMORY_VIEW */
321
+ #endif /* HAVE_RUBY_MEMORY_VIEW_H */
data/ext/fiddle/pointer.c CHANGED
@@ -6,13 +6,13 @@
6
6
  #include <ruby/ruby.h>
7
7
  #include <ruby/io.h>
8
8
 
9
+ #include <ctype.h>
10
+ #include <fiddle.h>
11
+
9
12
  #ifdef HAVE_RUBY_MEMORY_VIEW_H
10
13
  # include <ruby/memory_view.h>
11
14
  #endif
12
15
 
13
- #include <ctype.h>
14
- #include <fiddle.h>
15
-
16
16
  #ifdef PRIsVALUE
17
17
  # define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj)
18
18
  # define RB_OBJ_STRING(obj) (obj)
@@ -24,7 +24,7 @@
24
24
 
25
25
  VALUE rb_cPointer;
26
26
 
27
- typedef void (*freefunc_t)(void*);
27
+ typedef rb_fiddle_freefunc_t freefunc_t;
28
28
 
29
29
  struct ptr_data {
30
30
  void *ptr;
@@ -92,7 +92,7 @@ static const rb_data_type_t fiddle_ptr_data_type = {
92
92
  {fiddle_ptr_mark, fiddle_ptr_free, fiddle_ptr_memsize,},
93
93
  };
94
94
 
95
- #ifdef FIDDLE_MEMORY_VIEW
95
+ #ifdef HAVE_RUBY_MEMORY_VIEW_H
96
96
  static struct ptr_data *
97
97
  fiddle_ptr_check_memory_view(VALUE obj)
98
98
  {
@@ -125,7 +125,7 @@ static const rb_memory_view_entry_t fiddle_ptr_memory_view_entry = {
125
125
  #endif
126
126
 
127
127
  static VALUE
128
- rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
128
+ rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func, VALUE wrap0, VALUE wrap1)
129
129
  {
130
130
  struct ptr_data *data;
131
131
  VALUE val;
@@ -135,14 +135,22 @@ rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
135
135
  data->free = func;
136
136
  data->freed = false;
137
137
  data->size = size;
138
+ data->wrap[0] = wrap0;
139
+ data->wrap[1] = wrap1;
138
140
 
139
141
  return val;
140
142
  }
141
143
 
144
+ VALUE
145
+ rb_fiddle_ptr_new_wrap(void *ptr, long size, freefunc_t func, VALUE wrap0, VALUE wrap1)
146
+ {
147
+ return rb_fiddle_ptr_new2(rb_cPointer, ptr, size, func, wrap0, wrap1);
148
+ }
149
+
142
150
  static VALUE
143
151
  rb_fiddle_ptr_new(void *ptr, long size, freefunc_t func)
144
152
  {
145
- return rb_fiddle_ptr_new2(rb_cPointer, ptr, size, func);
153
+ return rb_fiddle_ptr_new2(rb_cPointer, ptr, size, func, 0, 0);
146
154
  }
147
155
 
148
156
  static VALUE
@@ -152,7 +160,7 @@ rb_fiddle_ptr_malloc(VALUE klass, long size, freefunc_t func)
152
160
 
153
161
  ptr = ruby_xmalloc((size_t)size);
154
162
  memset(ptr,0,(size_t)size);
155
- return rb_fiddle_ptr_new2(klass, ptr, size, func);
163
+ return rb_fiddle_ptr_new2(klass, ptr, size, func, 0, 0);
156
164
  }
157
165
 
158
166
  static void *
@@ -833,7 +841,7 @@ Init_fiddle_pointer(void)
833
841
  rb_define_method(rb_cPointer, "size", rb_fiddle_ptr_size_get, 0);
834
842
  rb_define_method(rb_cPointer, "size=", rb_fiddle_ptr_size_set, 1);
835
843
 
836
- #ifdef FIDDLE_MEMORY_VIEW
844
+ #ifdef HAVE_RUBY_MEMORY_VIEW_H
837
845
  rb_memory_view_register(rb_cPointer, &fiddle_ptr_memory_view_entry);
838
846
  #endif
839
847
 
data/fiddle.gemspec CHANGED
@@ -56,11 +56,7 @@ Gem::Specification.new do |spec|
56
56
  spec.require_paths = ["lib"]
57
57
  spec.extensions = ["ext/fiddle/extconf.rb"]
58
58
 
59
- spec.required_ruby_version = ">= 2.3.0"
60
-
61
- spec.add_development_dependency "bundler"
62
- spec.add_development_dependency "rake"
63
- spec.add_development_dependency "rake-compiler"
59
+ spec.required_ruby_version = ">= 2.5.0"
64
60
 
65
61
  spec.metadata["msys2_mingw_dependencies"] = "libffi"
66
62
  end
data/lib/fiddle/struct.rb CHANGED
@@ -13,6 +13,58 @@ module Fiddle
13
13
  CStructEntity
14
14
  end
15
15
 
16
+ def self.offsetof(name, members, types) # :nodoc:
17
+ offset = 0
18
+ worklist = name.split('.')
19
+ this_type = self
20
+ while search_name = worklist.shift
21
+ index = 0
22
+ member_index = members.index(search_name)
23
+
24
+ unless member_index
25
+ # Possibly a sub-structure
26
+ member_index = members.index { |member_name, _|
27
+ member_name == search_name
28
+ }
29
+ return unless member_index
30
+ end
31
+
32
+ types.each { |type, count = 1|
33
+ orig_offset = offset
34
+ if type.respond_to?(:entity_class)
35
+ align = type.alignment
36
+ type_size = type.size
37
+ else
38
+ align = PackInfo::ALIGN_MAP[type]
39
+ type_size = PackInfo::SIZE_MAP[type]
40
+ end
41
+
42
+ # Unions shouldn't advance the offset
43
+ if this_type.entity_class == CUnionEntity
44
+ type_size = 0
45
+ end
46
+
47
+ offset = PackInfo.align(orig_offset, align)
48
+
49
+ if worklist.empty?
50
+ return offset if index == member_index
51
+ else
52
+ if index == member_index
53
+ subtype = types[member_index]
54
+ members = subtype.members
55
+ types = subtype.types
56
+ this_type = subtype
57
+ break
58
+ end
59
+ end
60
+
61
+ offset += (type_size * count)
62
+ index += 1
63
+ }
64
+ end
65
+ nil
66
+ end
67
+
16
68
  def each
17
69
  return enum_for(__function__) unless block_given?
18
70
 
@@ -75,6 +127,10 @@ module Fiddle
75
127
  def CUnion.entity_class
76
128
  CUnionEntity
77
129
  end
130
+
131
+ def self.offsetof(name, members, types) # :nodoc:
132
+ 0
133
+ end
78
134
  end
79
135
 
80
136
  # Wrapper for arrays within a struct
@@ -172,6 +228,21 @@ module Fiddle
172
228
  define_method(:to_i){ @entity.to_i }
173
229
  define_singleton_method(:types) { types }
174
230
  define_singleton_method(:members) { members }
231
+
232
+ # Return the offset of a struct member given its name.
233
+ # For example:
234
+ #
235
+ # MyStruct = struct [
236
+ # "int64_t i",
237
+ # "char c",
238
+ # ]
239
+ #
240
+ # MyStruct.offsetof("i") # => 0
241
+ # MyStruct.offsetof("c") # => 8
242
+ #
243
+ define_singleton_method(:offsetof) { |name|
244
+ klass.offsetof(name, members, types)
245
+ }
175
246
  members.each{|name|
176
247
  name = name[0] if name.is_a?(Array) # name is a nested struct
177
248
  next if method_defined?(name)
@@ -1,3 +1,3 @@
1
1
  module Fiddle
2
- VERSION = "1.0.9"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fiddle
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.9
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
@@ -9,50 +9,8 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-06-19 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: bundler
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - ">="
19
- - !ruby/object:Gem::Version
20
- version: '0'
21
- type: :development
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- version: '0'
28
- - !ruby/object:Gem::Dependency
29
- name: rake
30
- requirement: !ruby/object:Gem::Requirement
31
- requirements:
32
- - - ">="
33
- - !ruby/object:Gem::Version
34
- version: '0'
35
- type: :development
36
- prerelease: false
37
- version_requirements: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- version: '0'
42
- - !ruby/object:Gem::Dependency
43
- name: rake-compiler
44
- requirement: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: '0'
49
- type: :development
50
- prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: '0'
12
+ date: 2021-10-22 00:00:00.000000000 Z
13
+ dependencies: []
56
14
  description: A libffi wrapper for Ruby.
57
15
  email:
58
16
  - aaron@tenderlovemaking.com
@@ -111,7 +69,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
69
  requirements:
112
70
  - - ">="
113
71
  - !ruby/object:Gem::Version
114
- version: 2.3.0
72
+ version: 2.5.0
115
73
  required_rubygems_version: !ruby/object:Gem::Requirement
116
74
  requirements:
117
75
  - - ">="