Last time, I covered runtimes, this time I want to briefly cover execution contexts. While a runtime owns all the machinery needed to execute code (heap, GC, JIT, etc.), it can’t just execute code on its own–it has to execute the code within a particular context. Each context shares its resources with other contexts in the runtime, but it has one crucial thing all to itself–the global object and everything that sits under it. So while code executed in two contexts that belong to the same runtime may use the same heap, they are nonetheless unable to see or affect one another at the language level. Contexts are effectively totally isolated from each other. Because objects created in a context are tied to that context’s unique global object, an object created in one context cannot be passed in to another context. The JsRT APIs check all incoming objects to ensure that they match the context being used and will error if they don’t.
To simplify the JsRT API, most of the APIs assume an ambient execution context. Once you set the current context on a thread using
JsSetCurrentContext, all APIs will assume that context until you call
JsSetCurrentContext again (APIs will return a
JsErrorNoCurrentContext error if there isn’t a context that’s been set current on the thread). Contexts are tied to their parent runtime’s thread–making a context current on a thread means that that runtime becomes current on that thread. If the runtime happens to be active on another thread at the time, then setting the current context will fail.
Within a thread, however, calls into contexts can be nested. So, for example, a runtime
r1 can create two contexts
c2. It can then run a script in
c1 which calls back into the host. The host callback can then set
c2 as the current context and run some more code, provided that it restores c1 as the current context when it’s done. So it’s legal to run code in
c1 is on the stack, you just have to make sure that you clean up when you’re done.
You should also follow me on Twitter here.