Skip to content

Commit dc73f07

Browse files
authored
[Strings] string.measure (WebAssembly#4775)
1 parent 876638f commit dc73f07

20 files changed

Lines changed: 201 additions & 8 deletions

scripts/gen-s-parser.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,8 @@
617617
("string.new_wtf8", "makeStringNew(s, StringNewWTF8)"),
618618
("string.new_wtf16", "makeStringNew(s, StringNewWTF16)"),
619619
("string.const", "makeStringConst(s)"),
620+
("string.measure_wtf8", "makeStringMeasure(s, StringMeasureWTF8)"),
621+
("string.measure_wtf16", "makeStringMeasure(s, StringMeasureWTF16)"),
620622
]
621623

622624

src/gen-s-parser.inc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3132,6 +3132,17 @@ switch (op[0]) {
31323132
case 'c':
31333133
if (strcmp(op, "string.const") == 0) { return makeStringConst(s); }
31343134
goto parse_error;
3135+
case 'm': {
3136+
switch (op[18]) {
3137+
case '1':
3138+
if (strcmp(op, "string.measure_wtf16") == 0) { return makeStringMeasure(s, StringMeasureWTF16); }
3139+
goto parse_error;
3140+
case '8':
3141+
if (strcmp(op, "string.measure_wtf8") == 0) { return makeStringMeasure(s, StringMeasureWTF8); }
3142+
goto parse_error;
3143+
default: goto parse_error;
3144+
}
3145+
}
31353146
case 'n': {
31363147
switch (op[14]) {
31373148
case '1':

src/ir/ReFinalize.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ void ReFinalize::visitArrayCopy(ArrayCopy* curr) { curr->finalize(); }
174174
void ReFinalize::visitRefAs(RefAs* curr) { curr->finalize(); }
175175
void ReFinalize::visitStringNew(StringNew* curr) { curr->finalize(); }
176176
void ReFinalize::visitStringConst(StringConst* curr) { curr->finalize(); }
177+
void ReFinalize::visitStringMeasure(StringMeasure* curr) { curr->finalize(); }
177178

178179
void ReFinalize::visitFunction(Function* curr) {
179180
// we may have changed the body from unreachable to none, which might be bad

src/ir/cost.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,9 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
675675
return 4 + visit(curr->ptr) + visit(curr->length);
676676
}
677677
CostType visitStringConst(StringConst* curr) { return 4; }
678+
CostType visitStringMeasure(StringMeasure* curr) {
679+
return 6 + visit(curr->ref);
680+
}
678681

679682
private:
680683
CostType nullCheckCost(Expression* ref) {

src/ir/effects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,7 @@ class EffectAnalyzer {
734734
}
735735
void visitStringNew(StringNew* curr) {}
736736
void visitStringConst(StringConst* curr) {}
737+
void visitStringMeasure(StringMeasure* curr) {}
737738
};
738739

739740
public:

src/ir/possible-contents.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,10 @@ struct InfoCollector
681681
void visitStringConst(StringConst* curr) {
682682
addRoot(curr, PossibleContents::exactType(curr->type));
683683
}
684+
void visitStringMeasure(StringMeasure* curr) {
685+
// TODO: optimize when possible
686+
addRoot(curr);
687+
}
684688

685689
// TODO: Model which throws can go to which catches. For now, anything thrown
686690
// is sent to the location of that tag, and any catch of that tag can

src/passes/Print.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,6 +2242,21 @@ struct PrintExpressionContents
22422242
o << curr->string.str;
22432243
o << '"';
22442244
}
2245+
void visitStringMeasure(StringMeasure* curr) {
2246+
switch (curr->op) {
2247+
case StringMeasureUTF8:
2248+
printMedium(o, "string.measure_wtf8 utf8");
2249+
break;
2250+
case StringMeasureWTF8:
2251+
printMedium(o, "string.measure_wtf8 wtf8");
2252+
break;
2253+
case StringMeasureWTF16:
2254+
printMedium(o, "string.measure_wtf16");
2255+
break;
2256+
default:
2257+
WASM_UNREACHABLE("invalid string.measure*");
2258+
}
2259+
}
22452260
};
22462261

22472262
// Prints an expression in s-expr format, including both the

src/wasm-binary.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,8 @@ enum ASTNodes {
11401140
StringNewWTF8 = 0x80,
11411141
StringNewWTF16 = 0x81,
11421142
StringConst = 0x82,
1143+
StringMeasureWTF8 = 0x84,
1144+
StringMeasureWTF16 = 0x85,
11431145
};
11441146

11451147
enum MemoryAccess {
@@ -1150,7 +1152,7 @@ enum MemoryAccess {
11501152

11511153
enum MemoryFlags { HasMaximum = 1 << 0, IsShared = 1 << 1, Is64 = 1 << 2 };
11521154

1153-
enum StringNewPolicy {
1155+
enum StringPolicy {
11541156
UTF8 = 0x00,
11551157
WTF8 = 0x01,
11561158
Replace = 0x02,
@@ -1722,6 +1724,7 @@ class WasmBinaryBuilder {
17221724
bool maybeVisitArrayCopy(Expression*& out, uint32_t code);
17231725
bool maybeVisitStringNew(Expression*& out, uint32_t code);
17241726
bool maybeVisitStringConst(Expression*& out, uint32_t code);
1727+
bool maybeVisitStringMeasure(Expression*& out, uint32_t code);
17251728
void visitSelect(Select* curr, uint8_t code);
17261729
void visitReturn(Return* curr);
17271730
void visitMemorySize(MemorySize* curr);

src/wasm-builder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,13 @@ class Builder {
10041004
ret->finalize();
10051005
return ret;
10061006
}
1007+
StringMeasure* makeStringMeasure(StringMeasureOp op, Expression* ref) {
1008+
auto* ret = wasm.allocator.alloc<StringMeasure>();
1009+
ret->op = op;
1010+
ret->ref = ref;
1011+
ret->finalize();
1012+
return ret;
1013+
}
10071014

10081015
// Additional helpers
10091016

src/wasm-delegations-fields.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,13 @@ switch (DELEGATE_ID) {
727727
DELEGATE_END(StringConst);
728728
break;
729729
}
730+
case Expression::Id::StringMeasureId: {
731+
DELEGATE_START(StringMeasure);
732+
DELEGATE_FIELD_INT(StringMeasure, op);
733+
DELEGATE_FIELD_CHILD(StringMeasure, ref);
734+
DELEGATE_END(StringMeasure);
735+
break;
736+
}
730737
}
731738

732739
#undef DELEGATE_ID

0 commit comments

Comments
 (0)