ffi 1.12.2 → 1.15.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +132 -0
  3. data/Gemfile +1 -2
  4. data/README.md +14 -2
  5. data/Rakefile +46 -65
  6. data/ext/ffi_c/AbstractMemory.c +24 -25
  7. data/ext/ffi_c/Buffer.c +4 -9
  8. data/ext/ffi_c/Call.c +3 -15
  9. data/ext/ffi_c/ClosurePool.c +75 -25
  10. data/ext/ffi_c/ClosurePool.h +3 -1
  11. data/ext/ffi_c/DynamicLibrary.c +1 -6
  12. data/ext/ffi_c/Function.c +38 -38
  13. data/ext/ffi_c/Function.h +0 -4
  14. data/ext/ffi_c/FunctionInfo.c +3 -8
  15. data/ext/ffi_c/LastError.c +2 -6
  16. data/ext/ffi_c/LongDouble.c +5 -3
  17. data/ext/ffi_c/LongDouble.h +0 -4
  18. data/ext/ffi_c/MemoryPointer.c +3 -8
  19. data/ext/ffi_c/MemoryPointer.h +0 -4
  20. data/ext/ffi_c/MethodHandle.c +21 -31
  21. data/ext/ffi_c/MethodHandle.h +3 -2
  22. data/ext/ffi_c/Platform.c +3 -7
  23. data/ext/ffi_c/Pointer.c +25 -26
  24. data/ext/ffi_c/Pointer.h +0 -4
  25. data/ext/ffi_c/Struct.c +3 -6
  26. data/ext/ffi_c/StructByValue.c +2 -7
  27. data/ext/ffi_c/StructLayout.c +9 -8
  28. data/ext/ffi_c/Thread.c +0 -8
  29. data/ext/ffi_c/Thread.h +1 -9
  30. data/ext/ffi_c/Type.c +1 -1
  31. data/ext/ffi_c/Types.c +6 -7
  32. data/ext/ffi_c/Types.h +3 -4
  33. data/ext/ffi_c/Variadic.c +14 -9
  34. data/ext/ffi_c/compat.h +4 -0
  35. data/ext/ffi_c/extconf.rb +36 -23
  36. data/ext/ffi_c/libffi/.travis.yml +4 -0
  37. data/ext/ffi_c/libffi/.travis/bfin-sim.exp +1 -1
  38. data/ext/ffi_c/libffi/.travis/build.sh +4 -0
  39. data/ext/ffi_c/libffi/.travis/m32r-sim.exp +1 -1
  40. data/ext/ffi_c/libffi/.travis/moxie-sim.exp +1 -1
  41. data/ext/ffi_c/libffi/.travis/or1k-sim.exp +1 -1
  42. data/ext/ffi_c/libffi/.travis/powerpc-eabisim.exp +1 -1
  43. data/ext/ffi_c/libffi/.travis/wine-sim.exp +1 -1
  44. data/ext/ffi_c/libffi/Makefile.am +49 -58
  45. data/ext/ffi_c/libffi/Makefile.in +93 -58
  46. data/ext/ffi_c/libffi/README.md +11 -1
  47. data/ext/ffi_c/libffi/config.guess +552 -331
  48. data/ext/ffi_c/libffi/config.sub +1321 -1306
  49. data/ext/ffi_c/libffi/configure +120 -24
  50. data/ext/ffi_c/libffi/configure.ac +31 -10
  51. data/ext/ffi_c/libffi/configure.host +32 -20
  52. data/ext/ffi_c/libffi/fficonfig.h.in +9 -0
  53. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -1
  54. data/ext/ffi_c/libffi/include/ffi.h.in +8 -0
  55. data/ext/ffi_c/libffi/libffi.map.in +8 -12
  56. data/ext/ffi_c/libffi/libtool-version +1 -1
  57. data/ext/ffi_c/libffi/ltmain.sh +6 -4
  58. data/ext/ffi_c/libffi/msvcc.sh +11 -11
  59. data/ext/ffi_c/libffi/src/aarch64/ffi.c +51 -35
  60. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +10 -5
  61. data/ext/ffi_c/libffi/src/aarch64/internal.h +1 -0
  62. data/ext/ffi_c/libffi/src/aarch64/sysv.S +14 -3
  63. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +1 -1
  64. data/ext/ffi_c/libffi/src/arm/ffi.c +22 -0
  65. data/ext/ffi_c/libffi/src/arm/sysv.S +4 -4
  66. data/ext/ffi_c/libffi/src/closures.c +33 -10
  67. data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
  68. data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
  69. data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
  70. data/ext/ffi_c/libffi/src/dlmalloc.c +1 -1
  71. data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
  72. data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
  73. data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
  74. data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
  75. data/ext/ffi_c/libffi/src/mips/ffi.c +5 -1
  76. data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
  77. data/ext/ffi_c/libffi/src/pa/ffi.c +46 -91
  78. data/ext/ffi_c/libffi/src/pa/ffitarget.h +1 -6
  79. data/ext/ffi_c/libffi/src/pa/hpux32.S +4 -2
  80. data/ext/ffi_c/libffi/src/pa/linux.S +4 -2
  81. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +13 -1
  82. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +1 -1
  83. data/ext/ffi_c/libffi/src/powerpc/linux64.S +8 -0
  84. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +13 -1
  85. data/ext/ffi_c/libffi/src/powerpc/sysv.S +5 -7
  86. data/ext/ffi_c/libffi/src/prep_cif.c +1 -1
  87. data/ext/ffi_c/libffi/src/x86/ffi.c +15 -6
  88. data/ext/ffi_c/libffi/src/x86/ffi64.c +17 -8
  89. data/ext/ffi_c/libffi/src/x86/ffitarget.h +15 -2
  90. data/ext/ffi_c/libffi/src/x86/ffiw64.c +15 -8
  91. data/ext/ffi_c/libffi/src/x86/sysv.S +15 -6
  92. data/ext/ffi_c/libffi/src/x86/unix64.S +59 -4
  93. data/ext/ffi_c/libffi/src/x86/win64.S +7 -3
  94. data/ext/ffi_c/libffi/src/x86/win64_intel.S +3 -2
  95. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +22 -2
  96. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +4 -4
  97. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2 -2
  98. data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +2 -0
  99. data/ffi.gemspec +2 -2
  100. data/lib/ffi.rb +10 -3
  101. data/lib/ffi/abstract_memory.rb +44 -0
  102. data/lib/ffi/autopointer.rb +1 -1
  103. data/lib/ffi/ffi.rb +1 -0
  104. data/lib/ffi/io.rb +3 -3
  105. data/lib/ffi/library.rb +7 -3
  106. data/lib/ffi/managedstruct.rb +2 -2
  107. data/lib/ffi/platform.rb +18 -8
  108. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  109. data/lib/ffi/platform/aarch64-freebsd/types.conf +2 -2
  110. data/lib/ffi/platform/aarch64-freebsd12/types.conf +113 -60
  111. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  112. data/lib/ffi/platform/arm-linux/types.conf +32 -4
  113. data/lib/ffi/platform/i386-windows/types.conf +26 -79
  114. data/lib/ffi/platform/powerpc-linux/types.conf +32 -2
  115. data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
  116. data/lib/ffi/platform/powerpc64le-linux/types.conf +100 -0
  117. data/lib/ffi/platform/riscv64-linux/types.conf +104 -0
  118. data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
  119. data/lib/ffi/platform/x86_64-darwin/types.conf +4 -0
  120. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +4 -22
  121. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  122. data/lib/ffi/platform/x86_64-linux/types.conf +21 -0
  123. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  124. data/lib/ffi/platform/x86_64-windows/types.conf +10 -78
  125. data/lib/ffi/pointer.rb +21 -14
  126. data/lib/ffi/struct.rb +8 -2
  127. data/lib/ffi/tools/const_generator.rb +2 -1
  128. data/lib/ffi/tools/struct_generator.rb +2 -1
  129. data/lib/ffi/tools/types_generator.rb +2 -0
  130. data/lib/ffi/variadic.rb +1 -10
  131. data/lib/ffi/version.rb +1 -1
  132. data/rakelib/ffi_gem_helper.rb +65 -0
  133. data/samples/getlogin.rb +1 -1
  134. data/samples/getpid.rb +1 -1
  135. data/samples/gettimeofday.rb +8 -8
  136. data/samples/hello.rb +2 -1
  137. data/samples/inotify.rb +1 -1
  138. data/samples/pty.rb +1 -2
  139. data/samples/qsort.rb +0 -1
  140. metadata +21 -12
  141. data/.appveyor.yml +0 -27
  142. data/.gitignore +0 -25
  143. data/.gitmodules +0 -4
  144. data/.travis.yml +0 -44
  145. data/.yardopts +0 -5
  146. data/ext/ffi_c/win32/stdbool.h +0 -8
  147. data/ext/ffi_c/win32/stdint.h +0 -201
  148. data/samples/sample_helper.rb +0 -6
@@ -30,7 +30,7 @@
30
30
  #if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
31
31
  # define E(BASE, X) .balign 8
32
32
  #else
33
- # define E(BASE, X) .balign 8; .org BASE + X * 8
33
+ # define E(BASE, X) .balign 8; .org BASE + (X) * 8
34
34
  #endif
35
35
 
36
36
  .text
@@ -48,6 +48,7 @@
48
48
  SEH(.seh_proc ffi_call_win64)
49
49
  C(ffi_call_win64):
50
50
  cfi_startproc
51
+ _CET_ENDBR
51
52
  /* Set up the local stack frame and install it in rbp/rsp. */
52
53
  movq (%rsp), %rax
53
54
  movq %rbp, (arg1)
@@ -80,7 +81,7 @@ C(ffi_call_win64):
80
81
  cmpl $FFI_TYPE_SMALL_STRUCT_4B, %ecx
81
82
  leaq (%r10, %rcx, 8), %r10
82
83
  ja 99f
83
- jmp *%r10
84
+ _CET_NOTRACK jmp *%r10
84
85
 
85
86
  /* Below, we're space constrained most of the time. Thus we eschew the
86
87
  modern "mov, pop, ret" sequence (5 bytes) for "leave, ret" (2 bytes). */
@@ -107,7 +108,8 @@ E(0b, FFI_TYPE_FLOAT)
107
108
  E(0b, FFI_TYPE_DOUBLE)
108
109
  movsd %xmm0, (%r8)
109
110
  epilogue
110
- E(0b, FFI_TYPE_LONGDOUBLE)
111
+ // FFI_TYPE_LONGDOUBLE may be FFI_TYPE_DOUBLE but we need a different value here.
112
+ E(0b, FFI_TYPE_DOUBLE + 1)
111
113
  call PLT(C(abort))
112
114
  E(0b, FFI_TYPE_UINT8)
113
115
  movzbl %al, %eax
@@ -176,6 +178,7 @@ E(0b, FFI_TYPE_SMALL_STRUCT_4B)
176
178
  SEH(.seh_proc ffi_go_closure_win64)
177
179
  C(ffi_go_closure_win64):
178
180
  cfi_startproc
181
+ _CET_ENDBR
179
182
  /* Save all integer arguments into the incoming reg stack space. */
180
183
  movq %rcx, 8(%rsp)
181
184
  movq %rdx, 16(%rsp)
@@ -196,6 +199,7 @@ C(ffi_go_closure_win64):
196
199
  SEH(.seh_proc ffi_closure_win64)
197
200
  C(ffi_closure_win64):
198
201
  cfi_startproc
202
+ _CET_ENDBR
199
203
  /* Save all integer arguments into the incoming reg stack space. */
200
204
  movq %rcx, 8(%rsp)
201
205
  movq %rdx, 16(%rsp)
@@ -29,7 +29,7 @@
29
29
  #if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
30
30
  # define E(BASE, X) ALIGN 8
31
31
  #else
32
- # define E(BASE, X) ALIGN 8; ORG BASE + X * 8
32
+ # define E(BASE, X) ALIGN 8; ORG BASE + (X) * 8
33
33
  #endif
34
34
 
35
35
  .CODE
@@ -107,7 +107,8 @@ E(0b, FFI_TYPE_FLOAT)
107
107
  E(0b, FFI_TYPE_DOUBLE)
108
108
  movsd qword ptr[r8], xmm0; movsd %xmm0, (%r8)
109
109
  epilogue
110
- E(0b, FFI_TYPE_LONGDOUBLE)
110
+ // FFI_TYPE_LONGDOUBLE may be FFI_TYPE_DOUBLE but we need a different value here.
111
+ E(0b, FFI_TYPE_DOUBLE + 1)
111
112
  call PLT(C(abort))
112
113
  E(0b, FFI_TYPE_UINT8)
113
114
  movzx eax, al ;movzbl %al, %eax
@@ -24,6 +24,11 @@ load_lib libgloss.exp
24
24
  load_gcc_lib target-libpath.exp
25
25
  load_gcc_lib wrapper.exp
26
26
 
27
+ proc check_effective_target_gccbug { } {
28
+ global has_gccbug
29
+ return $has_gccbug
30
+ }
31
+
27
32
  # Return 1 if the target matches the effective target 'arg', 0 otherwise.
28
33
  # This can be used with any check_* proc that takes no argument and
29
34
  # returns only 1 or 0. It could be used with check_* procs that take
@@ -477,6 +482,7 @@ proc libffi-dg-runtest { testcases default-extra-flags } {
477
482
 
478
483
  proc run-many-tests { testcases extra_flags } {
479
484
  global compiler_vendor
485
+ global has_gccbug
480
486
  global env
481
487
  switch $compiler_vendor {
482
488
  "clang" {
@@ -538,8 +544,22 @@ proc run-many-tests { testcases extra_flags } {
538
544
  foreach opt $optimizations {
539
545
  foreach abi $abis {
540
546
  set options [concat $common $opt $abi]
541
- verbose "Testing $testname, $options" 1
542
- dg-test $test $options ""
547
+ set has_gccbug false;
548
+ if { [string match $compiler_vendor "gnu"] \
549
+ && [string match "*MSABI*" $abi] \
550
+ && ( ( [string match "*DGTEST=57 *" $common] \
551
+ && [string match "*call.c*" $testname] ) \
552
+ || ( [string match "*DGTEST=54 *" $common] \
553
+ && [string match "*callback*" $testname] ) \
554
+ || [string match "*DGTEST=55 *" $common] \
555
+ || [string match "*DGTEST=56 *" $common] ) } then {
556
+ if [libffi_feature_test "#if (__GNUC__ < 9) || ((__GNUC__ == 9) && (__GNUC_MINOR__ < 3))"] {
557
+ set has_gccbug true;
558
+ }
559
+ }
560
+ verbose "Testing $testname, $options" 1
561
+ verbose "has_gccbug = $has_gccbug" 1
562
+ dg-test $test $options ""
543
563
  }
544
564
  }
545
565
  }
@@ -4,7 +4,7 @@
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify
6
6
  it under the terms of the GNU General Public License as published by
7
- the Free Software Foundation; either version 2 of the License, or
7
+ the Free Software Foundation; either version 3 of the License, or
8
8
  (at your option) any later version.
9
9
 
10
10
  This program is distributed in the hope that it will be useful,
@@ -16,7 +16,7 @@
16
16
  along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  **/
18
18
 
19
- /* { dg-do run } */
19
+ /* { dg-do run { xfail gccbug } } */
20
20
 
21
21
  #include <stdio.h>
22
22
  #include <stdlib.h>
@@ -1220,7 +1220,7 @@ void
1220
1220
  }
1221
1221
  fprintf(out,"->{%g}\n",Fr.x);
1222
1222
  fflush(out);
1223
- #endif
1223
+ #endif
1224
1224
  #if (!defined(DGTEST)) || DGTEST == 56
1225
1225
  Dr = D_fDd(f1,D2,d3);
1226
1226
  fprintf(out,"->{%g}\n",Dr.x);
@@ -1243,7 +1243,7 @@ void
1243
1243
  }
1244
1244
  fprintf(out,"->{%g}\n",Dr.x);
1245
1245
  fflush(out);
1246
- #endif
1246
+ #endif
1247
1247
  #if (!defined(DGTEST)) || DGTEST == 57
1248
1248
  Dr = D_Dfd(D1,f2,d3);
1249
1249
  fprintf(out,"->{%g}\n",Dr.x);
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * This program is free software: you can redistribute it and/or modify
6
6
  * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation; either version 2 of the License, or
7
+ * the Free Software Foundation; either version 3 of the License, or
8
8
  * (at your option) any later version.
9
9
  *
10
10
  * This program is distributed in the hope that it will be useful,
@@ -16,7 +16,7 @@
16
16
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
- /* { dg-do run } */
19
+ /* { dg-do run { xfail gccbug } } */
20
20
 
21
21
  #include <stdio.h>
22
22
  #include <stdlib.h>
@@ -9,6 +9,8 @@
9
9
  /* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
10
10
  /* { dg-options -Wformat=0 { target moxie*-*-elf or1k-*-* } } */
11
11
 
12
+ #include <inttypes.h>
13
+
12
14
  #include "ffitest.h"
13
15
 
14
16
  typedef struct BigStruct{
data/ffi.gemspec CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.metadata['mailing_list_uri'] = 'http://groups.google.com/group/ruby-ffi'
18
18
  end
19
19
  s.files = `git ls-files -z`.split("\x0").reject do |f|
20
- f =~ /^(bench|gen|libtest|nbproject|spec)/
20
+ f =~ /^(\.|bench|gen|libtest|nbproject|spec)/
21
21
  end
22
22
 
23
23
  # Add libffi git files
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
34
34
  s.rdoc_options = %w[--exclude=ext/ffi_c/.*\.o$ --exclude=ffi_c\.(bundle|so)$]
35
35
  s.license = 'BSD-3-Clause'
36
36
  s.require_paths << 'ext/ffi_c'
37
- s.required_ruby_version = '>= 2.0'
37
+ s.required_ruby_version = '>= 2.3'
38
38
  s.add_development_dependency 'rake', '~> 13.0'
39
39
  s.add_development_dependency 'rake-compiler', '~> 1.0'
40
40
  s.add_development_dependency 'rake-compiler-dock', '~> 1.0'
data/lib/ffi.rb CHANGED
@@ -1,5 +1,4 @@
1
- if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
2
- Object.send(:remove_const, :FFI) if defined?(::FFI)
1
+ if RUBY_ENGINE == 'ruby'
3
2
  begin
4
3
  require RUBY_VERSION.split('.')[0, 2].join('.') + '/ffi_c'
5
4
  rescue Exception
@@ -8,7 +7,15 @@ if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
8
7
 
9
8
  require 'ffi/ffi'
10
9
 
11
- elsif defined?(RUBY_ENGINE)
10
+ elsif RUBY_ENGINE == 'jruby' && (RUBY_ENGINE_VERSION.split('.').map(&:to_i) <=> [9, 3]) >= 0
11
+ JRuby::Util.load_ext("org.jruby.ext.ffi.FFIService")
12
+ require 'ffi/ffi'
13
+
14
+ elsif RUBY_ENGINE == 'truffleruby' && (RUBY_ENGINE_VERSION.split('.').map(&:to_i) <=> [20, 1, 0]) >= 0
15
+ require 'truffleruby/ffi_backend'
16
+ require 'ffi/ffi'
17
+
18
+ else
12
19
  # Remove the ffi gem dir from the load path, then reload the internal ffi implementation
13
20
  $LOAD_PATH.delete(File.dirname(__FILE__))
14
21
  $LOAD_PATH.delete(File.join(File.dirname(__FILE__), 'ffi'))
@@ -0,0 +1,44 @@
1
+ #
2
+ # Copyright (C) 2020 Lars Kanis
3
+ #
4
+ # This file is part of ruby-ffi.
5
+ #
6
+ # All rights reserved.
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions are met:
10
+ #
11
+ # * Redistributions of source code must retain the above copyright notice, this
12
+ # list of conditions and the following disclaimer.
13
+ # * Redistributions in binary form must reproduce the above copyright notice
14
+ # this list of conditions and the following disclaimer in the documentation
15
+ # and/or other materials provided with the distribution.
16
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
17
+ # may be used to endorse or promote products derived from this software
18
+ # without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
24
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
30
+
31
+
32
+ module FFI
33
+ class AbstractMemory
34
+ LONG_MAX = FFI::Pointer.new(1).size
35
+ private_constant :LONG_MAX
36
+
37
+ # Return +true+ if +self+ has a size limit.
38
+ #
39
+ # @return [Boolean]
40
+ def size_limit?
41
+ size != LONG_MAX
42
+ end
43
+ end
44
+ end
@@ -117,7 +117,7 @@ module FFI
117
117
  end
118
118
 
119
119
  # @abstract Base class for {AutoPointer}'s releasers.
120
- #
120
+ #
121
121
  # All subclasses of Releaser should define a +#release(ptr)+ method.
122
122
  # A releaser is an object in charge of release an {AutoPointer}.
123
123
  class Releaser
data/lib/ffi/ffi.rb CHANGED
@@ -33,6 +33,7 @@ require 'ffi/data_converter'
33
33
  require 'ffi/types'
34
34
  require 'ffi/library'
35
35
  require 'ffi/errno'
36
+ require 'ffi/abstract_memory'
36
37
  require 'ffi/pointer'
37
38
  require 'ffi/memorypointer'
38
39
  require 'ffi/struct'
data/lib/ffi/io.rb CHANGED
@@ -29,7 +29,7 @@
29
29
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
30
30
 
31
31
  module FFI
32
-
32
+
33
33
  # This module implements a couple of class methods to play with IO.
34
34
  module IO
35
35
  # @param [Integer] fd file decriptor
@@ -42,12 +42,12 @@ module FFI
42
42
 
43
43
  # @param [#read] io io to read from
44
44
  # @param [AbstractMemory] buf destination for data read from +io+
45
- # @param [nil, Numeric] len maximul number of bytes to read from +io+. If +nil+,
45
+ # @param [nil, Numeric] len maximul number of bytes to read from +io+. If +nil+,
46
46
  # read until end of file.
47
47
  # @return [Numeric] length really read, in bytes
48
48
  #
49
49
  # A version of IO#read that reads data from an IO and put then into a native buffer.
50
- #
50
+ #
51
51
  # This will be optimized at some future time to eliminate the double copy.
52
52
  #
53
53
  def self.native_read(io, buf, len)
data/lib/ffi/library.rb CHANGED
@@ -115,7 +115,7 @@ module FFI
115
115
  rescue Exception => ex
116
116
  ldscript = false
117
117
  if ex.message =~ /(([^ \t()])+\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)/
118
- if File.read($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/
118
+ if File.binread($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/
119
119
  libname = $1
120
120
  ldscript = true
121
121
  end
@@ -126,7 +126,7 @@ module FFI
126
126
  else
127
127
  # TODO better library lookup logic
128
128
  unless libname.start_with?("/") || FFI::Platform.windows?
129
- path = ['/usr/lib/','/usr/local/lib/','/opt/local/lib/'].find do |pth|
129
+ path = ['/usr/lib/','/usr/local/lib/','/opt/local/lib/', '/opt/homebrew/lib/'].find do |pth|
130
130
  File.exist?(pth + libname)
131
131
  end
132
132
  if path
@@ -394,7 +394,11 @@ module FFI
394
394
  options = Hash.new
395
395
  options[:convention] = ffi_convention
396
396
  options[:enums] = @ffi_enums if defined?(@ffi_enums)
397
- cb = FFI::CallbackInfo.new(find_type(ret), native_params, options)
397
+ ret_type = find_type(ret)
398
+ if ret_type == Type::STRING
399
+ raise TypeError, ":string is not allowed as return type of callbacks"
400
+ end
401
+ cb = FFI::CallbackInfo.new(ret_type, native_params, options)
398
402
 
399
403
  # Add to the symbol -> type map (unless there was no name)
400
404
  unless name.nil?
@@ -44,7 +44,7 @@ module FFI
44
44
  # attach_function :new_dlist, [], :pointer
45
45
  # attach_function :destroy_dlist, [:pointer], :void
46
46
  # end
47
- #
47
+ #
48
48
  # class DoublyLinkedList < FFI::ManagedStruct
49
49
  # @@@
50
50
  # struct do |s|
@@ -71,7 +71,7 @@ module FFI
71
71
 
72
72
  # @overload initialize(pointer)
73
73
  # @param [Pointer] pointer
74
- # Create a new ManagedStruct which will invoke the class method #release on
74
+ # Create a new ManagedStruct which will invoke the class method #release on
75
75
  # @overload initialize
76
76
  # A new instance of FFI::ManagedStruct.
77
77
  def initialize(pointer=nil)
data/lib/ffi/platform.rb CHANGED
@@ -61,9 +61,9 @@ module FFI
61
61
  CPU = RbConfig::CONFIG['host_cpu']
62
62
 
63
63
  ARCH = case CPU.downcase
64
- when /amd64|x86_64/
64
+ when /amd64|x86_64|x64/
65
65
  "x86_64"
66
- when /i?86|x86|i86pc/
66
+ when /i\d86|x86|i86pc/
67
67
  "i386"
68
68
  when /ppc64|powerpc64/
69
69
  "powerpc64"
@@ -71,13 +71,16 @@ module FFI
71
71
  "powerpc"
72
72
  when /sparcv9|sparc64/
73
73
  "sparcv9"
74
- else
75
- case RbConfig::CONFIG['host_cpu']
76
- when /^arm/
77
- "arm"
74
+ when /arm64|aarch64/ # MacOS calls it "arm64", other operating systems "aarch64"
75
+ "aarch64"
76
+ when /^arm/
77
+ if OS == "darwin" # Ruby before 3.0 reports "arm" instead of "arm64" as host_cpu on darwin
78
+ "aarch64"
78
79
  else
79
- RbConfig::CONFIG['host_cpu']
80
+ "arm"
80
81
  end
82
+ else
83
+ RbConfig::CONFIG['host_cpu']
81
84
  end
82
85
 
83
86
  private
@@ -129,7 +132,8 @@ module FFI
129
132
  end
130
133
 
131
134
  LIBC = if IS_WINDOWS
132
- RbConfig::CONFIG['RUBY_SO_NAME'].split('-')[-2] + '.dll'
135
+ crtname = RbConfig::CONFIG["RUBY_SO_NAME"][/msvc\w+/] || 'ucrtbase'
136
+ "#{crtname}.dll"
133
137
  elsif IS_GNU
134
138
  GNU_LIBC
135
139
  elsif OS == 'cygwin'
@@ -141,6 +145,12 @@ module FFI
141
145
  "#{LIBPREFIX}c.#{LIBSUFFIX}"
142
146
  end
143
147
 
148
+ LITTLE_ENDIAN = 1234 unless defined?(LITTLE_ENDIAN)
149
+ BIG_ENDIAN = 4321 unless defined?(BIG_ENDIAN)
150
+ unless defined?(BYTE_ORDER)
151
+ BYTE_ORDER = [0x12345678].pack("I") == [0x12345678].pack("N") ? BIG_ENDIAN : LITTLE_ENDIAN
152
+ end
153
+
144
154
  # Test if current OS is a *BSD (include MAC)
145
155
  # @return [Boolean]
146
156
  def self.bsd?
@@ -0,0 +1,130 @@
1
+ rbx.platform.typedef.__darwin_blkcnt_t = long_long
2
+ rbx.platform.typedef.__darwin_blksize_t = int
3
+ rbx.platform.typedef.__darwin_clock_t = ulong
4
+ rbx.platform.typedef.__darwin_ct_rune_t = int
5
+ rbx.platform.typedef.__darwin_dev_t = int
6
+ rbx.platform.typedef.__darwin_fsblkcnt_t = uint
7
+ rbx.platform.typedef.__darwin_fsfilcnt_t = uint
8
+ rbx.platform.typedef.__darwin_gid_t = uint
9
+ rbx.platform.typedef.__darwin_id_t = uint
10
+ rbx.platform.typedef.__darwin_ino64_t = ulong_long
11
+ rbx.platform.typedef.__darwin_ino_t = ulong_long
12
+ rbx.platform.typedef.__darwin_intptr_t = long
13
+ rbx.platform.typedef.__darwin_mach_port_name_t = uint
14
+ rbx.platform.typedef.__darwin_mach_port_t = uint
15
+ rbx.platform.typedef.__darwin_mode_t = ushort
16
+ rbx.platform.typedef.__darwin_natural_t = uint
17
+ rbx.platform.typedef.__darwin_off_t = long_long
18
+ rbx.platform.typedef.__darwin_pid_t = int
19
+ rbx.platform.typedef.__darwin_pthread_key_t = ulong
20
+ rbx.platform.typedef.__darwin_ptrdiff_t = long
21
+ rbx.platform.typedef.__darwin_rune_t = int
22
+ rbx.platform.typedef.__darwin_sigset_t = uint
23
+ rbx.platform.typedef.__darwin_size_t = ulong
24
+ rbx.platform.typedef.__darwin_socklen_t = uint
25
+ rbx.platform.typedef.__darwin_ssize_t = long
26
+ rbx.platform.typedef.__darwin_suseconds_t = int
27
+ rbx.platform.typedef.__darwin_time_t = long
28
+ rbx.platform.typedef.__darwin_uid_t = uint
29
+ rbx.platform.typedef.__darwin_useconds_t = uint
30
+ rbx.platform.typedef.__darwin_uuid_string_t[37] = char
31
+ rbx.platform.typedef.__darwin_uuid_t[16] = uchar
32
+ rbx.platform.typedef.__darwin_wchar_t = int
33
+ rbx.platform.typedef.__darwin_wint_t = int
34
+ rbx.platform.typedef.__int16_t = short
35
+ rbx.platform.typedef.__int32_t = int
36
+ rbx.platform.typedef.__int64_t = long_long
37
+ rbx.platform.typedef.__int8_t = char
38
+ rbx.platform.typedef.__uint16_t = ushort
39
+ rbx.platform.typedef.__uint32_t = uint
40
+ rbx.platform.typedef.__uint64_t = ulong_long
41
+ rbx.platform.typedef.__uint8_t = uchar
42
+ rbx.platform.typedef.blkcnt_t = long_long
43
+ rbx.platform.typedef.blksize_t = int
44
+ rbx.platform.typedef.caddr_t = string
45
+ rbx.platform.typedef.clock_t = ulong
46
+ rbx.platform.typedef.daddr_t = int
47
+ rbx.platform.typedef.dev_t = int
48
+ rbx.platform.typedef.errno_t = int
49
+ rbx.platform.typedef.fd_mask = int
50
+ rbx.platform.typedef.fixpt_t = uint
51
+ rbx.platform.typedef.fsblkcnt_t = uint
52
+ rbx.platform.typedef.fsfilcnt_t = uint
53
+ rbx.platform.typedef.gid_t = uint
54
+ rbx.platform.typedef.id_t = uint
55
+ rbx.platform.typedef.in_addr_t = uint
56
+ rbx.platform.typedef.in_port_t = ushort
57
+ rbx.platform.typedef.ino64_t = ulong_long
58
+ rbx.platform.typedef.ino_t = ulong_long
59
+ rbx.platform.typedef.int16_t = short
60
+ rbx.platform.typedef.int32_t = int
61
+ rbx.platform.typedef.int64_t = long_long
62
+ rbx.platform.typedef.int8_t = char
63
+ rbx.platform.typedef.int_fast16_t = short
64
+ rbx.platform.typedef.int_fast32_t = int
65
+ rbx.platform.typedef.int_fast64_t = long_long
66
+ rbx.platform.typedef.int_fast8_t = char
67
+ rbx.platform.typedef.int_least16_t = short
68
+ rbx.platform.typedef.int_least32_t = int
69
+ rbx.platform.typedef.int_least64_t = long_long
70
+ rbx.platform.typedef.int_least8_t = char
71
+ rbx.platform.typedef.intmax_t = long
72
+ rbx.platform.typedef.intptr_t = long
73
+ rbx.platform.typedef.key_t = int
74
+ rbx.platform.typedef.mode_t = ushort
75
+ rbx.platform.typedef.nlink_t = ushort
76
+ rbx.platform.typedef.off_t = long_long
77
+ rbx.platform.typedef.pid_t = int
78
+ rbx.platform.typedef.pthread_key_t = ulong
79
+ rbx.platform.typedef.ptrdiff_t = long
80
+ rbx.platform.typedef.qaddr_t = pointer
81
+ rbx.platform.typedef.quad_t = long_long
82
+ rbx.platform.typedef.register_t = long_long
83
+ rbx.platform.typedef.rlim_t = ulong_long
84
+ rbx.platform.typedef.rsize_t = ulong
85
+ rbx.platform.typedef.sa_family_t = uchar
86
+ rbx.platform.typedef.sae_associd_t = uint
87
+ rbx.platform.typedef.sae_connid_t = uint
88
+ rbx.platform.typedef.segsz_t = int
89
+ rbx.platform.typedef.size_t = ulong
90
+ rbx.platform.typedef.socklen_t = uint
91
+ rbx.platform.typedef.ssize_t = long
92
+ rbx.platform.typedef.suseconds_t = int
93
+ rbx.platform.typedef.swblk_t = int
94
+ rbx.platform.typedef.syscall_arg_t = ulong_long
95
+ rbx.platform.typedef.time_t = long
96
+ rbx.platform.typedef.u_char = uchar
97
+ rbx.platform.typedef.u_int = uint
98
+ rbx.platform.typedef.u_int16_t = ushort
99
+ rbx.platform.typedef.u_int32_t = uint
100
+ rbx.platform.typedef.u_int64_t = ulong_long
101
+ rbx.platform.typedef.u_int8_t = uchar
102
+ rbx.platform.typedef.u_long = ulong
103
+ rbx.platform.typedef.u_quad_t = ulong_long
104
+ rbx.platform.typedef.u_short = ushort
105
+ rbx.platform.typedef.uid_t = uint
106
+ rbx.platform.typedef.uint = uint
107
+ rbx.platform.typedef.uint16_t = ushort
108
+ rbx.platform.typedef.uint32_t = uint
109
+ rbx.platform.typedef.uint64_t = ulong_long
110
+ rbx.platform.typedef.uint8_t = uchar
111
+ rbx.platform.typedef.uint_fast16_t = ushort
112
+ rbx.platform.typedef.uint_fast32_t = uint
113
+ rbx.platform.typedef.uint_fast64_t = ulong_long
114
+ rbx.platform.typedef.uint_fast8_t = uchar
115
+ rbx.platform.typedef.uint_least16_t = ushort
116
+ rbx.platform.typedef.uint_least32_t = uint
117
+ rbx.platform.typedef.uint_least64_t = ulong_long
118
+ rbx.platform.typedef.uint_least8_t = uchar
119
+ rbx.platform.typedef.uintmax_t = ulong
120
+ rbx.platform.typedef.uintptr_t = ulong
121
+ rbx.platform.typedef.useconds_t = uint
122
+ rbx.platform.typedef.user_addr_t = ulong_long
123
+ rbx.platform.typedef.user_long_t = long_long
124
+ rbx.platform.typedef.user_off_t = long_long
125
+ rbx.platform.typedef.user_size_t = ulong_long
126
+ rbx.platform.typedef.user_ssize_t = long_long
127
+ rbx.platform.typedef.user_time_t = long_long
128
+ rbx.platform.typedef.user_ulong_t = ulong_long
129
+ rbx.platform.typedef.ushort = ushort
130
+ rbx.platform.typedef.wchar_t = int