diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 19 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 15 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 11 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 3 |
4 files changed, 45 insertions, 3 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 5427deea1..edcf5f7bf 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7261,6 +7261,7 @@ bool WasmBinaryBuilder::maybeVisitStringMeasure(Expression*& out, bool WasmBinaryBuilder::maybeVisitStringEncode(Expression*& out, uint32_t code) { StringEncodeOp op; + Expression* start = nullptr; // TODO: share this code with string.measure? if (code == BinaryConsts::StringEncodeWTF8) { auto policy = getU32LEB(); @@ -7276,12 +7277,28 @@ bool WasmBinaryBuilder::maybeVisitStringEncode(Expression*& out, } } else if (code == BinaryConsts::StringEncodeWTF16) { op = StringEncodeWTF16; + } else if (code == BinaryConsts::StringEncodeWTF8Array) { + auto policy = getU32LEB(); + switch (policy) { + case BinaryConsts::StringPolicy::UTF8: + op = StringEncodeUTF8Array; + break; + case BinaryConsts::StringPolicy::WTF8: + op = StringEncodeWTF8Array; + break; + default: + throwError("bad policy for string.encode"); + } + start = popNonVoidExpression(); + } else if (code == BinaryConsts::StringEncodeWTF16Array) { + op = StringEncodeWTF16Array; + start = popNonVoidExpression(); } else { return false; } auto* ptr = popNonVoidExpression(); auto* ref = popNonVoidExpression(); - out = Builder(wasm).makeStringEncode(op, ref, ptr); + out = Builder(wasm).makeStringEncode(op, ref, ptr, start); return true; } diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 97a25d2c4..38ec788ba 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2985,6 +2985,7 @@ Expression* SExpressionWasmBuilder::makeStringMeasure(Element& s, Expression* SExpressionWasmBuilder::makeStringEncode(Element& s, StringEncodeOp op) { size_t i = 1; + Expression* start = nullptr; if (op == StringEncodeWTF8) { const char* str = s[i++]->c_str(); if (strncmp(str, "utf8", 4) == 0) { @@ -2994,9 +2995,21 @@ Expression* SExpressionWasmBuilder::makeStringEncode(Element& s, } else { throw ParseException("bad string.new op", s.line, s.col); } + } else if (op == StringEncodeWTF8Array) { + const char* str = s[i++]->c_str(); + if (strncmp(str, "utf8", 4) == 0) { + op = StringEncodeUTF8Array; + } else if (strncmp(str, "wtf8", 4) == 0) { + op = StringEncodeWTF8Array; + } else { + throw ParseException("bad string.new op", s.line, s.col); + } + start = parseExpression(s[i + 2]); + } else if (op == StringEncodeWTF16Array) { + start = parseExpression(s[i + 2]); } return Builder(wasm).makeStringEncode( - op, parseExpression(s[i]), parseExpression(s[i + 1])); + op, parseExpression(s[i]), parseExpression(s[i + 1]), start); } Expression* SExpressionWasmBuilder::makeStringConcat(Element& s) { diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index c980d896b..2fc06b176 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2301,6 +2301,17 @@ void BinaryInstWriter::visitStringEncode(StringEncode* curr) { case StringEncodeWTF16: o << U32LEB(BinaryConsts::StringEncodeWTF16); break; + case StringEncodeUTF8Array: + o << U32LEB(BinaryConsts::StringEncodeWTF8Array) + << U32LEB(BinaryConsts::StringPolicy::UTF8); + break; + case StringEncodeWTF8Array: + o << U32LEB(BinaryConsts::StringEncodeWTF8Array) + << U32LEB(BinaryConsts::StringPolicy::WTF8); + break; + case StringEncodeWTF16Array: + o << U32LEB(BinaryConsts::StringEncodeWTF16Array); + break; default: WASM_UNREACHABLE("invalid string.new*"); } diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index bd83d62ed..1a6acf5bd 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1194,7 +1194,8 @@ void StringMeasure::finalize() { } void StringEncode::finalize() { - if (ref->type == Type::unreachable || ptr->type == Type::unreachable) { + if (ref->type == Type::unreachable || ptr->type == Type::unreachable || + (start && start->type == Type::unreachable)) { type = Type::unreachable; } else { type = Type::i32; |