mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
JavaScript string reads use UTF-16 indices over scriptc's UTF-8 storage, so charCodeAt, length, slice, substring and indexOf looked every receiver up in a small global index cache (scr_sidx) on each call, and a fresh short receiver evicted an entry and rescanned its bytes. In the tsc-ts self-check that lookup and its mapping were the largest string cost. Bit 31 of the capacity word now records that a string is proven all ASCII, where units are bytes. A clear bit means "not known", so the fact only needs to be exact where it is set: scr_str_new and its users prove it while copying, concatenations combine their operands' bits, number text, ASCII slices and repeat inherit it, emitted literals and runtime statics carry it in their capacity word, and an index-cache scan that proves ASCII records it. scr_str_hash_forget clears it with the cached key hash, so every in-place mutation drops it; an in-place append that keeps the string ASCII sets it again. Capacity stops at 2^31 - 1 bytes, still above the UTF-8 size of any string V8 can represent. Proven-ASCII receivers skip the index cache in every UTF-16 mapper. Sites for length and charCodeAt call small internal helpers (string-reads.ts) that LLVM inlines: a header load and, for an in-range index, one byte load; everything else defers to the runtime with unchanged semantics. For non-ASCII receivers the cache remembers its last hit (validated by owner and tier), charCodeAt answers sequential scans from the cached ASCII span before any other work, and appends that keep a string ASCII no longer walk the cache.