Files
scriptc/tests/corpus/short-char-codes.ts
T
Chris Tate 47904df3c2 Decode short non-ASCII strings directly in charCodeAt
charCodeAt on a non-ASCII string mapped the UTF-16 index to a byte offset
through a string index entry, which the first read claimed and the
string's release purged. For a string of one character, such as each
character of a for-of loop that codePointAt(0) classifies, the entry cost
more than the read.

A non-ASCII receiver of up to 16 bytes is now decoded from its start on
each read, as scr_str_utf16_len already counts short receivers. Longer
receivers keep the index entry and its cursor.
2026-10-27 01:07:00 -05:00

51 lines
1.8 KiB
TypeScript

// charCodeAt and codePointAt on short non-ASCII strings: characters of each
// UTF-8 length, astral pairs, lone surrogates, out-of-range and non-integer
// indexes, strings at the 16-byte boundary, and a long receiver scanned in
// between.
const samples = [
"é", "ß", "日", "語", "😀", "🚀", "a", "",
"café", "naïve", "straße", "日本語", "テキスト", "한국어",
"a😀b", "😀😀", "xéy日z",
"\ud800", "\udc00", "a\ud800b", "\ud83d", "\ude00x",
"0123456789abcdé", "0123456789abcdeé", "0123456789abcdefé", "ééééééé", "éééééééé", "ééééééééé",
];
function codes(s: string): string {
const out: string[] = [];
for (let i = -1; i <= s.length + 1; i++) out.push(String(s.charCodeAt(i)));
out.push(String(s.charCodeAt(0.5)), String(s.charCodeAt(NaN)), String(s.charCodeAt(1.9)));
return out.join(",");
}
function points(s: string): string {
const out: string[] = [];
for (let i = -1; i <= s.length + 1; i++) out.push(String(s.codePointAt(i)));
return out.join(",");
}
for (const s of samples) {
console.log(JSON.stringify(s), s.length, codes(s));
console.log(" points", points(s));
}
// A long receiver scanned while short ones are read.
let long = "";
for (let i = 0; i < 200; i++) long += i % 3 === 0 ? "é" : i % 3 === 1 ? "日" : "x";
let sum = 0;
for (let i = 0; i < long.length; i++) {
sum += long.charCodeAt(i);
sum += samples[i % samples.length]!.charCodeAt(0) || 0;
}
console.log("long", long.length, sum);
// Characters of a for-of loop classified by their code points.
let letters = 0;
let others = 0;
for (const c of "the café, 日本 😀 naïve!") {
const code = c.codePointAt(0)!;
if ((code >= 0x61 && code <= 0x7a) || code >= 0xc0) letters++;
else others++;
}
console.log("letters", letters, "others", others);