ffi 1.10.0 → 1.11.1

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.gitmodules +2 -1
  4. data/.travis.yml +17 -18
  5. data/CHANGELOG.md +33 -0
  6. data/Gemfile +1 -1
  7. data/README.md +20 -17
  8. data/Rakefile +10 -83
  9. data/appveyor.yml +6 -1
  10. data/ext/ffi_c/Call.c +16 -33
  11. data/ext/ffi_c/Call.h +2 -5
  12. data/ext/ffi_c/Function.c +24 -108
  13. data/ext/ffi_c/Platform.c +0 -47
  14. data/ext/ffi_c/Thread.c +6 -222
  15. data/ext/ffi_c/Thread.h +2 -13
  16. data/ext/ffi_c/Type.c +0 -18
  17. data/ext/ffi_c/Type.h +0 -1
  18. data/ext/ffi_c/Variadic.c +9 -15
  19. data/ext/ffi_c/extconf.rb +34 -20
  20. data/ext/ffi_c/ffi.c +3 -8
  21. data/ext/ffi_c/libffi/configure.ac +5 -1
  22. data/ext/ffi_c/libffi/include/ffi_common.h +1 -1
  23. data/ext/ffi_c/libffi/src/aarch64/ffi.c +2 -2
  24. data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
  25. data/ext/ffi_c/libffi/src/metag/ffi.c +1 -1
  26. data/ext/ffi_c/libffi/src/moxie/ffi.c +1 -1
  27. data/ext/ffi_c/libffi/src/riscv/ffi.c +42 -6
  28. data/ext/ffi_c/libffi/src/riscv/ffitarget.h +1 -0
  29. data/ext/ffi_c/libffi/src/riscv/sysv.S +86 -7
  30. data/ext/ffi_c/libffi/src/x86/ffi.c +2 -1
  31. data/ext/ffi_c/libffi/src/x86/ffiw64.c +1 -1
  32. data/ext/ffi_c/libffi/src/x86/sysv.S +88 -2
  33. data/ext/ffi_c/libffi/src/x86/unix64.S +41 -0
  34. data/ext/ffi_c/rbffi.h +0 -2
  35. data/ffi.gemspec +11 -4
  36. data/lib/ffi/data_converter.rb +67 -0
  37. data/lib/ffi/ffi.rb +1 -0
  38. data/lib/ffi/platform.rb +2 -0
  39. data/lib/ffi/pointer.rb +1 -1
  40. data/lib/ffi/struct.rb +3 -63
  41. data/lib/ffi/struct_by_reference.rb +72 -0
  42. data/lib/ffi/struct_layout.rb +96 -0
  43. data/lib/ffi/tools/const_generator.rb +5 -4
  44. data/lib/ffi/tools/generator.rb +47 -2
  45. data/lib/ffi/tools/generator_task.rb +13 -17
  46. data/lib/ffi/tools/struct_generator.rb +4 -4
  47. data/lib/ffi/types.rb +1 -1
  48. data/lib/ffi/version.rb +1 -1
  49. metadata +18 -13
  50. data/ext/ffi_c/DataConverter.c +0 -91
  51. data/ext/ffi_c/StructByReference.c +0 -190
  52. data/ext/ffi_c/StructByReference.h +0 -50
@@ -177,7 +177,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
177
177
  bytes = FFI_ALIGN (bytes, t->alignment);
178
178
  bytes += FFI_ALIGN (t->size, FFI_SIZEOF_ARG);
179
179
  }
180
- cif->bytes = FFI_ALIGN (bytes, 16);
180
+ cif->bytes = FFI_ALIGN (bytes, FFI_SIZEOF_ARG);
181
181
 
182
182
  return FFI_OK;
183
183
  }
@@ -545,6 +545,7 @@ ffi_prep_closure_loc (ffi_closure* closure,
545
545
  case FFI_REGISTER:
546
546
  dest = ffi_closure_REGISTER;
547
547
  op = 0x68; /* pushl imm */
548
+ break;
548
549
  default:
549
550
  return FFI_BAD_ABI;
550
551
  }
@@ -101,7 +101,7 @@ EFI64(ffi_prep_cif_machdep)(ffi_cif *cif)
101
101
  n += (flags == FFI_TYPE_STRUCT);
102
102
  if (n < 4)
103
103
  n = 4;
104
- cif->bytes = n * 8;
104
+ cif->bytes = n * FFI_SIZEOF_ARG;
105
105
 
106
106
  return FFI_OK;
107
107
  }
@@ -792,9 +792,9 @@ ENDF(C(ffi_closure_raw_THISCALL))
792
792
 
793
793
  #ifdef X86_DARWIN
794
794
  # define COMDAT(X) \
795
- .section __TEXT,__textcoal_nt,coalesced,pure_instructions; \
795
+ .section __TEXT,__text,coalesced,pure_instructions; \
796
796
  .weak_definition X; \
797
- .private_extern X
797
+ FFI_HIDDEN(X)
798
798
  #elif defined __ELF__ && !(defined(__sun__) && defined(__svr4__))
799
799
  # define COMDAT(X) \
800
800
  .section .text.X,"axG",@progbits,X,comdat; \
@@ -1035,6 +1035,92 @@ L(SFDE9):
1035
1035
  L(EFDE9):
1036
1036
  #endif /* !FFI_NO_RAW_API */
1037
1037
 
1038
+ #ifdef _WIN32
1039
+ .def @feat.00;
1040
+ .scl 3;
1041
+ .type 0;
1042
+ .endef
1043
+ .globl @feat.00
1044
+ @feat.00 = 1
1045
+ #endif
1046
+
1047
+ #ifdef __APPLE__
1048
+ .subsections_via_symbols
1049
+ .section __LD,__compact_unwind,regular,debug
1050
+
1051
+ /* compact unwind for ffi_call_i386 */
1052
+ .long C(ffi_call_i386)
1053
+ .set L1,L(UW5)-L(UW0)
1054
+ .long L1
1055
+ .long 0x04000000 /* use dwarf unwind info */
1056
+ .long 0
1057
+ .long 0
1058
+
1059
+ /* compact unwind for ffi_go_closure_EAX */
1060
+ .long C(ffi_go_closure_EAX)
1061
+ .set L2,L(UW8)-L(UW6)
1062
+ .long L2
1063
+ .long 0x04000000 /* use dwarf unwind info */
1064
+ .long 0
1065
+ .long 0
1066
+
1067
+ /* compact unwind for ffi_go_closure_ECX */
1068
+ .long C(ffi_go_closure_ECX)
1069
+ .set L3,L(UW11)-L(UW9)
1070
+ .long L3
1071
+ .long 0x04000000 /* use dwarf unwind info */
1072
+ .long 0
1073
+ .long 0
1074
+
1075
+ /* compact unwind for ffi_closure_i386 */
1076
+ .long C(ffi_closure_i386)
1077
+ .set L4,L(UW20)-L(UW12)
1078
+ .long L4
1079
+ .long 0x04000000 /* use dwarf unwind info */
1080
+ .long 0
1081
+ .long 0
1082
+
1083
+ /* compact unwind for ffi_go_closure_STDCALL */
1084
+ .long C(ffi_go_closure_STDCALL)
1085
+ .set L5,L(UW23)-L(UW21)
1086
+ .long L5
1087
+ .long 0x04000000 /* use dwarf unwind info */
1088
+ .long 0
1089
+ .long 0
1090
+
1091
+ /* compact unwind for ffi_closure_REGISTER */
1092
+ .long C(ffi_closure_REGISTER)
1093
+ .set L6,L(UW26)-L(UW24)
1094
+ .long L6
1095
+ .long 0x04000000 /* use dwarf unwind info */
1096
+ .long 0
1097
+ .long 0
1098
+
1099
+ /* compact unwind for ffi_closure_STDCALL */
1100
+ .long C(ffi_closure_STDCALL)
1101
+ .set L7,L(UW31)-L(UW27)
1102
+ .long L7
1103
+ .long 0x04000000 /* use dwarf unwind info */
1104
+ .long 0
1105
+ .long 0
1106
+
1107
+ /* compact unwind for ffi_closure_raw_SYSV */
1108
+ .long C(ffi_closure_raw_SYSV)
1109
+ .set L8,L(UW40)-L(UW32)
1110
+ .long L8
1111
+ .long 0x04000000 /* use dwarf unwind info */
1112
+ .long 0
1113
+ .long 0
1114
+
1115
+ /* compact unwind for ffi_closure_raw_THISCALL */
1116
+ .long C(ffi_closure_raw_THISCALL)
1117
+ .set L9,L(UW52)-L(UW41)
1118
+ .long L9
1119
+ .long 0x04000000 /* use dwarf unwind info */
1120
+ .long 0
1121
+ .long 0
1122
+ #endif /* __APPLE__ */
1123
+
1038
1124
  #endif /* ifndef _MSC_VER */
1039
1125
  #endif /* ifndef __x86_64__ */
1040
1126
 
@@ -517,6 +517,47 @@ L(SFDE5):
517
517
  L(EFDE5):
518
518
  #ifdef __APPLE__
519
519
  .subsections_via_symbols
520
+ .section __LD,__compact_unwind,regular,debug
521
+
522
+ /* compact unwind for ffi_call_unix64 */
523
+ .quad C(ffi_call_unix64)
524
+ .set L1,L(UW4)-L(UW0)
525
+ .long L1
526
+ .long 0x04000000 /* use dwarf unwind info */
527
+ .quad 0
528
+ .quad 0
529
+
530
+ /* compact unwind for ffi_closure_unix64_sse */
531
+ .quad C(ffi_closure_unix64_sse)
532
+ .set L2,L(UW7)-L(UW5)
533
+ .long L2
534
+ .long 0x04000000 /* use dwarf unwind info */
535
+ .quad 0
536
+ .quad 0
537
+
538
+ /* compact unwind for ffi_closure_unix64 */
539
+ .quad C(ffi_closure_unix64)
540
+ .set L3,L(UW11)-L(UW8)
541
+ .long L3
542
+ .long 0x04000000 /* use dwarf unwind info */
543
+ .quad 0
544
+ .quad 0
545
+
546
+ /* compact unwind for ffi_go_closure_unix64_sse */
547
+ .quad C(ffi_go_closure_unix64_sse)
548
+ .set L4,L(UW14)-L(UW12)
549
+ .long L4
550
+ .long 0x04000000 /* use dwarf unwind info */
551
+ .quad 0
552
+ .quad 0
553
+
554
+ /* compact unwind for ffi_go_closure_unix64 */
555
+ .quad C(ffi_go_closure_unix64)
556
+ .set L5,L(UW17)-L(UW15)
557
+ .long L5
558
+ .long 0x04000000 /* use dwarf unwind info */
559
+ .quad 0
560
+ .quad 0
520
561
  #endif
521
562
 
522
563
  #endif /* __x86_64__ */
@@ -44,7 +44,6 @@ extern void rbffi_Type_Init(VALUE ffiModule);
44
44
  extern void rbffi_Buffer_Init(VALUE ffiModule);
45
45
  extern void rbffi_Invoker_Init(VALUE ffiModule);
46
46
  extern void rbffi_Variadic_Init(VALUE ffiModule);
47
- extern void rbffi_DataConverter_Init(VALUE ffiModule);
48
47
  extern VALUE rbffi_AbstractMemoryClass, rbffi_InvokerClass;
49
48
  extern int rbffi_type_size(VALUE type);
50
49
  extern void rbffi_Thread_Init(VALUE moduleFFI);
@@ -54,4 +53,3 @@ extern void rbffi_Thread_Init(VALUE moduleFFI);
54
53
  #endif
55
54
 
56
55
  #endif /* RBFFI_RBFFI_H */
57
-
@@ -8,6 +8,14 @@ Gem::Specification.new do |s|
8
8
  s.homepage = 'http://wiki.github.com/ffi/ffi'
9
9
  s.summary = 'Ruby FFI'
10
10
  s.description = 'Ruby FFI library'
11
+ if s.respond_to?(:metadata)
12
+ s.metadata['bug_tracker_uri'] = 'https://github.com/ffi/ffi/issues'
13
+ s.metadata['changelog_uri'] = 'https://github.com/ffi/ffi/blob/master/CHANGELOG.md'
14
+ s.metadata['documentation_uri'] = 'https://github.com/ffi/ffi/wiki'
15
+ s.metadata['wiki_uri'] = 'https://github.com/ffi/ffi/wiki'
16
+ s.metadata['source_code_uri'] = 'https://github.com/ffi/ffi/'
17
+ s.metadata['mailing_list_uri'] = 'http://groups.google.com/group/ruby-ffi'
18
+ end
11
19
  s.files = `git ls-files -z`.split("\x0").reject do |f|
12
20
  f =~ /^(bench|gen|libtest|nbproject|spec)/
13
21
  end
@@ -23,14 +31,13 @@ Gem::Specification.new do |s|
23
31
  end
24
32
 
25
33
  s.extensions << 'ext/ffi_c/extconf.rb'
26
- s.has_rdoc = false
27
34
  s.rdoc_options = %w[--exclude=ext/ffi_c/.*\.o$ --exclude=ffi_c\.(bundle|so)$]
28
35
  s.license = 'BSD-3-Clause'
29
36
  s.require_paths << 'ext/ffi_c'
30
- s.required_ruby_version = '>= 1.9'
31
- s.add_development_dependency 'rake', '~> 10.1'
37
+ s.required_ruby_version = '>= 2.0'
38
+ s.add_development_dependency 'rake', '~> 12.1'
32
39
  s.add_development_dependency 'rake-compiler', '~> 1.0'
33
- s.add_development_dependency 'rake-compiler-dock', '~> 0.6.2'
40
+ s.add_development_dependency 'rake-compiler-dock', '~> 0.7.0'
34
41
  s.add_development_dependency 'rspec', '~> 2.14.1'
35
42
  s.add_development_dependency 'rubygems-tasks', "~> 0.2.4"
36
43
  end
@@ -0,0 +1,67 @@
1
+ #
2
+ # Copyright (C) 2008-2010 Wayne Meissner
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
+ module FFI
32
+ # This module is used to extend somes classes and give then a common API.
33
+ #
34
+ # Most of methods defined here must be overriden.
35
+ module DataConverter
36
+ # Get native type.
37
+ #
38
+ # @overload native_type(type)
39
+ # @param [String, Symbol, Type] type
40
+ # @return [Type]
41
+ # Get native type from +type+.
42
+ #
43
+ # @overload native_type
44
+ # @raise {NotImplementedError} This method must be overriden.
45
+ def native_type(type = nil)
46
+ if type
47
+ @native_type = FFI.find_type(type)
48
+ else
49
+ native_type = @native_type
50
+ unless native_type
51
+ raise NotImplementedError, 'native_type method not overridden and no native_type set'
52
+ end
53
+ native_type
54
+ end
55
+ end
56
+
57
+ # Convert to a native type.
58
+ def to_native(value, ctx)
59
+ value
60
+ end
61
+
62
+ # Convert from a native type.
63
+ def from_native(value, ctx)
64
+ value
65
+ end
66
+ end
67
+ end
@@ -29,6 +29,7 @@
29
29
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
30
 
31
31
  require 'ffi/platform'
32
+ require 'ffi/data_converter'
32
33
  require 'ffi/types'
33
34
  require 'ffi/library'
34
35
  require 'ffi/errno'
@@ -56,6 +56,8 @@ module FFI
56
56
 
57
57
  OSVERSION = RbConfig::CONFIG['host_os'].gsub(/[^\d]/, '').to_i
58
58
 
59
+ CPU = RbConfig::CONFIG['host_cpu']
60
+
59
61
  ARCH = case CPU.downcase
60
62
  when /amd64|x86_64/
61
63
  "x86_64"
@@ -49,7 +49,7 @@ module FFI
49
49
  # equivalent string if +len+ is not +nil+.
50
50
  def read_string(len=nil)
51
51
  if len
52
- return '' if len == 0
52
+ return ''.b if len == 0
53
53
  get_bytes(0, len)
54
54
  else
55
55
  get_string(0)
@@ -32,72 +32,12 @@
32
32
  #
33
33
 
34
34
  require 'ffi/platform'
35
+ require 'ffi/struct_layout'
35
36
  require 'ffi/struct_layout_builder'
37
+ require 'ffi/struct_by_reference'
36
38
 
37
39
  module FFI
38
40
 
39
- class StructLayout
40
-
41
- # @return [Array<Array(Symbol, Numeric)>
42
- # Get an array of tuples (field name, offset of the field).
43
- def offsets
44
- members.map { |m| [ m, self[m].offset ] }
45
- end
46
-
47
- # @return [Numeric]
48
- # Get the offset of a field.
49
- def offset_of(field_name)
50
- self[field_name].offset
51
- end
52
-
53
- # An enum {Field} in a {StructLayout}.
54
- class Enum < Field
55
-
56
- # @param [AbstractMemory] ptr pointer on a {Struct}
57
- # @return [Object]
58
- # Get an object of type {#type} from memory pointed by +ptr+.
59
- def get(ptr)
60
- type.find(ptr.get_int(offset))
61
- end
62
-
63
- # @param [AbstractMemory] ptr pointer on a {Struct}
64
- # @param value
65
- # @return [nil]
66
- # Set +value+ into memory pointed by +ptr+.
67
- def put(ptr, value)
68
- ptr.put_int(offset, type.find(value))
69
- end
70
-
71
- end
72
-
73
- class InnerStruct < Field
74
- def get(ptr)
75
- type.struct_class.new(ptr.slice(self.offset, self.size))
76
- end
77
-
78
- def put(ptr, value)
79
- raise TypeError, "wrong value type (expected #{type.struct_class})" unless value.is_a?(type.struct_class)
80
- ptr.slice(self.offset, self.size).__copy_from__(value.pointer, self.size)
81
- end
82
- end
83
-
84
- class Mapped < Field
85
- def initialize(name, offset, type, orig_field)
86
- super(name, offset, type)
87
- @orig_field = orig_field
88
- end
89
-
90
- def get(ptr)
91
- type.from_native(@orig_field.get(ptr), nil)
92
- end
93
-
94
- def put(ptr, value)
95
- @orig_field.put(ptr, type.to_native(value, nil))
96
- end
97
- end
98
- end
99
-
100
-
101
41
  class Struct
102
42
 
103
43
  # Get struct size
@@ -296,7 +236,7 @@ module FFI
296
236
  @packed = packed
297
237
  end
298
238
  alias :pack :packed
299
-
239
+
300
240
  def aligned(alignment = 1)
301
241
  @min_alignment = alignment
302
242
  end
@@ -0,0 +1,72 @@
1
+ #
2
+ # Copyright (C) 2010 Wayne Meissner
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
+ module FFI
32
+ # This class includes the {FFI::DataConverter} module.
33
+ class StructByReference
34
+ include DataConverter
35
+
36
+ attr_reader :struct_class
37
+
38
+ # @param [Struct] struct_class
39
+ def initialize(struct_class)
40
+ unless Class === struct_class and struct_class < FFI::Struct
41
+ raise TypeError, 'wrong type (expected subclass of FFI::Struct)'
42
+ end
43
+ @struct_class = struct_class
44
+ end
45
+
46
+ # Always get {FFI::Type}::POINTER.
47
+ def native_type
48
+ FFI::Type::POINTER
49
+ end
50
+
51
+ # @param [nil, Struct] value
52
+ # @param [nil] ctx
53
+ # @return [AbstractMemory] Pointer on +value+.
54
+ def to_native(value, ctx)
55
+ return Pointer::NULL if value.nil?
56
+
57
+ unless @struct_class === value
58
+ raise TypeError, "wrong argument type #{value.class} (expected #{@struct_class})"
59
+ end
60
+
61
+ value.pointer
62
+ end
63
+
64
+ # @param [AbstractMemory] value
65
+ # @param [nil] ctx
66
+ # @return [Struct]
67
+ # Create a struct from content of memory +value+.
68
+ def from_native(value, ctx)
69
+ @struct_class.new(value)
70
+ end
71
+ end
72
+ end