summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-01-25 15:29:21 -0800
committerGitHub <noreply@github.com>2023-01-25 23:29:21 +0000
commitb5476c6378e10350bf17080fae9bfd8ceeb83cd2 (patch)
tree85dc2d568a7d3dbed85f798a1039065bc6843bb2 /src
parent17d120a3337fe56567d4e45583db8ea62ee8bf6f (diff)
downloadbinaryen-b5476c6378e10350bf17080fae9bfd8ceeb83cd2.tar.gz
binaryen-b5476c6378e10350bf17080fae9bfd8ceeb83cd2.tar.bz2
binaryen-b5476c6378e10350bf17080fae9bfd8ceeb83cd2.zip
[Strings] Add string.compare (#5453)
See WebAssembly/stringref#58
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp2
-rw-r--r--src/gen-s-parser.inc56
-rw-r--r--src/passes/Print.cpp13
-rw-r--r--src/wasm-binary.h1
-rw-r--r--src/wasm-builder.h3
-rw-r--r--src/wasm-delegations-fields.def1
-rw-r--r--src/wasm-s-parser.h2
-rw-r--r--src/wasm.h7
-rw-r--r--src/wasm/wasm-binary.cpp9
-rw-r--r--src/wasm/wasm-s-parser.cpp6
-rw-r--r--src/wasm/wasm-stack.cpp12
-rw-r--r--src/wasm/wat-parser.cpp5
12 files changed, 87 insertions, 30 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 32dcfd8db..cd53f9ced 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -1880,7 +1880,7 @@ BinaryenExpressionRef BinaryenStringEq(BinaryenModuleRef module,
BinaryenExpressionRef right) {
return static_cast<Expression*>(
Builder(*(Module*)module)
- .makeStringEq((Expression*)left, (Expression*)right));
+ .makeStringEq(StringEqEqual, (Expression*)left, (Expression*)right));
}
BinaryenExpressionRef BinaryenStringAs(BinaryenModuleRef module,
BinaryenOp op,
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index b44329388..6f2c24a47 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -3138,13 +3138,21 @@ switch (buf[0]) {
}
}
case 'c': {
- switch (buf[10]) {
- case 'c':
- if (op == "string.concat"sv) { return makeStringConcat(s); }
- goto parse_error;
- case 's':
- if (op == "string.const"sv) { return makeStringConst(s); }
+ switch (buf[9]) {
+ case 'm':
+ if (op == "string.compare"sv) { return makeStringEq(s, StringEqCompare); }
goto parse_error;
+ case 'n': {
+ switch (buf[10]) {
+ case 'c':
+ if (op == "string.concat"sv) { return makeStringConcat(s); }
+ goto parse_error;
+ case 's':
+ if (op == "string.const"sv) { return makeStringConst(s); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
default: goto parse_error;
}
}
@@ -3178,7 +3186,7 @@ switch (buf[0]) {
}
}
case 'q':
- if (op == "string.eq"sv) { return makeStringEq(s); }
+ if (op == "string.eq"sv) { return makeStringEq(s, StringEqEqual); }
goto parse_error;
default: goto parse_error;
}
@@ -8812,21 +8820,33 @@ switch (buf[0]) {
}
}
case 'c': {
- switch (buf[10]) {
- case 'c':
- if (op == "string.concat"sv) {
- auto ret = makeStringConcat(ctx, pos);
+ switch (buf[9]) {
+ case 'm':
+ if (op == "string.compare"sv) {
+ auto ret = makeStringEq(ctx, pos, StringEqCompare);
CHECK_ERR(ret);
return *ret;
}
goto parse_error;
- case 's':
- if (op == "string.const"sv) {
- auto ret = makeStringConst(ctx, pos);
- CHECK_ERR(ret);
- return *ret;
+ case 'n': {
+ switch (buf[10]) {
+ case 'c':
+ if (op == "string.concat"sv) {
+ auto ret = makeStringConcat(ctx, pos);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ case 's':
+ if (op == "string.const"sv) {
+ auto ret = makeStringConst(ctx, pos);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ default: goto parse_error;
}
- goto parse_error;
+ }
default: goto parse_error;
}
}
@@ -8877,7 +8897,7 @@ switch (buf[0]) {
}
case 'q':
if (op == "string.eq"sv) {
- auto ret = makeStringEq(ctx, pos);
+ auto ret = makeStringEq(ctx, pos, StringEqEqual);
CHECK_ERR(ret);
return *ret;
}
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 38e88fde5..d9a4c38e5 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -2424,7 +2424,18 @@ struct PrintExpressionContents
void visitStringConcat(StringConcat* curr) {
printMedium(o, "string.concat");
}
- void visitStringEq(StringEq* curr) { printMedium(o, "string.eq"); }
+ void visitStringEq(StringEq* curr) {
+ switch (curr->op) {
+ case StringEqEqual:
+ printMedium(o, "string.eq");
+ break;
+ case StringEqCompare:
+ printMedium(o, "string.compare");
+ break;
+ default:
+ WASM_UNREACHABLE("invalid string.eq*");
+ }
+ }
void visitStringAs(StringAs* curr) {
switch (curr->op) {
case StringAsWTF8:
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index afb48106e..9ec097c57 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1162,6 +1162,7 @@ enum ASTNodes {
StringViewIterAdvance = 0xa2,
StringViewIterRewind = 0xa3,
StringViewIterSlice = 0xa4,
+ StringCompare = 0xa8,
StringNewWTF8Array = 0xb0,
StringNewWTF16Array = 0xb1,
StringEncodeWTF8Array = 0xb2,
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 263ee80fd..c25293999 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -1057,8 +1057,9 @@ public:
ret->finalize();
return ret;
}
- StringEq* makeStringEq(Expression* left, Expression* right) {
+ StringEq* makeStringEq(StringEqOp op, Expression* left, Expression* right) {
auto* ret = wasm.allocator.alloc<StringEq>();
+ ret->op = op;
ret->left = left;
ret->right = right;
ret->finalize();
diff --git a/src/wasm-delegations-fields.def b/src/wasm-delegations-fields.def
index 019cdbc0d..d9226b3d7 100644
--- a/src/wasm-delegations-fields.def
+++ b/src/wasm-delegations-fields.def
@@ -757,6 +757,7 @@ switch (DELEGATE_ID) {
}
case Expression::Id::StringEqId: {
DELEGATE_START(StringEq);
+ DELEGATE_FIELD_INT(StringEq, op);
DELEGATE_FIELD_CHILD(StringEq, right);
DELEGATE_FIELD_CHILD(StringEq, left);
DELEGATE_END(StringEq);
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index d5ca2d320..942f4c919 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -309,7 +309,7 @@ private:
Expression* makeStringMeasure(Element& s, StringMeasureOp op);
Expression* makeStringEncode(Element& s, StringEncodeOp op);
Expression* makeStringConcat(Element& s);
- Expression* makeStringEq(Element& s);
+ Expression* makeStringEq(Element& s, StringEqOp op);
Expression* makeStringAs(Element& s, StringAsOp op);
Expression* makeStringWTF8Advance(Element& s);
Expression* makeStringWTF16Get(Element& s);
diff --git a/src/wasm.h b/src/wasm.h
index f7683e6bb..d5b52b315 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -605,6 +605,11 @@ enum StringEncodeOp {
StringEncodeWTF16Array,
};
+enum StringEqOp {
+ StringEqEqual,
+ StringEqCompare,
+};
+
enum StringAsOp {
StringAsWTF8,
StringAsWTF16,
@@ -1748,6 +1753,8 @@ class StringEq : public SpecificExpression<Expression::StringEqId> {
public:
StringEq(MixedArena& allocator) {}
+ StringEqOp op;
+
Expression* left;
Expression* right;
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index abd51fcef..65734e68d 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -7345,12 +7345,17 @@ bool WasmBinaryBuilder::maybeVisitStringConcat(Expression*& out,
}
bool WasmBinaryBuilder::maybeVisitStringEq(Expression*& out, uint32_t code) {
- if (code != BinaryConsts::StringEq) {
+ StringEqOp op;
+ if (code == BinaryConsts::StringEq) {
+ op = StringEqEqual;
+ } else if (code == BinaryConsts::StringCompare) {
+ op = StringEqCompare;
+ } else {
return false;
}
auto* right = popNonVoidExpression();
auto* left = popNonVoidExpression();
- out = Builder(wasm).makeStringEq(left, right);
+ out = Builder(wasm).makeStringEq(op, left, right);
return true;
}
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 0c413af2a..829025a2c 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -3090,9 +3090,9 @@ Expression* SExpressionWasmBuilder::makeStringConcat(Element& s) {
parseExpression(s[2]));
}
-Expression* SExpressionWasmBuilder::makeStringEq(Element& s) {
- return Builder(wasm).makeStringEq(parseExpression(s[1]),
- parseExpression(s[2]));
+Expression* SExpressionWasmBuilder::makeStringEq(Element& s, StringEqOp op) {
+ return Builder(wasm).makeStringEq(
+ op, parseExpression(s[1]), parseExpression(s[2]));
}
Expression* SExpressionWasmBuilder::makeStringAs(Element& s, StringAsOp op) {
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 35ef12993..1f5722b59 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -2370,7 +2370,17 @@ void BinaryInstWriter::visitStringConcat(StringConcat* curr) {
}
void BinaryInstWriter::visitStringEq(StringEq* curr) {
- o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::StringEq);
+ o << int8_t(BinaryConsts::GCPrefix);
+ switch (curr->op) {
+ case StringEqEqual:
+ o << U32LEB(BinaryConsts::StringEq);
+ break;
+ case StringEqCompare:
+ o << U32LEB(BinaryConsts::StringCompare);
+ break;
+ default:
+ WASM_UNREACHABLE("invalid string.eq*");
+ }
}
void BinaryInstWriter::visitStringAs(StringAs* curr) {
diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp
index 66bba8862..dfc2190f3 100644
--- a/src/wasm/wat-parser.cpp
+++ b/src/wasm/wat-parser.cpp
@@ -2383,7 +2383,8 @@ template<typename Ctx>
Result<typename Ctx::InstrT> makeStringEncode(Ctx&, Index, StringEncodeOp op);
template<typename Ctx>
Result<typename Ctx::InstrT> makeStringConcat(Ctx&, Index);
-template<typename Ctx> Result<typename Ctx::InstrT> makeStringEq(Ctx&, Index);
+template<typename Ctx>
+Result<typename Ctx::InstrT> makeStringEq(Ctx&, Index, StringEqOp);
template<typename Ctx>
Result<typename Ctx::InstrT> makeStringAs(Ctx&, Index, StringAsOp op);
template<typename Ctx>
@@ -3589,7 +3590,7 @@ Result<typename Ctx::InstrT> makeStringConcat(Ctx& ctx, Index pos) {
}
template<typename Ctx>
-Result<typename Ctx::InstrT> makeStringEq(Ctx& ctx, Index pos) {
+Result<typename Ctx::InstrT> makeStringEq(Ctx& ctx, Index pos, StringEqOp op) {
return ctx.in.err("unimplemented instruction");
}