Skip to content

Commit e134b02

Browse files
committed
Avoid #set_class in IO.popen and create the right object from the start
1 parent 9c65768 commit e134b02

File tree

2 files changed

+31
-30
lines changed

2 files changed

+31
-30
lines changed

src/main/ruby/core/io.rb

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -805,27 +805,8 @@ def self.parse_mode(mode)
805805
ret
806806
end
807807

808-
def self.pipe(external=nil, internal=nil, options=nil)
809-
fds = FFI::MemoryPointer.new(:int, 2) do |ptr|
810-
r = Truffle::POSIX.pipe(ptr)
811-
Errno.handle if r == -1
812-
ptr.read_array_of_int(2)
813-
end
814-
815-
lhs = self.new(fds[0], RDONLY)
816-
rhs = self.new(fds[1], WRONLY)
817-
818-
lhs.close_on_exec = true
819-
rhs.close_on_exec = true
820-
821-
lhs.set_encoding external || Encoding.default_external,
822-
internal || Encoding.default_internal, options
823-
824-
lhs.sync = true
825-
rhs.sync = true
826-
827-
lhs.pipe = true
828-
rhs.pipe = true
808+
def self.pipe(external = nil, internal = nil, options = nil)
809+
lhs, rhs = Truffle::IOOperations.create_pipe(self, self, external, internal, options)
829810

830811
if block_given?
831812
begin
@@ -881,16 +862,14 @@ def self.popen(*args)
881862
readable = true
882863
end
883864

884-
pa_read, ch_write = pipe if readable
865+
# We only need the Bidirectional pipe if we're reading and writing.
866+
# Otherwise, we can just return the IO object for the proper half.
867+
read_class = (readable && writable) ? IO::BidirectionalPipe : self
868+
869+
pa_read, ch_write = Truffle::IOOperations.create_pipe(read_class, self) if readable
885870
ch_read, pa_write = pipe if writable
886871

887-
# We only need the Bidirectional pipe if we're reading and writing.
888-
# If we're only doing one, we can just return the IO object for
889-
# the proper half.
890872
if readable and writable
891-
# Transmogrify pa_read into a BidirectionalPipe object,
892-
# and then tell it about its pid and pa_write
893-
Truffle::Internal::Unsafe.set_class pa_read, IO::BidirectionalPipe
894873
pipe = pa_read
895874
pipe.set_pipe_info(pa_write)
896875
elsif readable

src/main/ruby/core/truffle/io_operations.rb

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ module IOOperations
1313
def self.last_line(a_binding)
1414
Truffle::KernelOperations.frame_local_variable_get(:$_, a_binding)
1515
end
16+
Truffle::Graal.always_split(method(:last_line))
1617

1718
def self.set_last_line(value, a_binding)
1819
Truffle::KernelOperations.frame_local_variable_set(:$_, a_binding, value)
1920
end
21+
Truffle::Graal.always_split(method(:set_last_line))
2022

2123
def self.print(io, args, last_line_binding)
2224
if args.empty?
@@ -96,7 +98,27 @@ def self.dup2_with_cloexec(old_fd, new_fd)
9698
end
9799
end
98100

99-
Truffle::Graal.always_split(method(:last_line))
100-
Truffle::Graal.always_split(method(:set_last_line))
101+
def self.pipe_end_setup(io)
102+
io.close_on_exec = true
103+
io.sync = true
104+
io.pipe = true
105+
io
106+
end
107+
108+
def self.create_pipe(read_class, write_class, external = nil, internal = nil, options = nil)
109+
fds = Truffle::FFI::MemoryPointer.new(:int, 2) do |ptr|
110+
res = Truffle::POSIX.pipe(ptr)
111+
Errno.handle if res == -1
112+
ptr.read_array_of_int(2)
113+
end
114+
115+
lhs = pipe_end_setup(read_class.new(fds[0], IO::RDONLY))
116+
rhs = pipe_end_setup(write_class.new(fds[1], IO::WRONLY))
117+
118+
lhs.set_encoding external || Encoding.default_external,
119+
internal || Encoding.default_internal, options
120+
121+
[lhs, rhs]
122+
end
101123
end
102124
end

0 commit comments

Comments
 (0)