Deduplicating string pool.
Interners are created per owner (each Chunk, each Shape, the compiler
itself) rather than as a single global. Keeping them local avoids
synchronisation, matches the isolation contract described in
design.md §1, and lets strip_debug() drop an entire pool at once when
M6 pushes size-sensitive release builds.
The returned ids are small non-negative integers assigned in the order the
strings were first interned. Ids from one Interner are meaningless in
another instance.