fiddle 1.0.9 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
  - - ">="