Skip to content

Commit 19a4375

Browse files
authored
[Strings] string.encode (#4776)
1 parent 9831b36 commit 19a4375

20 files changed

+213
-3
lines changed

scripts/gen-s-parser.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,8 @@
619619
("string.const", "makeStringConst(s)"),
620620
("string.measure_wtf8", "makeStringMeasure(s, StringMeasureWTF8)"),
621621
("string.measure_wtf16", "makeStringMeasure(s, StringMeasureWTF16)"),
622+
("string.encode_wtf8", "makeStringEncode(s, StringEncodeWTF8)"),
623+
("string.encode_wtf16", "makeStringEncode(s, StringEncodeWTF16)"),
622624
]
623625

624626

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 'e': {
3136+
switch (op[17]) {
3137+
case '1':
3138+
if (strcmp(op, "string.encode_wtf16") == 0) { return makeStringEncode(s, StringEncodeWTF16); }
3139+
goto parse_error;
3140+
case '8':
3141+
if (strcmp(op, "string.encode_wtf8") == 0) { return makeStringEncode(s, StringEncodeWTF8); }
3142+
goto parse_error;
3143+
default: goto parse_error;
3144+
}
3145+
}
31353146
case 'm': {
31363147
switch (op[18]) {
31373148
case '1':

src/ir/ReFinalize.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ void ReFinalize::visitRefAs(RefAs* curr) { curr->finalize(); }
175175
void ReFinalize::visitStringNew(StringNew* curr) { curr->finalize(); }
176176
void ReFinalize::visitStringConst(StringConst* curr) { curr->finalize(); }
177177
void ReFinalize::visitStringMeasure(StringMeasure* curr) { curr->finalize(); }
178+
void ReFinalize::visitStringEncode(StringEncode* curr) { curr->finalize(); }
178179

179180
void ReFinalize::visitFunction(Function* curr) {
180181
// 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
@@ -678,6 +678,9 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
678678
CostType visitStringMeasure(StringMeasure* curr) {
679679
return 6 + visit(curr->ref);
680680
}
681+
CostType visitStringEncode(StringEncode* curr) {
682+
return 6 + visit(curr->ref) + visit(curr->ptr);
683+
}
681684

682685
private:
683686
CostType nullCheckCost(Expression* ref) {

src/ir/effects.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,14 @@ class EffectAnalyzer {
734734
}
735735
void visitStringNew(StringNew* curr) {}
736736
void visitStringConst(StringConst* curr) {}
737-
void visitStringMeasure(StringMeasure* curr) {}
737+
void visitStringMeasure(StringMeasure* curr) {
738+
// traps when ref is null.
739+
parent.implicitTrap = true;
740+
}
741+
void visitStringEncode(StringEncode* curr) {
742+
// traps when ref is null or we write out of bounds.
743+
parent.implicitTrap = true;
744+
}
738745
};
739746

740747
public:

src/ir/possible-contents.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,10 @@ struct InfoCollector
685685
// TODO: optimize when possible
686686
addRoot(curr);
687687
}
688+
void visitStringEncode(StringEncode* curr) {
689+
// TODO: optimize when possible
690+
addRoot(curr);
691+
}
688692

689693
// TODO: Model which throws can go to which catches. For now, anything thrown
690694
// 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
@@ -2257,6 +2257,21 @@ struct PrintExpressionContents
22572257
WASM_UNREACHABLE("invalid string.measure*");
22582258
}
22592259
}
2260+
void visitStringEncode(StringEncode* curr) {
2261+
switch (curr->op) {
2262+
case StringEncodeUTF8:
2263+
printMedium(o, "string.encode_wtf8 utf8");
2264+
break;
2265+
case StringEncodeWTF8:
2266+
printMedium(o, "string.encode_wtf8 wtf8");
2267+
break;
2268+
case StringEncodeWTF16:
2269+
printMedium(o, "string.encode_wtf16");
2270+
break;
2271+
default:
2272+
WASM_UNREACHABLE("invalid string.encode*");
2273+
}
2274+
}
22602275
};
22612276

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

src/wasm-binary.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,8 @@ enum ASTNodes {
11421142
StringConst = 0x82,
11431143
StringMeasureWTF8 = 0x84,
11441144
StringMeasureWTF16 = 0x85,
1145+
StringEncodeWTF8 = 0x86,
1146+
StringEncodeWTF16 = 0x87,
11451147
};
11461148

11471149
enum MemoryAccess {
@@ -1725,6 +1727,7 @@ class WasmBinaryBuilder {
17251727
bool maybeVisitStringNew(Expression*& out, uint32_t code);
17261728
bool maybeVisitStringConst(Expression*& out, uint32_t code);
17271729
bool maybeVisitStringMeasure(Expression*& out, uint32_t code);
1730+
bool maybeVisitStringEncode(Expression*& out, uint32_t code);
17281731
void visitSelect(Select* curr, uint8_t code);
17291732
void visitReturn(Return* curr);
17301733
void visitMemorySize(MemorySize* curr);

src/wasm-builder.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,15 @@ class Builder {
10111011
ret->finalize();
10121012
return ret;
10131013
}
1014+
StringEncode*
1015+
makeStringEncode(StringEncodeOp op, Expression* ref, Expression* ptr) {
1016+
auto* ret = wasm.allocator.alloc<StringEncode>();
1017+
ret->op = op;
1018+
ret->ref = ref;
1019+
ret->ptr = ptr;
1020+
ret->finalize();
1021+
return ret;
1022+
}
10141023

10151024
// Additional helpers
10161025

src/wasm-delegations-fields.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,14 @@ switch (DELEGATE_ID) {
734734
DELEGATE_END(StringMeasure);
735735
break;
736736
}
737+
case Expression::Id::StringEncodeId: {
738+
DELEGATE_START(StringEncode);
739+
DELEGATE_FIELD_INT(StringEncode, op);
740+
DELEGATE_FIELD_CHILD(StringEncode, ptr);
741+
DELEGATE_FIELD_CHILD(StringEncode, ref);
742+
DELEGATE_END(StringEncode);
743+
break;
744+
}
737745
}
738746

739747
#undef DELEGATE_ID

0 commit comments

Comments
 (0)