Realms and Multiple Contexts
QuickJS supports multiple JavaScript contexts (realms) within a single runtime. This powerful feature allows you to create isolated JavaScript environments that can optionally share objects, similar to how iframes work in web browsers.Understanding Contexts and Realms
What is a Context?
AJSContext represents a JavaScript realm - a complete JavaScript environment with:
- Its own global object
- Its own set of built-in objects (Object, Array, etc.)
- Its own prototype chains
- Its own exception state
What is a Runtime?
AJSRuntime represents an isolated JavaScript engine instance with:
- A single garbage collector
- A shared memory heap
- Multiple contexts that can share objects
- No thread-safety (single-threaded execution)
Creating Multiple Contexts
Independent Contexts
You can create multiple independent contexts within the same runtime:Shared Contexts
UseJS_DupContext() to create contexts that share the same realm:
Sharing Objects Between Contexts
Transferring Objects
Objects can be shared between contexts in the same runtime:Important Rules
- Same Runtime Required: Objects can only be shared between contexts in the same runtime
- Reference Counting: Shared objects use reference counting - free them in each context that uses them
- Prototype Chains: Each context has its own prototypes, even for shared objects
- Global Objects: Each context has its own global object unless created with
JS_DupContext()
Use Cases
Sandboxing
Create isolated environments for untrusted code:Plugin Systems
Isolate plugins in separate contexts:Web Worker Simulation
Simulate Web Worker behavior:Testing Frameworks
Isolate test cases:Performance Considerations
Memory Usage
- Each context has its own global object and built-in objects
- Multiple contexts increase memory usage
- Use
JS_DupContext()when you need shared state to reduce overhead - Consider using
JS_NewContextRaw()with minimal intrinsics for worker contexts
Garbage Collection
- All contexts in a runtime share the same garbage collector
- GC runs affect all contexts in the runtime
- Objects shared between contexts are only freed when all references are gone
Context Switching
- Switching between contexts is lightweight
- No context switch overhead within the same runtime
- Multiple runtimes require separate processes/threads
Best Practices
- One Runtime Per Thread: Never share a runtime across threads
- Free in Reverse Order: Free contexts before the runtime
- Clean Exception State: Handle exceptions before switching contexts
- Document Context Ownership: Clearly document which context owns which objects
- Use Const Correctness: Use
JSValueConstfor parameters that don’t transfer ownership - Limit Context Count: Each context adds overhead; don’t create too many
- Consider Context Pools: Reuse contexts instead of creating/destroying frequently
Limitations
- No Thread Safety: Contexts cannot be safely accessed from multiple threads
- No Cross-Runtime Sharing: Objects cannot be shared between different runtimes
- Single GC: All contexts in a runtime are paused during garbage collection
- Prototype Isolation: Modifying built-in prototypes in one context doesn’t affect others
Related Functions
JS_NewContext()- Create a new independent contextJS_DupContext()- Create a context that shares the same realmJS_FreeContext()- Free a contextJS_GetRuntime()- Get the runtime associated with a contextJS_GetGlobalObject()- Get a context’s global objectJS_DupValue()- Duplicate a value for sharing between contexts