The UI for audio plugins generally work in an event driven manner: you get events like mouseMove, keyDown, repaint, etc. from your host. In response to those events, you run your script to figure out what you need to do. You have no control over which thread calls these things, it can be the GUI thread that runs all of them, it can be run on background threads in parallel, etc. Different hosts do it differently. If Janet using thread-local state, this just doesn't work: the state for one instance is completely different from another, and there's even no guarantee they're running the same scripts.
Consider the most famous embedded language, JavaScript in browsers: you can have any number of tabs open at the same time, and if the JavaScript interpreters for each of those used a bunch of thread-local storage, it would place huge restrictions on how the browsers could schedule and parallelize the callbacks for the JavaScript in those tabs.
The only way I can see this working is if you spin up a thread for each instance, and when these events come in, you wake up those threads, send over the event information, block until the interpreter thread finishes. But that's both inefficient and a real architectural hassle.
All I want is an object that's like `janet_interpreter *interpreter = janet_make_interpreter();` and then you pass that to the functions instead of doing all these magic things with global variables and thread local state. That's it.
Is there any particular plugin system you're referring to? I'm interested to learn more, out of curiosity. Janet's code is pretty easy to read, so you've got me learning about the vm now :)