Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 58 additions & 12 deletions src/support/string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,66 @@ Split handleBracketingOperators(Split split) {
}

bool wildcardMatch(const std::string& pattern, const std::string& value) {
for (size_t i = 0; i < pattern.size(); i++) {
if (pattern[i] == '*') {
return wildcardMatch(pattern.substr(i + 1), value.substr(i)) ||
(value.size() > 0 &&
wildcardMatch(pattern.substr(i), value.substr(i + 1)));
}
if (i >= value.size()) {
return false;
}
if (pattern[i] != value[i]) {
return false;
size_t psize = pattern.size(), vsize = value.size();
// When we start looking at a potential match after a wildcard, we must stash
// our current state in case we need to backtrack later. Store the positions
// in the pattern and the value.
std::vector<std::pair<size_t, size_t>> states;
states.emplace_back(0, 0);
while (!states.empty()) {
auto [p, v] = states.back();
states.pop_back();

// Consume input until we need to backtrack.
while (true) {
// Consume matching non-wildcard input from the pattern and value.
while (p < psize && v < vsize && pattern[p] != '*' &&
pattern[p] == value[v]) {
++p;
++v;
}

// Handle wildcards.
if (p < psize && pattern[p] == '*') {
// Skip past the sequence of wildcards.
while (p < psize && pattern[p] == '*') {
++p;
}
if (p == psize) {
// The pattern ended in a wildcard, so it matches the rest of the
// value no matter what it is.
return true;
}
// Find the next possible match.
while (v < vsize && value[v] != pattern[p]) {
++v;
}
if (v == vsize) {
// No match. Backtrack if possible.
break;
}
// We do lazy matching where the wildcard consumes as little as
// possible. Try continuing the match after the wildcard from here, but
// stash the alternative state where we still have a wildcard and it has
// consumed this character in case we need to backtrack.
states.emplace_back(p - 1, v + 1);
continue;
}

// Check end conditions.
if (p == psize && v == vsize) {
// Success! We've matched the full pattern against the full value.
return true;
}

// We're either out of pattern or out of value or we found a mismatch,
// so we need to try to backtrack.
assert(p == psize || v == vsize || pattern[p] != value[v]);
break;
}
}
return value.size() == pattern.size();
// No match, but cannot backtrack any further.
return false;
}

std::string trim(const std::string& input) {
Expand Down
121 changes: 121 additions & 0 deletions test/lit/passes/no-inline.wast
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
;; RUN: foreach %s %t wasm-opt --no-partial-inline=*maybe* --inlining --optimize-level=3 --partial-inlining-ifs=1 -S -o - | filecheck %s --check-prefix NO_PART
;; RUN: foreach %s %t wasm-opt --no-full-inline=*maybe* --inlining --optimize-level=3 --partial-inlining-ifs=1 -S -o - | filecheck %s --check-prefix NO_FULL
;; RUN: foreach %s %t wasm-opt --no-inline=*maybe* --inlining --optimize-level=3 --partial-inlining-ifs=1 -S -o - | filecheck %s --check-prefix NO_BOTH
;; RUN: foreach %s %t wasm-opt --no-inline=*****maybe***** --inlining --optimize-level=3 --partial-inlining-ifs=1 -S -o - | filecheck %s --check-prefix NO_BOTH

(module
;; YES_ALL: (type $0 (func))
Expand Down Expand Up @@ -638,6 +639,42 @@
)
)

(func $very-long-name-we-should-not-error-on-even-though-it-is-very-very-long
;; Test a long name.
)

;; NO_FULL: (func $very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long
;; NO_FULL-NEXT: )
;; NO_BOTH: (func $very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long
;; NO_BOTH-NEXT: )
(func $very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long
;; Test a long name with "maybe" in it.
)

;; NO_FULL: (func $very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long
;; NO_FULL-NEXT: )
;; NO_BOTH: (func $very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long
;; NO_BOTH-NEXT: )
(func $very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long
;; Test a long name with "maybe" in it, and a partial match earlier ("may").
)

(func $maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmayb
;; Test a long name with many partial matches but no real match.
)

;; NO_FULL: (func $maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybe
;; NO_FULL-NEXT: )
;; NO_BOTH: (func $maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybe
;; NO_BOTH-NEXT: )
(func $maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybe
;; Test a long name with many partial matches and one real match right at the end.
)

(func $mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
;; Test a long name with even more tiny partial matches but no real match.
)

;; YES_ALL: (func $caller
;; YES_ALL-NEXT: (local $0 i32)
;; YES_ALL-NEXT: (local $1 i32)
Expand Down Expand Up @@ -741,6 +778,30 @@
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: (block $__inlined_func$very-long-name-we-should-not-error-on-even-though-it-is-very-very-long$4
;; YES_ALL-NEXT: (block
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: (block $__inlined_func$very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long$5
;; YES_ALL-NEXT: (block
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: (block $__inlined_func$very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long$6
;; YES_ALL-NEXT: (block
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: (block $__inlined_func$maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmayb$7
;; YES_ALL-NEXT: (block
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: (block $__inlined_func$maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybe$8
;; YES_ALL-NEXT: (block
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: (block $__inlined_func$mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm$9
;; YES_ALL-NEXT: (block
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; YES_ALL-NEXT: )
;; NO_PART: (func $caller
;; NO_PART-NEXT: (call $maybe-partial-or-full-1
Expand All @@ -755,6 +816,30 @@
;; NO_PART-NEXT: (call $maybe-partial-or-full-2
;; NO_PART-NEXT: (i32.const 1)
;; NO_PART-NEXT: )
;; NO_PART-NEXT: (block $__inlined_func$very-long-name-we-should-not-error-on-even-though-it-is-very-very-long
;; NO_PART-NEXT: (block
;; NO_PART-NEXT: )
;; NO_PART-NEXT: )
;; NO_PART-NEXT: (block $__inlined_func$very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long$1
;; NO_PART-NEXT: (block
;; NO_PART-NEXT: )
;; NO_PART-NEXT: )
;; NO_PART-NEXT: (block $__inlined_func$very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long$2
;; NO_PART-NEXT: (block
;; NO_PART-NEXT: )
;; NO_PART-NEXT: )
;; NO_PART-NEXT: (block $__inlined_func$maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmayb$3
;; NO_PART-NEXT: (block
;; NO_PART-NEXT: )
;; NO_PART-NEXT: )
;; NO_PART-NEXT: (block $__inlined_func$maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybe$4
;; NO_PART-NEXT: (block
;; NO_PART-NEXT: )
;; NO_PART-NEXT: )
;; NO_PART-NEXT: (block $__inlined_func$mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm$5
;; NO_PART-NEXT: (block
;; NO_PART-NEXT: )
;; NO_PART-NEXT: )
;; NO_PART-NEXT: )
;; NO_FULL: (func $caller
;; NO_FULL-NEXT: (local $0 i32)
Expand Down Expand Up @@ -817,6 +902,21 @@
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: (block $__inlined_func$very-long-name-we-should-not-error-on-even-though-it-is-very-very-long$4
;; NO_FULL-NEXT: (block
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: (call $very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long)
;; NO_FULL-NEXT: (call $very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long)
;; NO_FULL-NEXT: (block $__inlined_func$maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmayb$5
;; NO_FULL-NEXT: (block
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: (call $maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybe)
;; NO_FULL-NEXT: (block $__inlined_func$mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm$6
;; NO_FULL-NEXT: (block
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: )
;; NO_FULL-NEXT: )
;; NO_BOTH: (func $caller
;; NO_BOTH-NEXT: (call $maybe-partial-or-full-1
Expand All @@ -831,6 +931,21 @@
;; NO_BOTH-NEXT: (call $maybe-partial-or-full-2
;; NO_BOTH-NEXT: (i32.const 1)
;; NO_BOTH-NEXT: )
;; NO_BOTH-NEXT: (block $__inlined_func$very-long-name-we-should-not-error-on-even-though-it-is-very-very-long
;; NO_BOTH-NEXT: (block
;; NO_BOTH-NEXT: )
;; NO_BOTH-NEXT: )
;; NO_BOTH-NEXT: (call $very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long)
;; NO_BOTH-NEXT: (call $very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long)
;; NO_BOTH-NEXT: (block $__inlined_func$maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmayb$1
;; NO_BOTH-NEXT: (block
;; NO_BOTH-NEXT: )
;; NO_BOTH-NEXT: )
;; NO_BOTH-NEXT: (call $maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybe)
;; NO_BOTH-NEXT: (block $__inlined_func$mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm$2
;; NO_BOTH-NEXT: (block
;; NO_BOTH-NEXT: )
;; NO_BOTH-NEXT: )
;; NO_BOTH-NEXT: )
(func $caller
;; In YES_ALL we will fully inline all of these. In NO_FULL we will partially
Expand All @@ -851,6 +966,12 @@
(call $maybe-partial-or-full-2
(i32.const 1)
)
(call $very-long-name-we-should-not-error-on-even-though-it-is-very-very-long)
(call $very-long-name-we-should-not-error-on-maybe-even-though-it-is-very-very-long)
(call $very-long-name-we-may-should-not-error-on-maybe-even-though-it-is-very-very-long)
(call $maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmayb)
(call $maybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybmaybe)
(call $mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm)
)
)
;; NO_FULL: (func $byn-split-outlined-B$maybe-partial-or-full-1 (param $x i32)
Expand Down
Loading