diff options
author | Alon Zakai <azakai@google.com> | 2023-01-25 15:29:21 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-25 23:29:21 +0000 |
commit | b5476c6378e10350bf17080fae9bfd8ceeb83cd2 (patch) | |
tree | 85dc2d568a7d3dbed85f798a1039065bc6843bb2 /src | |
parent | 17d120a3337fe56567d4e45583db8ea62ee8bf6f (diff) | |
download | binaryen-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.cpp | 2 | ||||
-rw-r--r-- | src/gen-s-parser.inc | 56 | ||||
-rw-r--r-- | src/passes/Print.cpp | 13 | ||||
-rw-r--r-- | src/wasm-binary.h | 1 | ||||
-rw-r--r-- | src/wasm-builder.h | 3 | ||||
-rw-r--r-- | src/wasm-delegations-fields.def | 1 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 2 | ||||
-rw-r--r-- | src/wasm.h | 7 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 9 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 6 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 12 | ||||
-rw-r--r-- | src/wasm/wat-parser.cpp | 5 |
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"); } |