summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gen-s-parser.inc76
-rw-r--r--src/passes/Print.cpp9
-rw-r--r--src/wasm-binary.h2
-rw-r--r--src/wasm-builder.h7
-rw-r--r--src/wasm-delegations-fields.def1
-rw-r--r--src/wasm.h10
-rw-r--r--src/wasm/wasm-binary.cpp19
-rw-r--r--src/wasm/wasm-s-parser.cpp15
-rw-r--r--src/wasm/wasm-stack.cpp11
-rw-r--r--src/wasm/wasm.cpp3
10 files changed, 130 insertions, 23 deletions
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index 59eee1070..301164f87 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -3165,12 +3165,28 @@ switch (op[0]) {
switch (op[8]) {
case 'n': {
switch (op[17]) {
- case '1':
- if (strcmp(op, "string.encode_wtf16") == 0) { return makeStringEncode(s, StringEncodeWTF16); }
- goto parse_error;
- case '8':
- if (strcmp(op, "string.encode_wtf8") == 0) { return makeStringEncode(s, StringEncodeWTF8); }
- goto parse_error;
+ case '1': {
+ switch (op[19]) {
+ case '\0':
+ if (strcmp(op, "string.encode_wtf16") == 0) { return makeStringEncode(s, StringEncodeWTF16); }
+ goto parse_error;
+ case '_':
+ if (strcmp(op, "string.encode_wtf16_array") == 0) { return makeStringEncode(s, StringEncodeWTF16Array); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
+ case '8': {
+ switch (op[18]) {
+ case '\0':
+ if (strcmp(op, "string.encode_wtf8") == 0) { return makeStringEncode(s, StringEncodeWTF8); }
+ goto parse_error;
+ case '_':
+ if (strcmp(op, "string.encode_wtf8_array") == 0) { return makeStringEncode(s, StringEncodeWTF8Array); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
default: goto parse_error;
}
}
@@ -8879,20 +8895,44 @@ switch (op[0]) {
switch (op[8]) {
case 'n': {
switch (op[17]) {
- case '1':
- if (op == "string.encode_wtf16"sv) {
- auto ret = makeStringEncode(ctx, in, StringEncodeWTF16);
- CHECK_ERR(ret);
- return *ret;
+ case '1': {
+ switch (op[19]) {
+ case '\0':
+ if (op == "string.encode_wtf16"sv) {
+ auto ret = makeStringEncode(ctx, in, StringEncodeWTF16);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ case '_':
+ if (op == "string.encode_wtf16_array"sv) {
+ auto ret = makeStringEncode(ctx, in, StringEncodeWTF16Array);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ default: goto parse_error;
}
- goto parse_error;
- case '8':
- if (op == "string.encode_wtf8"sv) {
- auto ret = makeStringEncode(ctx, in, StringEncodeWTF8);
- CHECK_ERR(ret);
- return *ret;
+ }
+ case '8': {
+ switch (op[18]) {
+ case '\0':
+ if (op == "string.encode_wtf8"sv) {
+ auto ret = makeStringEncode(ctx, in, StringEncodeWTF8);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ case '_':
+ if (op == "string.encode_wtf8_array"sv) {
+ auto ret = makeStringEncode(ctx, in, StringEncodeWTF8Array);
+ CHECK_ERR(ret);
+ return *ret;
+ }
+ goto parse_error;
+ default: goto parse_error;
}
- goto parse_error;
+ }
default: goto parse_error;
}
}
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 440ff114f..a6a0f7919 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -2330,6 +2330,15 @@ struct PrintExpressionContents
case StringEncodeWTF16:
printMedium(o, "string.encode_wtf16");
break;
+ case StringEncodeUTF8Array:
+ printMedium(o, "string.encode_wtf8_array utf8");
+ break;
+ case StringEncodeWTF8Array:
+ printMedium(o, "string.encode_wtf8_array wtf8");
+ break;
+ case StringEncodeWTF16Array:
+ printMedium(o, "string.encode_wtf16_array");
+ break;
default:
WASM_UNREACHABLE("invalid string.encode*");
}
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 8f44c6ecf..cf0428625 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1161,6 +1161,8 @@ enum ASTNodes {
StringViewIterSlice = 0xa4,
StringNewWTF8Array = 0xb0,
StringNewWTF16Array = 0xb1,
+ StringEncodeWTF8Array = 0xb2,
+ StringEncodeWTF16Array = 0xb3,
};
enum MemoryAccess {
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index d76d24b21..61227a811 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -1012,12 +1012,15 @@ public:
ret->finalize();
return ret;
}
- StringEncode*
- makeStringEncode(StringEncodeOp op, Expression* ref, Expression* ptr) {
+ StringEncode* makeStringEncode(StringEncodeOp op,
+ Expression* ref,
+ Expression* ptr,
+ Expression* start = nullptr) {
auto* ret = wasm.allocator.alloc<StringEncode>();
ret->op = op;
ret->ref = ref;
ret->ptr = ptr;
+ ret->start = start;
ret->finalize();
return ret;
}
diff --git a/src/wasm-delegations-fields.def b/src/wasm-delegations-fields.def
index a8dfcc750..55a9edd16 100644
--- a/src/wasm-delegations-fields.def
+++ b/src/wasm-delegations-fields.def
@@ -737,6 +737,7 @@ switch (DELEGATE_ID) {
case Expression::Id::StringEncodeId: {
DELEGATE_START(StringEncode);
DELEGATE_FIELD_INT(StringEncode, op);
+ DELEGATE_FIELD_OPTIONAL_CHILD(StringEncode, start);
DELEGATE_FIELD_CHILD(StringEncode, ptr);
DELEGATE_FIELD_CHILD(StringEncode, ref);
DELEGATE_END(StringEncode);
diff --git a/src/wasm.h b/src/wasm.h
index 99a2d9f94..8c0e48da2 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -608,6 +608,9 @@ enum StringEncodeOp {
StringEncodeUTF8,
StringEncodeWTF8,
StringEncodeWTF16,
+ StringEncodeUTF8Array,
+ StringEncodeWTF8Array,
+ StringEncodeWTF16Array,
};
enum StringAsOp {
@@ -1746,8 +1749,15 @@ public:
StringEncodeOp op;
Expression* ref;
+
+ // In linear memory variations this is the pointer in linear memory. In the
+ // GC variations this is an Array.
Expression* ptr;
+ // Used only in GC variations, where it is the index in |ptr| to start
+ // encoding from.
+ Expression* start = nullptr;
+
void finalize();
};
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;