binaryen 1.1.6.7 → 1.1.6.9

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: 18c535d2045e224d5ba46b3117e7eced2ff502b0cb338c6e7307113f011cb5fa
4
+ data.tar.gz: 8d1a5f09b94e86221e142d0773c8b23ea0a1987275a322a175daf84db2b2e01b
5
5
  SHA512:
6
- metadata.gz: 21ec4f01eacfa0d38b08acae723f5f6bf662f42047950354c3260b9d461b774ba91749b82b162a74b83ef0e70aa4b6541fcbbbb70111cd30b11b969955a2cfec
7
- data.tar.gz: 5dbbf03fe6f8325cdaa1e78c81bfb7feef07d1887d53a647202f56dc58e5ac1b628a2057f0e5cce083bd2868894e622054f1a999d476a568ef04a5c1558a2d72
6
+ metadata.gz: dea3bf6b7f13d19fc83dc18632092306650ae3b077f2221fa62c0f35beaee50a4acf54ff50f114049da1bdf4b4485076f19e3039e9ec714b158468fb07286850
7
+ data.tar.gz: ac18a83b7221afaa90c2643ccad41af25f1be1bac141011afb056cc16a824e98c7c75832fe03b7f18b703184479faff1fe9bff127eb255cec321d50904a2e35e
@@ -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
+ io.close
75
+ elsif io == stdout
76
+ out << data_buffer
77
+ elsif io == stderr_stream && stderr
78
+ stderr << data_buffer
79
+ end
80
+ rescue Errno::EINTR
81
+ # This means that the read was interrupted by a signal, which is not an error. So we just retry.
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.9"
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.9
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: 2024-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: posix-spawn
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
106
  - !ruby/object:Gem::Version
107
107
  version: '0'
108
108
  requirements: []
109
- rubygems_version: 3.4.22
109
+ rubygems_version: 3.5.4
110
110
  signing_key:
111
111
  specification_version: 4
112
112
  summary: Vendors binaryen libraries, headers, and executables for use in Ruby