diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gen-s-parser.inc | 76 | ||||
-rw-r--r-- | src/passes/Print.cpp | 9 | ||||
-rw-r--r-- | src/wasm-binary.h | 2 | ||||
-rw-r--r-- | src/wasm-builder.h | 7 | ||||
-rw-r--r-- | src/wasm-delegations-fields.def | 1 | ||||
-rw-r--r-- | src/wasm.h | 10 | ||||
-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 |
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; |