summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-02-17 08:54:04 -0800
committerGitHub <noreply@github.com>2023-02-17 08:54:04 -0800
commitc2f3bbff0d77d3f6ad87a1e47570d4d5d5171284 (patch)
treec7bd8c9aa678387b9de93a2a6af13519c65b9578 /src
parent6370b7528103f7a92bcfcd839614620f51475865 (diff)
downloadbinaryen-c2f3bbff0d77d3f6ad87a1e47570d4d5d5171284.tar.gz
binaryen-c2f3bbff0d77d3f6ad87a1e47570d4d5d5171284.tar.bz2
binaryen-c2f3bbff0d77d3f6ad87a1e47570d4d5d5171284.zip
[Strings] Interpret string.eq and string.compare (#5501)
Diffstat (limited to 'src')
-rw-r--r--src/wasm-interpreter.h67
1 files changed, 66 insertions, 1 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 87b0e0c67..4615e8625 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1843,7 +1843,72 @@ public:
Flow visitStringMeasure(StringMeasure* curr) { WASM_UNREACHABLE("unimp"); }
Flow visitStringEncode(StringEncode* curr) { WASM_UNREACHABLE("unimp"); }
Flow visitStringConcat(StringConcat* curr) { WASM_UNREACHABLE("unimp"); }
- Flow visitStringEq(StringEq* curr) { WASM_UNREACHABLE("unimp"); }
+ Flow visitStringEq(StringEq* curr) {
+ NOTE_ENTER("StringEq");
+ Flow flow = visit(curr->left);
+ if (flow.breaking()) {
+ return flow;
+ }
+ auto left = flow.getSingleValue();
+ flow = visit(curr->right);
+ if (flow.breaking()) {
+ return flow;
+ }
+ auto right = flow.getSingleValue();
+ NOTE_EVAL2(left, right);
+ auto leftData = left.getGCData();
+ auto rightData = right.getGCData();
+ int32_t result;
+ switch (curr->op) {
+ case StringEqEqual: {
+ // They are equal if both are null, or both are non-null and equal.
+ result =
+ (!leftData && !rightData) ||
+ (leftData && rightData && leftData->values == rightData->values);
+ break;
+ }
+ case StringEqCompare: {
+ if (!leftData || !rightData) {
+ trap("null ref");
+ }
+ auto& leftValues = leftData->values;
+ auto& rightValues = rightData->values;
+ Index i = 0;
+ while (1) {
+ if (i == leftValues.size() && i == rightValues.size()) {
+ // We reached the end, and they are equal.
+ result = 0;
+ break;
+ } else if (i == leftValues.size()) {
+ // The left string is short.
+ result = -1;
+ break;
+ } else if (i == rightValues.size()) {
+ result = 1;
+ break;
+ }
+ auto left = leftValues[i].getInteger();
+ auto right = rightValues[i].getInteger();
+ if (left < right) {
+ // The left character is lower.
+ result = -1;
+ break;
+ } else if (left > right) {
+ result = 1;
+ break;
+ } else {
+ // Look further.
+ i++;
+ }
+ }
+ break;
+ }
+ default: {
+ WASM_UNREACHABLE("bad op");
+ }
+ }
+ return Literal(result);
+ }
Flow visitStringAs(StringAs* curr) { WASM_UNREACHABLE("unimp"); }
Flow visitStringWTF8Advance(StringWTF8Advance* curr) {
WASM_UNREACHABLE("unimp");