fiddle 1.0.0.beta1 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,13 +24,23 @@ typedef union
24
24
  void * pointer; /* ffi_type_pointer */
25
25
  } fiddle_generic;
26
26
 
27
+ /* Deprecated. Use rb_fiddle_*() version. */
28
+ VALUE rb_fiddle_type_ensure(VALUE type);
29
+ ffi_type * rb_fiddle_int_to_ffi_type(int type);
30
+ void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst);
31
+ VALUE rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval);
32
+
33
+ /* Deprecated. Use rb_fiddle_*() version. */
27
34
  ffi_type * int_to_ffi_type(int type);
28
- void value_to_generic(int type, VALUE src, fiddle_generic * dst);
35
+ void value_to_generic(int type, VALUE src, fiddle_generic *dst);
29
36
  VALUE generic_to_value(VALUE rettype, fiddle_generic retval);
30
37
 
31
- #define VALUE2GENERIC(_type, _src, _dst) value_to_generic((_type), (_src), (_dst))
32
- #define INT2FFI_TYPE(_type) int_to_ffi_type(_type)
33
- #define GENERIC2VALUE(_type, _retval) generic_to_value((_type), (_retval))
38
+ #define VALUE2GENERIC(_type, _src, _dst) \
39
+ rb_fiddle_value_to_generic((_type), &(_src), (_dst))
40
+ #define INT2FFI_TYPE(_type) \
41
+ rb_fiddle_int_to_ffi_type(_type)
42
+ #define GENERIC2VALUE(_type, _retval) \
43
+ rb_fiddle_generic_to_value((_type), (_retval))
34
44
 
35
45
  #if SIZEOF_VOIDP == SIZEOF_LONG
36
46
  # define PTR2NUM(x) (LONG2NUM((long)(x)))
@@ -0,0 +1,83 @@
1
+ PWD =
2
+
3
+ CONFIGURE_LIBFFI = \
4
+ $(LIBFFI_CONFIGURE) --disable-shared \
5
+ --host=$(LIBFFI_ARCH) --enable-builddir=$(arch) \
6
+ CC="$(CC)" CFLAGS="$(LIBFFI_CFLAGS)" \
7
+ LD="$(LD)" LDFLAGS="$(LIBFFI_LDFLAGS)"
8
+
9
+ $(STATIC_LIB) $(RUBYARCHDIR)/$(DLLIB) $(DLLIB): $(LIBFFI_A)
10
+
11
+ $(OBJS): $(FFI_H)
12
+
13
+ .PHONY: .FORCE hdr
14
+
15
+ .FORCE:
16
+
17
+ hdr: $(FFI_H)
18
+
19
+ configure-libffi build-libffi: .FORCE
20
+ configure-libffi \
21
+ $(LIBFFI_DIR)/include/ffi.h \
22
+ $(LIBFFI_DIR)/include/ffitarget.h \
23
+ $(LIBFFI_DIR)/fficonfig.h \
24
+ $(LIBFFI_DIR)/Makefile:
25
+ $(Q) $(MAKEDIRS) $(LIBFFI_DIR)
26
+ $(Q) $(CONFIGURE_LIBFFI)
27
+
28
+ build-libffi $(LIBFFI_A):
29
+ $(Q) $(SUBMAKE_PRE) $(MAKE) $(SUBMAKE_ARG)
30
+
31
+ clean-none:
32
+ clean-libffi:
33
+ $(Q) $(SUBMAKE_PRE) $(MAKE) $(SUBMAKE_ARG) clean
34
+
35
+ distclean-none:
36
+ distclean-libffi:
37
+ $(Q) $(SUBMAKE_PRE) $(MAKE) $(SUBMAKE_ARG) distclean
38
+ $(Q) $(RM) $(LIBFFI_DIR)/local.exp
39
+ $(Q) $(RUBY) -rfileutils -e "FileUtils.rmdir(Dir.glob(ARGV[0]+'/**/{,.*/}'), :parents=>true)" $(LIBFFI_DIR)
40
+
41
+ realclean-none:
42
+ realclean-libffi:
43
+ $(Q) $(RMALL) $(LIBFFI_DIR)
44
+
45
+ .PHONY: clean-libffi distclean-libffi realclean-libffi
46
+ .PHONY: clean-none distclean-none realclean-none
47
+
48
+ clean: clean-$(LIBFFI_CLEAN)
49
+ distclean: distclean-$(LIBFFI_CLEAN)
50
+ realclean: realclean-$(LIBFFI_CLEAN)
51
+
52
+ .PHONY: configure configure-libffi
53
+
54
+ closure.o: closure.c
55
+ closure.o: closure.h
56
+ closure.o: conversions.h
57
+ closure.o: fiddle.h
58
+ closure.o: function.h
59
+ conversions.o: closure.h
60
+ conversions.o: conversions.c
61
+ conversions.o: conversions.h
62
+ conversions.o: fiddle.h
63
+ conversions.o: function.h
64
+ fiddle.o: closure.h
65
+ fiddle.o: conversions.h
66
+ fiddle.o: fiddle.c
67
+ fiddle.o: fiddle.h
68
+ fiddle.o: function.h
69
+ function.o: closure.h
70
+ function.o: conversions.h
71
+ function.o: fiddle.h
72
+ function.o: function.c
73
+ function.o: function.h
74
+ handle.o: closure.h
75
+ handle.o: conversions.h
76
+ handle.o: fiddle.h
77
+ handle.o: function.h
78
+ handle.o: handle.c
79
+ pointer.o: closure.h
80
+ pointer.o: conversions.h
81
+ pointer.o: fiddle.h
82
+ pointer.o: function.h
83
+ pointer.o: pointer.c
@@ -1,52 +1,72 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  require 'mkmf'
3
3
 
4
4
  # :stopdoc:
5
5
 
6
+ libffi_version = nil
7
+ have_libffi = false
6
8
  bundle = enable_config('bundled-libffi')
7
- if ! bundle
9
+ unless bundle
8
10
  dir_config 'libffi'
9
11
 
10
- pkg_config("libffi") and
11
- ver = pkg_config("libffi", "modversion")
12
+ if pkg_config("libffi")
13
+ libffi_version = pkg_config("libffi", "modversion")
14
+ end
12
15
 
16
+ have_ffi_header = false
13
17
  if have_header(ffi_header = 'ffi.h')
14
- true
18
+ have_ffi_header = true
15
19
  elsif have_header(ffi_header = 'ffi/ffi.h')
16
- $defs.push(format('-DUSE_HEADER_HACKS'))
17
- true
18
- end and (have_library('ffi') || have_library('libffi'))
19
- end or
20
- begin
21
- ver = bundle != false &&
22
- Dir.glob("#{$srcdir}/libffi-*/")
23
- .map {|n| File.basename(n)}
24
- .max_by {|n| n.scan(/\d+/).map(&:to_i)}
25
- unless ver
20
+ $defs.push('-DUSE_HEADER_HACKS')
21
+ have_ffi_header = true
22
+ end
23
+ if have_ffi_header && (have_library('ffi') || have_library('libffi'))
24
+ have_libffi = true
25
+ end
26
+ end
27
+
28
+ unless have_libffi
29
+ # for https://github.com/ruby/fiddle
30
+ extlibs_rb = File.expand_path("../../bin/extlibs.rb", $srcdir)
31
+ if bundle && File.exist?(extlibs_rb)
32
+ require "fileutils"
33
+ require_relative "../../bin/extlibs"
34
+ extlibs = ExtLibs.new
35
+ cache_dir = File.expand_path("../../tmp/.download_cache", $srcdir)
36
+ ext_dir = File.expand_path("../../ext", $srcdir)
37
+ Dir.glob("#{$srcdir}/libffi-*/").each{|dir| FileUtils.rm_rf(dir)}
38
+ extlibs.run(["--cache=#{cache_dir}", ext_dir])
39
+ end
40
+ if bundle != false
41
+ libffi_package_name = Dir.glob("#{$srcdir}/libffi-*/")
42
+ .map {|n| File.basename(n)}
43
+ .max_by {|n| n.scan(/\d+/).map(&:to_i)}
44
+ end
45
+ unless libffi_package_name
26
46
  raise "missing libffi. Please install libffi."
27
47
  end
28
48
 
29
- srcdir = "#{$srcdir}/#{ver}"
49
+ libffi_srcdir = "#{$srcdir}/#{libffi_package_name}"
30
50
  ffi_header = 'ffi.h'
31
51
  libffi = Struct.new(*%I[dir srcdir builddir include lib a cflags ldflags opt arch]).new
32
- libffi.dir = ver
52
+ libffi.dir = libffi_package_name
33
53
  if $srcdir == "."
34
- libffi.builddir = "#{ver}/#{RUBY_PLATFORM}"
54
+ libffi.builddir = libffi_package_name
35
55
  libffi.srcdir = "."
36
56
  else
37
57
  libffi.builddir = libffi.dir
38
- libffi.srcdir = relative_from(srcdir, "..")
58
+ libffi.srcdir = relative_from(libffi_srcdir, "..")
39
59
  end
40
60
  libffi.include = "#{libffi.builddir}/include"
41
61
  libffi.lib = "#{libffi.builddir}/.libs"
42
62
  libffi.a = "#{libffi.lib}/libffi_convenience.#{$LIBEXT}"
43
63
  nowarn = CONFIG.merge("warnflags"=>"")
44
- libffi.cflags = RbConfig.expand("$(CFLAGS)", nowarn)
45
- ver = ver[/libffi-(.*)/, 1]
64
+ libffi.cflags = RbConfig.expand("$(CFLAGS)".dup, nowarn)
65
+ libffi_version = libffi_package_name[/libffi-(.*)/, 1]
46
66
 
47
67
  FileUtils.mkdir_p(libffi.dir)
48
68
  libffi.opt = CONFIG['configure_args'][/'(-C)'/, 1]
49
- libffi.ldflags = RbConfig.expand("$(LDFLAGS) #{libpathflag([relative_from($topdir, "..")])} #{$LIBRUBYARG}")
69
+ libffi.ldflags = RbConfig.expand("$(LDFLAGS) #{libpathflag([relative_from($topdir, "..")])} #{$LIBRUBYARG}".dup)
50
70
  libffi.arch = RbConfig::CONFIG['host']
51
71
  if $mswin
52
72
  unless find_executable(as = /x64/ =~ libffi.arch ? "ml64" : "ml")
@@ -71,13 +91,12 @@ begin
71
91
  args.concat %W[
72
92
  --srcdir=#{libffi.srcdir}
73
93
  --host=#{libffi.arch}
74
- --enable-builddir=#{RUBY_PLATFORM}
75
94
  ]
76
95
  args << ($enable_shared || !$static ? '--enable-shared' : '--enable-static')
77
96
  args << libffi.opt if libffi.opt
78
97
  args.concat %W[
79
98
  CC=#{cc} CFLAGS=#{libffi.cflags}
80
- CXX=#{cxx} CXXFLAGS=#{RbConfig.expand("$(CXXFLAGS)", nowarn)}
99
+ CXX=#{cxx} CXXFLAGS=#{RbConfig.expand("$(CXXFLAGS)".dup, nowarn)}
81
100
  LD=#{ld} LDFLAGS=#{libffi.ldflags}
82
101
  ]
83
102
 
@@ -88,7 +107,7 @@ begin
88
107
  begin
89
108
  IO.copy_stream(libffi.dir + "/config.log", Logging.instance_variable_get(:@logfile))
90
109
  rescue SystemCallError => e
91
- Logfile.message("%s\n", e.message)
110
+ Logging.message("%s\n", e.message)
92
111
  end
93
112
  raise "failed to configure libffi. Please install libffi."
94
113
  end
@@ -97,15 +116,31 @@ begin
97
116
  FileUtils.rm_f("#{libffi.include}/ffitarget.h")
98
117
  end
99
118
  unless File.file?("#{libffi.include}/ffitarget.h")
100
- FileUtils.cp("#{srcdir}/src/x86/ffitarget.h", libffi.include, preserve: true)
119
+ FileUtils.cp("#{libffi_srcdir}/src/x86/ffitarget.h", libffi.include, preserve: true)
101
120
  end
102
121
  $INCFLAGS << " -I" << libffi.include
103
122
  end
104
123
 
105
- if ver
106
- ver = ver.gsub(/-rc\d+/, '') # If ver contains rc version, just ignored.
107
- ver = (ver.split('.') + [0,0])[0,3]
108
- $defs.push(%{-DRUBY_LIBFFI_MODVERSION=#{ '%d%03d%03d' % ver }})
124
+ if libffi_version
125
+ # If libffi_version contains rc version, just ignored.
126
+ libffi_version = libffi_version.gsub(/-rc\d+/, '')
127
+ libffi_version = (libffi_version.split('.').map(&:to_i) + [0,0])[0,3]
128
+ $defs.push(%{-DRUBY_LIBFFI_MODVERSION=#{ '%d%03d%03d' % libffi_version }})
129
+ warn "libffi_version: #{libffi_version.join('.')}"
130
+ end
131
+
132
+ case
133
+ when $mswin, $mingw, (libffi_version && (libffi_version <=> [3, 2]) >= 0)
134
+ $defs << "-DUSE_FFI_CLOSURE_ALLOC=1"
135
+ when (libffi_version && (libffi_version <=> [3, 2]) < 0)
136
+ else
137
+ have_func('ffi_closure_alloc', ffi_header)
138
+ end
139
+
140
+ if libffi
141
+ $defs << "-DHAVE_FFI_PREP_CIF_VAR"
142
+ else
143
+ have_func('ffi_prep_cif_var', ffi_header)
109
144
  end
110
145
 
111
146
  have_header 'sys/mman.h'
@@ -132,11 +167,13 @@ types.each do |type, signed|
132
167
  if /^\#define\s+SIZEOF_#{type}\s+(SIZEOF_(.+)|\d+)/ =~ config
133
168
  if size = $2 and size != 'VOIDP'
134
169
  size = types.fetch(size) {size}
135
- $defs << format("-DTYPE_%s=TYPE_%s", signed||type, size)
170
+ $defs << "-DTYPE_#{signed||type}=TYPE_#{size}"
136
171
  end
137
172
  if signed
138
173
  check_signedness(type.downcase, "stddef.h")
139
174
  end
175
+ else
176
+ check_signedness(type.downcase, "stddef.h")
140
177
  end
141
178
  end
142
179
 
@@ -1,2 +1,13 @@
1
- ftp://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz md5:83b89587607e3eb65c70d361f13bab43
2
- win32/libffi-3.2.1-mswin.patch -p0
1
+ ver = 3.2.1
2
+ pkg = libffi-$(ver)
3
+
4
+ https://ftp.osuosl.org/pub/blfs/conglomeration/libffi/$(pkg).tar.gz \
5
+ md5:83b89587607e3eb65c70d361f13bab43 \
6
+ sha512:980ca30a8d76f963fca722432b1fe5af77d7a4e4d2eac5144fbc5374d4c596609a293440573f4294207e1bdd9fda80ad1e1cafb2ffb543df5a275bc3bd546483 \
7
+ #
8
+ win32/$(pkg)-mswin.patch -p0
9
+
10
+ $(pkg)/config.guess -> /tool/config.guess
11
+ $(pkg)/config.sub -> /tool/config.sub
12
+
13
+ ! chdir: $(pkg)| autoconf || exit 0
@@ -1,41 +1,11 @@
1
1
  #include <fiddle.h>
2
2
 
3
3
  VALUE mFiddle;
4
+ VALUE rb_eFiddleDLError;
4
5
  VALUE rb_eFiddleError;
5
6
 
6
- #ifndef TYPE_SSIZE_T
7
- # if SIZEOF_SIZE_T == SIZEOF_INT
8
- # define TYPE_SSIZE_T TYPE_INT
9
- # elif SIZEOF_SIZE_T == SIZEOF_LONG
10
- # define TYPE_SSIZE_T TYPE_LONG
11
- # elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
12
- # define TYPE_SSIZE_T TYPE_LONG_LONG
13
- # endif
14
- #endif
15
- #define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
16
-
17
- #ifndef TYPE_PTRDIFF_T
18
- # if SIZEOF_PTRDIFF_T == SIZEOF_INT
19
- # define TYPE_PTRDIFF_T TYPE_INT
20
- # elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
21
- # define TYPE_PTRDIFF_T TYPE_LONG
22
- # elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
23
- # define TYPE_PTRDIFF_T TYPE_LONG_LONG
24
- # endif
25
- #endif
26
-
27
- #ifndef TYPE_INTPTR_T
28
- # if SIZEOF_INTPTR_T == SIZEOF_INT
29
- # define TYPE_INTPTR_T TYPE_INT
30
- # elif SIZEOF_INTPTR_T == SIZEOF_LONG
31
- # define TYPE_INTPTR_T TYPE_LONG
32
- # elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
33
- # define TYPE_INTPTR_T TYPE_LONG_LONG
34
- # endif
35
- #endif
36
- #define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
37
-
38
7
  void Init_fiddle_pointer(void);
8
+ void Init_fiddle_pinned(void);
39
9
 
40
10
  /*
41
11
  * call-seq: Fiddle.malloc(size)
@@ -47,8 +17,7 @@ static VALUE
47
17
  rb_fiddle_malloc(VALUE self, VALUE size)
48
18
  {
49
19
  void *ptr;
50
-
51
- ptr = (void*)ruby_xmalloc(NUM2SIZET(size));
20
+ ptr = (void*)ruby_xcalloc(1, NUM2SIZET(size));
52
21
  return PTR2NUM(ptr);
53
22
  }
54
23
 
@@ -163,12 +132,33 @@ Init_fiddle(void)
163
132
  */
164
133
  mFiddle = rb_define_module("Fiddle");
165
134
 
135
+ /*
136
+ * Document-class: Fiddle::Error
137
+ *
138
+ * Generic error class for Fiddle
139
+ */
140
+ rb_eFiddleError = rb_define_class_under(mFiddle, "Error", rb_eStandardError);
141
+
142
+ /*
143
+ * Ruby installed by RubyInstaller for Windows always require
144
+ * bundled Fiddle because ruby_installer/runtime/dll_directory.rb
145
+ * requires Fiddle. It's used by
146
+ * rubygems/defaults/operating_system.rb. It means that the
147
+ * bundled Fiddle is always required on initialization.
148
+ *
149
+ * We just remove existing Fiddle::DLError here to override
150
+ * the bundled Fiddle.
151
+ */
152
+ if (rb_const_defined(mFiddle, rb_intern("DLError"))) {
153
+ rb_const_remove(mFiddle, rb_intern("DLError"));
154
+ }
155
+
166
156
  /*
167
157
  * Document-class: Fiddle::DLError
168
158
  *
169
159
  * standard dynamic load exception
170
160
  */
171
- rb_eFiddleError = rb_define_class_under(mFiddle, "DLError", rb_eStandardError);
161
+ rb_eFiddleDLError = rb_define_class_under(mFiddle, "DLError", rb_eFiddleError);
172
162
 
173
163
  /* Document-const: TYPE_VOID
174
164
  *
@@ -226,6 +216,20 @@ Init_fiddle(void)
226
216
  */
227
217
  rb_define_const(mFiddle, "TYPE_DOUBLE", INT2NUM(TYPE_DOUBLE));
228
218
 
219
+ #ifdef HAVE_FFI_PREP_CIF_VAR
220
+ /* Document-const: TYPE_VARIADIC
221
+ *
222
+ * C type - ...
223
+ */
224
+ rb_define_const(mFiddle, "TYPE_VARIADIC", INT2NUM(TYPE_VARIADIC));
225
+ #endif
226
+
227
+ /* Document-const: TYPE_CONST_STRING
228
+ *
229
+ * C type - const char* ('\0' terminated const char*)
230
+ */
231
+ rb_define_const(mFiddle, "TYPE_CONST_STRING", INT2NUM(TYPE_CONST_STRING));
232
+
229
233
  /* Document-const: TYPE_SIZE_T
230
234
  *
231
235
  * C type - size_t
@@ -426,6 +430,12 @@ Init_fiddle(void)
426
430
  */
427
431
  rb_define_const(mFiddle, "SIZEOF_UINTPTR_T", INT2NUM(sizeof(uintptr_t)));
428
432
 
433
+ /* Document-const: SIZEOF_CONST_STRING
434
+ *
435
+ * size of a const char*
436
+ */
437
+ rb_define_const(mFiddle, "SIZEOF_CONST_STRING", INT2NUM(sizeof(const char*)));
438
+
429
439
  /* Document-const: RUBY_FREE
430
440
  *
431
441
  * Address of the ruby_xfree() function
@@ -450,5 +460,6 @@ Init_fiddle(void)
450
460
  Init_fiddle_closure();
451
461
  Init_fiddle_handle();
452
462
  Init_fiddle_pointer();
463
+ Init_fiddle_pinned();
453
464
  }
454
465
  /* vim: set noet sws=4 sw=4: */
@@ -115,6 +115,40 @@
115
115
  #endif
116
116
  #define TYPE_FLOAT 7
117
117
  #define TYPE_DOUBLE 8
118
+ #define TYPE_VARIADIC 9
119
+ #define TYPE_CONST_STRING 10
120
+
121
+ #ifndef TYPE_SSIZE_T
122
+ # if SIZEOF_SIZE_T == SIZEOF_INT
123
+ # define TYPE_SSIZE_T TYPE_INT
124
+ # elif SIZEOF_SIZE_T == SIZEOF_LONG
125
+ # define TYPE_SSIZE_T TYPE_LONG
126
+ # elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
127
+ # define TYPE_SSIZE_T TYPE_LONG_LONG
128
+ # endif
129
+ #endif
130
+ #define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
131
+
132
+ #ifndef TYPE_PTRDIFF_T
133
+ # if SIZEOF_PTRDIFF_T == SIZEOF_INT
134
+ # define TYPE_PTRDIFF_T TYPE_INT
135
+ # elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
136
+ # define TYPE_PTRDIFF_T TYPE_LONG
137
+ # elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
138
+ # define TYPE_PTRDIFF_T TYPE_LONG_LONG
139
+ # endif
140
+ #endif
141
+
142
+ #ifndef TYPE_INTPTR_T
143
+ # if SIZEOF_INTPTR_T == SIZEOF_INT
144
+ # define TYPE_INTPTR_T TYPE_INT
145
+ # elif SIZEOF_INTPTR_T == SIZEOF_LONG
146
+ # define TYPE_INTPTR_T TYPE_LONG
147
+ # elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
148
+ # define TYPE_INTPTR_T TYPE_LONG_LONG
149
+ # endif
150
+ #endif
151
+ #define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
118
152
 
119
153
  #define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
120
154
 
@@ -130,7 +164,7 @@
130
164
  #define ALIGN_DOUBLE ALIGN_OF(double)
131
165
 
132
166
  extern VALUE mFiddle;
133
- extern VALUE rb_eFiddleError;
167
+ extern VALUE rb_eFiddleDLError;
134
168
 
135
169
  VALUE rb_fiddle_new_function(VALUE address, VALUE arg_types, VALUE ret_type);
136
170