binaryen 1.1.6.7 → 1.1.6.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e208c99114153cd5edae8ca1125d26eeecb8f2b5f91e218ccc63f807827ee4fe
4
- data.tar.gz: 6839fedb4b0c710fc1aa852909f3a24daf1729a2f1531e6c3c47b7594f2819d3
3
+ metadata.gz: 4217d4168d453c8e5316e9c66929d5e09057ec356dc6f80802c41521de6fd612
4
+ data.tar.gz: 2cb4b068c0456d72dcc55cf0d945a5357df0d3ad8c82166fca8a57dcd2908ec4
5
5
  SHA512:
6
- metadata.gz: 21ec4f01eacfa0d38b08acae723f5f6bf662f42047950354c3260b9d461b774ba91749b82b162a74b83ef0e70aa4b6541fcbbbb70111cd30b11b969955a2cfec
7
- data.tar.gz: 5dbbf03fe6f8325cdaa1e78c81bfb7feef07d1887d53a647202f56dc58e5ac1b628a2057f0e5cce083bd2868894e622054f1a999d476a568ef04a5c1558a2d72
6
+ metadata.gz: 9e3fd947316b466a8d592014bc57b1c34148da5b3042e0630b2bc5f56e54c287ab4c6416e78c1ef392e88429cbbcba0c0c3549bdd8b99d7068972c1adeb0c698
7
+ data.tar.gz: 2cdfe8e57ab692f16e911e7a819cb6cfecbf9b31027a04c8863eb919fd952cb6d92832d3884768cf05704507c7c408bcfb19eed3c47b90dfcbb6f1e7eaefc679
@@ -1,50 +1,108 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "English"
4
- require "shellwords"
5
- require "timeout"
6
3
  require "posix/spawn"
4
+ require "timeout"
5
+ require "tempfile"
7
6
 
8
7
  module Binaryen
9
- # Wrapper around a binaryen executable command with a timeout and streaming IO.
10
- #
11
- # @example Running wasm-opt
12
- #
13
- # ```ruby
14
- # command = Binaryen::Command.new("wasm-opt", timeout: 10)
15
- # optimized_wasm = command.run("-O4", stdin: "(module)")
16
- # ```
17
8
  class Command
18
- MAX_OUTPUT_SIZE = 256 * 1024 * 1024
9
+ include POSIX::Spawn
10
+ DEFAULT_MAX_OUTPUT_SIZE = 256 * 1024 * 1024
11
+ DEFAULT_TIMEOUT = 10
19
12
  DEFAULT_ARGS_FOR_COMMAND = {
20
13
  "wasm-opt" => ["--output=-"],
21
14
  }.freeze
22
15
 
23
- def initialize(cmd, timeout: 10, ignore_missing: false)
16
+ def initialize(cmd, timeout: DEFAULT_TIMEOUT, max_output_size: DEFAULT_MAX_OUTPUT_SIZE, ignore_missing: false)
24
17
  @cmd = command_path(cmd, ignore_missing) || raise(ArgumentError, "command not found: #{cmd}")
25
18
  @timeout = timeout
26
19
  @default_args = DEFAULT_ARGS_FOR_COMMAND.fetch(cmd, [])
20
+ @max_output_size = max_output_size
27
21
  end
28
22
 
29
23
  def run(*arguments, stdin: nil, stderr: nil)
30
24
  args = [@cmd] + arguments + @default_args
31
- child = POSIX::Spawn::Child.new(*args, input: stdin, timeout: @timeout, max: MAX_OUTPUT_SIZE)
32
- stderr&.write(child.err)
33
- status = child.status
34
25
 
35
- raise Binaryen::NonZeroExitStatus, "command exited with status #{status.exitstatus}" unless status.success?
36
-
37
- child.out
38
- rescue POSIX::Spawn::MaximumOutputExceeded => e
39
- raise Binaryen::MaximumOutputExceeded, e.message
40
- rescue POSIX::Spawn::TimeoutExceeded => e
41
- raise Timeout::Error, e.message
26
+ if stdin
27
+ with_stdin_tempfile(stdin) { |path| spawn_command(*args, path, stderr: stderr) }
28
+ else
29
+ spawn_command(*args, stderr: stderr)
30
+ end
42
31
  end
43
32
 
44
33
  private
45
34
 
35
+ def with_stdin_tempfile(content)
36
+ Tempfile.open("binaryen-stdin") do |f|
37
+ f.binmode
38
+ f.write(content)
39
+ f.close
40
+ yield f.path
41
+ end
42
+ end
43
+
46
44
  def command_path(cmd, ignore_missing)
47
45
  Dir[File.join(Binaryen.bindir, cmd)].first || (ignore_missing && cmd)
48
46
  end
47
+
48
+ def spawn_command(*args, stderr: nil)
49
+ out = "".b
50
+ data_buffer = "".b
51
+ start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
52
+ pid, stdin, stdout, stderr_stream = popen4(*args)
53
+ stdin.close
54
+ @pid = pid
55
+ readers = [stdout, stderr_stream]
56
+
57
+ while readers.any?
58
+ elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
59
+ remaining_time = @timeout - elapsed_time
60
+ ready = IO.select(readers, nil, nil, remaining_time)
61
+ raise Timeout::Error, "command timed out after #{@timeout} seconds" if ready.nil?
62
+
63
+ ready[0].each do |io|
64
+ max_amount_to_read = @max_output_size - out.bytesize + 1
65
+ data = io.read_nonblock(max_amount_to_read, data_buffer, exception: false)
66
+
67
+ if data == :wait_readable
68
+ # If the IO object is not ready for reading, read_nonblock returns :wait_readable.
69
+ # This isn't an error, but a notification.
70
+ next
71
+ elsif data.nil?
72
+ # At EOF, read_nonblock returns nil instead of raising EOFError.
73
+ readers.delete(io)
74
+ elsif io == stdout
75
+ out << data_buffer
76
+ elsif io == stderr_stream && stderr
77
+ stderr << data_buffer
78
+ end
79
+ rescue Errno::EPIPE, Errno::EINTR
80
+ # Handle EPIPE and EINTR errors
81
+ readers.delete(io)
82
+ end
83
+
84
+ if out.bytesize > @max_output_size
85
+ Process.kill("TERM", @pid)
86
+ raise Binaryen::MaximumOutputExceeded, "maximum output size exceeded (#{@max_output_size} bytes)"
87
+ end
88
+
89
+ if remaining_time < 0
90
+ Process.kill("TERM", @pid)
91
+ raise Timeout::Error, "command timed out after #{@timeout} seconds"
92
+ end
93
+ end
94
+
95
+ _, status = Process.waitpid2(pid, Process::WUNTRACED)
96
+
97
+ raise Binaryen::NonZeroExitStatus, "command exited with status #{status.exitstatus}" unless status.success?
98
+
99
+ out
100
+ ensure
101
+ [stdin, stdout, stderr_stream].each do |io|
102
+ io.close
103
+ rescue
104
+ nil
105
+ end
106
+ end
49
107
  end
50
108
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Binaryen
4
- VERSION = "1.1.6.7"
4
+ VERSION = "1.1.6.8"
5
5
  BINARYEN_VERSION = "version_116"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: binaryen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.6.7
4
+ version: 1.1.6.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-18 00:00:00.000000000 Z
11
+ date: 2023-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: posix-spawn