diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 21 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 18 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 15 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 3 |
4 files changed, 53 insertions, 4 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 8108027d4..e2588422c 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7157,6 +7157,7 @@ bool WasmBinaryBuilder::maybeVisitArrayCopy(Expression*& out, uint32_t code) { bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) { StringNewOp op; + Expression* length = nullptr; if (code == BinaryConsts::StringNewWTF8) { auto policy = getU32LEB(); switch (policy) { @@ -7172,12 +7173,30 @@ bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) { default: throwError("bad policy for string.new"); } + length = popNonVoidExpression(); } else if (code == BinaryConsts::StringNewWTF16) { op = StringNewWTF16; + length = popNonVoidExpression(); + } else if (code == BinaryConsts::StringNewWTF8Array) { + auto policy = getU32LEB(); + switch (policy) { + case BinaryConsts::StringPolicy::UTF8: + op = StringNewUTF8Array; + break; + case BinaryConsts::StringPolicy::WTF8: + op = StringNewWTF8Array; + break; + case BinaryConsts::StringPolicy::Replace: + op = StringNewReplaceArray; + break; + default: + throwError("bad policy for string.new"); + } + } else if (code == BinaryConsts::StringNewWTF16Array) { + op = StringNewWTF16Array; } else { return false; } - auto* length = popNonVoidExpression(); auto* ptr = popNonVoidExpression(); out = Builder(wasm).makeStringNew(op, ptr, length); return true; diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index f3bafe3de..bfe09280d 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2937,6 +2937,7 @@ Expression* SExpressionWasmBuilder::makeRefAs(Element& s, RefAsOp op) { Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op) { size_t i = 1; + Expression* length = nullptr; if (op == StringNewWTF8) { const char* str = s[i++]->c_str(); if (strncmp(str, "utf8", 4) == 0) { @@ -2948,9 +2949,22 @@ Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op) { } else { throw ParseException("bad string.new op", s.line, s.col); } + length = parseExpression(s[i + 1]); + } else if (op == StringNewWTF16) { + length = parseExpression(s[i + 1]); + } else if (op == StringNewWTF8Array) { + const char* str = s[i++]->c_str(); + if (strncmp(str, "utf8", 4) == 0) { + op = StringNewUTF8Array; + } else if (strncmp(str, "wtf8", 4) == 0) { + op = StringNewWTF8Array; + } else if (strncmp(str, "replace", 7) == 0) { + op = StringNewReplaceArray; + } else { + throw ParseException("bad string.new op", s.line, s.col); + } } - return Builder(wasm).makeStringNew( - op, parseExpression(s[i]), parseExpression(s[i + 1])); + return Builder(wasm).makeStringNew(op, parseExpression(s[i]), length); } Expression* SExpressionWasmBuilder::makeStringConst(Element& s) { diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 0e39862e7..28472aebd 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2252,6 +2252,21 @@ void BinaryInstWriter::visitStringNew(StringNew* curr) { case StringNewWTF16: o << U32LEB(BinaryConsts::StringNewWTF16); break; + case StringNewUTF8Array: + o << U32LEB(BinaryConsts::StringNewWTF8Array) + << U32LEB(BinaryConsts::StringPolicy::UTF8); + break; + case StringNewWTF8Array: + o << U32LEB(BinaryConsts::StringNewWTF8Array) + << U32LEB(BinaryConsts::StringPolicy::WTF8); + break; + case StringNewReplaceArray: + o << U32LEB(BinaryConsts::StringNewWTF8Array) + << U32LEB(BinaryConsts::StringPolicy::Replace); + break; + case StringNewWTF16Array: + o << U32LEB(BinaryConsts::StringNewWTF16Array); + break; default: WASM_UNREACHABLE("invalid string.new*"); } diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 0a3ca1929..eceb4585b 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1175,7 +1175,8 @@ void RefAs::finalize() { } void StringNew::finalize() { - if (ptr->type == Type::unreachable || length->type == Type::unreachable) { + if (ptr->type == Type::unreachable || + (length && length->type == Type::unreachable)) { type = Type::unreachable; } else { type = Type(HeapType::string, NonNullable); |