From 9bd4d3e03e59b0fc87c9d078887cca1d5f378eb9 Mon Sep 17 00:00:00 2001 From: sagudev <16504129+sagudev@users.noreply.github.com> Date: Tue, 11 Nov 2025 07:58:08 +0100 Subject: [PATCH 1/6] deal with realm stuff Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --- mozjs/benches/latin1_string_conversion.rs | 6 +- mozjs/examples/eval.rs | 6 +- mozjs/examples/wasm.rs | 4 +- mozjs/src/generate_wrappers.py | 2 +- mozjs/src/glue2_wrappers.in.rs | 2 +- mozjs/src/lib.rs | 1 + mozjs/src/realm.rs | 129 ++++++++++++++++++++++ mozjs/src/rust.rs | 40 +++---- mozjs/tests/callback.rs | 24 ++-- mozjs/tests/capture_stack.rs | 23 ++-- mozjs/tests/enforce_range.rs | 29 ++--- mozjs/tests/enumerate.rs | 15 ++- mozjs/tests/evaluate.rs | 14 ++- mozjs/tests/external_string.rs | 6 +- mozjs/tests/iterate_stack.rs | 14 +-- mozjs/tests/jsvalue.rs | 13 ++- mozjs/tests/panic.rs | 17 ++- mozjs/tests/property_descriptor.rs | 6 +- mozjs/tests/rootable.rs | 6 +- mozjs/tests/rooting.rs | 8 +- mozjs/tests/runtime.rs | 6 +- mozjs/tests/stack_gc_vector.rs | 19 ++-- mozjs/tests/stack_limit.rs | 19 ++-- mozjs/tests/typedarray.rs | 27 ++--- mozjs/tests/typedarray_panic.rs | 6 +- mozjs/tests/vec_conversion.rs | 37 ++++--- 26 files changed, 331 insertions(+), 148 deletions(-) create mode 100644 mozjs/src/realm.rs diff --git a/mozjs/benches/latin1_string_conversion.rs b/mozjs/benches/latin1_string_conversion.rs index 3179b29a33f..03866afc277 100644 --- a/mozjs/benches/latin1_string_conversion.rs +++ b/mozjs/benches/latin1_string_conversion.rs @@ -5,7 +5,8 @@ use criterion::{ use mozjs::context::JSContext; use mozjs::conversions::jsstr_to_string; use mozjs::glue::{CreateJSExternalStringCallbacks, JSExternalStringCallbacksTraps}; -use mozjs::jsapi::{JSAutoRealm, OnNewGlobalHookOption}; +use mozjs::jsapi::OnNewGlobalHookOption; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::{JS_NewExternalStringLatin1, JS_NewGlobalObject}; use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; @@ -72,7 +73,8 @@ fn external_string(c: &mut Criterion) { h_option, &*c_option, )}); - let _ac = JSAutoRealm::new(unsafe { context.raw_cx() }, global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); let mut group = c.benchmark_group("Latin1 conversion"); diff --git a/mozjs/examples/eval.rs b/mozjs/examples/eval.rs index f6af979bacf..57427db1028 100644 --- a/mozjs/examples/eval.rs +++ b/mozjs/examples/eval.rs @@ -18,7 +18,9 @@ use ::std::ptr; use mozjs::jsapi::OnNewGlobalHookOption; use mozjs::jsval::UndefinedValue; use mozjs::rooted; +use mozjs::rust::evaluate_script; use mozjs::rust::wrappers2::*; +use mozjs::rust::CompileOptionsWrapper; use mozjs::rust::SIMPLE_GLOBAL_CLASS; use mozjs::rust::{JSEngine, RealmOptions, Runtime}; @@ -45,8 +47,8 @@ fn run(mut rt: Runtime) { */ let source: &'static str = "40 + 2"; - let options = rt.new_compile_options(filename, lineno); - let res = rt.evaluate_script(global.handle(), source, rval.handle_mut(), options); + let options = CompileOptionsWrapper::new(rt.cx_no_gc(), filename, lineno); + let res = evaluate_script(rt.cx(), global.handle(), source, rval.handle_mut(), options); if res.is_ok() { /* Should get a number back from the example source. */ diff --git a/mozjs/examples/wasm.rs b/mozjs/examples/wasm.rs index 752679d75c8..0f628ff566b 100644 --- a/mozjs/examples/wasm.rs +++ b/mozjs/examples/wasm.rs @@ -15,6 +15,7 @@ use ::std::ptr::null_mut; use mozjs::jsapi::*; use mozjs::jsval::ObjectValue; use mozjs::jsval::UndefinedValue; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::{ Call, Construct1, JS_DefineFunction, JS_GetProperty, JS_NewGlobalObject, JS_NewPlainObject, @@ -58,7 +59,8 @@ fn run(mut rt: Runtime) { OnNewGlobalHookOption::FireOnNewGlobalHook, &*options) }); - let _ac = JSAutoRealm::new(unsafe { cx.raw_cx() }, global.get()); + let mut realm = AutoRealm::new_from_handle(cx, global.handle()); + let cx = realm.cx(); // Get WebAssembly.Module and WebAssembly.Instance constructors. rooted!(&in(cx) let mut wasm = UndefinedValue()); diff --git a/mozjs/src/generate_wrappers.py b/mozjs/src/generate_wrappers.py index 9c5d79f8f64..54853827bcd 100755 --- a/mozjs/src/generate_wrappers.py +++ b/mozjs/src/generate_wrappers.py @@ -124,7 +124,7 @@ def replace_in_line(fn: tuple[str, str | None]) -> str: .replace("*mut JSContext", "&mut JSContext") .replace("*const JSContext", "&JSContext") ) - if link_name in no_gc: + if link_name in no_gc or "NewCompileOptions" in sig: sig = sig.replace("&mut JSContext", "&JSContext") return sig diff --git a/mozjs/src/glue2_wrappers.in.rs b/mozjs/src/glue2_wrappers.in.rs index b30c1b51838..887195823d2 100644 --- a/mozjs/src/glue2_wrappers.in.rs +++ b/mozjs/src/glue2_wrappers.in.rs @@ -3,7 +3,7 @@ wrap!(glue: pub fn InvokeHasOwn(handler: *const ::std::os::raw::c_void, cx: &mut wrap!(glue: pub fn CallJitGetterOp(info: *const JSJitInfo, cx: &mut JSContext, thisObj: HandleObject, specializedThis: *mut ::std::os::raw::c_void, argc: ::std::os::raw::c_uint, vp: *mut Value) -> bool); wrap!(glue: pub fn CallJitSetterOp(info: *const JSJitInfo, cx: &mut JSContext, thisObj: HandleObject, specializedThis: *mut ::std::os::raw::c_void, argc: ::std::os::raw::c_uint, vp: *mut Value) -> bool); wrap!(glue: pub fn CallJitMethodOp(info: *const JSJitInfo, cx: &mut JSContext, thisObj: HandleObject, specializedThis: *mut ::std::os::raw::c_void, argc: u32, vp: *mut Value) -> bool); -wrap!(glue: pub fn NewCompileOptions(aCx: &mut JSContext, aFile: *const ::std::os::raw::c_char, aLine: ::std::os::raw::c_uint) -> *mut ReadOnlyCompileOptions); +wrap!(glue: pub fn NewCompileOptions(aCx: &JSContext, aFile: *const ::std::os::raw::c_char, aLine: ::std::os::raw::c_uint) -> *mut ReadOnlyCompileOptions); wrap!(glue: pub fn NewProxyObject(aCx: &mut JSContext, aHandler: *const ::std::os::raw::c_void, aPriv: HandleValue, proto: *mut JSObject, aClass: *const JSClass, aLazyProto: bool) -> *mut JSObject); wrap!(glue: pub fn WrapperNew(aCx: &mut JSContext, aObj: HandleObject, aHandler: *const ::std::os::raw::c_void, aClass: *const JSClass) -> *mut JSObject); wrap!(glue: pub fn NewWindowProxy(aCx: &mut JSContext, aObj: HandleObject, aHandler: *const ::std::os::raw::c_void) -> *mut JSObject); diff --git a/mozjs/src/lib.rs b/mozjs/src/lib.rs index 89d8b2b6993..d92f12dbebd 100644 --- a/mozjs/src/lib.rs +++ b/mozjs/src/lib.rs @@ -53,6 +53,7 @@ pub mod conversions; pub mod error; pub mod gc; pub mod panic; +pub mod realm; pub mod typedarray; pub use crate::consts::*; diff --git a/mozjs/src/realm.rs b/mozjs/src/realm.rs new file mode 100644 index 00000000000..e7507e37138 --- /dev/null +++ b/mozjs/src/realm.rs @@ -0,0 +1,129 @@ +use std::marker::PhantomData; +use std::ptr::NonNull; + +use mozjs_sys::jsapi::JS::Realm; +use mozjs_sys::jsapi::{JSAutoRealm, JSObject}; + +use crate::context::JSContext; +use crate::gc::Handle; +use crate::rust::wrappers2::{CurrentGlobalOrNull, GetCurrentRealmOrNull}; + +pub struct AutoRealm<'cx> { + cx: JSContext, + realm: JSAutoRealm, + phantom: PhantomData<&'cx mut ()>, +} + +impl<'cx> AutoRealm<'cx> { + /// 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 via `&mut`, + /// thus effectively preventing any out of order drops. + pub fn new(cx: &'cx mut JSContext, target: NonNull) -> AutoRealm<'cx> { + let realm = JSAutoRealm::new(unsafe { cx.raw_cx_no_gc() }, target.as_ptr()); + AutoRealm { + cx: unsafe { JSContext::from_ptr(NonNull::new_unchecked(cx.raw_cx())) }, + realm, + phantom: PhantomData, + } + } + + pub fn new_from_handle( + cx: &'cx mut JSContext, + target: Handle<*mut JSObject>, + ) -> AutoRealm<'cx> { + Self::new(cx, NonNull::new(target.get()).unwrap()) + } + + pub fn cx(&mut self) -> &mut JSContext { + &mut self.cx + } + + pub fn cx_no_gc(&self) -> &JSContext { + &self.cx + } + + pub fn in_realm(&'cx mut self) -> InRealm<'cx> { + InRealm::Entered(self) + } + + pub fn global(&'_ self) -> Handle<'_, *mut JSObject> { + // SAFETY: object is rooted by realm + unsafe { Handle::from_marked_location(CurrentGlobalOrNull(self.cx_no_gc()) as _) } + } + + pub unsafe fn erase_lifetime(self) -> AutoRealm<'static> { + std::mem::transmute(self) + } + + pub fn realm(&self) -> &JSAutoRealm { + &self.realm + } +} + +impl<'cx> Drop for AutoRealm<'cx> { + // this is not trivially dropped type + // not sure why we need to do this manually + fn drop(&mut self) {} +} + +pub struct AlreadyInRealm<'cx> { + cx: &'cx mut JSContext, + realm: NonNull, +} + +impl<'cx> AlreadyInRealm<'cx> { + pub fn assert(cx: &'cx mut JSContext) -> AlreadyInRealm<'cx> { + let realm = unsafe { GetCurrentRealmOrNull(cx) }; + AlreadyInRealm { + cx, + realm: NonNull::new(realm).unwrap(), + } + } + + pub fn cx(&mut self) -> &mut JSContext { + self.cx + } + + pub fn cx_no_gc(&self) -> &JSContext { + &self.cx + } + + pub fn in_realm(&'cx mut self) -> InRealm<'cx> { + InRealm::Already(self) + } + + pub fn global(&'_ self) -> Handle<'_, *mut JSObject> { + // SAFETY: object is rooted by realm + unsafe { Handle::from_marked_location(CurrentGlobalOrNull(self.cx_no_gc()) as _) } + } + + pub fn realm(&self) -> &NonNull { + &self.realm + } +} + +pub enum InRealm<'cx> { + Already(&'cx mut AlreadyInRealm<'cx>), + Entered(&'cx mut AutoRealm<'cx>), +} + +impl<'cx> InRealm<'cx> { + pub fn cx(&mut self) -> &mut JSContext { + match self { + InRealm::Already(already_in_realm) => already_in_realm.cx(), + InRealm::Entered(auto_realm) => auto_realm.cx(), + } + } + + pub fn cx_no_gc(&self) -> &JSContext { + match self { + InRealm::Already(already_in_realm) => already_in_realm.cx_no_gc(), + InRealm::Entered(auto_realm) => auto_realm.cx_no_gc(), + } + } + + pub fn global(&'_ self) -> Handle<'_, *mut JSObject> { + // SAFETY: object is rooted by realm + unsafe { Handle::from_marked_location(CurrentGlobalOrNull(self.cx_no_gc()) as _) } + } +} diff --git a/mozjs/src/rust.rs b/mozjs/src/rust.rs index cd565e0eef8..f209c8a5abb 100644 --- a/mozjs/src/rust.rs +++ b/mozjs/src/rust.rs @@ -47,20 +47,18 @@ use crate::jsapi::JS_AddExtraGCRootsTracer; use crate::jsapi::MutableHandleIdVector as RawMutableHandleIdVector; use crate::jsapi::{already_AddRefed, jsid}; use crate::jsapi::{BuildStackString, CaptureCurrentStack, StackFormat}; -use crate::jsapi::{Evaluate2, HandleValueArray, StencilRelease}; +use crate::jsapi::{HandleValueArray, StencilRelease}; use crate::jsapi::{InitSelfHostedCode, IsWindowSlow}; -use crate::jsapi::{ - JSAutoRealm, JS_SetGCParameter, JS_SetNativeStackQuota, JS_WrapObject, JS_WrapValue, -}; use crate::jsapi::{JSAutoStructuredCloneBuffer, JSStructuredCloneCallbacks, StructuredCloneScope}; use crate::jsapi::{JSClass, JSClassOps, JSContext, Realm, JSCLASS_RESERVED_SLOTS_SHIFT}; use crate::jsapi::{JSErrorReport, JSFunctionSpec, JSGCParamKey}; use crate::jsapi::{JSObject, JSPropertySpec, JSRuntime}; use crate::jsapi::{JSString, Object, PersistentRootedIdVector}; use crate::jsapi::{JS_DefineFunctions, JS_DefineProperties, JS_DestroyContext, JS_ShutDown}; -use crate::jsapi::{JS_EnumerateStandardClasses, JS_GetRuntime, JS_GlobalObjectTraceHook}; +use crate::jsapi::{JS_EnumerateStandardClasses, JS_GlobalObjectTraceHook}; use crate::jsapi::{JS_MayResolveStandardClass, JS_NewContext, JS_ResolveStandardClass}; use crate::jsapi::{JS_RequestInterruptCallback, JS_RequestInterruptCallbackCanWait}; +use crate::jsapi::{JS_SetGCParameter, JS_SetNativeStackQuota, JS_WrapObject, JS_WrapValue}; use crate::jsapi::{JS_StackCapture_AllFrames, JS_StackCapture_MaxFrames}; use crate::jsapi::{PersistentRootedObjectVector, ReadOnlyCompileOptions, RootingContext}; use crate::jsapi::{SetWarningReporter, SourceText, ToBooleanSlow}; @@ -68,6 +66,7 @@ use crate::jsapi::{ToInt32Slow, ToInt64Slow, ToNumberSlow, ToStringSlow, ToUint1 use crate::jsapi::{ToUint32Slow, ToUint64Slow, ToWindowProxyIfWindowSlow}; use crate::jsval::{JSVal, ObjectValue}; use crate::panic::maybe_resume_unwind; +use crate::realm::AutoRealm; use log::{debug, warn}; use mozjs_sys::jsapi::JS::SavedFrameResult; pub use mozjs_sys::jsgc::{GCMethods, IntoHandle, IntoMutableHandle}; @@ -397,8 +396,7 @@ impl Runtime { /// Returns the `JSRuntime` object. pub fn rt(&self) -> *mut JSRuntime { - // SAFETY: JS_GetRuntime does not trigger GC - unsafe { JS_GetRuntime(self.cx.raw_cx_no_gc()) } + unsafe { wrappers2::JS_GetRuntime(self.cx_no_gc()) } } /// Returns the `JSContext` object. @@ -410,21 +408,6 @@ impl Runtime { pub fn cx_no_gc<'rt>(&'rt self) -> &'rt crate::context::JSContext { &self.cx } - - pub fn evaluate_script( - &mut self, - glob: HandleObject, - script: &str, - rval: MutableHandleValue, - options: CompileOptionsWrapper, - ) -> Result<(), ()> { - evaluate_script(self.cx(), glob, script, rval, options) - } - - pub fn new_compile_options(&self, filename: &str, line: u32) -> CompileOptionsWrapper { - // SAFETY: `cx` argument points to a non-null, valid JSContext - unsafe { CompileOptionsWrapper::new(self.cx_no_gc().raw_cx_no_gc(), filename, line) } - } } pub fn evaluate_script( @@ -440,11 +423,12 @@ pub fn evaluate_script( script ); - let _ac = JSAutoRealm::new(unsafe { cx.raw_cx() }, glob.get()); + let mut realm = AutoRealm::new_from_handle(cx, glob); + let cx = realm.cx(); unsafe { let mut source = transform_str_to_source_text(&script); - if !Evaluate2(cx.raw_cx(), options.ptr, &mut source, rval.into()) { + if !wrappers2::Evaluate2(cx, options.ptr, &mut source, rval.into()) { debug!("...err!"); maybe_resume_unwind(); Err(()) @@ -550,10 +534,16 @@ pub struct CompileOptionsWrapper { } impl CompileOptionsWrapper { + pub fn new(cx: &crate::context::JSContext, filename: &str, line: u32) -> Self { + let filename = CString::new(filename.as_bytes()).unwrap(); + let ptr = unsafe { wrappers2::NewCompileOptions(cx, filename.as_ptr(), line) }; + assert!(!ptr.is_null()); + Self { ptr, filename } + } /// # Safety /// `cx` must point to a non-null, valid [`JSContext`]. /// To create an instance from safe code, use [`Runtime::new_compile_options`]. - pub unsafe fn new(cx: *mut JSContext, filename: &str, line: u32) -> Self { + pub unsafe fn new_raw(cx: *mut JSContext, filename: &str, line: u32) -> Self { let filename = CString::new(filename.as_bytes()).unwrap(); let ptr = NewCompileOptions(cx, filename.as_ptr(), line); assert!(!ptr.is_null()); diff --git a/mozjs/tests/callback.rs b/mozjs/tests/callback.rs index d3126cc693b..3aa2ebbaa8f 100644 --- a/mozjs/tests/callback.rs +++ b/mozjs/tests/callback.rs @@ -8,11 +8,14 @@ use std::ptr::NonNull; use std::str; use mozjs::context::{JSContext, RawJSContext}; -use mozjs::jsapi::{CallArgs, JSAutoRealm, JS_ReportErrorASCII, OnNewGlobalHookOption, Value}; +use mozjs::jsapi::{CallArgs, JS_ReportErrorASCII, OnNewGlobalHookOption, Value}; use mozjs::jsval::UndefinedValue; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::{EncodeStringToUTF8, JS_DefineFunction, JS_NewGlobalObject}; -use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; +use mozjs::rust::{ + evaluate_script, CompileOptionsWrapper, JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS, +}; #[test] fn callback() { @@ -34,7 +37,8 @@ fn callback() { h_option, &*c_option, )); - let _ac = JSAutoRealm::new(context.raw_cx(), global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); let function = JS_DefineFunction( context, @@ -48,11 +52,15 @@ fn callback() { let javascript = "puts('Test Iñtërnâtiônàlizætiøn ┬─┬ノ( º _ ºノ) ');"; rooted!(&in(context) let mut rval = UndefinedValue()); - // Rust automagically drops context here, so we can continue to use runtime here - let options = runtime.new_compile_options("test.js", 0); - assert!(runtime - .evaluate_script(global.handle(), javascript, rval.handle_mut(), options) - .is_ok()); + let options = CompileOptionsWrapper::new(&context, "test.js", 0); + assert!(evaluate_script( + context, + global.handle(), + javascript, + rval.handle_mut(), + options + ) + .is_ok()); } } diff --git a/mozjs/tests/capture_stack.rs b/mozjs/tests/capture_stack.rs index 2cbdad177f4..b649448e6a3 100644 --- a/mozjs/tests/capture_stack.rs +++ b/mozjs/tests/capture_stack.rs @@ -5,11 +5,14 @@ use std::ptr; use mozjs::capture_stack; -use mozjs::jsapi::{CallArgs, JSAutoRealm, JSContext, OnNewGlobalHookOption, StackFormat, Value}; +use mozjs::jsapi::{CallArgs, JSContext, OnNewGlobalHookOption, StackFormat, Value}; use mozjs::jsval::UndefinedValue; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::{JS_DefineFunction, JS_NewGlobalObject}; -use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; +use mozjs::rust::{ + evaluate_script, CompileOptionsWrapper, JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS, +}; #[test] fn capture_stack() { @@ -49,7 +52,8 @@ fn capture_stack() { h_option, &*c_option, )); - let _ac = JSAutoRealm::new(context.raw_cx(), global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); let function = JS_DefineFunction( context, @@ -72,9 +76,14 @@ fn capture_stack() { foo(\"arg1-value\"); "; rooted!(&in(context) let mut rval = UndefinedValue()); - let options = runtime.new_compile_options("test.js", 0); - assert!(runtime - .evaluate_script(global.handle(), javascript, rval.handle_mut(), options) - .is_ok()); + let options = CompileOptionsWrapper::new(&context, "test.js", 0); + assert!(evaluate_script( + context, + global.handle(), + javascript, + rval.handle_mut(), + options + ) + .is_ok()); } } diff --git a/mozjs/tests/enforce_range.rs b/mozjs/tests/enforce_range.rs index 6eb36a86408..07917701242 100644 --- a/mozjs/tests/enforce_range.rs +++ b/mozjs/tests/enforce_range.rs @@ -5,15 +5,16 @@ use std::ptr; use mozjs::conversions::{ConversionBehavior, ConversionResult, FromJSValConvertible}; -use mozjs::jsapi::JSAutoRealm; use mozjs::jsapi::{Heap, JSObject, OnNewGlobalHookOption}; use mozjs::jsval::UndefinedValue; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::{JS_ClearPendingException, JS_IsExceptionPending, JS_NewGlobalObject}; +use mozjs::rust::{evaluate_script, CompileOptionsWrapper}; use mozjs::rust::{HandleObject, JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; struct SM { - _ac: JSAutoRealm, + _realm: AutoRealm<'static>, global: Box>, rt: Runtime, _engine: JSEngine, @@ -37,12 +38,13 @@ impl SM { h_option, &*c_option, )}); - let _ac = JSAutoRealm::new(unsafe { cx.raw_cx() }, global.get()); + let realm = AutoRealm::new_from_handle(cx, global.handle()); Self { _engine: engine, + // SAFETY: This is safe because the lifetime of the realm is tied to the Runtime. + _realm: unsafe { realm.erase_lifetime() }, rt, global: Heap::boxed(global.get()), - _ac, } } @@ -54,16 +56,15 @@ impl SM { let cx = self.rt.cx(); rooted!(&in(cx) let mut rval = UndefinedValue()); unsafe { - let options = self.rt.new_compile_options("test", 1); - self.rt - .evaluate_script( - HandleObject::from_raw(self.global.handle()), - js, - rval.handle_mut(), - options, - ) - .unwrap(); - let cx = self.rt.cx(); + let options = CompileOptionsWrapper::new(&cx, "test", 1); + evaluate_script( + cx, + HandleObject::from_raw(self.global.handle()), + js, + rval.handle_mut(), + options, + ) + .unwrap(); assert!(!JS_IsExceptionPending(cx)); match ::from_jsval( cx.raw_cx(), diff --git a/mozjs/tests/enumerate.rs b/mozjs/tests/enumerate.rs index 1e874ccbc63..c1b477eca7f 100644 --- a/mozjs/tests/enumerate.rs +++ b/mozjs/tests/enumerate.rs @@ -8,6 +8,7 @@ use mozjs::jsapi::{OnNewGlobalHookOption, JSITER_OWNONLY}; use mozjs::jsval::UndefinedValue; use mozjs::rooted; use mozjs::rust::wrappers2::{GetPropertyKeys, JS_NewGlobalObject, JS_StringEqualsAscii}; +use mozjs::rust::{evaluate_script, CompileOptionsWrapper}; use mozjs::rust::{IdVector, JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; #[test] @@ -32,11 +33,15 @@ fn enumerate() { )); rooted!(&in(context) let mut rval = UndefinedValue()); - let options = runtime.new_compile_options("test", 1); - assert!(runtime - .evaluate_script(global.handle(), "({ 'a': 7 })", rval.handle_mut(), options,) - .is_ok()); - let context = runtime.cx(); + let options = CompileOptionsWrapper::new(&context, "test", 1); + assert!(evaluate_script( + context, + global.handle(), + "({ 'a': 7 })", + rval.handle_mut(), + options + ) + .is_ok()); assert!(rval.is_object()); rooted!(&in(context) let object = rval.to_object()); diff --git a/mozjs/tests/evaluate.rs b/mozjs/tests/evaluate.rs index adf09670090..eef5a0e877f 100644 --- a/mozjs/tests/evaluate.rs +++ b/mozjs/tests/evaluate.rs @@ -9,6 +9,7 @@ use mozjs::jsval::UndefinedValue; use mozjs::rooted; use mozjs::rust::wrappers2::JS_NewGlobalObject; use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; +use mozjs::rust::{evaluate_script, CompileOptionsWrapper}; #[test] fn evaluate() { @@ -32,10 +33,15 @@ fn evaluate() { )); rooted!(&in(context) let mut rval = UndefinedValue()); - let options = runtime.new_compile_options("test", 1); - assert!(runtime - .evaluate_script(global.handle(), "1 + 1", rval.handle_mut(), options) - .is_ok()); + let options = CompileOptionsWrapper::new(&context, "test", 1); + assert!(evaluate_script( + context, + global.handle(), + "1 + 1", + rval.handle_mut(), + options + ) + .is_ok()); assert_eq!(rval.get().to_int32(), 2); } } diff --git a/mozjs/tests/external_string.rs b/mozjs/tests/external_string.rs index 2470ad5a737..29e905bde32 100644 --- a/mozjs/tests/external_string.rs +++ b/mozjs/tests/external_string.rs @@ -10,7 +10,8 @@ use std::ptr::NonNull; use mozjs::context::JSContext; use mozjs::conversions::jsstr_to_string; use mozjs::glue::{CreateJSExternalStringCallbacks, JSExternalStringCallbacksTraps}; -use mozjs::jsapi::{JSAutoRealm, OnNewGlobalHookOption}; +use mozjs::jsapi::OnNewGlobalHookOption; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::{ JS_NewExternalStringLatin1, JS_NewExternalUCString, JS_NewGlobalObject, @@ -37,7 +38,8 @@ fn external_string() { h_option, &*c_option, )); - let _ac = JSAutoRealm::new(context.raw_cx(), global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); test_latin1_string(context, "test latin1"); test_latin1_string(context, "abcdefghijklmnop"); // exactly 16 bytes diff --git a/mozjs/tests/iterate_stack.rs b/mozjs/tests/iterate_stack.rs index a0ca2760ca5..57822582984 100644 --- a/mozjs/tests/iterate_stack.rs +++ b/mozjs/tests/iterate_stack.rs @@ -2,10 +2,11 @@ use std::ptr::{self, NonNull}; use mozjs::{ capture_stack, - jsapi::{self, JSAutoRealm, JSContext, OnNewGlobalHookOption, Value}, + jsapi::{self, JSContext, OnNewGlobalHookOption, Value}, jsval::UndefinedValue, rooted, - rust::{wrappers2, JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}, + realm::AutoRealm, + rust::{wrappers2, JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS, evaluate_script, CompileOptionsWrapper}, }; #[test] @@ -68,7 +69,8 @@ fn iterate_stack_frames() { h_option, &*c_option, )); - let _ac = JSAutoRealm::new(context.raw_cx(), global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); let function = wrappers2::JS_DefineFunction( context, @@ -93,9 +95,7 @@ fn iterate_stack_frames() { foo(); "; rooted!(&in(context) let mut rval = UndefinedValue()); - let options = runtime.new_compile_options("test.js", 0); - assert!(runtime - .evaluate_script(global.handle(), javascript, rval.handle_mut(), options) - .is_ok()); + let options = CompileOptionsWrapper::new(&context, "test.js", 0); + assert!(evaluate_script(context, global.handle(), javascript, rval.handle_mut(), options).is_ok()); } } diff --git a/mozjs/tests/jsvalue.rs b/mozjs/tests/jsvalue.rs index dd0f2f353bf..d75a466dad3 100644 --- a/mozjs/tests/jsvalue.rs +++ b/mozjs/tests/jsvalue.rs @@ -8,6 +8,7 @@ use mozjs::jsapi::OnNewGlobalHookOption; use mozjs::jsval::{BooleanValue, DoubleValue, Int32Value, NullValue, UndefinedValue}; use mozjs::rooted; use mozjs::rust::wrappers2::JS_NewGlobalObject; +use mozjs::rust::{evaluate_script, CompileOptionsWrapper}; use mozjs::rust::{ HandleObject, JSEngine, RealmOptions, RootedGuard, Runtime, SIMPLE_GLOBAL_CLASS, }; @@ -22,14 +23,14 @@ unsafe fn tester)>( rust: JSVal, test: F, ) { - rooted!(&in(rt.cx()) let mut rval = UndefinedValue()); - let options = rt.new_compile_options("test", 1); - assert!(rt - .evaluate_script(global, js, rval.handle_mut(), options) - .is_ok()); + let cx = rt.cx(); + rooted!(&in(cx) let mut rval = UndefinedValue()); + + let options = CompileOptionsWrapper::new(&cx, "test", 1); + assert!(evaluate_script(cx, global, js, rval.handle_mut(), options).is_ok()); test(rval); - rooted!(&in(rt.cx()) let mut val = rust); + rooted!(&in(cx) let mut val = rust); test(val); } diff --git a/mozjs/tests/panic.rs b/mozjs/tests/panic.rs index 09346a11f44..d92f79c4166 100644 --- a/mozjs/tests/panic.rs +++ b/mozjs/tests/panic.rs @@ -6,11 +6,13 @@ use std::ptr::{self, NonNull}; use mozjs::context::{JSContext, RawJSContext}; use mozjs::gc::HandleValue; -use mozjs::jsapi::{ExceptionStackBehavior, JSAutoRealm, OnNewGlobalHookOption, Value}; +use mozjs::jsapi::{ExceptionStackBehavior, OnNewGlobalHookOption, Value}; use mozjs::jsval::UndefinedValue; use mozjs::panic::wrap_panic; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::{JS_DefineFunction, JS_NewGlobalObject, JS_SetPendingException}; +use mozjs::rust::{evaluate_script, CompileOptionsWrapper}; use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; #[test] @@ -34,7 +36,8 @@ fn test_panic() { h_option, &*c_option, )); - let _ac = JSAutoRealm::new(context.raw_cx(), global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); let function = JS_DefineFunction( context, @@ -47,8 +50,14 @@ fn test_panic() { assert!(!function.is_null()); rooted!(&in(context) let mut rval = UndefinedValue()); - let options = runtime.new_compile_options("test.js", 0); - let _ = runtime.evaluate_script(global.handle(), "test();", rval.handle_mut(), options); + let options = CompileOptionsWrapper::new(&context, "test.js", 0); + let _ = evaluate_script( + context, + global.handle(), + "test();", + rval.handle_mut(), + options, + ); } } diff --git a/mozjs/tests/property_descriptor.rs b/mozjs/tests/property_descriptor.rs index d6db82dbabe..108fa203c81 100644 --- a/mozjs/tests/property_descriptor.rs +++ b/mozjs/tests/property_descriptor.rs @@ -5,9 +5,10 @@ use std::ptr; use mozjs::jsapi::JSObject; -use mozjs::jsapi::{JSAutoRealm, OnNewGlobalHookOption, PropertyDescriptor}; +use mozjs::jsapi::{OnNewGlobalHookOption, PropertyDescriptor}; use mozjs::jsapi::{JSPROP_ENUMERATE, JSPROP_PERMANENT, JSPROP_READONLY}; use mozjs::jsval::{Int32Value, NullValue}; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::{ FromPropertyDescriptor, JS_DefineProperty, JS_GetProperty, JS_GetPropertyDescriptor, @@ -37,7 +38,8 @@ fn property_descriptor() { h_option, &*c_option, )); - let _ac = JSAutoRealm::new(context.raw_cx(), global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); rooted!(&in(context) let object = JS_NewPlainObject(context)); rooted!(&in(context) let property = Int32Value(32)); diff --git a/mozjs/tests/rootable.rs b/mozjs/tests/rootable.rs index 488b35825f5..431fe3a04fd 100644 --- a/mozjs/tests/rootable.rs +++ b/mozjs/tests/rootable.rs @@ -7,8 +7,9 @@ use std::ptr; use mozjs::jsapi::SetGCZeal; -use mozjs::jsapi::{JSAutoRealm, JSTracer, OnNewGlobalHookOption, Value}; +use mozjs::jsapi::{JSTracer, OnNewGlobalHookOption, Value}; use mozjs::jsval::ObjectValue; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::{GetRealmObjectPrototype, JS_NewGlobalObject}; use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; @@ -47,7 +48,8 @@ fn rooting() { h_option, &*c_option, )); - let _ac = JSAutoRealm::new(context.raw_cx(), global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); rooted!(&in(context) let prototype_proto = GetRealmObjectPrototype(context)); rooted!(&in(context) let some_container = ContainsGCValue { diff --git a/mozjs/tests/rooting.rs b/mozjs/tests/rooting.rs index 91e3b4f89fd..a588c64f615 100644 --- a/mozjs/tests/rooting.rs +++ b/mozjs/tests/rooting.rs @@ -9,10 +9,11 @@ use std::ptr; use mozjs::jsapi::SetGCZeal; use mozjs::jsapi::JSPROP_ENUMERATE; use mozjs::jsapi::{ - JSAutoRealm, JSClass, JSContext, JSFunction, JSFunctionSpec, JSNativeWrapper, JSObject, - JSPropertySpec_Name, JSString, OnNewGlobalHookOption, Value, + JSClass, JSContext, JSFunction, JSFunctionSpec, JSNativeWrapper, JSObject, JSPropertySpec_Name, + JSString, OnNewGlobalHookOption, Value, }; use mozjs::jsval::JSVal; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::{ GetRealmObjectPrototype, JS_NewGlobalObject, JS_NewObjectWithGivenProto, @@ -36,7 +37,8 @@ fn rooting() { h_option, &*c_option, )); - let _ac = JSAutoRealm::new(context.raw_cx(), global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); rooted!(&in(context) let prototype_proto = GetRealmObjectPrototype(context)); rooted!(&in(context) let proto = JS_NewObjectWithGivenProto(context, &CLASS as *const _, prototype_proto.handle().into())); diff --git a/mozjs/tests/runtime.rs b/mozjs/tests/runtime.rs index 5535db70c19..b4c0226505b 100644 --- a/mozjs/tests/runtime.rs +++ b/mozjs/tests/runtime.rs @@ -10,7 +10,8 @@ use std::thread; use mozjs::jsapi::GCContext; use mozjs::jsapi::JSCLASS_FOREGROUND_FINALIZE; -use mozjs::jsapi::{JSAutoRealm, JSClass, JSClassOps, JSObject, OnNewGlobalHookOption}; +use mozjs::jsapi::{JSClass, JSClassOps, JSObject, OnNewGlobalHookOption}; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::{JS_NewGlobalObject, JS_NewObject}; use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; @@ -35,7 +36,8 @@ fn runtime() { h_option, &*c_option, )); - let _ac = JSAutoRealm::new(context.raw_cx(), global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); rooted!(&in(context) let _object = JS_NewObject(context, &CLASS as *const _)); } diff --git a/mozjs/tests/stack_gc_vector.rs b/mozjs/tests/stack_gc_vector.rs index d62e42403c4..cd96a235641 100644 --- a/mozjs/tests/stack_gc_vector.rs +++ b/mozjs/tests/stack_gc_vector.rs @@ -14,6 +14,7 @@ use mozjs::jsapi::{ use mozjs::jsval::{JSVal, UndefinedValue}; use mozjs::rooted; use mozjs::rust::wrappers2::{JS_NewGlobalObject, JS_SetSecurityCallbacks}; +use mozjs::rust::{evaluate_script, CompileOptionsWrapper}; use mozjs::rust::{Handle as SafeHandle, JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; static SECURITY_CALLBACKS: JSSecurityCallbacks = JSSecurityCallbacks { @@ -88,15 +89,15 @@ fn csp_allow_arguments() { )); rooted!(&in(context) let mut rval = UndefinedValue()); - let options = runtime.new_compile_options("test", 1); - assert!(runtime - .evaluate_script( - global.handle(), - "Function(\"a\", \"b\", \"return a + b\")", - rval.handle_mut(), - options - ) - .is_ok()); + let options = CompileOptionsWrapper::new(&context, "test", 1); + assert!(evaluate_script( + context, + global.handle(), + "Function(\"a\", \"b\", \"return a + b\")", + rval.handle_mut(), + options + ) + .is_ok()); assert!(rval.get().is_object()); assert!(*RAN_CSP_CALLBACK.lock().unwrap()); diff --git a/mozjs/tests/stack_limit.rs b/mozjs/tests/stack_limit.rs index 7f1e65c9310..f937bfdd42c 100644 --- a/mozjs/tests/stack_limit.rs +++ b/mozjs/tests/stack_limit.rs @@ -8,6 +8,7 @@ use mozjs::jsapi::OnNewGlobalHookOption; use mozjs::jsval::UndefinedValue; use mozjs::rooted; use mozjs::rust::wrappers2::JS_NewGlobalObject; +use mozjs::rust::{evaluate_script, CompileOptionsWrapper}; use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; #[test] @@ -31,14 +32,14 @@ fn stack_limit() { &*c_option, )); rooted!(&in(context) let mut rval = UndefinedValue()); - let options = runtime.new_compile_options("test", 1); - assert!(runtime - .evaluate_script( - global.handle(), - "function f() { f.apply() } f()", - rval.handle_mut(), - options, - ) - .is_err()); + let options = CompileOptionsWrapper::new(&context, "test", 1); + assert!(evaluate_script( + context, + global.handle(), + "function f() { f.apply() } f()", + rval.handle_mut(), + options, + ) + .is_err()); } } diff --git a/mozjs/tests/typedarray.rs b/mozjs/tests/typedarray.rs index d23ada43836..1daf2c68067 100644 --- a/mozjs/tests/typedarray.rs +++ b/mozjs/tests/typedarray.rs @@ -4,10 +4,12 @@ use std::ptr; -use mozjs::jsapi::{JSAutoRealm, JSObject, OnNewGlobalHookOption, Type}; +use mozjs::jsapi::{JSObject, OnNewGlobalHookOption, Type}; use mozjs::jsval::UndefinedValue; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::JS_NewGlobalObject; +use mozjs::rust::{evaluate_script, CompileOptionsWrapper}; use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; use mozjs::typedarray; use mozjs::typedarray::{CreateWith, Uint32Array}; @@ -32,22 +34,21 @@ fn typedarray() { h_option, &*c_option, )); - let _ac = JSAutoRealm::new(context.raw_cx(), global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); rooted!(&in(context) let mut rval = UndefinedValue()); - let options = runtime.new_compile_options("test", 1); - assert!(runtime - .evaluate_script( - global.handle(), - "new Uint8Array([0, 2, 4])", - rval.handle_mut(), - options, - ) - .is_ok()); + let options = CompileOptionsWrapper::new(&context, "test", 1); + assert!(evaluate_script( + context, + global.handle(), + "new Uint8Array([0, 2, 4])", + rval.handle_mut(), + options, + ) + .is_ok()); assert!(rval.is_object()); - let context = runtime.cx(); - typedarray!(&in(context) let array: Uint8Array = rval.to_object()); assert_eq!(array.unwrap().as_slice(), &[0, 2, 4][..]); diff --git a/mozjs/tests/typedarray_panic.rs b/mozjs/tests/typedarray_panic.rs index 7de958d1b23..4c7a5e5ba5d 100644 --- a/mozjs/tests/typedarray_panic.rs +++ b/mozjs/tests/typedarray_panic.rs @@ -4,7 +4,8 @@ use std::ptr; -use mozjs::jsapi::{JSAutoRealm, JSObject, OnNewGlobalHookOption}; +use mozjs::jsapi::{JSObject, OnNewGlobalHookOption}; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::JS_NewGlobalObject; use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; @@ -28,7 +29,8 @@ fn typedarray_update_panic() { h_option, &*c_option, )); - let _ac = JSAutoRealm::new(context.raw_cx(), global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); rooted!(&in(context) let mut rval = ptr::null_mut::()); let _ = Uint32Array::create( diff --git a/mozjs/tests/vec_conversion.rs b/mozjs/tests/vec_conversion.rs index cedad5da32e..a4eb3cf6e88 100644 --- a/mozjs/tests/vec_conversion.rs +++ b/mozjs/tests/vec_conversion.rs @@ -7,10 +7,12 @@ use std::ptr; use mozjs::conversions::{ ConversionBehavior, ConversionResult, FromJSValConvertible, ToJSValConvertible, }; -use mozjs::jsapi::{JSAutoRealm, OnNewGlobalHookOption}; +use mozjs::jsapi::OnNewGlobalHookOption; use mozjs::jsval::UndefinedValue; +use mozjs::realm::AutoRealm; use mozjs::rooted; use mozjs::rust::wrappers2::{InitRealmStandardClasses, JS_NewGlobalObject}; +use mozjs::rust::{evaluate_script, CompileOptionsWrapper}; use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; #[test] @@ -35,7 +37,8 @@ fn vec_conversion() { h_option, &*c_option, )); - let _ac = JSAutoRealm::new(context.raw_cx(), global.get()); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); assert!(InitRealmStandardClasses(context)); rooted!(&in(context) let mut rval = UndefinedValue()); @@ -54,27 +57,27 @@ fn vec_conversion() { assert_eq!(&orig_vec, converted.get_success_value().unwrap()); - let options = runtime.new_compile_options("test", 1); - assert!(runtime - .evaluate_script( - global.handle(), - "new Set([1, 2, 3])", - rval.handle_mut(), - options, - ) - .is_ok()); - let context = runtime.cx(); + let options = CompileOptionsWrapper::new(&context, "test", 1); + assert!(evaluate_script( + context, + global.handle(), + "new Set([1, 2, 3])", + rval.handle_mut(), + options, + ) + .is_ok()); + let converted = Vec::::from_jsval(context.raw_cx(), rval.handle(), ConversionBehavior::Default) .unwrap(); assert_eq!(&orig_vec, converted.get_success_value().unwrap()); - let options = runtime.new_compile_options("test", 1); - assert!(runtime - .evaluate_script(global.handle(), "({})", rval.handle_mut(), options) - .is_ok()); - let context = runtime.cx(); + let options = CompileOptionsWrapper::new(&context, "test", 1); + assert!( + evaluate_script(context, global.handle(), "({})", rval.handle_mut(), options).is_ok() + ); + let converted = Vec::::from_jsval(context.raw_cx(), rval.handle(), ConversionBehavior::Default); assert!(match converted { From 3c3a7e31814dfb4054cc31865487f7af1fbbe583 Mon Sep 17 00:00:00 2001 From: sagudev <16504129+sagudev@users.noreply.github.com> Date: Tue, 11 Nov 2025 08:21:52 +0100 Subject: [PATCH 2/6] fmt Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --- mozjs/tests/evaluate.rs | 2 +- mozjs/tests/iterate_stack.rs | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/mozjs/tests/evaluate.rs b/mozjs/tests/evaluate.rs index eef5a0e877f..35de3fa3183 100644 --- a/mozjs/tests/evaluate.rs +++ b/mozjs/tests/evaluate.rs @@ -8,8 +8,8 @@ use mozjs::jsapi::OnNewGlobalHookOption; use mozjs::jsval::UndefinedValue; use mozjs::rooted; use mozjs::rust::wrappers2::JS_NewGlobalObject; -use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; use mozjs::rust::{evaluate_script, CompileOptionsWrapper}; +use mozjs::rust::{JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS}; #[test] fn evaluate() { diff --git a/mozjs/tests/iterate_stack.rs b/mozjs/tests/iterate_stack.rs index 57822582984..23026e22556 100644 --- a/mozjs/tests/iterate_stack.rs +++ b/mozjs/tests/iterate_stack.rs @@ -4,9 +4,12 @@ use mozjs::{ capture_stack, jsapi::{self, JSContext, OnNewGlobalHookOption, Value}, jsval::UndefinedValue, - rooted, realm::AutoRealm, - rust::{wrappers2, JSEngine, RealmOptions, Runtime, SIMPLE_GLOBAL_CLASS, evaluate_script, CompileOptionsWrapper}, + rooted, + rust::{ + evaluate_script, wrappers2, CompileOptionsWrapper, JSEngine, RealmOptions, Runtime, + SIMPLE_GLOBAL_CLASS, + }, }; #[test] @@ -69,8 +72,8 @@ fn iterate_stack_frames() { h_option, &*c_option, )); - let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); + let mut realm = AutoRealm::new_from_handle(context, global.handle()); + let context = realm.cx(); let function = wrappers2::JS_DefineFunction( context, @@ -96,6 +99,13 @@ fn iterate_stack_frames() { "; rooted!(&in(context) let mut rval = UndefinedValue()); let options = CompileOptionsWrapper::new(&context, "test.js", 0); - assert!(evaluate_script(context, global.handle(), javascript, rval.handle_mut(), options).is_ok()); + assert!(evaluate_script( + context, + global.handle(), + javascript, + rval.handle_mut(), + options + ) + .is_ok()); } } From 6cebb50ee36910b2e4759dfe62e5985242e98c14 Mon Sep 17 00:00:00 2001 From: sagudev <16504129+sagudev@users.noreply.github.com> Date: Tue, 11 Nov 2025 08:36:11 +0100 Subject: [PATCH 3/6] There is only one CurrentRealm anyway Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --- mozjs/src/realm.rs | 89 ++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 50 deletions(-) diff --git a/mozjs/src/realm.rs b/mozjs/src/realm.rs index e7507e37138..59f7b5f79dc 100644 --- a/mozjs/src/realm.rs +++ b/mozjs/src/realm.rs @@ -15,9 +15,12 @@ pub struct AutoRealm<'cx> { } impl<'cx> 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 via `&mut`, - /// thus effectively preventing any out of order drops. + /// but because [AutoRealm] can act as a [JSContext] we need to take `&mut JSContext`. pub fn new(cx: &'cx mut JSContext, target: NonNull) -> AutoRealm<'cx> { let realm = JSAutoRealm::new(unsafe { cx.raw_cx_no_gc() }, target.as_ptr()); AutoRealm { @@ -27,6 +30,12 @@ impl<'cx> 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`. pub fn new_from_handle( cx: &'cx mut JSContext, target: Handle<*mut JSObject>, @@ -34,27 +43,34 @@ impl<'cx> AutoRealm<'cx> { Self::new(cx, NonNull::new(target.get()).unwrap()) } - pub fn cx(&mut self) -> &mut JSContext { - &mut self.cx - } - - pub fn cx_no_gc(&self) -> &JSContext { - &self.cx - } - - pub fn in_realm(&'cx mut self) -> InRealm<'cx> { - InRealm::Entered(self) + /// If we can get &mut AutoRealm then we are current realm, + /// because if there existed other current realm, we couldn't get &mut AutoRealm. + pub fn current_realm(&'cx mut self) -> CurrentRealm<'cx> { + CurrentRealm::assert(self.cx()) } + /// Obtain the handle to the global object of the current realm. pub fn global(&'_ self) -> Handle<'_, *mut JSObject> { // SAFETY: object is rooted by realm unsafe { Handle::from_marked_location(CurrentGlobalOrNull(self.cx_no_gc()) as _) } } + /// Erase the lifetime of this [AutoRealm]. + /// + /// # Safety + /// - The caller must ensure that the [AutoRealm] does not outlive the [JSContext] it was created with. pub unsafe fn erase_lifetime(self) -> AutoRealm<'static> { std::mem::transmute(self) } + pub fn cx(&mut self) -> &mut JSContext { + &mut self.cx + } + + pub fn cx_no_gc(&self) -> &JSContext { + &self.cx + } + pub fn realm(&self) -> &JSAutoRealm { &self.realm } @@ -66,64 +82,37 @@ impl<'cx> Drop for AutoRealm<'cx> { fn drop(&mut self) {} } -pub struct AlreadyInRealm<'cx> { +/// Represents the current realm of [JSContext] (top realm on realm stack). +pub struct CurrentRealm<'cx> { cx: &'cx mut JSContext, realm: NonNull, } -impl<'cx> AlreadyInRealm<'cx> { - pub fn assert(cx: &'cx mut JSContext) -> AlreadyInRealm<'cx> { +impl<'cx> CurrentRealm<'cx> { + /// Asserts that the current realm is valid and returns it. + pub fn assert(cx: &'cx mut JSContext) -> CurrentRealm<'cx> { let realm = unsafe { GetCurrentRealmOrNull(cx) }; - AlreadyInRealm { + CurrentRealm { cx, realm: NonNull::new(realm).unwrap(), } } - pub fn cx(&mut self) -> &mut JSContext { - self.cx - } - - pub fn cx_no_gc(&self) -> &JSContext { - &self.cx - } - - pub fn in_realm(&'cx mut self) -> InRealm<'cx> { - InRealm::Already(self) - } - + /// Obtain the handle to the global object of the current realm. pub fn global(&'_ self) -> Handle<'_, *mut JSObject> { // SAFETY: object is rooted by realm unsafe { Handle::from_marked_location(CurrentGlobalOrNull(self.cx_no_gc()) as _) } } - pub fn realm(&self) -> &NonNull { - &self.realm - } -} - -pub enum InRealm<'cx> { - Already(&'cx mut AlreadyInRealm<'cx>), - Entered(&'cx mut AutoRealm<'cx>), -} - -impl<'cx> InRealm<'cx> { pub fn cx(&mut self) -> &mut JSContext { - match self { - InRealm::Already(already_in_realm) => already_in_realm.cx(), - InRealm::Entered(auto_realm) => auto_realm.cx(), - } + self.cx } pub fn cx_no_gc(&self) -> &JSContext { - match self { - InRealm::Already(already_in_realm) => already_in_realm.cx_no_gc(), - InRealm::Entered(auto_realm) => auto_realm.cx_no_gc(), - } + &self.cx } - pub fn global(&'_ self) -> Handle<'_, *mut JSObject> { - // SAFETY: object is rooted by realm - unsafe { Handle::from_marked_location(CurrentGlobalOrNull(self.cx_no_gc()) as _) } + pub fn realm(&self) -> &NonNull { + &self.realm } } From 6d8661502c37acc50576ed9132043f1a91abdbdf Mon Sep 17 00:00:00 2001 From: sagudev <16504129+sagudev@users.noreply.github.com> Date: Tue, 11 Nov 2025 12:04:48 +0100 Subject: [PATCH 4/6] docs Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --- mozjs/src/realm.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/mozjs/src/realm.rs b/mozjs/src/realm.rs index 59f7b5f79dc..18f997b5258 100644 --- a/mozjs/src/realm.rs +++ b/mozjs/src/realm.rs @@ -1,13 +1,63 @@ use std::marker::PhantomData; use std::ptr::NonNull; -use mozjs_sys::jsapi::JS::Realm; -use mozjs_sys::jsapi::{JSAutoRealm, JSObject}; +use crate::jsapi::JS::Realm; +use crate::jsapi::{JSAutoRealm, JSObject}; use crate::context::JSContext; use crate::gc::Handle; use crate::rust::wrappers2::{CurrentGlobalOrNull, GetCurrentRealmOrNull}; +/// 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 act as [JSContext] (using [AutoRealm::cx] and [AutoRealm::cx_no_gc]) +/// with additional information of entered/current realm: +/// ```compile_fail +/// use mozjs::context::JSContext; +/// use mozjs::jsapi::JSObject; +/// use mozjs::realm::AutoRealm; +/// use std::ptr::NonNull; +/// +/// fn f(cx: &mut JSContext, target: NonNull) { +/// 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) { +/// let mut realm = AutoRealm::new(cx, target); +/// let mut cx = realm.cx(); // 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]: +/// ```compile_fail +/// use mozjs::context::JSContext; +/// use mozjs::jsapi::JSObject; +/// use mozjs::realm::AutoRealm; +/// use std::ptr::NonNull; +/// +/// fn f(cx: &mut JSContext, t1: NonNull, t2: NonNull) { +/// let mut realm1 = AutoRealm::new(cx, t1); +/// let mut cx = realm1.cx(); +/// let realm2 = AutoRealm::new(cx, t2); +/// drop(realm1); // it's not possible to drop realm1 before realm2 +/// } +/// ``` pub struct AutoRealm<'cx> { cx: JSContext, realm: JSAutoRealm, From a86d97454a83acdd60932b7f8356a94716941511 Mon Sep 17 00:00:00 2001 From: sagudev <16504129+sagudev@users.noreply.github.com> Date: Tue, 11 Nov 2025 13:06:20 +0100 Subject: [PATCH 5/6] more docs Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --- mozjs/src/realm.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/mozjs/src/realm.rs b/mozjs/src/realm.rs index 18f997b5258..e89009c9104 100644 --- a/mozjs/src/realm.rs +++ b/mozjs/src/realm.rs @@ -127,12 +127,27 @@ impl<'cx> AutoRealm<'cx> { } impl<'cx> Drop for AutoRealm<'cx> { - // this is not trivially dropped type - // not sure why we need to do this manually + // if we do not implement this rust can shorten lifetime of cx, + // without effecting JSAutoRealm (realm drops after we lose lifetime of cx) fn drop(&mut self) {} } /// Represents the current realm of [JSContext] (top realm on realm stack). +/// +/// Similarly to [AutoRealm], while you can access this type via `&mut`/`&mut` +/// we know that this realm is current (on top of realm stack). +/// +/// ```compile_fail +/// use mozjs::context::JSContext; +/// use mozjs::jsapi::JSObject; +/// use mozjs::realm::{AutoRealm, CurrentRealm}; +/// use std::ptr::NonNull; +/// +/// fn f(current_realm: CurrentRealm, target: NonNull) { +/// let mut realm = AutoRealm::new(current_realm.cx(), target); +/// let cx = current_realm.cx(); // we cannot use current realm while it's not current +/// } +/// ``` pub struct CurrentRealm<'cx> { cx: &'cx mut JSContext, realm: NonNull, From 71ca44cc70c91cc5fe0f4d95022c501cf2cfd595 Mon Sep 17 00:00:00 2001 From: sagudev <16504129+sagudev@users.noreply.github.com> Date: Wed, 12 Nov 2025 11:05:38 +0100 Subject: [PATCH 6/6] use Deref and DerefMut instead of cx,cx_no_gc This allows us to use realm in place of cx without calling any methods as compiler will deref automatically. Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --- mozjs/benches/latin1_string_conversion.rs | 5 +-- mozjs/examples/wasm.rs | 2 +- mozjs/src/realm.rs | 51 ++++++++++++++--------- mozjs/src/rust.rs | 3 +- mozjs/tests/callback.rs | 2 +- mozjs/tests/capture_stack.rs | 2 +- mozjs/tests/external_string.rs | 2 +- mozjs/tests/iterate_stack.rs | 2 +- mozjs/tests/panic.rs | 9 ++-- mozjs/tests/property_descriptor.rs | 2 +- mozjs/tests/rootable.rs | 2 +- mozjs/tests/rooting.rs | 2 +- mozjs/tests/runtime.rs | 2 +- mozjs/tests/typedarray.rs | 2 +- mozjs/tests/typedarray_panic.rs | 2 +- mozjs/tests/vec_conversion.rs | 2 +- 16 files changed, 51 insertions(+), 41 deletions(-) diff --git a/mozjs/benches/latin1_string_conversion.rs b/mozjs/benches/latin1_string_conversion.rs index 03866afc277..0f51a0b684c 100644 --- a/mozjs/benches/latin1_string_conversion.rs +++ b/mozjs/benches/latin1_string_conversion.rs @@ -74,17 +74,16 @@ fn external_string(c: &mut Criterion) { &*c_option, )}); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); let mut group = c.benchmark_group("Latin1 conversion"); let ascii_example = b"test latin-1 tes"; - bench_str_repetition(&mut group, context, "ascii a-z", ascii_example); + bench_str_repetition(&mut group, &mut realm, "ascii a-z", ascii_example); // fastpath for the first few characters, then slowpath for the remaining (long part) // TODO: make generator functions, so we can define at which percentage of the size // the first high byte shows up (which forces the slow path). let ascii_with_high = b"test latin-1 \xD6\xC0\xFF"; - bench_str_repetition(&mut group, context, "ascii with high", ascii_with_high); + bench_str_repetition(&mut group, &mut realm, "ascii with high", ascii_with_high); } static EXTERNAL_STRING_CALLBACKS_TRAPS: JSExternalStringCallbacksTraps = diff --git a/mozjs/examples/wasm.rs b/mozjs/examples/wasm.rs index 0f628ff566b..83fe77a6e79 100644 --- a/mozjs/examples/wasm.rs +++ b/mozjs/examples/wasm.rs @@ -60,7 +60,7 @@ fn run(mut rt: Runtime) { &*options) }); let mut realm = AutoRealm::new_from_handle(cx, global.handle()); - let cx = realm.cx(); + let cx = &mut realm; // Get WebAssembly.Module and WebAssembly.Instance constructors. rooted!(&in(cx) let mut wasm = UndefinedValue()); diff --git a/mozjs/src/realm.rs b/mozjs/src/realm.rs index e89009c9104..7932c390ef4 100644 --- a/mozjs/src/realm.rs +++ b/mozjs/src/realm.rs @@ -1,4 +1,5 @@ use std::marker::PhantomData; +use std::ops::{Deref, DerefMut}; use std::ptr::NonNull; use crate::jsapi::JS::Realm; @@ -15,7 +16,7 @@ use crate::rust::wrappers2::{CurrentGlobalOrNull, GetCurrentRealmOrNull}; /// Drop exits realm. /// /// While creating [AutoRealm] will not trigger GC, -/// it still takes `&mut JSContext`, because it can act as [JSContext] (using [AutoRealm::cx] and [AutoRealm::cx_no_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: /// ```compile_fail /// use mozjs::context::JSContext; @@ -38,7 +39,7 @@ use crate::rust::wrappers2::{CurrentGlobalOrNull, GetCurrentRealmOrNull}; /// /// fn f(cx: &mut JSContext, target: NonNull) { /// let mut realm = AutoRealm::new(cx, target); -/// let mut cx = realm.cx(); // this JSContext is bounded to AutoRealm +/// let cx = &mut realm; // this JSContext is bounded to AutoRealm /// // which in turn is bounded to original JSContext /// f(cx, target); /// } @@ -53,7 +54,7 @@ use crate::rust::wrappers2::{CurrentGlobalOrNull, GetCurrentRealmOrNull}; /// /// fn f(cx: &mut JSContext, t1: NonNull, t2: NonNull) { /// let mut realm1 = AutoRealm::new(cx, t1); -/// let mut cx = realm1.cx(); +/// let cx = &mut realm1; /// let realm2 = AutoRealm::new(cx, t2); /// drop(realm1); // it's not possible to drop realm1 before realm2 /// } @@ -96,13 +97,13 @@ impl<'cx> AutoRealm<'cx> { /// If we can get &mut AutoRealm then we are current realm, /// because if there existed other current realm, we couldn't get &mut AutoRealm. pub fn current_realm(&'cx mut self) -> CurrentRealm<'cx> { - CurrentRealm::assert(self.cx()) + CurrentRealm::assert(self) } /// Obtain the handle to the global object of the current realm. pub fn global(&'_ self) -> Handle<'_, *mut JSObject> { // SAFETY: object is rooted by realm - unsafe { Handle::from_marked_location(CurrentGlobalOrNull(self.cx_no_gc()) as _) } + unsafe { Handle::from_marked_location(CurrentGlobalOrNull(&*self) as _) } } /// Erase the lifetime of this [AutoRealm]. @@ -113,16 +114,22 @@ impl<'cx> AutoRealm<'cx> { std::mem::transmute(self) } - pub fn cx(&mut self) -> &mut JSContext { - &mut self.cx + pub fn realm(&self) -> &JSAutoRealm { + &self.realm } +} + +impl<'cx> Deref for AutoRealm<'cx> { + type Target = JSContext; - pub fn cx_no_gc(&self) -> &JSContext { + fn deref(&'_ self) -> &'_ Self::Target { &self.cx } +} - pub fn realm(&self) -> &JSAutoRealm { - &self.realm +impl<'cx> DerefMut for AutoRealm<'cx> { + fn deref_mut(&'_ mut self) -> &'_ mut Self::Target { + &mut self.cx } } @@ -143,9 +150,9 @@ impl<'cx> Drop for AutoRealm<'cx> { /// use mozjs::realm::{AutoRealm, CurrentRealm}; /// use std::ptr::NonNull; /// -/// fn f(current_realm: CurrentRealm, target: NonNull) { -/// let mut realm = AutoRealm::new(current_realm.cx(), target); -/// let cx = current_realm.cx(); // we cannot use current realm while it's not current +/// fn f(current_realm: &mut CurrentRealm, target: NonNull) { +/// let mut realm = AutoRealm::new(current_realm, target); +/// let cx: &mut JSContext = &mut *current_realm; // we cannot use current realm while it's not current /// } /// ``` pub struct CurrentRealm<'cx> { @@ -166,18 +173,24 @@ impl<'cx> CurrentRealm<'cx> { /// Obtain the handle to the global object of the current realm. pub fn global(&'_ self) -> Handle<'_, *mut JSObject> { // SAFETY: object is rooted by realm - unsafe { Handle::from_marked_location(CurrentGlobalOrNull(self.cx_no_gc()) as _) } + unsafe { Handle::from_marked_location(CurrentGlobalOrNull(&*self) as _) } } - pub fn cx(&mut self) -> &mut JSContext { - self.cx + pub fn realm(&self) -> &NonNull { + &self.realm } +} + +impl<'cx> Deref for CurrentRealm<'cx> { + type Target = JSContext; - pub fn cx_no_gc(&self) -> &JSContext { + fn deref(&'_ self) -> &'_ Self::Target { &self.cx } +} - pub fn realm(&self) -> &NonNull { - &self.realm +impl<'cx> DerefMut for CurrentRealm<'cx> { + fn deref_mut(&'_ mut self) -> &'_ mut Self::Target { + &mut self.cx } } diff --git a/mozjs/src/rust.rs b/mozjs/src/rust.rs index f209c8a5abb..dd3fa544cab 100644 --- a/mozjs/src/rust.rs +++ b/mozjs/src/rust.rs @@ -424,11 +424,10 @@ pub fn evaluate_script( ); let mut realm = AutoRealm::new_from_handle(cx, glob); - let cx = realm.cx(); unsafe { let mut source = transform_str_to_source_text(&script); - if !wrappers2::Evaluate2(cx, options.ptr, &mut source, rval.into()) { + if !wrappers2::Evaluate2(&mut realm, options.ptr, &mut source, rval.into()) { debug!("...err!"); maybe_resume_unwind(); Err(()) diff --git a/mozjs/tests/callback.rs b/mozjs/tests/callback.rs index 3aa2ebbaa8f..89f3be35f05 100644 --- a/mozjs/tests/callback.rs +++ b/mozjs/tests/callback.rs @@ -38,7 +38,7 @@ fn callback() { &*c_option, )); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); + let context = &mut realm; let function = JS_DefineFunction( context, diff --git a/mozjs/tests/capture_stack.rs b/mozjs/tests/capture_stack.rs index b649448e6a3..a3ecec1757d 100644 --- a/mozjs/tests/capture_stack.rs +++ b/mozjs/tests/capture_stack.rs @@ -53,7 +53,7 @@ fn capture_stack() { &*c_option, )); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); + let context = &mut realm; let function = JS_DefineFunction( context, diff --git a/mozjs/tests/external_string.rs b/mozjs/tests/external_string.rs index 29e905bde32..5c450ed5473 100644 --- a/mozjs/tests/external_string.rs +++ b/mozjs/tests/external_string.rs @@ -39,7 +39,7 @@ fn external_string() { &*c_option, )); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); + let context = &mut *realm; test_latin1_string(context, "test latin1"); test_latin1_string(context, "abcdefghijklmnop"); // exactly 16 bytes diff --git a/mozjs/tests/iterate_stack.rs b/mozjs/tests/iterate_stack.rs index 23026e22556..da19fa94852 100644 --- a/mozjs/tests/iterate_stack.rs +++ b/mozjs/tests/iterate_stack.rs @@ -73,7 +73,7 @@ fn iterate_stack_frames() { &*c_option, )); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); + let context = &mut *realm; let function = wrappers2::JS_DefineFunction( context, diff --git a/mozjs/tests/panic.rs b/mozjs/tests/panic.rs index d92f79c4166..588ff972afe 100644 --- a/mozjs/tests/panic.rs +++ b/mozjs/tests/panic.rs @@ -37,10 +37,9 @@ fn test_panic() { &*c_option, )); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); let function = JS_DefineFunction( - context, + &mut realm, global.handle().into(), c"test".as_ptr(), Some(test), @@ -49,10 +48,10 @@ fn test_panic() { ); assert!(!function.is_null()); - rooted!(&in(context) let mut rval = UndefinedValue()); - let options = CompileOptionsWrapper::new(&context, "test.js", 0); + rooted!(&in(&mut realm) let mut rval = UndefinedValue()); + let options = CompileOptionsWrapper::new(&mut realm, "test.js", 0); let _ = evaluate_script( - context, + &mut realm, global.handle(), "test();", rval.handle_mut(), diff --git a/mozjs/tests/property_descriptor.rs b/mozjs/tests/property_descriptor.rs index 108fa203c81..e16e657ae86 100644 --- a/mozjs/tests/property_descriptor.rs +++ b/mozjs/tests/property_descriptor.rs @@ -39,7 +39,7 @@ fn property_descriptor() { &*c_option, )); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); + let context = &mut realm; rooted!(&in(context) let object = JS_NewPlainObject(context)); rooted!(&in(context) let property = Int32Value(32)); diff --git a/mozjs/tests/rootable.rs b/mozjs/tests/rootable.rs index 431fe3a04fd..3d312213bdd 100644 --- a/mozjs/tests/rootable.rs +++ b/mozjs/tests/rootable.rs @@ -49,7 +49,7 @@ fn rooting() { &*c_option, )); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); + let context = &mut realm; rooted!(&in(context) let prototype_proto = GetRealmObjectPrototype(context)); rooted!(&in(context) let some_container = ContainsGCValue { diff --git a/mozjs/tests/rooting.rs b/mozjs/tests/rooting.rs index a588c64f615..8d10530b5c9 100644 --- a/mozjs/tests/rooting.rs +++ b/mozjs/tests/rooting.rs @@ -38,7 +38,7 @@ fn rooting() { &*c_option, )); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); + let context = &mut realm; rooted!(&in(context) let prototype_proto = GetRealmObjectPrototype(context)); rooted!(&in(context) let proto = JS_NewObjectWithGivenProto(context, &CLASS as *const _, prototype_proto.handle().into())); diff --git a/mozjs/tests/runtime.rs b/mozjs/tests/runtime.rs index b4c0226505b..203c5f223ef 100644 --- a/mozjs/tests/runtime.rs +++ b/mozjs/tests/runtime.rs @@ -37,7 +37,7 @@ fn runtime() { &*c_option, )); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); + let context = &mut realm; rooted!(&in(context) let _object = JS_NewObject(context, &CLASS as *const _)); } diff --git a/mozjs/tests/typedarray.rs b/mozjs/tests/typedarray.rs index 1daf2c68067..ce62cd805ca 100644 --- a/mozjs/tests/typedarray.rs +++ b/mozjs/tests/typedarray.rs @@ -35,7 +35,7 @@ fn typedarray() { &*c_option, )); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); + let context = &mut realm; rooted!(&in(context) let mut rval = UndefinedValue()); let options = CompileOptionsWrapper::new(&context, "test", 1); diff --git a/mozjs/tests/typedarray_panic.rs b/mozjs/tests/typedarray_panic.rs index 4c7a5e5ba5d..cabcd355f99 100644 --- a/mozjs/tests/typedarray_panic.rs +++ b/mozjs/tests/typedarray_panic.rs @@ -30,7 +30,7 @@ fn typedarray_update_panic() { &*c_option, )); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); + let context = &mut realm; rooted!(&in(context) let mut rval = ptr::null_mut::()); let _ = Uint32Array::create( diff --git a/mozjs/tests/vec_conversion.rs b/mozjs/tests/vec_conversion.rs index a4eb3cf6e88..3e6dfcde46a 100644 --- a/mozjs/tests/vec_conversion.rs +++ b/mozjs/tests/vec_conversion.rs @@ -38,7 +38,7 @@ fn vec_conversion() { &*c_option, )); let mut realm = AutoRealm::new_from_handle(context, global.handle()); - let context = realm.cx(); + let context = &mut realm; assert!(InitRealmStandardClasses(context)); rooted!(&in(context) let mut rval = UndefinedValue());