summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/StringLowering.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/passes/StringLowering.cpp b/src/passes/StringLowering.cpp
index e4b3ed865..e1bae8520 100644
--- a/src/passes/StringLowering.cpp
+++ b/src/passes/StringLowering.cpp
@@ -239,13 +239,20 @@ struct StringLowering : public StringGathering {
// Imported string functions.
Name fromCharCodeArrayImport;
+ Name intoCharCodeArrayImport;
Name fromCodePointImport;
+ Name equalsImport;
+ Name compareImport;
+ Name lengthImport;
+ Name codePointAtImport;
+ Name substringImport;
// The name of the module to import string functions from.
Name WasmStringsModule = "wasm:js-string";
// Common types used in imports.
Type nullArray16 = Type(Array(Field(Field::i16, Mutable)), Nullable);
+ Type nullExt = Type(HeapType::ext, Nullable);
Type nnExt = Type(HeapType::ext, NonNullable);
// Creates an imported string function, returning its name (which is equal to
@@ -269,6 +276,23 @@ struct StringLowering : public StringGathering {
module, "fromCharCodeArray", {nullArray16, Type::i32, Type::i32}, nnExt);
// string.fromCodePoint: codepoint -> ext
fromCodePointImport = addImport(module, "fromCodePoint", Type::i32, nnExt);
+ // string.intoCharCodeArray: string, array, start -> num written
+ intoCharCodeArrayImport = addImport(module,
+ "intoCharCodeArray",
+ {nullExt, nullArray16, Type::i32},
+ Type::i32);
+ // string.equals: string, string -> i32
+ equalsImport = addImport(module, "equals", {nullExt, nullExt}, Type::i32);
+ // string.compare: string, string -> i32
+ compareImport = addImport(module, "compare", {nullExt, nullExt}, Type::i32);
+ // string.length: string -> i32
+ lengthImport = addImport(module, "length", nullExt, Type::i32);
+ // string.codePointAt: string, offset -> i32
+ codePointAtImport =
+ addImport(module, "codePointAt", {nullExt, Type::i32}, Type::i32);
+ // string.substring: string, start, end -> string
+ substringImport =
+ addImport(module, "substring", {nullExt, Type::i32, Type::i32}, nnExt);
// Replace the string instructions in parallel.
struct Replacer : public WalkerPass<PostWalker<Replacer>> {
@@ -304,6 +328,66 @@ struct StringLowering : public StringGathering {
// strings: they are all just JS strings, so no conversion is needed.
replaceCurrent(curr->ref);
}
+
+ void visitStringEncode(StringEncode* curr) {
+ Builder builder(*getModule());
+ switch (curr->op) {
+ case StringEncodeWTF16Array:
+ replaceCurrent(builder.makeCall(lowering.intoCharCodeArrayImport,
+ {curr->ref, curr->ptr, curr->start},
+ Type::i32));
+ return;
+ default:
+ WASM_UNREACHABLE("TODO: all of string.encode*");
+ }
+ }
+
+ void visitStringEq(StringEq* curr) {
+ Builder builder(*getModule());
+ switch (curr->op) {
+ case StringEqEqual:
+ replaceCurrent(builder.makeCall(
+ lowering.equalsImport, {curr->left, curr->right}, Type::i32));
+ return;
+ case StringEqCompare:
+ replaceCurrent(builder.makeCall(
+ lowering.compareImport, {curr->left, curr->right}, Type::i32));
+ return;
+ default:
+ WASM_UNREACHABLE("invalid string.eq*");
+ }
+ }
+
+ void visitStringMeasure(StringMeasure* curr) {
+ Builder builder(*getModule());
+ switch (curr->op) {
+ case StringMeasureWTF16View:
+ replaceCurrent(
+ builder.makeCall(lowering.lengthImport, {curr->ref}, Type::i32));
+ return;
+ default:
+ WASM_UNREACHABLE("invalid string.measure*");
+ }
+ }
+
+ void visitStringWTF16Get(StringWTF16Get* curr) {
+ Builder builder(*getModule());
+ replaceCurrent(builder.makeCall(
+ lowering.codePointAtImport, {curr->ref, curr->pos}, Type::i32));
+ }
+
+ void visitStringSliceWTF(StringSliceWTF* curr) {
+ Builder builder(*getModule());
+ switch (curr->op) {
+ case StringSliceWTF16:
+ replaceCurrent(builder.makeCall(lowering.substringImport,
+ {curr->ref, curr->start, curr->end},
+ lowering.nnExt));
+ return;
+ default:
+ WASM_UNREACHABLE("TODO: all string.slice*");
+ }
+ }
};
Replacer replacer(*this);