summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/Asyncify.cpp3
-rw-r--r--src/support/string.h42
-rw-r--r--test/unit/input/asyncify-pure.wast3
-rw-r--r--test/unit/test_asyncify.py2
4 files changed, 50 insertions, 0 deletions
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp
index 361976fc3..379452d42 100644
--- a/src/passes/Asyncify.cpp
+++ b/src/passes/Asyncify.cpp
@@ -1043,6 +1043,9 @@ struct Asyncify : public Pass {
String::Split whitelist(
runner->options.getArgumentOrDefault("asyncify-whitelist", ""), ",");
+ blacklist = handleBracketingOperators(blacklist);
+ whitelist = handleBracketingOperators(whitelist);
+
// The lists contain human-readable strings. Turn them into the internal
// escaped names for later comparisons
auto processList = [module](String::Split& list, const std::string& which) {
diff --git a/src/support/string.h b/src/support/string.h
index c8a8cb445..72bbdb509 100644
--- a/src/support/string.h
+++ b/src/support/string.h
@@ -31,6 +31,8 @@ namespace String {
// Creates a vector of the split parts of a string, by a delimiter.
class Split : public std::vector<std::string> {
public:
+ Split() = default;
+
Split(const std::string& input, const std::string& delim) {
size_t lastEnd = 0;
while (lastEnd < input.size()) {
@@ -44,6 +46,46 @@ public:
}
};
+// Handles bracketing in a list initially split by ",", but the list may
+// contain nested ","s. For example,
+// void foo(int, double)
+// must be kept together because of the "(". Likewise, "{", "<", "[" are
+// handled.
+inline String::Split handleBracketingOperators(String::Split split) {
+ String::Split ret;
+ std::string last;
+ int nesting = 0;
+ auto handlePart = [&](std::string part) {
+ if (part.empty()) {
+ return;
+ }
+ for (const char c : part) {
+ if (c == '(' || c == '<' || c == '[' || c == '{') {
+ nesting++;
+ } else if (c == ')' || c == '>' || c == ']' || c == '}') {
+ nesting--;
+ }
+ }
+ if (last.empty()) {
+ last = part;
+ } else {
+ last += ',' + part;
+ }
+ if (nesting == 0) {
+ ret.push_back(last);
+ last.clear();
+ }
+ };
+ for (auto& part : split) {
+ handlePart(part);
+ }
+ handlePart("");
+ if (nesting != 0) {
+ Fatal() << "Asyncify: failed to parse lists";
+ }
+ return ret;
+}
+
// Does a simple wildcard match between a pattern and a value. Currently
// supports a '*' at the end of the pattern.
inline bool wildcardMatch(const std::string& pattern,
diff --git a/test/unit/input/asyncify-pure.wast b/test/unit/input/asyncify-pure.wast
index 27c9da111..961ab9442 100644
--- a/test/unit/input/asyncify-pure.wast
+++ b/test/unit/input/asyncify-pure.wast
@@ -55,5 +55,8 @@
(call $main)
(call $print (i32.const 500))
)
+ ;; interesting escaped name
+ (func $DOS_ReadFile\28unsigned\20short\2c\20unsigned\20char*\2c\20unsigned\20short*\2c\20bool\29 (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
+ )
)
diff --git a/test/unit/test_asyncify.py b/test/unit/test_asyncify.py
index 3856c262d..f2d7839b6 100644
--- a/test/unit/test_asyncify.py
+++ b/test/unit/test_asyncify.py
@@ -35,6 +35,8 @@ class AsyncifyTest(BinaryenTestCase):
('--pass-arg=asyncify-whitelist@nonexistent', 'nonexistent'),
('--pass-arg=asyncify-blacklist@main', None),
('--pass-arg=asyncify-whitelist@main', None),
+ ('--pass-arg=asyncify-whitelist@main', None),
+ ('--pass-arg=asyncify-whitelist@DOS_ReadFile(unsigned short, unsigned char*, unsigned short*, bool)', None),
]:
print(arg, warning)
err = run_process(WASM_OPT + [self.input_path('asyncify-pure.wast'), '--asyncify', arg], stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.strip()