diff options
author | Alon Zakai <azakai@google.com> | 2022-07-07 10:32:57 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-07 10:32:57 -0700 |
commit | dc73f07807400eb48b8c4bc173bae37f188fc90b (patch) | |
tree | ed9672cb7847c6d9d33657151dc76fa4cb519ff3 /src/wasm | |
parent | 876638f8fb5bfc8b264eddc6c0c0d54ed40d0095 (diff) | |
download | binaryen-dc73f07807400eb48b8c4bc173bae37f188fc90b.tar.gz binaryen-dc73f07807400eb48b8c4bc173bae37f188fc90b.tar.bz2 binaryen-dc73f07807400eb48b8c4bc173bae37f188fc90b.zip |
[Strings] string.measure (#4775)
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 34 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 16 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 25 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 8 |
4 files changed, 77 insertions, 6 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 16950f88f..d81aa0ca4 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -3924,6 +3924,9 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { if (maybeVisitStringConst(curr, opcode)) { break; } + if (maybeVisitStringMeasure(curr, opcode)) { + break; + } if (opcode == BinaryConsts::RefIsFunc || opcode == BinaryConsts::RefIsData || opcode == BinaryConsts::RefIsI31) { @@ -7127,13 +7130,13 @@ bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) { if (code == BinaryConsts::StringNewWTF8) { auto policy = getU32LEB(); switch (policy) { - case BinaryConsts::StringNewPolicy::UTF8: + case BinaryConsts::StringPolicy::UTF8: op = StringNewUTF8; break; - case BinaryConsts::StringNewPolicy::WTF8: + case BinaryConsts::StringPolicy::WTF8: op = StringNewWTF8; break; - case BinaryConsts::StringNewPolicy::Replace: + case BinaryConsts::StringPolicy::Replace: op = StringNewReplace; break; default: @@ -7162,6 +7165,31 @@ bool WasmBinaryBuilder::maybeVisitStringConst(Expression*& out, uint32_t code) { return true; } +bool WasmBinaryBuilder::maybeVisitStringMeasure(Expression*& out, + uint32_t code) { + StringMeasureOp op; + if (code == BinaryConsts::StringMeasureWTF8) { + auto policy = getU32LEB(); + switch (policy) { + case BinaryConsts::StringPolicy::UTF8: + op = StringMeasureUTF8; + break; + case BinaryConsts::StringPolicy::WTF8: + op = StringMeasureWTF8; + break; + default: + throwError("bad policy for string.measure"); + } + } else if (code == BinaryConsts::StringMeasureWTF16) { + op = StringMeasureWTF16; + } else { + return false; + } + auto* ref = popNonVoidExpression(); + out = Builder(wasm).makeStringMeasure(op, ref); + return true; +} + void WasmBinaryBuilder::visitRefAs(RefAs* curr, uint8_t code) { BYN_TRACE("zz node: RefAs\n"); switch (code) { diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index cd6c167c0..98ed64c2d 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2957,6 +2957,22 @@ Expression* SExpressionWasmBuilder::makeStringConst(Element& s) { return Builder(wasm).makeStringConst(s[1]->str()); } +Expression* SExpressionWasmBuilder::makeStringMeasure(Element& s, + StringMeasureOp op) { + size_t i = 1; + if (op == StringMeasureWTF8) { + const char* str = s[i++]->c_str(); + if (strncmp(str, "utf8", 4) == 0) { + op = StringMeasureUTF8; + } else if (strncmp(str, "wtf8", 4) == 0) { + op = StringMeasureWTF8; + } else { + throw ParseException("bad string.new op", s.line, s.col); + } + } + return Builder(wasm).makeStringMeasure(op, parseExpression(s[i])); +} + // converts an s-expression string representing binary data into an output // sequence of raw bytes this appends to data, which may already contain // content. diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index e131ab207..e3740ecee 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2239,15 +2239,15 @@ void BinaryInstWriter::visitStringNew(StringNew* curr) { switch (curr->op) { case StringNewUTF8: o << U32LEB(BinaryConsts::StringNewWTF8) - << U32LEB(BinaryConsts::StringNewPolicy::UTF8); + << U32LEB(BinaryConsts::StringPolicy::UTF8); break; case StringNewWTF8: o << U32LEB(BinaryConsts::StringNewWTF8) - << U32LEB(BinaryConsts::StringNewPolicy::WTF8); + << U32LEB(BinaryConsts::StringPolicy::WTF8); break; case StringNewReplace: o << U32LEB(BinaryConsts::StringNewWTF8) - << U32LEB(BinaryConsts::StringNewPolicy::Replace); + << U32LEB(BinaryConsts::StringPolicy::Replace); break; case StringNewWTF16: o << U32LEB(BinaryConsts::StringNewWTF16); @@ -2262,6 +2262,25 @@ void BinaryInstWriter::visitStringConst(StringConst* curr) { << U32LEB(parent.getStringIndex(curr->string)); } +void BinaryInstWriter::visitStringMeasure(StringMeasure* curr) { + o << int8_t(BinaryConsts::GCPrefix); + switch (curr->op) { + case StringMeasureUTF8: + o << U32LEB(BinaryConsts::StringMeasureWTF8) + << U32LEB(BinaryConsts::StringPolicy::UTF8); + break; + case StringMeasureWTF8: + o << U32LEB(BinaryConsts::StringMeasureWTF8) + << U32LEB(BinaryConsts::StringPolicy::WTF8); + break; + case StringMeasureWTF16: + o << U32LEB(BinaryConsts::StringMeasureWTF16); + break; + default: + WASM_UNREACHABLE("invalid string.new*"); + } +} + void BinaryInstWriter::emitScopeEnd(Expression* curr) { assert(!breakStack.empty()); breakStack.pop_back(); diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 86eed184f..749a44339 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1184,6 +1184,14 @@ void StringNew::finalize() { void StringConst::finalize() { type = Type(HeapType::string, NonNullable); } +void StringMeasure::finalize() { + if (ref->type == Type::unreachable) { + type = Type::unreachable; + } else { + type = Type::i32; + } +} + size_t Function::getNumParams() { return getParams().size(); } size_t Function::getNumVars() { return vars.size(); } |