Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
work
  • Loading branch information
kripken committed Feb 7, 2024
commit 959377ce4336f5cfbc29ae3926231306cd78392e
18 changes: 18 additions & 0 deletions src/passes/StringLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,13 +239,15 @@ struct StringLowering : public StringGathering {

// Imported string functions.
Name fromCharCodeArrayImport;
Name intoCharCodeArrayImport;
Name fromCodePointImport;

// 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
Expand All @@ -269,6 +271,9 @@ 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);

// Replace the string instructions in parallel.
struct Replacer : public WalkerPass<PostWalker<Replacer>> {
Expand Down Expand Up @@ -304,6 +309,19 @@ 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*");
}
}
};

Replacer replacer(*this);
Expand Down
8 changes: 8 additions & 0 deletions test/lit/passes/string-gathering.wast
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

;; LOWER: (type $3 (func (param i32) (result (ref extern))))

;; LOWER: (type $4 (func (param externref (ref null $1) i32) (result i32)))

;; LOWER: (import "string.const" "0" (global $string.const_bar (ref extern)))

;; LOWER: (import "string.const" "1" (global $string.const_other (ref extern)))
Expand All @@ -43,6 +45,8 @@

;; LOWER: (import "wasm:js-string" "fromCodePoint" (func $fromCodePoint (type $3) (param i32) (result (ref extern))))

;; LOWER: (import "wasm:js-string" "intoCharCodeArray" (func $intoCharCodeArray (type $4) (param externref (ref null $1) i32) (result i32)))

;; LOWER: (global $global2 externref (global.get $string.const_bar))
(global $global2 (ref null string) (string.const "bar"))

Expand Down Expand Up @@ -127,6 +131,8 @@

;; LOWER: (type $2 (func (param i32) (result (ref extern))))

;; LOWER: (type $3 (func (param externref (ref null $0) i32) (result i32)))

;; LOWER: (import "a" "b" (global $import (ref extern)))
(import "a" "b" (global $import (ref string)))

Expand All @@ -142,6 +148,8 @@

;; LOWER: (import "wasm:js-string" "fromCodePoint" (func $fromCodePoint (type $2) (param i32) (result (ref extern))))

;; LOWER: (import "wasm:js-string" "intoCharCodeArray" (func $intoCharCodeArray (type $3) (param externref (ref null $0) i32) (result i32)))

;; LOWER: (global $global2 (ref extern) (global.get $global1))
(global $global2 (ref string) (string.const "foo"))

Expand Down
61 changes: 40 additions & 21 deletions test/lit/passes/string-lowering-instructions.wast
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,36 @@
;; RUN: foreach %s %t wasm-opt --string-lowering -all -S -o - | filecheck %s

(module
;; CHECK: (type $0 (func))

;; CHECK: (type $array16 (array (mut i16)))
(type $array16 (array (mut i16)))

;; CHECK: (type $1 (func))

;; CHECK: (rec
;; CHECK-NEXT: (type $2 (func (param (ref $array16))))
;; CHECK-NEXT: (type $2 (func (param externref (ref $array16)) (result i32)))

;; CHECK: (type $3 (func (result externref)))

;; CHECK: (type $4 (func (param (ref $array16))))

;; CHECK: (type $3 (func (param externref externref externref externref)))
;; CHECK: (type $5 (func (param externref externref externref externref)))

;; CHECK: (type $4 (func (param (ref null $array16) i32 i32) (result (ref extern))))
;; CHECK: (type $6 (func (param (ref null $array16) i32 i32) (result (ref extern))))

;; CHECK: (type $5 (func (param i32) (result (ref extern))))
;; CHECK: (type $7 (func (param i32) (result (ref extern))))

;; CHECK: (import "colliding" "name" (func $fromCodePoint (type $0)))
;; CHECK: (type $8 (func (param externref (ref null $array16) i32) (result i32)))

;; CHECK: (import "colliding" "name" (func $fromCodePoint (type $1)))
(import "colliding" "name" (func $fromCodePoint))

;; CHECK: (import "wasm:js-string" "fromCharCodeArray" (func $fromCharCodeArray (type $4) (param (ref null $array16) i32 i32) (result (ref extern))))
;; CHECK: (import "wasm:js-string" "fromCharCodeArray" (func $fromCharCodeArray (type $6) (param (ref null $array16) i32 i32) (result (ref extern))))

;; CHECK: (import "wasm:js-string" "fromCodePoint" (func $fromCodePoint_6 (type $7) (param i32) (result (ref extern))))

;; CHECK: (import "wasm:js-string" "fromCodePoint" (func $fromCodePoint_5 (type $5) (param i32) (result (ref extern))))
;; CHECK: (import "wasm:js-string" "intoCharCodeArray" (func $intoCharCodeArray (type $8) (param externref (ref null $array16) i32) (result i32)))

;; CHECK: (func $string.as (type $3) (param $a externref) (param $b externref) (param $c externref) (param $d externref)
;; CHECK: (func $string.as (type $5) (param $a externref) (param $b externref) (param $c externref) (param $d externref)
;; CHECK-NEXT: (local.set $b
;; CHECK-NEXT: (local.get $a)
;; CHECK-NEXT: )
Expand Down Expand Up @@ -59,7 +67,7 @@
)
)

;; CHECK: (func $string.new.gc (type $2) (param $array16 (ref $array16))
;; CHECK: (func $string.new.gc (type $4) (param $array16 (ref $array16))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $fromCharCodeArray
;; CHECK-NEXT: (local.get $array16)
Expand All @@ -78,18 +86,29 @@
)
)

;; CHECK: (func $string.from_code_point (type $0)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $fromCodePoint_5
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK: (func $string.from_code_point (type $3) (result externref)
;; CHECK-NEXT: (call $fromCodePoint_6
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $string.from_code_point
(drop
(string.from_code_point
(i32.const 1)
)
(func $string.from_code_point (result stringref)
(string.from_code_point
(i32.const 1)
)
)

;; CHECK: (func $string.encode (type $2) (param $ref externref) (param $array16 (ref $array16)) (result i32)
;; CHECK-NEXT: (call $intoCharCodeArray
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: (local.get $array16)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $string.encode (param $ref stringref) (param $array16 (ref $array16)) (result i32)
(string.encode_wtf16_array
(local.get $ref)
(local.get $array16)
(i32.const 10)
)
)
)