binaryen 1.1.6.3 → 1.1.6.5

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: ae90a4e59e6f813687257623ab4d4a35633c9409de5459101d8080d65fe1fdf1
4
- data.tar.gz: 20c161cfa875c14801d03ae2f7a43f5342a0e0a8b9c70f9d9e2d1f44b722f3e7
3
+ metadata.gz: 7ec6cd19949163f81747301353e37912f7d2924205816df9f6620f0cb6a266ce
4
+ data.tar.gz: cfc6e449979a806440f5c893640618bd321597e1ae8848108fea8c7b9da88d72
5
5
  SHA512:
6
- metadata.gz: 74f7b3010d06316d25eb8b3e74fc2fd33b60f50fcd3bd6db83db8b11c135e003f49f460779e02992e0826a86240b220d3c8e1c82e56361e1e6d054cc7b172679
7
- data.tar.gz: 90de5bc2e078f8083116a8dc8244e3807185ff35c1697ef210070bcd4f01d7bf730f13fa1731f479b06032dcc778109faf848a0daa2da0915ab7fe18b033a3e0
6
+ metadata.gz: 9e83c357446ac3c2e04d6de7a575d8dca7b4164cd4050416edd87d23fe864165085f25b5e3f7a7f28d46debedcc7fa146f1416aa8a529376c5ea07dfd8f1713b
7
+ data.tar.gz: 8f3e7d8a8582608436191bdea891aa8564cebc0ccceceb750bdbce38b563bd590c32e8b5025a9a63761eb6592347709e06983c023b950d377b016354da111b35
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "English"
4
+ require "shellwords"
3
5
  require "timeout"
4
6
  require "posix/spawn"
5
7
 
@@ -13,6 +15,8 @@ module Binaryen
13
15
  # optimized_wasm = command.run("-O4", stdin: "(module)")
14
16
  # ```
15
17
  class Command
18
+ include POSIX::Spawn
19
+
16
20
  DEFAULT_ARGS_FOR_COMMAND = {
17
21
  "wasm-opt" => ["--output=-"],
18
22
  }.freeze
@@ -40,26 +44,86 @@ module Binaryen
40
44
  @default_args = DEFAULT_ARGS_FOR_COMMAND.fetch(cmd, [])
41
45
  end
42
46
 
43
- def run(*arguments, stdin: nil, stderr: File::NULL)
44
- args = build_arguments(*arguments)
45
- child = POSIX::Spawn::Child.new(@cmd, *args, input: stdin, timeout: @timeout)
46
- if child.status && !child.status.success?
47
- err_io = stderr.is_a?(String) ? File.open(stderr, "w") : stderr
48
- err_io.binmode
49
- err_io.write(child.err)
50
- err_io.rewind
51
- raise NonZeroExitStatus, "command exited with non-zero status: #{child.status}"
47
+ def run(*arguments, stdin: nil, stderr: nil)
48
+ end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) + @timeout
49
+ command = build_command(*arguments)
50
+ pid, iwr, ord, erd = popen4(*command)
51
+ timeout_checker = TimeoutChecker.new(end_time: end_time, pid: pid)
52
+
53
+ write_to_pipe(iwr, stdin, timeout_checker) if stdin
54
+ if stderr
55
+ err_output = read_from_pipe(erd, timeout_checker)
56
+ begin
57
+ write_to_pipe(stderr, err_output, timeout_checker, close_write: false)
58
+ rescue Errno::EPIPE
59
+ # ignore
60
+ end
52
61
  end
62
+ output = read_from_pipe(ord, timeout_checker)
63
+ wait_or_kill(pid, timeout_checker, erd, stderr)
53
64
 
54
- child.out
55
- rescue POSIX::Spawn::TimeoutExceeded => e
56
- raise Timeout::Error, e.message
65
+ output
57
66
  end
58
67
 
59
68
  private
60
69
 
61
- def build_arguments(*arguments)
62
- arguments + @default_args
70
+ def write_to_pipe(pipe, stdin, timeout_checker, close_write: true)
71
+ offset = 0
72
+ length = stdin.bytesize
73
+
74
+ while offset < length
75
+ remaining_time = timeout_checker.check!
76
+
77
+ if IO.select(nil, [pipe], nil, remaining_time)
78
+ written = pipe.write_nonblock(stdin.byteslice(offset, length), exception: false)
79
+ offset += written if written.is_a?(Integer)
80
+ else
81
+ raise Timeout::Error, "Command timed out"
82
+ end
83
+ end
84
+
85
+ pipe.close_write if close_write
86
+ end
87
+
88
+ def read_from_pipe(pipe, timeout_checker)
89
+ output = +""
90
+
91
+ while (result = pipe.read_nonblock(8192, exception: false))
92
+ remaining_time = timeout_checker.check!
93
+ raise Timeout::Error, "Command timed out" if remaining_time <= 0
94
+
95
+ case result
96
+ when :wait_readable
97
+ IO.select([pipe], nil, nil, remaining_time)
98
+ when nil
99
+ break
100
+ else
101
+ output << result
102
+ end
103
+ end
104
+
105
+ output
106
+ end
107
+
108
+ def wait_or_kill(pid, timeout_checker, err_read, err_write)
109
+ loop do
110
+ remaining_time = timeout_checker.check!
111
+ raise Timeout::Error, "timed out waiting on process" if remaining_time <= 0
112
+
113
+ if (_, status = Process.wait2(pid, Process::WNOHANG))
114
+
115
+ raise Binaryen::NonZeroExitStatus,
116
+ "command exited with status #{status.exitstatus}" if status.exitstatus != 0
117
+
118
+ return true
119
+ else
120
+ sleep(0.1)
121
+ end
122
+ end
123
+ end
124
+
125
+ def build_command(*arguments)
126
+ [@cmd] + arguments + @default_args
63
127
  end
64
128
 
65
129
  def command_path(cmd, ignore_missing)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Binaryen
4
- VERSION = "1.1.6.3"
4
+ VERSION = "1.1.6.5"
5
5
  BINARYEN_VERSION = "version_116"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: binaryen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.6.3
4
+ version: 1.1.6.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify Inc.
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.3'
19
+ version: 0.3.15
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.3'
26
+ version: 0.3.15
27
27
  description:
28
28
  email:
29
29
  - gems@shopify.com