The initial use case is to store the current output stream. Previously, we passed it as an explicit argument to the top-level entry function, but that meant we couldn't throw errors from non-inlined functions. Fixing that using explicit arguments would mean adding the output stream as an argument to every function. Why can't we just treat the output stream as a link-time constant? Well, although it's a constant for a particular top-level block's execution, different top-level blocks need to use different output streams, even though they may enter exactly the same chunk of executable code when they call a non-inlined function.
Instead, we treat the output stream as a dynamically scoped variable. We implement it using thread-local storage (TLS) via the pthreads API.
The initial use case is to store the current output stream. Previously, we passed it as an explicit argument to the top-level entry function, but that meant we couldn't throw errors from non-inlined functions. Fixing that using explicit arguments would mean adding the output stream as an argument to every function. Why can't we just treat the output stream as a link-time constant? Well, although it's a constant for a particular top-level block's execution, different top-level blocks need to use different output streams, even though they may enter exactly the same chunk of executable code when they call a non-inlined function.
Instead, we treat the output stream as a dynamically scoped variable. We implement it using thread-local storage (TLS) via the pthreads API.