AutoRealm

Struct AutoRealm 

Source
pub struct AutoRealm<'cx> {
    cx: JSContext,
    realm: JSAutoRealm,
    phantom: PhantomData<&'cx mut ()>,
}
Expand description

Safe wrapper around JSAutoRealm.

On creation it enters the realm of the target object, realm becomes current (it’s on top of the realm stack). Drop exits realm.

While creating AutoRealm will not trigger GC, it still takes &mut JSContext, because it can be used in place of JSContext (by Deref/DerefMut). with additional information of entered/current realm:

use mozjs::context::JSContext;
use mozjs::jsapi::JSObject;
use mozjs::realm::AutoRealm;
use std::ptr::NonNull;

fn f(cx: &mut JSContext, target: NonNull<JSObject>) {
    let realm = AutoRealm::new(cx, target);
    f(cx, target); // one cannot use JSContext here,
                  // because that could allow out of order realm drops.
}

instead do this:

use mozjs::context::JSContext;
use mozjs::jsapi::JSObject;
use mozjs::realm::AutoRealm;
use std::ptr::NonNull;

fn f(cx: &mut JSContext, target: NonNull<JSObject>) {
    let mut realm = AutoRealm::new(cx, target);
    let cx = &mut realm; // this JSContext is bounded to AutoRealm
                             // which in turn is bounded to original JSContext
    f(cx, target);
}

This also enforces LIFO entering/exiting realms, which is not enforced by JSAutoRealm:

use mozjs::context::JSContext;
use mozjs::jsapi::JSObject;
use mozjs::realm::AutoRealm;
use std::ptr::NonNull;

fn f(cx: &mut JSContext, t1: NonNull<JSObject>, t2: NonNull<JSObject>) {
    let mut realm1 = AutoRealm::new(cx, t1);
    let cx = &mut realm1;
    let realm2 = AutoRealm::new(cx, t2);
    drop(realm1); // it's not possible to drop realm1 before realm2
}

Fields§

§cx: JSContext§realm: JSAutoRealm§phantom: PhantomData<&'cx mut ()>

Implementations§

Source§

impl<'cx> AutoRealm<'cx>

Source

pub fn new(cx: &'cx mut JSContext, target: NonNull<JSObject>) -> AutoRealm<'cx>

Enters the realm of the given target object. The realm becomes the current realm (it’s on top of the realm stack). The realm is exited when the AutoRealm is dropped.

While this function will not trigger GC (it will in fact root the object) but because AutoRealm can act as a JSContext we need to take &mut JSContext.

Source

pub fn new_from_handle( cx: &'cx mut JSContext, target: Handle<'_, *mut JSObject>, ) -> AutoRealm<'cx>

Enters the realm of the given target object. The realm becomes the current realm (it’s on top of the realm stack). The realm is exited when the AutoRealm is dropped.

While this function will not trigger GC (it will in fact root the object) but because AutoRealm can act as a JSContext we need to take &mut JSContext.

Source

pub fn current_realm(&mut self) -> CurrentRealm<'_>

If we can get &mut AutoRealm then we are current realm, because if there existed other current realm, we couldn’t get &mut AutoRealm.

use mozjs::context::JSContext;
use mozjs::jsapi::JSObject;
use mozjs::realm::AutoRealm;
use std::ptr::NonNull;

fn f(cx: &mut JSContext, t: NonNull<JSObject>) {
    let mut realm = AutoRealm::new(cx, t);
    let mut current_realm = realm.current_realm();
}
Source

pub fn global(&self) -> Handle<'_, *mut JSObject>

Obtain the handle to the global object of the this realm. Because the handle is bounded with lifetime to realm, you cannot do this:

use mozjs::context::JSContext;
use mozjs::jsapi::JSObject;
use mozjs::realm::AutoRealm;
use std::ptr::NonNull;
use mozjs::rust::Handle;

fn g(realm: &'_ mut AutoRealm, global: Handle<'_, *mut JSObject>) {
}

fn f(realm: &mut AutoRealm) {
    let global = realm.global();
    g(realm, global);
}

instead use AutoRealm::global_and_reborrow.

Source

pub fn global_and_reborrow(&mut self) -> (Handle<'_, *mut JSObject>, &mut Self)

Obtain the handle to the global object of the this realm and reborrow the realm.

use mozjs::context::JSContext;
use mozjs::jsapi::JSObject;
use mozjs::realm::AutoRealm;
use std::ptr::NonNull;
use mozjs::rust::Handle;

fn g(realm: &'_ mut AutoRealm, global: Handle<'_, *mut JSObject>) {
}

fn f(realm: &mut AutoRealm) {
    let (global, realm) = realm.global_and_reborrow();
    g(realm, global);
}
Source

pub unsafe fn erase_lifetime(self) -> AutoRealm<'static>

Erase the lifetime of this AutoRealm.

§Safety
  • The caller must ensure that the AutoRealm does not outlive the JSContext it was created with.
Source

pub fn realm(&self) -> &JSAutoRealm

Methods from Deref<Target = JSContext>§

Source

pub fn no_gc<'cx>(&'cx self) -> &'cx NoGC<'cx>

Returns NoGC token bounded to this JSContext. No function that accepts &mut JSContext (read: triggers GC) can be called while this is alive.

Source

pub unsafe fn raw_cx(&mut self) -> *mut RawJSContext

Obtain RawJSContext mutable pointer.

§Safety

No NoGC tokens should be constructed while returned pointer is available to user. In practices this means that one should use the result as direct argument to SpiderMonkey function and not store it in variable.

use mozjs::context::*;
use mozjs::jsapi::JSContext as RawJSContext;

fn SM_function_that_can_trigger_gc(_cx: *mut RawJSContext) {}

fn can_trigger_gc(cx: &mut JSContext) {
    unsafe { SM_function_that_can_trigger_gc(cx.raw_cx()) } // returned pointer is immediately used
    cx.no_gc(); // this is ok because no outstanding raw pointer is alive
}
Source

pub unsafe fn raw_cx_no_gc(&self) -> *mut RawJSContext

Obtain RawJSContext mutable pointer, that will not be used for GC.

§Safety

No &mut calls should be done on JSContext while returned pointer is available. In practices this means that one should use the result as direct argument to SpiderMonkey function and not store it in variable.

use mozjs::context::*;
use mozjs::jsapi::JSContext as RawJSContext;

fn SM_function_that_cannot_trigger_gc(_cx: *mut RawJSContext) {}

fn f(cx: &mut JSContext) {
    unsafe { SM_function_that_cannot_trigger_gc(cx.raw_cx_no_gc()) } // returned pointer is immediately used
}

Trait Implementations§

Source§

impl<'cx> Deref for AutoRealm<'cx>

Source§

type Target = JSContext

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<'cx> DerefMut for AutoRealm<'cx>

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
Source§

impl<'cx> Drop for AutoRealm<'cx>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<'cx> Freeze for AutoRealm<'cx>

§

impl<'cx> RefUnwindSafe for AutoRealm<'cx>

§

impl<'cx> !Send for AutoRealm<'cx>

§

impl<'cx> !Sync for AutoRealm<'cx>

§

impl<'cx> Unpin for AutoRealm<'cx>

§

impl<'cx> !UnwindSafe for AutoRealm<'cx>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Filterable for T

Source§

fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(DataRequest<'_>) -> bool>

Creates a filterable data provider with the given name for debugging. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T