diff options
-rw-r--r-- | src/passes/Asyncify.cpp | 12 | ||||
-rw-r--r-- | src/support/file.cpp | 8 | ||||
-rw-r--r-- | src/support/file.h | 6 | ||||
-rw-r--r-- | src/support/string.h | 10 | ||||
-rw-r--r-- | test/unit/test_asyncify.py | 14 |
5 files changed, 48 insertions, 2 deletions
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp index 379452d42..1394cd015 100644 --- a/src/passes/Asyncify.cpp +++ b/src/passes/Asyncify.cpp @@ -199,6 +199,13 @@ // (aside from the asyncify.* imports, which are always assumed to). // Each entry can end in a '*' in which case it is matched as a prefix. // +// The list of imports can be a response file (which is convenient if it +// is long, or you don't want to bother escaping it on the commandline +// etc.), e.g. --pass-arg=asyncify-imports@@file.txt will load the +// contents of file.txt (note the double "@@" - the first is the +// separator for --pass-arg, and the second is the usual convention for +// indicating a response file). +// // --pass-arg=asyncify-ignore-imports // // Ignore all imports (except for bynsyncify.*), that is, assume none of @@ -241,6 +248,7 @@ #include "ir/module-utils.h" #include "ir/utils.h" #include "pass.h" +#include "support/file.h" #include "support/string.h" #include "support/unique_deferring_queue.h" #include "wasm-builder.h" @@ -1029,8 +1037,8 @@ struct Asyncify : public Pass { MemoryUtils::ensureExists(module->memory); // Find which things can change the state. - auto stateChangingImports = - runner->options.getArgumentOrDefault("asyncify-imports", ""); + auto stateChangingImports = String::trim(read_possible_response_file( + runner->options.getArgumentOrDefault("asyncify-imports", ""))); auto ignoreImports = runner->options.getArgumentOrDefault("asyncify-ignore-imports", ""); bool allImportsCanChangeState = diff --git a/src/support/file.cpp b/src/support/file.cpp index b4c410b5e..68ffbb5ac 100644 --- a/src/support/file.cpp +++ b/src/support/file.cpp @@ -77,6 +77,14 @@ T wasm::read_file(const std::string& filename, return input; } +std::string wasm::read_possible_response_file(const std::string& input) { + if (input.size() == 0 || input[0] != '@') { + return input; + } + return wasm::read_file<std::string>( + input.substr(1), Flags::Text, Flags::Release); +} + // Explicit instantiations for the explicit specializations. template std::string wasm::read_file<>(const std::string&, Flags::BinaryOption, Flags::DebugOption); diff --git a/src/support/file.h b/src/support/file.h index 67d63315b..fb3cad564 100644 --- a/src/support/file.h +++ b/src/support/file.h @@ -39,12 +39,18 @@ template<typename T> T read_file(const std::string& filename, Flags::BinaryOption binary, Flags::DebugOption debug); + // Declare the valid explicit specializations. extern template std::string read_file<>(const std::string&, Flags::BinaryOption, Flags::DebugOption); extern template std::vector<char> read_file<>(const std::string&, Flags::BinaryOption, Flags::DebugOption); +// Given a string which may be a response file (i.e., a filename starting +// with "@"), if it is a response file read it and return that, or if it +// is not a response file, return it as is. +std::string read_possible_response_file(const std::string&); + class Output { public: // An empty filename will open stdout instead. diff --git a/src/support/string.h b/src/support/string.h index 72bbdb509..b3d12c6ae 100644 --- a/src/support/string.h +++ b/src/support/string.h @@ -21,6 +21,7 @@ #ifndef wasm_support_string_h #define wasm_support_string_h +#include <cctype> #include <string> #include <vector> @@ -104,6 +105,15 @@ inline bool wildcardMatch(const std::string& pattern, return value.size() == pattern.size(); } +// Removes any extra whitespace or \0. +inline std::string trim(const std::string& input) { + size_t size = input.size(); + while (size > 0 && (isspace(input[size - 1]) || input[size - 1] == '\0')) { + size--; + } + return input.substr(0, size); +} + } // namespace String } // namespace wasm diff --git a/test/unit/test_asyncify.py b/test/unit/test_asyncify.py index a8161cc1d..e2fe82af9 100644 --- a/test/unit/test_asyncify.py +++ b/test/unit/test_asyncify.py @@ -1,5 +1,6 @@ import os import subprocess +import tempfile from scripts.test.shared import WASM_OPT, WASM_DIS, WASM_SHELL, NODEJS, run_process from .utils import BinaryenTestCase @@ -50,3 +51,16 @@ class AsyncifyTest(BinaryenTestCase): proc = run_process(WASM_OPT + [self.input_path('asyncify-pure.wast'), '--asyncify', '--pass-arg=asyncify-whitelist@main', '--pass-arg=asyncify-blacklist@main'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) self.assertNotEqual(proc.returncode, 0, 'must error on using both lists at once') self.assertIn('It makes no sense to use both a blacklist and a whitelist with asyncify', proc.stdout) + + def test_asyncify_imports(self): + def test(args): + return run_process(WASM_OPT + [self.input_path('asyncify-sleep.wast'), '--asyncify', '--print'] + args, stdout=subprocess.PIPE).stdout + + normal = test(['--pass-arg=asyncify-imports@env.sleep']) + temp = tempfile.NamedTemporaryFile().name + with open(temp, 'w') as f: + f.write('env.sleep') + response = test(['--pass-arg=asyncify-imports@@%s' % temp]) + self.assertEqual(normal, response) + without = test(['--pass-arg=asyncify-imports@without.anything']) + self.assertNotEqual(normal, without) |