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 +4 -4
- data/lib/binaryen/command.rb +81 -23
- data/lib/binaryen/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18c535d2045e224d5ba46b3117e7eced2ff502b0cb338c6e7307113f011cb5fa
|
4
|
+
data.tar.gz: 8d1a5f09b94e86221e142d0773c8b23ea0a1987275a322a175daf84db2b2e01b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dea3bf6b7f13d19fc83dc18632092306650ae3b077f2221fa62c0f35beaee50a4acf54ff50f114049da1bdf4b4485076f19e3039e9ec714b158468fb07286850
|
7
|
+
data.tar.gz: ac18a83b7221afaa90c2643ccad41af25f1be1bac141011afb056cc16a824e98c7c75832fe03b7f18b703184479faff1fe9bff127eb255cec321d50904a2e35e
|
data/lib/binaryen/command.rb
CHANGED
@@ -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
|
-
|
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:
|
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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
data/lib/binaryen/version.rb
CHANGED
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.
|
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:
|
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
|
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
|