ffi 1.10.0 → 1.11.1

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