diff --git a/std/assembly/util/string.ts b/std/assembly/util/string.ts index 76e993ec96..e812a38c48 100644 --- a/std/assembly/util/string.ts +++ b/std/assembly/util/string.ts @@ -4,13 +4,13 @@ import { ipow32 } from "../math"; // All tables are stored as two staged lookup tables (static tries) // because the full range of Unicode symbols can't be efficiently // represented as-is in memory (see Unicode spec ch 5, p.196): -// https://www.unicode.org/versions/Unicode12.0.0/ch05.pdf +// https://www.unicode.org/versions/Unicode13.0.0/ch05.pdf // Tables have been generated using these forked musl tools: // https://github.com/MaxGraey/musl-chartable-tools/tree/case-ignorable // Lookup table to check if a character is alphanumeric or not // See: https://git.musl-libc.org/cgit/musl/tree/src/ctype/alpha.h -// size: 3904 bytes +// size: 4032 bytes (compressed to ~3500 after binaryen) // @ts-ignore @inline @lazy const ALPHA_TABLE = memory.data([ 18,17,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,17,34,35,36,17,37,38,39,40, @@ -191,7 +191,7 @@ import { ipow32 } from "../math"; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,3 ]); -// size: 1568 bytes (compressed to ~1380 bytes after binaryen) +// size: 1568 bytes (compressed to ~1300 bytes after binaryen) // @ts-ignore: decorator @lazy @inline const CASED = memory.data([ 18,19,20,21,22,23,16,16,16,16,16,16,16,16,16,16, @@ -274,7 +274,7 @@ import { ipow32 } from "../math"; 0,0,0,0,0,0,0,0 ]); -// size: 2976 bytes (compressed to ~2050 bytes after binaryen) +// size: 2976 bytes (compressed to ~2000 bytes after binaryen) // @ts-ignore: decorator @lazy @inline const CASE_IGNORABLES = memory.data([ 18,16,19,20,21,22,23,24,25,26,27,28,29,30,31,32, @@ -983,25 +983,25 @@ export function joinStringArray(dataStart: usize, length: i32, separator: string // @ts-ignore: type if (value !== null) estLen += value.length; } - var offset = 0; - var sepLen = separator.length; - var result = __alloc((estLen + sepLen * lastIndex) << 1, idof()); + var offset: usize = 0; + var sepLen = separator.length << 1; + var result = __alloc((estLen << 1) + sepLen * lastIndex, idof()); for (let i = 0; i < lastIndex; ++i) { value = load(dataStart + (i << alignof())); if (value !== null) { - let valueLen = value.length; + let valueLen = value.length << 1; memory.copy( - result + (offset << 1), + result + offset, changetype(value), - valueLen << 1 + valueLen ); offset += valueLen; } if (sepLen) { memory.copy( - result + (offset << 1), + result + offset, changetype(separator), - sepLen << 1 + sepLen ); offset += sepLen; } @@ -1009,7 +1009,7 @@ export function joinStringArray(dataStart: usize, length: i32, separator: string value = load(dataStart + (lastIndex << alignof())); if (value !== null) { memory.copy( - result + (offset << 1), + result + offset, changetype(value), value.length << 1 ); @@ -1017,6 +1017,38 @@ export function joinStringArray(dataStart: usize, length: i32, separator: string return changetype(result); // retains } +export function concat3(a: string, b: string, c: string): string { + var bytesLenA = a.length << 1; + var bytesLenB = b.length << 1; + var bytesLenC = c.length << 1; + var result = __alloc(bytesLenA + bytesLenB + bytesLenC, idof()); + var offset: usize = 0; + if (bytesLenA) { + memory.copy( + result, + changetype(a), + bytesLenA + ); + offset += bytesLenA; + } + if (bytesLenB) { + memory.copy( + result + offset, + changetype(b), + bytesLenB + ); + offset += bytesLenB; + } + if (bytesLenC) { + memory.copy( + result + offset, + changetype(c), + bytesLenC + ); + } + return changetype(result); // retains +} + export function joinReferenceArray(dataStart: usize, length: i32, separator: string): string { var lastIndex = length - 1; if (lastIndex < 0) return ""; diff --git a/tests/compiler/std/array.untouched.wat b/tests/compiler/std/array.untouched.wat index 347bea9cff..7c88527e6a 100644 --- a/tests/compiler/std/array.untouched.wat +++ b/tests/compiler/std/array.untouched.wat @@ -16072,15 +16072,17 @@ local.set $10 local.get $2 call $~lib/string/String#get:length + i32.const 1 + i32.shl local.set $11 local.get $5 + i32.const 1 + i32.shl local.get $11 local.get $3 i32.mul i32.add i32.const 1 - i32.shl - i32.const 1 call $~lib/rt/tlsf/__alloc local.set $12 i32.const 0 @@ -16117,16 +16119,14 @@ if local.get $6 call $~lib/string/String#get:length + i32.const 1 + i32.shl local.set $9 local.get $12 local.get $10 - i32.const 1 - i32.shl i32.add local.get $6 local.get $9 - i32.const 1 - i32.shl call $~lib/memory/memory.copy local.get $10 local.get $9 @@ -16137,13 +16137,9 @@ if local.get $12 local.get $10 - i32.const 1 - i32.shl i32.add local.get $2 local.get $11 - i32.const 1 - i32.shl call $~lib/memory/memory.copy local.get $10 local.get $11 @@ -16182,8 +16178,6 @@ if local.get $12 local.get $10 - i32.const 1 - i32.shl i32.add local.get $6 local.get $6