summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-binary.cpp21
-rw-r--r--src/wasm/wasm-s-parser.cpp18
-rw-r--r--src/wasm/wasm-stack.cpp15
-rw-r--r--src/wasm/wasm.cpp3
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);