diff --git a/scripts/gen-s-parser.py b/scripts/gen-s-parser.py index 451430cc9d8..d0848622f9c 100755 --- a/scripts/gen-s-parser.py +++ b/scripts/gen-s-parser.py @@ -619,6 +619,7 @@ ("string.const", "makeStringConst(s)"), ("string.measure_wtf8", "makeStringMeasure(s, StringMeasureWTF8)"), ("string.measure_wtf16", "makeStringMeasure(s, StringMeasureWTF16)"), + ("string.is_usv_sequence", "makeStringMeasure(s, StringMeasureIsUSV)"), ("string.encode_wtf8", "makeStringEncode(s, StringEncodeWTF8)"), ("string.encode_wtf16", "makeStringEncode(s, StringEncodeWTF16)"), ("string.concat", "makeStringConcat(s)"), diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 9c3fa90e4b3..7001cb10b0a 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -3159,6 +3159,9 @@ switch (op[0]) { default: goto parse_error; } } + case 'i': + if (strcmp(op, "string.is_usv_sequence") == 0) { return makeStringMeasure(s, StringMeasureIsUSV); } + goto parse_error; case 'm': { switch (op[18]) { case '1': diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index cf4e6c9e97b..ec9926a3028 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2253,6 +2253,9 @@ struct PrintExpressionContents case StringMeasureWTF16: printMedium(o, "string.measure_wtf16"); break; + case StringMeasureIsUSV: + printMedium(o, "string.is_usv_sequence"); + break; default: WASM_UNREACHABLE("invalid string.measure*"); } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index f89391186a8..97f6bc24e02 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1146,6 +1146,7 @@ enum ASTNodes { StringEncodeWTF16 = 0x87, StringConcat = 0x88, StringEq = 0x89, + StringIsUSV = 0x8a, }; enum MemoryAccess { diff --git a/src/wasm.h b/src/wasm.h index 41eaf328af0..42de60a9894 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -594,6 +594,7 @@ enum StringMeasureOp { StringMeasureUTF8, StringMeasureWTF8, StringMeasureWTF16, + StringMeasureIsUSV, }; enum StringEncodeOp { diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index ef564db6e14..0ae17f47cbd 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7191,6 +7191,8 @@ bool WasmBinaryBuilder::maybeVisitStringMeasure(Expression*& out, } } else if (code == BinaryConsts::StringMeasureWTF16) { op = StringMeasureWTF16; + } else if (code == BinaryConsts::StringIsUSV) { + op = StringMeasureIsUSV; } else { return false; } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 9a5db2928df..e1b093b26aa 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2276,6 +2276,9 @@ void BinaryInstWriter::visitStringMeasure(StringMeasure* curr) { case StringMeasureWTF16: o << U32LEB(BinaryConsts::StringMeasureWTF16); break; + case StringMeasureIsUSV: + o << U32LEB(BinaryConsts::StringIsUSV); + break; default: WASM_UNREACHABLE("invalid string.new*"); } diff --git a/test/lit/strings.wast b/test/lit/strings.wast index 687de8e3dab..d1a9fd0535d 100644 --- a/test/lit/strings.wast +++ b/test/lit/strings.wast @@ -225,4 +225,23 @@ ) ) ) + + ;; CHECK: (func $string.is_usv_sequence (param $ref stringref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (string.is_usv_sequence + ;; CHECK-NEXT: (local.get $ref) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $string.is_usv_sequence (param $ref stringref) + (drop + (i32.eqz ;; validate the output is i32 + (string.is_usv_sequence + (local.get $ref) + ) + ) + ) + ) )