pub struct JsContext { /* private fields */ }Expand description
Parasitic JSContext — borrows servo’s JSContext pointer. Does NOT own a mozjs::rust::Runtime; servo owns that lifetime.
铁律: Bao 始终寄生 servo 的 JSContext,不存在独立 JSContext。 所有模式(CLI/browser/CDP)共享 servo 的唯一 JSContext。
Realm model (first-principles, ECMA-262/Node semantics): a Realm belongs
to the agent (= this JsContext) for the latter’s whole lifetime, NOT to a
single script execution. Scripts execute inside the realm; the realm
persists across eval calls. This is what lets setTimeout/server
handlers registered by one script fire after that script returns, and
what makes globalThis.x set by eval A visible to eval B.
Concretely JsContext lazily owns ONE global object (realm_global),
created on the first eval/eval_module_setup and reused by every
subsequent eval (which merely AutoRealms into it). The global is
persistent-rooted via JS_AddExtraRoot for the context’s lifetime —
SpiderMonkey does not auto-root globals.
Implementations§
Source§impl JsContext
impl JsContext
Sourcepub fn init_runtime() -> Result<(JsContext, Option<SmRuntimeGuard>), JsError>
pub fn init_runtime() -> Result<(JsContext, Option<SmRuntimeGuard>), JsError>
Initialize SpiderMonkey Runtime for CLI mode.
Returns (JsContext, Option<SmRuntimeGuard>). The guard owns the
Runtime lifetime. The JSEngine is a process-wide singleton (never dropped).
If servo already initialized the Runtime (browser mode ran first),
returns (JsContext, None) — servo owns the lifetime.
Sourcepub unsafe fn from_servo_runtime() -> Result<JsContext, JsError>
pub unsafe fn from_servo_runtime() -> Result<JsContext, JsError>
Parasitize servo’s Runtime on this thread.
§Safety
servo’s Runtime must be alive on this thread (set via Runtime::new or bao_browser initialization).
Sourcepub fn shutdown_engine()
pub fn shutdown_engine()
Shut down the SpiderMonkey engine entirely (process exit only).
Calls JS_ShutDown to clean up SpiderMonkey’s process-wide C++ state.
After this, no new Runtime/JSContext can be created on any thread.
This should only be called at process exit (e.g., via atexit).
Tests should use shutdown_thread_sm() instead, which only destroys
the per-thread Runtime without shutting down the engine.
Sourcepub fn cx(&self) -> JSContext
pub fn cx(&self) -> JSContext
Create a JSContext value wrapper from the stored pointer. The returned value is a zero-sized newtype — safe to create on demand. Caller holds this value and gets &mut from it for mozjs APIs.
pub fn raw_cx(&self) -> *mut JSContext
pub fn set_global_setup( &mut self, setup: unsafe fn(&mut JSContext, Handle<'_, *mut JSObject>), )
pub fn set_post_eval_hook(&mut self, hook: fn(&mut JSContext) -> bool)
pub fn global_setup( &self, ) -> Option<unsafe fn(&mut JSContext, Handle<'_, *mut JSObject>)>
pub fn post_eval_hook(&self) -> Option<fn(&mut JSContext) -> bool>
pub fn eval(&mut self, source: &str, filename: &str) -> Result<JsValue, JsError>
Sourcepub fn ensure_realm_global(
&mut self,
cx: &mut JSContext,
global_setup: Option<unsafe fn(&mut JSContext, Handle<'_, *mut JSObject>)>,
) -> Result<*mut JSObject, JsError>
pub fn ensure_realm_global( &mut self, cx: &mut JSContext, global_setup: Option<unsafe fn(&mut JSContext, Handle<'_, *mut JSObject>)>, ) -> Result<*mut JSObject, JsError>
Lazily create this context’s single persistent realm global on the
first call, applying global_setup (install_console + the caller’s
globals like Bun/process/require). On every subsequent call the
stored global is returned verbatim — setup is NOT re-applied (the
realm already has those globals). Returns the realm’s global pointer;
also published to THREAD_REALM_GLOBAL for async dispatch.
Rooting: the global is AddRawValueRoot-ed inside PersistentGlobal
for the context’s lifetime — SpiderMonkey does not auto-root globals.
pub so the module path (ModuleLoader::eval_module / worker
bootstrap) can proactively initialize the persistent realm when the
FIRST execution on the context is a module rather than a script —
there is no prior eval to lazily trigger it, and an empty-eval
workaround would be unsafe (it would route through
post_eval_drain_then_exit and misfire process 'exit' dispatch).
Auto Trait Implementations§
impl !Send for JsContext
impl !Sync for JsContext
impl Freeze for JsContext
impl RefUnwindSafe for JsContext
impl Unpin for JsContext
impl UnsafeUnpin for JsContext
impl UnwindSafe for JsContext
Blanket Implementations§
Source§impl<T> AsCtxPtr for Twhere
T: ?Sized,
impl<T> AsCtxPtr for Twhere
T: ?Sized,
Source§fn as_ctx_ptr(&self) -> *mut Selfwhere
Self: Sized,
fn as_ctx_ptr(&self) -> *mut Selfwhere
Self: Sized,
self’s address as *mut Self for deferred-task / scopeguard /
ref_guard ctx slots. The closures/trampolines deref it as shared
(&*p) — every method they reach is &self post-R-2, so no write
provenance is required; the *mut spelling is purely to match the
existing DerefOnDrop / HasAutoFlush / RefCount ABI.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Filterable for T
impl<T> Filterable for T
Source§fn filterable(
self,
filter_name: &'static str,
) -> RequestFilterDataProvider<T, fn(DataRequest<'_>) -> bool>
fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(DataRequest<'_>) -> bool>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more