Skip to content

Commit 9e8a50c

Browse files
committed
[GR-15145] Remove the old FFI and migrate the socket stdlib to use the full FFI.
PullRequest: truffleruby/907
2 parents b5e65db + 896906b commit 9e8a50c

File tree

25 files changed

+158
-715
lines changed

25 files changed

+158
-715
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Compatibility:
2222
* Implemented `ENV#{filter,filter!}` aliases for `select` and `select!`.
2323
* Non-blocking `StringIO` and `Socket` APIs now support `exception: false` like MRI (#1702).
2424
* Added `Kernel#then` (#1703).
25+
* `FFI::Struct#[]=` is now supported for inline character arrays.
26+
* `blocking: true` is now supported for `FFI::Library#attach_function`.
2527

2628
Changes:
2729

lib/truffle/socket.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626

2727
require 'fcntl'
2828

29-
require 'truffle/ffi/ffi'
30-
require 'truffle/ffi/ffi_struct'
29+
require 'ffi'
3130

3231
require 'socket/truffle'
3332
require 'socket/truffle/socket_options'

lib/truffle/socket/basic_socket.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def send(message, flags, dest_sockaddr = nil)
137137
bytes_sent = Truffle::Socket::Foreign
138138
.sendto(@descriptor, buffer, bytes, flags, addr, addr.size)
139139
ensure
140-
addr.free
140+
addr.pointer.free
141141
end
142142
else
143143
bytes_sent = Truffle::Socket::Foreign
@@ -230,9 +230,9 @@ def recv_nonblock(bytes_to_read, flags = 0, buf = nil, exception: true)
230230
return msg_buffer.read_string(msg_size), addr, header.flags
231231
ensure
232232
msg_buffer.free
233-
address.free
234-
io_vec.free
235-
header.free
233+
address.pointer.free
234+
io_vec.pointer.free
235+
header.pointer.free
236236
end
237237
end
238238

@@ -284,9 +284,9 @@ def recvmsg_nonblock(max_msg_len = nil, flags = 0, max_control_len = nil, except
284284

285285
num_bytes
286286
ensure
287-
address.free if address
288-
header.free
289-
io_vec.free
287+
address.pointer.free if address
288+
header.pointer.free
289+
io_vec.pointer.free
290290
msg_buffer.free
291291
end
292292
end

lib/truffle/socket/option.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def self.linger(onoff, secs)
4545

4646
new(:UNSPEC, :SOCKET, :LINGER, linger.to_s)
4747
ensure
48-
linger.free
48+
linger.pointer.free
4949
end
5050
end
5151

lib/truffle/socket/socket.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def self.gethostbyname(hostname)
138138
addrinfos.each do |a|
139139
sockaddr = Socket.sockaddr_in(0, a[3])
140140

141-
141+
# Done manually because we want to read the full address as a String, even if it contains nul bytes
142142
if a[4] == AF_INET
143143
offset = Truffle::Config['platform.sockaddr_in.sin_addr.offset']
144144
size = Truffle::Config['platform.sockaddr_in.sin_addr.size']
@@ -282,7 +282,7 @@ def self.pack_sockaddr_un(file)
282282
begin
283283
struct.to_s
284284
ensure
285-
struct.free
285+
struct.pointer.free
286286
end
287287
end
288288

@@ -292,7 +292,7 @@ def self.unpack_sockaddr_un(addr)
292292
begin
293293
struct[:sun_path].to_s
294294
ensure
295-
struct.free
295+
struct.pointer.free
296296
end
297297
end
298298

lib/truffle/socket/truffle.rb

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,31 @@ def self.unix_socket_support?
3838
::Socket::Constants.const_defined?(:AF_UNIX)
3939
end
4040

41+
def self.config(struct_class, base, *fields)
42+
struct_class.instance_variable_set(:@size, Truffle::Config["#{base}.sizeof"])
43+
layout_args = []
44+
45+
fields.each do |field|
46+
field = field.to_sym
47+
offset = Truffle::Config["#{base}.#{field}.offset"]
48+
size = Truffle::Config["#{base}.#{field}.size"]
49+
type = Truffle::Config.lookup("#{base}.#{field}.type")
50+
type = if type == 'char_array'
51+
[:char, size]
52+
else
53+
type.to_sym
54+
end
55+
56+
if !(Array === type) && ::FFI.find_type(type).size != size
57+
raise ArgumentError, "FFI::Type#size of #{type} (#{::FFI.find_type(type).size}) differs from config size (#{size})"
58+
end
59+
60+
layout_args << field << type << offset
61+
end
62+
63+
struct_class.layout(*layout_args)
64+
end
65+
4166
def self.aliases_for_hostname(hostname)
4267
pointer = Foreign.gethostbyname(hostname)
4368
return [] if pointer.null? # Truffle: added null check
@@ -94,7 +119,7 @@ def self.internal_accept(source, new_class, exception)
94119

95120
return socket, addrinfo
96121
ensure
97-
sockaddr.free
122+
sockaddr.pointer.free
98123
end
99124
end
100125
private_class_method :internal_accept

lib/truffle/socket/truffle/foreign.rb

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,10 @@
2727
module Truffle
2828
module Socket
2929
module Foreign
30-
def self.attach_function(method_name, native_name = method_name, args_types, return_type, blocking: false)
31-
Truffle::POSIX.attach_function(native_name, args_types, return_type,
32-
Truffle::POSIX::LIBC, blocking, method_name, self)
33-
end
30+
extend ::FFI::Library
31+
ffi_lib ::FFI::Library::LIBC
3432

35-
SIZEOF_INT = Truffle::FFI.type_size(:int)
33+
SIZEOF_INT = ::FFI.type_size(:int)
3634

3735
attach_function :_bind, :bind, [:int, :pointer, :socklen_t], :int
3836
attach_function :_connect, :connect, [:int, :pointer, :socklen_t], :int, blocking: true
@@ -82,10 +80,10 @@ def self.attach_function(method_name, native_name = method_name, args_types, ret
8280
attach_function :gethostbyname, [:string], :pointer
8381
attach_function :gethostbyaddr, [:pointer, :socklen_t, :int], :pointer
8482

85-
attach_function :htons, [:uint16_t], :uint16_t
86-
attach_function :ntohs, [:uint16_t], :uint16_t
83+
attach_function :htons, [:uint16], :uint16
84+
attach_function :ntohs, [:uint16], :uint16
8785

88-
attach_function :inet_network, [:string], :uint32_t
86+
attach_function :inet_network, [:string], :uint32
8987
attach_function :inet_pton, [:int, :string, :pointer], :int
9088

9189
attach_function :_getnameinfo,
@@ -168,7 +166,7 @@ def self.getaddrinfo(host, service = nil, family = nil, socktype = nil,
168166

169167
addrinfos
170168
ensure
171-
hints.free if hints
169+
hints.pointer.free if hints
172170

173171
if res_p
174172
ptr = res_p.read_pointer
@@ -284,7 +282,7 @@ def self.pack_sockaddr_in(host, port, family = ::Socket::AF_UNSPEC,
284282

285283
res[:ai_addr].read_string(res[:ai_addrlen])
286284
ensure
287-
hints.free if hints
285+
hints.pointer.free if hints
288286

289287
if res_p
290288
ptr = res_p.read_pointer
@@ -329,12 +327,12 @@ def self.char_pointer(length, &block)
329327
end
330328

331329
def self.memory_pointer(*args, &block)
332-
Truffle::FFI::MemoryPointer.new(*args, &block)
330+
::FFI::MemoryPointer.new(*args, &block)
333331
end
334332

335333
def self.pointers_of_type(current, type)
336334
pointers = []
337-
size = Truffle::FFI.type_size(type)
335+
size = ::FFI.type_size(type)
338336
pointer = current.read_pointer
339337

340338
until pointer.null?

lib/truffle/socket/truffle/foreign/addrinfo.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
module Truffle
2828
module Socket
2929
module Foreign
30-
class Addrinfo < Truffle::FFI::Struct
31-
config('platform.addrinfo', :ai_flags, :ai_family, :ai_socktype,
30+
class Addrinfo < ::FFI::Struct
31+
Truffle::Socket.config(self, 'platform.addrinfo', :ai_flags, :ai_family, :ai_socktype,
3232
:ai_protocol, :ai_addrlen, :ai_addr, :ai_canonname, :ai_next)
3333
end
3434
end

lib/truffle/socket/truffle/foreign/hostent.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
module Truffle
2828
module Socket
2929
module Foreign
30-
class Hostent < Truffle::FFI::Struct
31-
config('platform.hostent', :h_name, :h_aliases, :h_addrtype,
30+
class Hostent < ::FFI::Struct
31+
Truffle::Socket.config(self, 'platform.hostent', :h_name, :h_aliases, :h_addrtype,
3232
:h_length, :h_addr_list)
3333

3434
def hostname

lib/truffle/socket/truffle/foreign/ifaddrs.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ module Foreign
3737
# To ensure Rubinius doesn't accidentally free invalid pointers all
3838
# pointers (including the pointer of "self") stored in this class have the
3939
# "autorelease" option set to false.
40-
class Ifaddrs < Truffle::FFI::Struct
41-
config('platform.ifaddrs', :ifa_next, :ifa_name, :ifa_flags,
40+
class Ifaddrs < ::FFI::Struct
41+
Truffle::Socket.config(self, 'platform.ifaddrs', :ifa_next, :ifa_name, :ifa_flags,
4242
:ifa_addr, :ifa_netmask, :ifa_broadaddr, :ifa_dstaddr)
4343

4444
POINTERS = [

0 commit comments

Comments
 (0)