binaryen 1.1.6.3 → 1.1.6.4

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: e0f235a249bcf6c38016c2033776997d2d636126cea0b37d47c98dc2b932dd08
4
+ data.tar.gz: 3f123ebb5bdb0f24ebf004097e02ccab417d09838e9ec663a87e43ae472cb9a1
5
5
  SHA512:
6
- metadata.gz: 74f7b3010d06316d25eb8b3e74fc2fd33b60f50fcd3bd6db83db8b11c135e003f49f460779e02992e0826a86240b220d3c8e1c82e56361e1e6d054cc7b172679
7
- data.tar.gz: 90de5bc2e078f8083116a8dc8244e3807185ff35c1697ef210070bcd4f01d7bf730f13fa1731f479b06032dcc778109faf848a0daa2da0915ab7fe18b033a3e0
6
+ metadata.gz: 8d58caa196cbc38e9178dba6fa0efdcdde270d298ef5c3f34e523f5281630ae18c32bac9bd6da379fb7b758a536b94afc2c3c3faddb68118c5ccb64255c256da
7
+ data.tar.gz: 85f826a48ba40d0e3d48e4806cc52faf265c058b53421af32efdc67eb811075f99c7e83488f6aab85b141478cac104c2d1031931374df75c650972107c8acd5a
@@ -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,82 @@ 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
+ write_to_pipe(stderr, err_output, timeout_checker, close_write: false)
52
57
  end
58
+ output = read_from_pipe(ord, timeout_checker)
59
+ wait_or_kill(pid, timeout_checker, erd, stderr)
53
60
 
54
- child.out
55
- rescue POSIX::Spawn::TimeoutExceeded => e
56
- raise Timeout::Error, e.message
61
+ output
57
62
  end
58
63
 
59
64
  private
60
65
 
61
- def build_arguments(*arguments)
62
- arguments + @default_args
66
+ def write_to_pipe(pipe, stdin, timeout_checker, close_write: true)
67
+ offset = 0
68
+ length = stdin.bytesize
69
+
70
+ while offset < length
71
+ remaining_time = timeout_checker.check!
72
+
73
+ if IO.select(nil, [pipe], nil, remaining_time)
74
+ written = pipe.write_nonblock(stdin.byteslice(offset, length), exception: false)
75
+ offset += written if written.is_a?(Integer)
76
+ else
77
+ raise Timeout::Error, "Command timed out"
78
+ end
79
+ end
80
+
81
+ pipe.close_write if close_write
82
+ end
83
+
84
+ def read_from_pipe(pipe, timeout_checker)
85
+ output = +""
86
+
87
+ while (result = pipe.read_nonblock(8192, exception: false))
88
+ remaining_time = timeout_checker.check!
89
+ raise Timeout::Error, "Command timed out" if remaining_time <= 0
90
+
91
+ case result
92
+ when :wait_readable
93
+ IO.select([pipe], nil, nil, remaining_time)
94
+ when nil
95
+ break
96
+ else
97
+ output << result
98
+ end
99
+ end
100
+
101
+ output
102
+ end
103
+
104
+ def wait_or_kill(pid, timeout_checker, err_read, err_write)
105
+ loop do
106
+ remaining_time = timeout_checker.check!
107
+ raise Timeout::Error, "timed out waiting on process" if remaining_time <= 0
108
+
109
+ if (_, status = Process.wait2(pid, Process::WNOHANG))
110
+
111
+ raise Binaryen::NonZeroExitStatus,
112
+ "command exited with status #{status.exitstatus}" if status.exitstatus != 0
113
+
114
+ return true
115
+ else
116
+ sleep(0.1)
117
+ end
118
+ end
119
+ end
120
+
121
+ def build_command(*arguments)
122
+ [@cmd] + arguments + @default_args
63
123
  end
64
124
 
65
125
  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.4"
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.4
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