Skip to content

Commit

Permalink
Support one-line-one-function file format for asyncify lists (WebAsse…
Browse files Browse the repository at this point in the history
…mbly#6051)

If there are newlines in the list, then we split using them in a simple manner
(that does not take into account nesting of any other delimiters).

Fixes WebAssembly#6047
Fixes WebAssembly#5271
  • Loading branch information
caiiiycuk authored and radekdoulik committed Jul 12, 2024
1 parent 8373cfc commit 342c205
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 7 deletions.
11 changes: 7 additions & 4 deletions src/passes/Asyncify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1626,7 +1626,8 @@ struct Asyncify : public Pass {
options.getArgumentOrDefault("asyncify-ignore-imports", "");
bool allImportsCanChangeState =
stateChangingImports == "" && ignoreImports == "";
String::Split listedImports(stateChangingImports, ",");
String::Split listedImports(stateChangingImports,
String::Split::NewLineOr(","));
// canIndirectChangeState is the default. asyncify-ignore-indirect sets it
// to false.
auto canIndirectChangeState =
Expand All @@ -1638,19 +1639,21 @@ struct Asyncify : public Pass {
removeListInput = options.getArgumentOrDefault("asyncify-blacklist", "");
}
String::Split removeList(
String::trim(read_possible_response_file(removeListInput)), ",");
String::trim(read_possible_response_file(removeListInput)),
String::Split::NewLineOr(","));
String::Split addList(
String::trim(read_possible_response_file(
options.getArgumentOrDefault("asyncify-addlist", ""))),
",");
String::Split::NewLineOr(","));
std::string onlyListInput =
options.getArgumentOrDefault("asyncify-onlylist", "");
if (onlyListInput.empty()) {
// Support old name for now to avoid immediate breakage TODO remove
onlyListInput = options.getArgumentOrDefault("asyncify-whitelist", "");
}
String::Split onlyList(
String::trim(read_possible_response_file(onlyListInput)), ",");
String::trim(read_possible_response_file(onlyListInput)),
String::Split::NewLineOr(","));
auto asserts = options.hasArgument("asyncify-asserts");
auto verbose = options.hasArgument("asyncify-verbose");
auto relocatable = options.hasArgument("asyncify-relocatable");
Expand Down
39 changes: 36 additions & 3 deletions src/support/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ namespace wasm::String {

// Creates a vector of the split parts of a string, by a delimiter.
class Split : public std::vector<std::string> {
public:
Split() = default;
private:
// If we split on newlines then we do not need to handle bracketing at all.
// Otherwise, splitting on say "," does require us to understanding the
// scoping of brackets, e.g., "foo(x, y),bar" should be split as "foo(x, y)",
// "bar".
bool needToHandleBracketingOperations = true;

Split(const std::string& input, const std::string& delim) {
void split(const std::string& input, const std::string& delim) {
size_t lastEnd = 0;
while (lastEnd < input.size()) {
auto nextDelim = input.find(delim, lastEnd);
Expand All @@ -44,6 +48,31 @@ class Split : public std::vector<std::string> {
(*this).push_back(input.substr(lastEnd, nextDelim - lastEnd));
lastEnd = nextDelim + delim.size();
}
needToHandleBracketingOperations = delim != "\n";
}
friend String::Split handleBracketingOperators(String::Split split);

public:
// This can be used when we want to split on newlines if there are any, and if
// there are not, then using the given delimiter.
struct NewLineOr {
const std::string delim;
explicit NewLineOr(const std::string& delim) : delim(delim) {}
};

Split() = default;

Split(const std::string& input, const NewLineOr& newLineOrDelim) {
auto first = input.find("\n", 0);
if (first != std::string::npos && first != input.length() - 1) {
split(input, "\n");
} else {
split(input, newLineOrDelim.delim);
}
}

Split(const std::string& input, const std::string& delim) {
split(input, delim);
}
};

Expand All @@ -53,6 +82,10 @@ class Split : public std::vector<std::string> {
// must be kept together because of the "(". Likewise, "{", "<", "[" are
// handled.
inline String::Split handleBracketingOperators(String::Split split) {
if (!split.needToHandleBracketingOperations) {
return split;
}

String::Split ret;
std::string last;
int nesting = 0;
Expand Down
2 changes: 2 additions & 0 deletions test/lit/passes/asyncify-foo,bar-nl.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
foo
bar
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up.

;; RUN: foreach %s %t wasm-opt --asyncify --pass-arg=asyncify-blacklist@foo,bar -S -o - | filecheck %s
;; RUN: foreach %s %t wasm-opt --asyncify --pass-arg=asyncify-blacklist@@%S/asyncify-foo,bar-nl.txt -S -o - | filecheck %s

(module
(memory 1 2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up.

;; RUN: foreach %s %t wasm-opt --asyncify --pass-arg=asyncify-onlylist@foo,bar -S -o - | filecheck %s
;; RUN: foreach %s %t wasm-opt --asyncify --pass-arg=asyncify-onlylist@@%S/asyncify-foo,bar-nl.txt -S -o - | filecheck %s

(module
(memory 1 2)
Expand Down

0 comments on commit 342c205

Please sign in to comment.