Use structured data for string contexts.

Rather than relying on magic characters and string scanning to extract information out of a string context, a string's context is now a structured data type.

To avoid fragmentation and extra allocations, the context struct and the memory for the strings it points to are all allocated in one call.