From 88d0d31b079ed5c092168b2afbb269b5c0110f06 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 11:30:35 -0800 Subject: [PATCH 01/13] yolo --- scripts/gen-s-parser.py | 2 + src/binaryen-c.cpp | 3 +- src/gen-s-parser.inc | 112 ++++++++++++++++++++++---------- src/wasm-binary.h | 3 + src/wasm-builder.h | 7 +- src/wasm-delegations-fields.def | 1 + src/wasm-s-parser.h | 2 +- src/wasm.h | 8 ++- src/wasm/wasm-binary.cpp | 11 ++-- src/wasm/wasm-s-parser.cpp | 10 +-- src/wasm/wasm-stack.cpp | 14 +++- src/wasm/wat-parser.cpp | 4 +- 12 files changed, 122 insertions(+), 55 deletions(-) diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index f6c8e6e280e..87b355c05e8 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -611,6 +611,8 @@ ("string.new_wtf16", "makeStringNew(s, StringNewWTF16)"), ("string.new_wtf8_array", "makeStringNew(s, StringNewWTF8Array)"), ("string.new_wtf16_array", "makeStringNew(s, StringNewWTF16Array)"), + ("string.new_utf8_try", "makeStringNew(s, StringNewWTF8, true)"), + ("string.new_utf8_array_try", "makeStringNew(s, StringNewWTF8Array, true)"), ("string.const", "makeStringConst(s)"), ("string.measure_wtf8", "makeStringMeasure(s, StringMeasureWTF8)"), ("string.measure_wtf16", "makeStringMeasure(s, StringMeasureWTF16)"), diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index cd53f9ced98..cafeb52f49d 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -1843,7 +1843,8 @@ BinaryenExpressionRef BinaryenStringNew(BinaryenModuleRef module, : builder.makeStringNew(StringNewOp(op), (Expression*)ptr, (Expression*)start, - (Expression*)end)); + (Expression*)end), + false /* try */); } BinaryenExpressionRef BinaryenStringConst(BinaryenModuleRef module, const char* name) { diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 6f2c24a47c4..66dd9eb2f53 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -3206,26 +3206,42 @@ switch (buf[0]) { } } case 'n': { - switch (buf[14]) { - case '1': { + switch (buf[11]) { + case 'u': { switch (buf[16]) { - case '\0': - if (op == "string.new_wtf16"sv) { return makeStringNew(s, StringNewWTF16); } + case 'a': + if (op == "string.new_utf8_array_try"sv) { return makeStringNew(s, StringNewWTF8Array, true); } goto parse_error; - case '_': - if (op == "string.new_wtf16_array"sv) { return makeStringNew(s, StringNewWTF16Array); } + case 't': + if (op == "string.new_utf8_try"sv) { return makeStringNew(s, StringNewWTF8, true); } goto parse_error; default: goto parse_error; } } - case '8': { - switch (buf[15]) { - case '\0': - if (op == "string.new_wtf8"sv) { return makeStringNew(s, StringNewWTF8); } - goto parse_error; - case '_': - if (op == "string.new_wtf8_array"sv) { return makeStringNew(s, StringNewWTF8Array); } - goto parse_error; + case 'w': { + switch (buf[14]) { + case '1': { + switch (buf[16]) { + case '\0': + if (op == "string.new_wtf16"sv) { return makeStringNew(s, StringNewWTF16); } + goto parse_error; + case '_': + if (op == "string.new_wtf16_array"sv) { return makeStringNew(s, StringNewWTF16Array); } + goto parse_error; + default: goto parse_error; + } + } + case '8': { + switch (buf[15]) { + case '\0': + if (op == "string.new_wtf8"sv) { return makeStringNew(s, StringNewWTF8); } + goto parse_error; + case '_': + if (op == "string.new_wtf8_array"sv) { return makeStringNew(s, StringNewWTF8Array); } + goto parse_error; + default: goto parse_error; + } + } default: goto parse_error; } } @@ -8932,19 +8948,19 @@ switch (buf[0]) { } } case 'n': { - switch (buf[14]) { - case '1': { + switch (buf[11]) { + case 'u': { switch (buf[16]) { - case '\0': - if (op == "string.new_wtf16"sv) { - auto ret = makeStringNew(ctx, pos, StringNewWTF16); + case 'a': + if (op == "string.new_utf8_array_try"sv) { + auto ret = makeStringNew(ctx, pos, StringNewWTF8Array, true); CHECK_ERR(ret); return *ret; } goto parse_error; - case '_': - if (op == "string.new_wtf16_array"sv) { - auto ret = makeStringNew(ctx, pos, StringNewWTF16Array); + case 't': + if (op == "string.new_utf8_try"sv) { + auto ret = makeStringNew(ctx, pos, StringNewWTF8, true); CHECK_ERR(ret); return *ret; } @@ -8952,22 +8968,46 @@ switch (buf[0]) { default: goto parse_error; } } - case '8': { - switch (buf[15]) { - case '\0': - if (op == "string.new_wtf8"sv) { - auto ret = makeStringNew(ctx, pos, StringNewWTF8); - CHECK_ERR(ret); - return *ret; + case 'w': { + switch (buf[14]) { + case '1': { + switch (buf[16]) { + case '\0': + if (op == "string.new_wtf16"sv) { + auto ret = makeStringNew(ctx, pos, StringNewWTF16); + CHECK_ERR(ret); + return *ret; + } + goto parse_error; + case '_': + if (op == "string.new_wtf16_array"sv) { + auto ret = makeStringNew(ctx, pos, StringNewWTF16Array); + CHECK_ERR(ret); + return *ret; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; - case '_': - if (op == "string.new_wtf8_array"sv) { - auto ret = makeStringNew(ctx, pos, StringNewWTF8Array); - CHECK_ERR(ret); - return *ret; + } + case '8': { + switch (buf[15]) { + case '\0': + if (op == "string.new_wtf8"sv) { + auto ret = makeStringNew(ctx, pos, StringNewWTF8); + CHECK_ERR(ret); + return *ret; + } + goto parse_error; + case '_': + if (op == "string.new_wtf8_array"sv) { + auto ret = makeStringNew(ctx, pos, StringNewWTF8Array); + CHECK_ERR(ret); + return *ret; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; + } default: goto parse_error; } } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 9ec097c572a..cd1ac40f7d3 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1150,6 +1150,7 @@ enum ASTNodes { StringConcat = 0x88, StringEq = 0x89, StringIsUSV = 0x8a, + StringNewUTF8Try = 0x8f, StringAsWTF8 = 0x90, StringViewWTF8Advance = 0x91, StringViewWTF8Slice = 0x93, @@ -1167,8 +1168,10 @@ enum ASTNodes { StringNewWTF16Array = 0xb1, StringEncodeWTF8Array = 0xb2, StringEncodeWTF16Array = 0xb3, + StringNewUTF8ArrayTry = 0xb8, }; + enum MemoryAccess { Offset = 0x10, // bit 4 Alignment = 0x80, // bit 7 diff --git a/src/wasm-builder.h b/src/wasm-builder.h index c2529399991..bd6d365e12f 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1005,23 +1005,26 @@ class Builder { return ret; } StringNew* - makeStringNew(StringNewOp op, Expression* ptr, Expression* length) { + makeStringNew(StringNewOp op, Expression* ptr, Expression* length, bool try_) { auto* ret = wasm.allocator.alloc(); ret->op = op; ret->ptr = ptr; ret->length = length; + ret->try_ = try_; ret->finalize(); return ret; } StringNew* makeStringNew(StringNewOp op, Expression* ptr, Expression* start, - Expression* end) { + Expression* end, + bool try_) { auto* ret = wasm.allocator.alloc(); ret->op = op; ret->ptr = ptr; ret->start = start; ret->end = end; + ret->try_ = try_; ret->finalize(); return ret; } diff --git a/src/wasm-delegations-fields.def b/src/wasm-delegations-fields.def index d9226b3d779..cd182e31997 100644 --- a/src/wasm-delegations-fields.def +++ b/src/wasm-delegations-fields.def @@ -719,6 +719,7 @@ switch (DELEGATE_ID) { case Expression::Id::StringNewId: { DELEGATE_START(StringNew); DELEGATE_FIELD_INT(StringNew, op); + DELEGATE_FIELD_INT(StringNew, try_); DELEGATE_FIELD_OPTIONAL_CHILD(StringNew, end); DELEGATE_FIELD_OPTIONAL_CHILD(StringNew, start); DELEGATE_FIELD_OPTIONAL_CHILD(StringNew, length); diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 942f4c9199c..d6a9c86d632 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -304,7 +304,7 @@ class SExpressionWasmBuilder { Expression* makeArrayCopy(Element& s); Expression* makeRefAs(Element& s, RefAsOp op); Expression* makeRefAsNonNull(Element& s); - Expression* makeStringNew(Element& s, StringNewOp op); + Expression* makeStringNew(Element& s, StringNewOp op, bool try_); Expression* makeStringConst(Element& s); Expression* makeStringMeasure(Element& s, StringMeasureOp op); Expression* makeStringEncode(Element& s, StringEncodeOp op); diff --git a/src/wasm.h b/src/wasm.h index d5b52b3153d..779efe9914a 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -586,6 +586,8 @@ enum StringNewOp { StringNewWTF8Array, StringNewReplaceArray, StringNewWTF16Array, + // Other + StringNewFromCodePoint, }; enum StringMeasureOp { @@ -1684,7 +1686,7 @@ class StringNew : public SpecificExpression { StringNewOp op; // In linear memory variations this is the pointer in linear memory. In the - // GC variations this is an Array. + // GC variations this is an Array. In from_codepoint this is the code point. Expression* ptr; // Used only in linear memory variations. @@ -1694,6 +1696,10 @@ class StringNew : public SpecificExpression { Expression* start = nullptr; Expression* end = nullptr; + // The "try" variants will return null if an encoding error happens, rather + // than trap. + bool try_ = false; + void finalize(); }; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 65734e68d30..7cb98a8936a 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7184,7 +7184,9 @@ bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) { Expression* length = nullptr; Expression* start = nullptr; Expression* end = nullptr; - if (code == BinaryConsts::StringNewWTF8) { + bool try_; + if (code == BinaryConsts::StringNewWTF8 || code == BinaryConsts::StringNewUTF8Try) { + try_ = code == BinaryConsts::StringNewUTF8Try; if (getInt8() != 0) { throwError("Unexpected nonzero memory index"); } @@ -7209,7 +7211,8 @@ bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) { } op = StringNewWTF16; length = popNonVoidExpression(); - } else if (code == BinaryConsts::StringNewWTF8Array) { + } else if (code == BinaryConsts::StringNewWTF8Array || code == BinaryConsts::StringNewUTF8ArrayTry) { + try_ = code == BinaryConsts::StringNewUTF8ArrayTry; auto policy = getU32LEB(); switch (policy) { case BinaryConsts::StringPolicy::UTF8: @@ -7235,9 +7238,9 @@ bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) { } auto* ptr = popNonVoidExpression(); if (length) { - out = Builder(wasm).makeStringNew(op, ptr, length); + out = Builder(wasm).makeStringNew(op, ptr, length, try_); } else { - out = Builder(wasm).makeStringNew(op, ptr, start, end); + out = Builder(wasm).makeStringNew(op, ptr, start, end, try_); } return true; } diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 829025a2ca8..243a1a3ee64 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2990,7 +2990,7 @@ Expression* SExpressionWasmBuilder::makeRefAs(Element& s, RefAsOp op) { return Builder(wasm).makeRefAs(op, value); } -Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op) { +Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op, bool try_) { size_t i = 1; Expression* length = nullptr; if (op == StringNewWTF8) { @@ -3005,10 +3005,10 @@ Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op) { throw ParseException("bad string.new op", s.line, s.col); } length = parseExpression(s[i + 1]); - return Builder(wasm).makeStringNew(op, parseExpression(s[i]), length); + return Builder(wasm).makeStringNew(op, parseExpression(s[i]), length, try_); } else if (op == StringNewWTF16) { length = parseExpression(s[i + 1]); - return Builder(wasm).makeStringNew(op, parseExpression(s[i]), length); + return Builder(wasm).makeStringNew(op, parseExpression(s[i]), length, try_); } else if (op == StringNewWTF8Array) { std::string_view str = s[i++]->str().str; if (str == "utf8") { @@ -3022,11 +3022,11 @@ Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op) { } auto* start = parseExpression(s[i + 1]); auto* end = parseExpression(s[i + 2]); - return Builder(wasm).makeStringNew(op, parseExpression(s[i]), start, end); + return Builder(wasm).makeStringNew(op, parseExpression(s[i]), start, end, try_); } else if (op == StringNewWTF16Array) { auto* start = parseExpression(s[i + 1]); auto* end = parseExpression(s[i + 2]); - return Builder(wasm).makeStringNew(op, parseExpression(s[i]), start, end); + return Builder(wasm).makeStringNew(op, parseExpression(s[i]), start, end, try_); } else { throw ParseException("bad string.new op", s.line, s.col); } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 1f5722b5923..1d176fa08b8 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2264,7 +2264,11 @@ void BinaryInstWriter::visitStringNew(StringNew* curr) { o << int8_t(BinaryConsts::GCPrefix); switch (curr->op) { case StringNewUTF8: - o << U32LEB(BinaryConsts::StringNewWTF8); + if (!curr->try_) { + o << U32LEB(BinaryConsts::StringNewWTF8); + } else { + o << U32LEB(BinaryConsts::StringNewUTF8Try); + } o << int8_t(0); // Memory index. o << U32LEB(BinaryConsts::StringPolicy::UTF8); break; @@ -2283,8 +2287,12 @@ void BinaryInstWriter::visitStringNew(StringNew* curr) { o << int8_t(0); // Memory index. break; case StringNewUTF8Array: - o << U32LEB(BinaryConsts::StringNewWTF8Array) - << U32LEB(BinaryConsts::StringPolicy::UTF8); + if (!curr->try_) { + o << U32LEB(BinaryConsts::StringNewWTF8Array); + } else { + o << U32LEB(BinaryConsts::StringNewUTF8ArrayTry); + } + o << U32LEB(BinaryConsts::StringPolicy::UTF8); break; case StringNewWTF8Array: o << U32LEB(BinaryConsts::StringNewWTF8Array) diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp index dfc2190f396..844cf406b13 100644 --- a/src/wasm/wat-parser.cpp +++ b/src/wasm/wat-parser.cpp @@ -2374,7 +2374,7 @@ template Result makeArrayCopy(Ctx&, Index); template Result makeRefAs(Ctx&, Index, RefAsOp op); template -Result makeStringNew(Ctx&, Index, StringNewOp op); +Result makeStringNew(Ctx&, Index, StringNewOp op, bool try_); template Result makeStringConst(Ctx&, Index); template @@ -3563,7 +3563,7 @@ Result makeRefAs(Ctx& ctx, Index pos, RefAsOp op) { template Result -makeStringNew(Ctx& ctx, Index pos, StringNewOp op) { +makeStringNew(Ctx& ctx, Index pos, StringNewOp op, bool try_) { return ctx.in.err("unimplemented instruction"); } From c0f80279e2b3033814ed410e0add9d07e3a80832 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 11:31:11 -0800 Subject: [PATCH 02/13] format --- src/binaryen-c.cpp | 2 +- src/wasm-binary.h | 1 - src/wasm-builder.h | 6 ++++-- src/wasm/wasm-binary.cpp | 6 ++++-- src/wasm/wasm-s-parser.cpp | 9 ++++++--- src/wasm/wat-parser.cpp | 3 ++- 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index cafeb52f49d..0251f8b3033 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -1843,7 +1843,7 @@ BinaryenExpressionRef BinaryenStringNew(BinaryenModuleRef module, : builder.makeStringNew(StringNewOp(op), (Expression*)ptr, (Expression*)start, - (Expression*)end), + (Expression*)end, false /* try */); } BinaryenExpressionRef BinaryenStringConst(BinaryenModuleRef module, diff --git a/src/wasm-binary.h b/src/wasm-binary.h index cd1ac40f7d3..9464c423e88 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1171,7 +1171,6 @@ enum ASTNodes { StringNewUTF8ArrayTry = 0xb8, }; - enum MemoryAccess { Offset = 0x10, // bit 4 Alignment = 0x80, // bit 7 diff --git a/src/wasm-builder.h b/src/wasm-builder.h index bd6d365e12f..324ed6fd296 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1004,8 +1004,10 @@ class Builder { ret->finalize(); return ret; } - StringNew* - makeStringNew(StringNewOp op, Expression* ptr, Expression* length, bool try_) { + StringNew* makeStringNew(StringNewOp op, + Expression* ptr, + Expression* length, + bool try_) { auto* ret = wasm.allocator.alloc(); ret->op = op; ret->ptr = ptr; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 7cb98a8936a..0f69fbab4ab 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7185,7 +7185,8 @@ bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) { Expression* start = nullptr; Expression* end = nullptr; bool try_; - if (code == BinaryConsts::StringNewWTF8 || code == BinaryConsts::StringNewUTF8Try) { + if (code == BinaryConsts::StringNewWTF8 || + code == BinaryConsts::StringNewUTF8Try) { try_ = code == BinaryConsts::StringNewUTF8Try; if (getInt8() != 0) { throwError("Unexpected nonzero memory index"); @@ -7211,7 +7212,8 @@ bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) { } op = StringNewWTF16; length = popNonVoidExpression(); - } else if (code == BinaryConsts::StringNewWTF8Array || code == BinaryConsts::StringNewUTF8ArrayTry) { + } else if (code == BinaryConsts::StringNewWTF8Array || + code == BinaryConsts::StringNewUTF8ArrayTry) { try_ = code == BinaryConsts::StringNewUTF8ArrayTry; auto policy = getU32LEB(); switch (policy) { diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 243a1a3ee64..87addd9f1f7 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2990,7 +2990,8 @@ Expression* SExpressionWasmBuilder::makeRefAs(Element& s, RefAsOp op) { return Builder(wasm).makeRefAs(op, value); } -Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op, bool try_) { +Expression* +SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op, bool try_) { size_t i = 1; Expression* length = nullptr; if (op == StringNewWTF8) { @@ -3022,11 +3023,13 @@ Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op, bo } auto* start = parseExpression(s[i + 1]); auto* end = parseExpression(s[i + 2]); - return Builder(wasm).makeStringNew(op, parseExpression(s[i]), start, end, try_); + return Builder(wasm).makeStringNew( + op, parseExpression(s[i]), start, end, try_); } else if (op == StringNewWTF16Array) { auto* start = parseExpression(s[i + 1]); auto* end = parseExpression(s[i + 2]); - return Builder(wasm).makeStringNew(op, parseExpression(s[i]), start, end, try_); + return Builder(wasm).makeStringNew( + op, parseExpression(s[i]), start, end, try_); } else { throw ParseException("bad string.new op", s.line, s.col); } diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp index 844cf406b13..1408ffe0d74 100644 --- a/src/wasm/wat-parser.cpp +++ b/src/wasm/wat-parser.cpp @@ -2374,7 +2374,8 @@ template Result makeArrayCopy(Ctx&, Index); template Result makeRefAs(Ctx&, Index, RefAsOp op); template -Result makeStringNew(Ctx&, Index, StringNewOp op, bool try_); +Result +makeStringNew(Ctx&, Index, StringNewOp op, bool try_); template Result makeStringConst(Ctx&, Index); template From 6df03bc4c576d7a073efec08e042af3db4a7062c Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 12:19:15 -0800 Subject: [PATCH 03/13] work --- scripts/gen-s-parser.py | 8 ++++---- src/binaryen-c.cpp | 6 ++++-- src/gen-s-parser.inc | 16 ++++++++-------- src/wasm/wasm-binary.cpp | 10 +++++++--- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 87b355c05e8..724a39246f3 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -607,10 +607,10 @@ ("ref.as_i31", "makeRefCast(s, Type(HeapType::i31, NonNullable))"), ("extern.internalize", "makeRefAs(s, ExternInternalize)"), ("extern.externalize", "makeRefAs(s, ExternExternalize)"), - ("string.new_wtf8", "makeStringNew(s, StringNewWTF8)"), - ("string.new_wtf16", "makeStringNew(s, StringNewWTF16)"), - ("string.new_wtf8_array", "makeStringNew(s, StringNewWTF8Array)"), - ("string.new_wtf16_array", "makeStringNew(s, StringNewWTF16Array)"), + ("string.new_wtf8", "makeStringNew(s, StringNewWTF8, false)"), + ("string.new_wtf16", "makeStringNew(s, StringNewWTF16, false)"), + ("string.new_wtf8_array", "makeStringNew(s, StringNewWTF8Array, false)"), + ("string.new_wtf16_array", "makeStringNew(s, StringNewWTF16Array, false)"), ("string.new_utf8_try", "makeStringNew(s, StringNewWTF8, true)"), ("string.new_utf8_array_try", "makeStringNew(s, StringNewWTF8Array, true)"), ("string.const", "makeStringConst(s)"), diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 0251f8b3033..7ca4f24e514 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -1837,14 +1837,16 @@ BinaryenExpressionRef BinaryenStringNew(BinaryenModuleRef module, BinaryenExpressionRef start, BinaryenExpressionRef end) { Builder builder(*(Module*)module); + // TODO: add API support for this + bool try_ = false; return static_cast( length ? builder.makeStringNew( - StringNewOp(op), (Expression*)ptr, (Expression*)length) + StringNewOp(op), (Expression*)ptr, (Expression*)length, try_) : builder.makeStringNew(StringNewOp(op), (Expression*)ptr, (Expression*)start, (Expression*)end, - false /* try */); + try_); } BinaryenExpressionRef BinaryenStringConst(BinaryenModuleRef module, const char* name) { diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 66dd9eb2f53..8e277b976d4 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -3223,10 +3223,10 @@ switch (buf[0]) { case '1': { switch (buf[16]) { case '\0': - if (op == "string.new_wtf16"sv) { return makeStringNew(s, StringNewWTF16); } + if (op == "string.new_wtf16"sv) { return makeStringNew(s, StringNewWTF16, false); } goto parse_error; case '_': - if (op == "string.new_wtf16_array"sv) { return makeStringNew(s, StringNewWTF16Array); } + if (op == "string.new_wtf16_array"sv) { return makeStringNew(s, StringNewWTF16Array, false); } goto parse_error; default: goto parse_error; } @@ -3234,10 +3234,10 @@ switch (buf[0]) { case '8': { switch (buf[15]) { case '\0': - if (op == "string.new_wtf8"sv) { return makeStringNew(s, StringNewWTF8); } + if (op == "string.new_wtf8"sv) { return makeStringNew(s, StringNewWTF8, false); } goto parse_error; case '_': - if (op == "string.new_wtf8_array"sv) { return makeStringNew(s, StringNewWTF8Array); } + if (op == "string.new_wtf8_array"sv) { return makeStringNew(s, StringNewWTF8Array, false); } goto parse_error; default: goto parse_error; } @@ -8974,14 +8974,14 @@ switch (buf[0]) { switch (buf[16]) { case '\0': if (op == "string.new_wtf16"sv) { - auto ret = makeStringNew(ctx, pos, StringNewWTF16); + auto ret = makeStringNew(ctx, pos, StringNewWTF16, false); CHECK_ERR(ret); return *ret; } goto parse_error; case '_': if (op == "string.new_wtf16_array"sv) { - auto ret = makeStringNew(ctx, pos, StringNewWTF16Array); + auto ret = makeStringNew(ctx, pos, StringNewWTF16Array, false); CHECK_ERR(ret); return *ret; } @@ -8993,14 +8993,14 @@ switch (buf[0]) { switch (buf[15]) { case '\0': if (op == "string.new_wtf8"sv) { - auto ret = makeStringNew(ctx, pos, StringNewWTF8); + auto ret = makeStringNew(ctx, pos, StringNewWTF8, false); CHECK_ERR(ret); return *ret; } goto parse_error; case '_': if (op == "string.new_wtf8_array"sv) { - auto ret = makeStringNew(ctx, pos, StringNewWTF8Array); + auto ret = makeStringNew(ctx, pos, StringNewWTF8Array, false); CHECK_ERR(ret); return *ret; } diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 0f69fbab4ab..76db1854d68 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7184,10 +7184,12 @@ bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) { Expression* length = nullptr; Expression* start = nullptr; Expression* end = nullptr; - bool try_; + bool try_ = false; if (code == BinaryConsts::StringNewWTF8 || code == BinaryConsts::StringNewUTF8Try) { - try_ = code == BinaryConsts::StringNewUTF8Try; + if (code == BinaryConsts::StringNewUTF8Try) { + try_ = true; + } if (getInt8() != 0) { throwError("Unexpected nonzero memory index"); } @@ -7214,7 +7216,9 @@ bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) { length = popNonVoidExpression(); } else if (code == BinaryConsts::StringNewWTF8Array || code == BinaryConsts::StringNewUTF8ArrayTry) { - try_ = code == BinaryConsts::StringNewUTF8ArrayTry; + if (code == BinaryConsts::StringNewUTF8ArrayTry) { + try_ = true; + } auto policy = getU32LEB(); switch (policy) { case BinaryConsts::StringPolicy::UTF8: From f376a52eb7b8898663b54889cdea273dec2da686 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 12:20:30 -0800 Subject: [PATCH 04/13] fix --- src/binaryen-c.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 7ca4f24e514..9bbcbaf9e77 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -1836,9 +1836,10 @@ BinaryenExpressionRef BinaryenStringNew(BinaryenModuleRef module, BinaryenExpressionRef length, BinaryenExpressionRef start, BinaryenExpressionRef end) { - Builder builder(*(Module*)module); // TODO: add API support for this bool try_ = false; + + Builder builder(*(Module*)module); return static_cast( length ? builder.makeStringNew( StringNewOp(op), (Expression*)ptr, (Expression*)length, try_) @@ -1846,7 +1847,7 @@ BinaryenExpressionRef BinaryenStringNew(BinaryenModuleRef module, (Expression*)ptr, (Expression*)start, (Expression*)end, - try_); + try_)); } BinaryenExpressionRef BinaryenStringConst(BinaryenModuleRef module, const char* name) { From 7551c5a32900abfb6a1eb5a703f1d94215c0c45a Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 12:35:21 -0800 Subject: [PATCH 05/13] work --- src/passes/Print.cpp | 12 +++++++++-- src/wasm/wasm-s-parser.cpp | 40 ++++++++++++++++++++---------------- test/lit/passes/O1_skip.wast | 3 --- test/lit/strings.wast | 33 +++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index d9a4c38e5f0..1ecde20ece3 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2348,7 +2348,11 @@ struct PrintExpressionContents printMedium(o, "string.new_wtf8 utf8"); break; case StringNewWTF8: - printMedium(o, "string.new_wtf8 wtf8"); + if (!curr->try_) { + printMedium(o, "string.new_wtf8 wtf8"); + } else { + printMedium(o, "string.new_utf8_try"); + } break; case StringNewReplace: printMedium(o, "string.new_wtf8 replace"); @@ -2360,7 +2364,11 @@ struct PrintExpressionContents printMedium(o, "string.new_wtf8_array utf8"); break; case StringNewWTF8Array: - printMedium(o, "string.new_wtf8_array wtf8"); + if (!curr->try_) { + printMedium(o, "string.new_wtf8_array wtf8"); + } else { + printMedium(o, "string.new_utf8_array_try"); + } break; case StringNewReplaceArray: printMedium(o, "string.new_wtf8_array replace"); diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 87addd9f1f7..130d83440c0 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2995,15 +2995,17 @@ SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op, bool try_) { size_t i = 1; Expression* length = nullptr; if (op == StringNewWTF8) { - std::string_view str = s[i++]->str().str; - if (str == "utf8") { - op = StringNewUTF8; - } else if (str == "wtf8") { - op = StringNewWTF8; - } else if (str == "replace") { - op = StringNewReplace; - } else { - throw ParseException("bad string.new op", s.line, s.col); + if (!try_) { + std::string_view str = s[i++]->str().str; + if (str == "utf8") { + op = StringNewUTF8; + } else if (str == "wtf8") { + op = StringNewWTF8; + } else if (str == "replace") { + op = StringNewReplace; + } else { + throw ParseException("bad string.new op", s.line, s.col); + } } length = parseExpression(s[i + 1]); return Builder(wasm).makeStringNew(op, parseExpression(s[i]), length, try_); @@ -3011,15 +3013,17 @@ SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op, bool try_) { length = parseExpression(s[i + 1]); return Builder(wasm).makeStringNew(op, parseExpression(s[i]), length, try_); } else if (op == StringNewWTF8Array) { - std::string_view str = s[i++]->str().str; - if (str == "utf8") { - op = StringNewUTF8Array; - } else if (str == "wtf8") { - op = StringNewWTF8Array; - } else if (str == "replace") { - op = StringNewReplaceArray; - } else { - throw ParseException("bad string.new op", s.line, s.col); + if (!try_) { + std::string_view str = s[i++]->str().str; + if (str == "utf8") { + op = StringNewUTF8Array; + } else if (str == "wtf8") { + op = StringNewWTF8Array; + } else if (str == "replace") { + op = StringNewReplaceArray; + } else { + throw ParseException("bad string.new op", s.line, s.col); + } } auto* start = parseExpression(s[i + 1]); auto* end = parseExpression(s[i + 2]); diff --git a/test/lit/passes/O1_skip.wast b/test/lit/passes/O1_skip.wast index ebbf9df4af7..c22242aa6cd 100644 --- a/test/lit/passes/O1_skip.wast +++ b/test/lit/passes/O1_skip.wast @@ -1,6 +1,3 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up. - ;; RUN: foreach %s %t wasm-opt -O2 --coalesce-locals --skip-pass=coalesce-locals -S -o - 2>&1 | filecheck %s ;; We should skip coalese-locals even though it is run in -O2 and also we ask to diff --git a/test/lit/strings.wast b/test/lit/strings.wast index 22e433479fd..ac67d08fe64 100644 --- a/test/lit/strings.wast +++ b/test/lit/strings.wast @@ -35,6 +35,8 @@ ;; CHECK: (type $stringref_ref|$array|_ref|$array16|_=>_none (func (param stringref (ref $array) (ref $array16)))) + ;; CHECK: (type $ref|$array|_=>_none (func (param (ref $array)))) + ;; CHECK: (global $string-const stringref (string.const "string in a global \01\ff\00\t\t\n\n\r\r\"\"\'\'\\\\")) (global $string-const stringref (string.const "string in a global \01\ff\00\t\09\n\0a\r\0d\"\22\'\27\\\5c")) @@ -578,4 +580,35 @@ ) ) ) + + ;; CHECK: (func $string.new_try (type $ref|$array|_=>_none) (param $array (ref $array)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.new_utf8_try + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.new_utf8_array_try + ;; CHECK-NEXT: (local.get $array) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string.new_try (param $array (ref $array)) + (drop + (string.new_utf8_try + (i32.const 1) + (i32.const 2) + ) + ) + (drop + (string.new_utf8_array_try + (local.get $array) + (i32.const 3) + (i32.const 4) + ) + ) + ) ) From b645c8c01d5818a39df0bc225567e0c61106f9d1 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 12:39:13 -0800 Subject: [PATCH 06/13] work --- scripts/gen-s-parser.py | 1 + src/passes/Print.cpp | 3 +++ src/wasm-binary.h | 1 + src/wasm/wasm-binary.cpp | 2 ++ src/wasm/wasm-stack.cpp | 3 +++ 5 files changed, 10 insertions(+) diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 724a39246f3..4f5a4ce4066 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -611,6 +611,7 @@ ("string.new_wtf16", "makeStringNew(s, StringNewWTF16, false)"), ("string.new_wtf8_array", "makeStringNew(s, StringNewWTF8Array, false)"), ("string.new_wtf16_array", "makeStringNew(s, StringNewWTF16Array, false)"), + ("string.from_code_point", "makeStringNew(s, StringNewFromCodePoint, false)"), ("string.new_utf8_try", "makeStringNew(s, StringNewWTF8, true)"), ("string.new_utf8_array_try", "makeStringNew(s, StringNewWTF8Array, true)"), ("string.const", "makeStringConst(s)"), diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 1ecde20ece3..34d3cd13bac 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2376,6 +2376,9 @@ struct PrintExpressionContents case StringNewWTF16Array: printMedium(o, "string.new_wtf16_array"); break; + case StringNewFromCodePoint: + printMedium(o, "string.from_code_point"); + break; default: WASM_UNREACHABLE("invalid string.new*"); } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 9464c423e88..a40a96c0087 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1164,6 +1164,7 @@ enum ASTNodes { StringViewIterRewind = 0xa3, StringViewIterSlice = 0xa4, StringCompare = 0xa8, + StringFromCodePoint = 0xa9, StringNewWTF8Array = 0xb0, StringNewWTF16Array = 0xb1, StringEncodeWTF8Array = 0xb2, diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 76db1854d68..fc507d4e17a 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7239,6 +7239,8 @@ bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) { op = StringNewWTF16Array; end = popNonVoidExpression(); start = popNonVoidExpression(); + } else if (code == BinaryConsts::StringFromCodePoint) { + op = StringNewFromCodePoint; } else { return false; } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 1d176fa08b8..694ed4269f6 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2305,6 +2305,9 @@ void BinaryInstWriter::visitStringNew(StringNew* curr) { case StringNewWTF16Array: o << U32LEB(BinaryConsts::StringNewWTF16Array); break; + case StringNewFromCodePoint: + o << U32LEB(BinaryConsts::StringFromCodePoint); + break; default: WASM_UNREACHABLE("invalid string.new*"); } From 67ec892d159f43f70b628050f769bbafea2a633f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 12:39:56 -0800 Subject: [PATCH 07/13] work --- test/lit/strings.wast | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/lit/strings.wast b/test/lit/strings.wast index ac67d08fe64..cbde7394bd2 100644 --- a/test/lit/strings.wast +++ b/test/lit/strings.wast @@ -581,6 +581,14 @@ ) ) + (func $string.from_code_point + (drop + (string.from_code_point + (i32.const 1) + ) + ) + ) + ;; CHECK: (func $string.new_try (type $ref|$array|_=>_none) (param $array (ref $array)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.new_utf8_try From cb919db38056a51918464f96c8328f823839aed8 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 12:44:11 -0800 Subject: [PATCH 08/13] parse --- src/gen-s-parser.inc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 8e277b976d4..fb3a3654aa9 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -3191,6 +3191,9 @@ switch (buf[0]) { default: goto parse_error; } } + case 'f': + if (op == "string.from_code_point"sv) { return makeStringNew(s, StringNewFromCodePoint, false); } + goto parse_error; case 'i': if (op == "string.is_usv_sequence"sv) { return makeStringMeasure(s, StringMeasureIsUSV); } goto parse_error; @@ -8921,6 +8924,13 @@ switch (buf[0]) { default: goto parse_error; } } + case 'f': + if (op == "string.from_code_point"sv) { + auto ret = makeStringNew(ctx, pos, StringNewFromCodePoint, false); + CHECK_ERR(ret); + return *ret; + } + goto parse_error; case 'i': if (op == "string.is_usv_sequence"sv) { auto ret = makeStringMeasure(ctx, pos, StringMeasureIsUSV); From f051e818fce03f85936425dc18801d62c8c438d9 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 12:46:54 -0800 Subject: [PATCH 09/13] fix --- src/wasm/wasm-s-parser.cpp | 2 ++ test/lit/strings.wast | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 130d83440c0..b74ace61722 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -3034,6 +3034,8 @@ SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op, bool try_) { auto* end = parseExpression(s[i + 2]); return Builder(wasm).makeStringNew( op, parseExpression(s[i]), start, end, try_); + } else if (op == StringNewFromCodePoint) { + return Builder(wasm).makeStringNew(op, parseExpression(s[i]), nullptr, try_); } else { throw ParseException("bad string.new op", s.line, s.col); } diff --git a/test/lit/strings.wast b/test/lit/strings.wast index cbde7394bd2..a871811e55a 100644 --- a/test/lit/strings.wast +++ b/test/lit/strings.wast @@ -22,13 +22,13 @@ ;; CHECK: (type $array (array (mut i8))) (type $array (array_subtype (mut i8) data)) + ;; CHECK: (type $none_=>_none (func)) + ;; CHECK: (type $array16 (array (mut i16))) (type $array16 (array_subtype (mut i16) data)) ;; CHECK: (type $stringref_stringview_wtf8_stringview_wtf16_stringview_iter_stringref_stringview_wtf8_stringview_wtf16_stringview_iter_ref|string|_ref|stringview_wtf8|_ref|stringview_wtf16|_ref|stringview_iter|_=>_none (func (param stringref stringview_wtf8 stringview_wtf16 stringview_iter stringref stringview_wtf8 stringview_wtf16 stringview_iter (ref string) (ref stringview_wtf8) (ref stringview_wtf16) (ref stringview_iter)))) - ;; CHECK: (type $none_=>_none (func)) - ;; CHECK: (type $stringview_wtf16_=>_none (func (param stringview_wtf16))) ;; CHECK: (type $ref|$array|_ref|$array16|_=>_none (func (param (ref $array) (ref $array16)))) @@ -581,6 +581,13 @@ ) ) + ;; CHECK: (func $string.from_code_point (type $none_=>_none) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (string.from_code_point + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) (func $string.from_code_point (drop (string.from_code_point From 4ca93495eb4f31f6078d0c90be3c16411374db15 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 12:47:08 -0800 Subject: [PATCH 10/13] format --- src/wasm/wasm-s-parser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index b74ace61722..dc35b564728 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -3035,7 +3035,8 @@ SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op, bool try_) { return Builder(wasm).makeStringNew( op, parseExpression(s[i]), start, end, try_); } else if (op == StringNewFromCodePoint) { - return Builder(wasm).makeStringNew(op, parseExpression(s[i]), nullptr, try_); + return Builder(wasm).makeStringNew( + op, parseExpression(s[i]), nullptr, try_); } else { throw ParseException("bad string.new op", s.line, s.col); } From 2aefd9b9de8d4231d151783c63cfd5e7dae4d20f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 13:27:13 -0800 Subject: [PATCH 11/13] work --- scripts/gen-s-parser.py | 4 ++-- src/gen-s-parser.inc | 8 ++++---- src/passes/Print.cpp | 16 ++++++++-------- src/wasm/wasm-s-parser.cpp | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 4f5a4ce4066..f8ad5fce200 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -612,8 +612,8 @@ ("string.new_wtf8_array", "makeStringNew(s, StringNewWTF8Array, false)"), ("string.new_wtf16_array", "makeStringNew(s, StringNewWTF16Array, false)"), ("string.from_code_point", "makeStringNew(s, StringNewFromCodePoint, false)"), - ("string.new_utf8_try", "makeStringNew(s, StringNewWTF8, true)"), - ("string.new_utf8_array_try", "makeStringNew(s, StringNewWTF8Array, true)"), + ("string.new_utf8_try", "makeStringNew(s, StringNewUTF8, true)"), + ("string.new_utf8_array_try", "makeStringNew(s, StringNewUTF8Array, true)"), ("string.const", "makeStringConst(s)"), ("string.measure_wtf8", "makeStringMeasure(s, StringMeasureWTF8)"), ("string.measure_wtf16", "makeStringMeasure(s, StringMeasureWTF16)"), diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index fb3a3654aa9..48906628452 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -3213,10 +3213,10 @@ switch (buf[0]) { case 'u': { switch (buf[16]) { case 'a': - if (op == "string.new_utf8_array_try"sv) { return makeStringNew(s, StringNewWTF8Array, true); } + if (op == "string.new_utf8_array_try"sv) { return makeStringNew(s, StringNewUTF8Array, true); } goto parse_error; case 't': - if (op == "string.new_utf8_try"sv) { return makeStringNew(s, StringNewWTF8, true); } + if (op == "string.new_utf8_try"sv) { return makeStringNew(s, StringNewUTF8, true); } goto parse_error; default: goto parse_error; } @@ -8963,14 +8963,14 @@ switch (buf[0]) { switch (buf[16]) { case 'a': if (op == "string.new_utf8_array_try"sv) { - auto ret = makeStringNew(ctx, pos, StringNewWTF8Array, true); + auto ret = makeStringNew(ctx, pos, StringNewUTF8Array, true); CHECK_ERR(ret); return *ret; } goto parse_error; case 't': if (op == "string.new_utf8_try"sv) { - auto ret = makeStringNew(ctx, pos, StringNewWTF8, true); + auto ret = makeStringNew(ctx, pos, StringNewUTF8, true); CHECK_ERR(ret); return *ret; } diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 34d3cd13bac..8c112d6a58f 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2345,15 +2345,15 @@ struct PrintExpressionContents void visitStringNew(StringNew* curr) { switch (curr->op) { case StringNewUTF8: - printMedium(o, "string.new_wtf8 utf8"); - break; - case StringNewWTF8: if (!curr->try_) { - printMedium(o, "string.new_wtf8 wtf8"); + printMedium(o, "string.new_wtf8 utf8"); } else { printMedium(o, "string.new_utf8_try"); } break; + case StringNewWTF8: + printMedium(o, "string.new_wtf8 wtf8"); + break; case StringNewReplace: printMedium(o, "string.new_wtf8 replace"); break; @@ -2361,15 +2361,15 @@ struct PrintExpressionContents printMedium(o, "string.new_wtf16"); break; case StringNewUTF8Array: - printMedium(o, "string.new_wtf8_array utf8"); - break; - case StringNewWTF8Array: if (!curr->try_) { - printMedium(o, "string.new_wtf8_array wtf8"); + printMedium(o, "string.new_wtf8_array utf8"); } else { printMedium(o, "string.new_utf8_array_try"); } break; + case StringNewWTF8Array: + printMedium(o, "string.new_wtf8_array wtf8"); + break; case StringNewReplaceArray: printMedium(o, "string.new_wtf8_array replace"); break; diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index dc35b564728..6bbd824762a 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2994,7 +2994,7 @@ Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op, bool try_) { size_t i = 1; Expression* length = nullptr; - if (op == StringNewWTF8) { + if (op == StringNewWTF8 || op == StringNewUTF8) { if (!try_) { std::string_view str = s[i++]->str().str; if (str == "utf8") { @@ -3012,7 +3012,7 @@ SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op, bool try_) { } else if (op == StringNewWTF16) { length = parseExpression(s[i + 1]); return Builder(wasm).makeStringNew(op, parseExpression(s[i]), length, try_); - } else if (op == StringNewWTF8Array) { + } else if (op == StringNewWTF8Array || op == StringNewUTF8Array) { if (!try_) { std::string_view str = s[i++]->str().str; if (str == "utf8") { From 11b6dee1b21f01f40a4c9c716dd0b11be5b73608 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 13:40:10 -0800 Subject: [PATCH 12/13] fix --- src/wasm/wasm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index fa13515411b..f58aaf0dac3 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1134,7 +1134,7 @@ void StringNew::finalize() { (length && length->type == Type::unreachable)) { type = Type::unreachable; } else { - type = Type(HeapType::string, NonNullable); + type = Type(HeapType::string, try_ ? Nullable : NonNullable); } } From 4d66c56ea079c330760865d7dbf51f97cdd9778f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 26 Jan 2023 15:04:52 -0800 Subject: [PATCH 13/13] feedback --- src/wasm/wasm-binary.cpp | 1 + test/lit/passes/O1_skip.wast | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index fc507d4e17a..cd5763c1239 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7190,6 +7190,7 @@ bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) { if (code == BinaryConsts::StringNewUTF8Try) { try_ = true; } + // FIXME: the memory index should be an LEB like all other places if (getInt8() != 0) { throwError("Unexpected nonzero memory index"); } diff --git a/test/lit/passes/O1_skip.wast b/test/lit/passes/O1_skip.wast index c22242aa6cd..ebbf9df4af7 100644 --- a/test/lit/passes/O1_skip.wast +++ b/test/lit/passes/O1_skip.wast @@ -1,3 +1,6 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up. + ;; RUN: foreach %s %t wasm-opt -O2 --coalesce-locals --skip-pass=coalesce-locals -S -o - 2>&1 | filecheck %s ;; We should skip coalese-locals even though it is run in -O2 and also we ask to