From 103a747836773448e5367e2399c18fd58dedab81 Mon Sep 17 00:00:00 2001 From: Redfire Date: Tue, 5 Dec 2023 20:11:21 +0800 Subject: [PATCH] Changed StableTraceable Trait Methods Deprecated `Context::root_*` Methods --- ion-proc/src/class/constructor.rs | 2 +- ion/src/bigint.rs | 12 ++--- ion/src/class/mod.rs | 4 +- ion/src/context.rs | 24 +++++----- ion/src/conversions/key.rs | 14 +++--- ion/src/conversions/value/from.rs | 10 ++-- ion/src/error.rs | 10 ++-- ion/src/exception.rs | 8 ++-- ion/src/format/object.rs | 2 +- ion/src/format/primitive.rs | 4 +- ion/src/functions/closure.rs | 6 +-- ion/src/functions/function.rs | 11 ++--- ion/src/module.rs | 10 ++-- ion/src/objects/array.rs | 8 ++-- ion/src/objects/date.rs | 2 +- ion/src/objects/descriptor.rs | 12 ++--- ion/src/objects/iterator.rs | 4 +- ion/src/objects/key.rs | 8 ++-- ion/src/objects/mod.rs | 2 +- ion/src/objects/object.rs | 12 ++--- ion/src/objects/promise.rs | 4 +- ion/src/objects/regexp.rs | 4 +- ion/src/objects/typedarray/buffer.rs | 6 +-- ion/src/root.rs | 46 ++++++++++++------- ion/src/script.rs | 2 +- ion/src/string/mod.rs | 12 ++--- ion/src/symbol.rs | 6 +-- ion/src/value.rs | 24 +++++----- runtime/src/event_loop/future.rs | 2 +- runtime/src/event_loop/macrotasks.rs | 4 +- runtime/src/event_loop/microtasks.rs | 4 +- runtime/src/globals/fetch/mod.rs | 2 +- runtime/src/globals/fetch/response/options.rs | 2 +- runtime/src/runtime.rs | 15 +++--- 34 files changed, 155 insertions(+), 143 deletions(-) diff --git a/ion-proc/src/class/constructor.rs b/ion-proc/src/class/constructor.rs index 1d1c4535..5984aa6f 100644 --- a/ion-proc/src/class/constructor.rs +++ b/ion-proc/src/class/constructor.rs @@ -23,7 +23,7 @@ pub(super) fn impl_constructor(ion: &TokenStream, mut constructor: ItemFn, ty: & let cx = &#ion::Context::new_unchecked(cx); let args = &mut #ion::Arguments::new(cx, argc, vp); let mut this = #ion::Object::from( - cx.root_object( + cx.root( ::mozjs::jsapi::JS_NewObjectForConstructor(cx.as_ptr(), &<#ty as #ion::ClassDefinition>::class().base, &args.call_args()) ) ); diff --git a/ion/src/bigint.rs b/ion/src/bigint.rs index 3787b4df..dc1b547f 100644 --- a/ion/src/bigint.rs +++ b/ion/src/bigint.rs @@ -23,17 +23,17 @@ pub struct BigInt { impl BigInt { /// Creates a [BigInt] from a boolean. pub fn from_bool(cx: &Context, boolean: bool) -> BigInt { - BigInt::from(cx.root_bigint(unsafe { BigIntFromBool(cx.as_ptr(), boolean) })) + BigInt::from(cx.root(unsafe { BigIntFromBool(cx.as_ptr(), boolean) })) } /// Creates a [BigInt] from a 64-bit signed integer. pub fn from_i64(cx: &Context, number: i64) -> BigInt { - BigInt::from(cx.root_bigint(unsafe { BigIntFromInt64(cx.as_ptr(), number) })) + BigInt::from(cx.root(unsafe { BigIntFromInt64(cx.as_ptr(), number) })) } /// Creates a [BigInt] from a 64-bit unsigned integer. pub fn from_u64(cx: &Context, number: u64) -> BigInt { - BigInt::from(cx.root_bigint(unsafe { BigIntFromUint64(cx.as_ptr(), number) })) + BigInt::from(cx.root(unsafe { BigIntFromUint64(cx.as_ptr(), number) })) } /// Creates a [BigInt] from a double. @@ -41,7 +41,7 @@ impl BigInt { pub fn from_f64(cx: &Context, number: f64) -> Result { let bi = unsafe { NumberToBigInt(cx.as_ptr(), number) }; if !bi.is_null() { - Ok(BigInt::from(cx.root_bigint(bi))) + Ok(BigInt::from(cx.root(bi))) } else { Err(Exception::new(cx).unwrap()) } @@ -72,7 +72,7 @@ impl BigInt { }; let bi = unsafe { StringToBigInt1(cx.as_ptr(), chars) }; if !bi.is_null() { - Ok(BigInt::from(cx.root_bigint(bi))) + Ok(BigInt::from(cx.root(bi))) } else { Err(Exception::new(cx)) } @@ -109,7 +109,7 @@ impl BigInt { None } else { let string = unsafe { BigIntToString(cx.as_ptr(), self.handle().into(), radix) }; - Some(String::from(cx.root_string(string))) + Some(String::from(cx.root(string))) } } diff --git a/ion/src/class/mod.rs b/ion/src/class/mod.rs index a4c31e2c..3a22a4e5 100644 --- a/ion/src/class/mod.rs +++ b/ion/src/class/mod.rs @@ -94,10 +94,10 @@ pub trait ClassDefinition: NativeObject { static_functions.as_ptr(), ) }; - let prototype = cx.root_object(class); + let prototype = cx.root(class); let constructor = unsafe { JS_GetConstructor(cx.as_ptr(), prototype.handle().into()) }; - let constructor = Object::from(cx.root_object(constructor)); + let constructor = Object::from(cx.root(constructor)); let constructor = Function::from_object(cx, &constructor).unwrap(); let class_info = ClassInfo { diff --git a/ion/src/context.rs b/ion/src/context.rs index e06151b5..d1a8f8ed 100644 --- a/ion/src/context.rs +++ b/ion/src/context.rs @@ -24,12 +24,13 @@ use crate::class::ClassInfo; use crate::module::ModuleLoader; use crate::Root; -pub trait StableTraceable: Traceable + Sized + 'static { - type Traced; - - fn traced(&self) -> *const Self::Traced; +pub trait StableTraceable +where + Heap: Traceable, +{ + type Traced: Copy + GCMethods + 'static; - fn traceable(&self) -> *const dyn Traceable; + fn heap(&self) -> &Heap; } impl StableTraceable for Box> @@ -38,12 +39,8 @@ where { type Traced = T; - fn traced(&self) -> *const T { - self.get_unsafe().cast_const() - } - - fn traceable(&self) -> *const dyn Traceable { - self.traced() as *const Heap as *const _ + fn heap(&self) -> &Heap { + self } } @@ -151,6 +148,7 @@ macro_rules! impl_root_methods { ($(($fn_name:ident, $pointer:ty, $key:ident, $gc_type:ident)$(,)?)*) => { $( #[doc = concat!("Roots a [", stringify!($pointer), "](", stringify!($pointer), ") as a ", stringify!($gc_type), " ands returns a [Local] to it.")] + #[deprecated] pub fn $fn_name(&self, ptr: $pointer) -> Root>> { self.root(ptr) } @@ -170,8 +168,8 @@ impl Context { unsafe { let roots = &(*self.get_inner_data().as_ptr()).roots; - roots.root(heap.traceable()); - Root::new(heap, NonNull::new(roots as *const _ as *mut _).unwrap()) + roots.root(heap.heap()); + Root::new(heap, roots) } } diff --git a/ion/src/conversions/key.rs b/ion/src/conversions/key.rs index 5618ee25..cebe0e59 100644 --- a/ion/src/conversions/key.rs +++ b/ion/src/conversions/key.rs @@ -43,7 +43,7 @@ impl_to_key_for_integer!(u32); impl ToPropertyKey for *mut JSString { fn to_key(&self, cx: &Context) -> Option { - String::from(cx.root_string(*self)).to_key(cx) + String::from(cx.root(*self)).to_key(cx) } } @@ -51,7 +51,7 @@ impl ToPropertyKey for String { fn to_key(&self, cx: &Context) -> Option { rooted!(in(cx.as_ptr()) let mut key = VoidId()); if unsafe { JS_StringToId(cx.as_ptr(), self.handle().into(), key.handle_mut().into()) } { - Some(PropertyKey::from(cx.root_property_key(key.get()))) + Some(PropertyKey::from(cx.root(key.get()))) } else { None } @@ -72,7 +72,7 @@ impl ToPropertyKey for &str { impl ToPropertyKey for *mut JSSymbol { fn to_key(&self, cx: &Context) -> Option { - Some(cx.root_property_key(SymbolId(*self)).into()) + Some(cx.root(SymbolId(*self)).into()) } } @@ -90,7 +90,7 @@ impl ToPropertyKey for WellKnownSymbolCode { impl ToPropertyKey for JSVal { fn to_key(&self, cx: &Context) -> Option { - Value::from(cx.root_value(*self)).to_key(cx) + Value::from(cx.root(*self)).to_key(cx) } } @@ -98,7 +98,7 @@ impl ToPropertyKey for Value { fn to_key(&self, cx: &Context) -> Option { rooted!(in(cx.as_ptr()) let mut key = VoidId()); if unsafe { JS_ValueToId(cx.as_ptr(), self.handle().into(), key.handle_mut().into()) } { - Some(PropertyKey::from(cx.root_property_key(key.get()))) + Some(PropertyKey::from(cx.root(key.get()))) } else { None } @@ -107,7 +107,7 @@ impl ToPropertyKey for Value { impl ToPropertyKey for JSPropertyKey { fn to_key(&self, cx: &Context) -> Option { - Some(cx.root_property_key(*self).into()) + Some(cx.root(*self).into()) } } @@ -123,7 +123,7 @@ impl ToPropertyKey for OwnedKey { OwnedKey::Int(i) => i.to_key(cx), OwnedKey::String(str) => str.to_key(cx), OwnedKey::Symbol(symbol) => symbol.to_key(cx), - OwnedKey::Void => Some(cx.root_property_key(VoidId()).into()), + OwnedKey::Void => Some(cx.root(VoidId()).into()), } } } diff --git a/ion/src/conversions/value/from.rs b/ion/src/conversions/value/from.rs index 41f0d596..b6e78b79 100644 --- a/ion/src/conversions/value/from.rs +++ b/ion/src/conversions/value/from.rs @@ -120,7 +120,7 @@ impl FromValue for crate::String { type Config = (); fn from_value(cx: &Context, value: &Value, strict: bool, config: ()) -> Result { - <*mut JSString>::from_value(cx, value, strict, config).map(|str| crate::String::from(cx.root_string(str))) + <*mut JSString>::from_value(cx, value, strict, config).map(|str| crate::String::from(cx.root(str))) } } @@ -315,7 +315,7 @@ impl FromValue for Symbol { type Config = (); fn from_value(cx: &Context, value: &Value, strict: bool, config: Self::Config) -> Result { - <*mut JSSymbol>::from_value(cx, value, strict, config).map(|s| cx.root_symbol(s).into()) + <*mut JSSymbol>::from_value(cx, value, strict, config).map(|s| cx.root(s).into()) } } @@ -339,7 +339,7 @@ impl FromValue for Value { unsafe { AssertSameCompartment1(cx.as_ptr(), value.into()); } - Ok(cx.root_value(value.get()).into()) + Ok(cx.root(value.get()).into()) } } @@ -362,7 +362,7 @@ struct ForOfIteratorGuard<'a> { impl<'a> ForOfIteratorGuard<'a> { fn new(cx: &Context, root: &'a mut ForOfIterator) -> Self { - cx.root_object(root.iterator.ptr); + cx.root(root.iterator.ptr); ForOfIteratorGuard { root } } } @@ -436,7 +436,7 @@ impl FromValue for TypedArray { let value = value.handle(); if value.is_object() { let object = value.to_object(); - cx.root_object(object); + cx.root(object); TypedArray::from(object).map_err(|_| Error::new("Expected Typed Array", ErrorKind::Type)) } else { Err(Error::new("Expected Object", ErrorKind::Type)) diff --git a/ion/src/error.rs b/ion/src/error.rs index 485989bc..9bab68bd 100644 --- a/ion/src/error.rs +++ b/ion/src/error.rs @@ -136,7 +136,7 @@ impl Error { pub fn to_object(&self, cx: &Context) -> Option { if let Some(object) = self.object { - return Some(cx.root_object(object).into()); + return Some(cx.root(object).into()); } if self.kind != ErrorKind::None { unsafe { @@ -150,17 +150,17 @@ impl Error { .map(|location| (&*location.file, location.lineno, location.column)) .unwrap_or_default(); - let stack = Object::from(cx.root_object(stack.object.unwrap())); + let stack = Object::from(cx.root(stack.object.unwrap())); let file = file.to_value(cx).unwrap(); - let file_name = cx.root_string(file.handle().to_string()); + let file_name = cx.root(file.handle().to_string()); let message = (!self.message.is_empty()).then(|| { let value = self.message.to_value(cx).unwrap(); - crate::String::from(cx.root_string(value.handle().to_string())) + crate::String::from(cx.root(value.handle().to_string())) }); - let message = message.unwrap_or_else(|| crate::String::from(cx.root_string(ptr::null_mut()))); + let message = message.unwrap_or_else(|| crate::String::from(cx.root(ptr::null_mut()))); rooted!(in(cx.as_ptr()) let mut error = UndefinedValue()); diff --git a/ion/src/exception.rs b/ion/src/exception.rs index 716a4d13..036c4aaa 100644 --- a/ion/src/exception.rs +++ b/ion/src/exception.rs @@ -125,7 +125,7 @@ impl Exception { Exception::Other(value) => { format!( "Uncaught Exception - {}", - format_value(cx, Config::default(), &cx.root_value(*value).into()) + format_value(cx, Config::default(), &cx.root(*value).into()) ) } } @@ -137,7 +137,7 @@ impl ThrowException for Exception { match self { Exception::Error(error) => { if let Error { object: Some(object), .. } = error { - let exception = Value::from(cx.root_value(ObjectValue(*object))); + let exception = Value::from(cx.root(ObjectValue(*object))); unsafe { JS_SetPendingException( cx.as_ptr(), @@ -150,7 +150,7 @@ impl ThrowException for Exception { } } Exception::Other(value) => { - let value = Value::from(cx.root_value(*value)); + let value = Value::from(cx.root(*value)); unsafe { JS_SetPendingException(cx.as_ptr(), value.handle().into(), ExceptionStackBehavior::Capture) } } } @@ -202,7 +202,7 @@ impl ErrorReport { stack_: Rooted::new_unrooted(), }; if GetPendingExceptionStack(cx.as_ptr(), &mut exception_stack) { - let exception = Value::from(cx.root_value(exception_stack.exception_.ptr)); + let exception = Value::from(cx.root(exception_stack.exception_.ptr)); let exception = Exception::from_value(cx, &exception); let stack = Stack::from_object(cx, exception_stack.stack_.ptr); Exception::clear(cx); diff --git a/ion/src/format/object.rs b/ion/src/format/object.rs index 66277ca2..292fad54 100644 --- a/ion/src/format/object.rs +++ b/ion/src/format/object.rs @@ -43,7 +43,7 @@ impl Display for ObjectDisplay<'_> { let cx = self.cx; let cfg = self.cfg; - let object = Object::from(cx.root_object(self.object.handle().get())); + let object = Object::from(cx.root(self.object.handle().get())); let class = self.object.get_builtin_class(cx); diff --git a/ion/src/format/primitive.rs b/ion/src/format/primitive.rs index 9dcbea4a..0a348144 100644 --- a/ion/src/format/primitive.rs +++ b/ion/src/format/primitive.rs @@ -61,7 +61,7 @@ impl Display for PrimitiveDisplay<'_> { } else if value.is_undefined() { write!(f, "{}", "undefined".color(colours.undefined)) } else if value.is_bigint() { - let bi = BigInt::from(self.cx.root_bigint(value.to_bigint())); + let bi = BigInt::from(self.cx.root(value.to_bigint())); write!( f, "{}{}", @@ -69,7 +69,7 @@ impl Display for PrimitiveDisplay<'_> { "n".color(colours.bigint) ) } else if value.is_symbol() { - let symbol = Symbol::from(self.cx.root_symbol(value.to_symbol())); + let symbol = Symbol::from(self.cx.root(value.to_symbol())); write!(f, "{}", format_symbol(self.cx, self.cfg, &symbol)) } else if value.is_magic() { write!(f, "{}", "".color(colours.boolean)) diff --git a/ion/src/functions/closure.rs b/ion/src/functions/closure.rs index 8c3212d4..c887d0da 100644 --- a/ion/src/functions/closure.rs +++ b/ion/src/functions/closure.rs @@ -24,7 +24,7 @@ pub type Closure = dyn FnMut(&mut Arguments) -> ResultExc + 'static; pub(crate) fn create_closure_object(cx: &Context, closure: Box) -> Object { unsafe { - let object = Object::from(cx.root_object(JS_NewObject(cx.as_ptr(), &CLOSURE_CLASS))); + let object = Object::from(cx.root(JS_NewObject(cx.as_ptr(), &CLOSURE_CLASS))); JS_SetReservedSlot( object.handle().get(), CLOSURE_SLOT, @@ -38,8 +38,8 @@ pub(crate) unsafe extern "C" fn call_closure(cx: *mut JSContext, argc: u32, vp: let cx = &unsafe { Context::new_unchecked(cx) }; let args = &mut unsafe { Arguments::new(cx, argc, vp) }; - let callee = cx.root_object(args.call_args().callee()); - let reserved = cx.root_value(unsafe { *GetFunctionNativeReserved(callee.get(), 0) }); + let callee = cx.root(args.call_args().callee()); + let reserved = cx.root(unsafe { *GetFunctionNativeReserved(callee.get(), 0) }); let mut value = UndefinedValue(); unsafe { JS_GetReservedSlot(reserved.handle().to_object(), CLOSURE_SLOT, &mut value) }; diff --git a/ion/src/functions/function.rs b/ion/src/functions/function.rs index 4ff7660f..6c6c103f 100644 --- a/ion/src/functions/function.rs +++ b/ion/src/functions/function.rs @@ -36,15 +36,14 @@ impl Function { pub fn new(cx: &Context, name: &str, func: Option, nargs: u32, flags: PropertyFlags) -> Function { let name = CString::new(name).unwrap(); Function { - function: cx - .root_function(unsafe { JS_NewFunction(cx.as_ptr(), func, nargs, flags.bits() as u32, name.as_ptr()) }), + function: cx.root(unsafe { JS_NewFunction(cx.as_ptr(), func, nargs, flags.bits() as u32, name.as_ptr()) }), } } /// Creates a new [Function] with the given [`spec`](JSFunctionSpec). pub fn from_spec(cx: &Context, spec: &JSFunctionSpec) -> Function { Function { - function: cx.root_function(unsafe { NewFunctionFromSpec1(cx.as_ptr(), spec) }), + function: cx.root(unsafe { NewFunctionFromSpec1(cx.as_ptr(), spec) }), } } @@ -52,7 +51,7 @@ impl Function { pub fn from_closure(cx: &Context, name: &str, closure: Box, nargs: u32, flags: PropertyFlags) -> Function { unsafe { let function = Function { - function: cx.root_function(NewFunctionWithReserved( + function: cx.root(NewFunctionWithReserved( cx.as_ptr(), Some(call_closure), nargs, @@ -75,7 +74,7 @@ impl Function { pub fn from_object(cx: &Context, obj: &Root>>) -> Option { if unsafe { Function::is_function_raw(obj.get()) } { Some(Function { - function: cx.root_function(unsafe { JS_GetObjectFunction(obj.get()) }), + function: cx.root(unsafe { JS_GetObjectFunction(obj.get()) }), }) } else { None @@ -84,7 +83,7 @@ impl Function { /// Converts the [Function] into an [Object]. pub fn to_object(&self, cx: &Context) -> Object { - cx.root_object(unsafe { JS_GetFunctionObject(self.get()) }).into() + cx.root(unsafe { JS_GetFunctionObject(self.get()) }).into() } /// Converts the [Function] into a [String] in the form of its definition/source. diff --git a/ion/src/module.rs b/ion/src/module.rs index f6df60aa..70ff3a0c 100644 --- a/ion/src/module.rs +++ b/ion/src/module.rs @@ -49,20 +49,20 @@ impl ModuleRequest { /// Creates a new [ModuleRequest] with a given specifier. pub fn new>(cx: &Context, specifier: S) -> ModuleRequest { let specifier = crate::String::copy_from_str(cx, specifier.as_ref()).unwrap(); - ModuleRequest(cx.root_object(unsafe { CreateModuleRequest(cx.as_ptr(), specifier.handle().into()) }).into()) + ModuleRequest(cx.root(unsafe { CreateModuleRequest(cx.as_ptr(), specifier.handle().into()) }).into()) } /// Creates a new [ModuleRequest] from a raw handle. /// /// ### Safety /// `request` must be a valid module request object. - pub fn from_request(cx: &Context, request: Handle<*mut JSObject>) -> ModuleRequest { + pub unsafe fn from_request(cx: &Context, request: Handle<*mut JSObject>) -> ModuleRequest { ModuleRequest(Object::from(cx.root(request.get()))) } /// Returns the specifier of the request. pub fn specifier(&self, cx: &Context) -> crate::String { - cx.root_string(unsafe { GetModuleRequestSpecifier(cx.as_ptr(), self.0.handle().into()) }).into() + cx.root(unsafe { GetModuleRequestSpecifier(cx.as_ptr(), self.0.handle().into()) }).into() } } @@ -113,7 +113,7 @@ impl Module { let module = unsafe { CompileModule(cx.as_ptr(), options.ptr.cast_const().cast(), &mut source) }; if !module.is_null() { - let module = Module(Object::from(cx.root_object(module))); + let module = Module(Object::from(cx.root(module))); let data = ModuleData { path: path.and_then(Path::to_str).map(String::from), @@ -208,7 +208,7 @@ pub fn init_module_loader(cx: &Context, loader: ML) .as_mut() .map(|loader| { let private = Value::from(cx.root(private.get())); - let request = ModuleRequest::from_request(cx, request); + let request = unsafe { ModuleRequest::from_request(cx, request) }; loader.resolve(cx, &private, &request) }) .unwrap_or_else(ptr::null_mut) diff --git a/ion/src/objects/array.rs b/ion/src/objects/array.rs index 5f61688f..4df1235a 100644 --- a/ion/src/objects/array.rs +++ b/ion/src/objects/array.rs @@ -31,7 +31,7 @@ impl Array { /// Creates an empty [Array] with the given length. pub fn new_with_length(cx: &Context, length: usize) -> Array { Array { - arr: cx.root_object(unsafe { NewArrayObject1(cx.as_ptr(), length) }).into(), + arr: cx.root(unsafe { NewArrayObject1(cx.as_ptr(), length) }).into(), } } @@ -43,7 +43,7 @@ impl Array { /// Creates an [Array] from a [HandleValueArray]. pub fn from_handle(cx: &Context, handle: HandleValueArray) -> Array { Array { - arr: cx.root_object(unsafe { NewArrayObject(cx.as_ptr(), &handle) }).into(), + arr: cx.root(unsafe { NewArrayObject(cx.as_ptr(), &handle) }).into(), } } @@ -69,7 +69,7 @@ impl Array { /// Converts an [Array] to a [Vec]. /// Returns an empty [Vec] if the conversion fails. pub fn to_vec(&self, cx: &Context) -> Vec { - let value = cx.root_value(ObjectValue(self.arr.handle().get())).into(); + let value = cx.root(ObjectValue(self.arr.handle().get())).into(); if let Ok(vec) = Vec::from_value(cx, &value, true, ()) { vec } else { @@ -79,7 +79,7 @@ impl Array { /// Converts an [Array] to an [Object]. pub fn to_object(&self, cx: &Context) -> Object { - Object::from(cx.root_object(self.arr.handle().get())) + Object::from(cx.root(self.arr.handle().get())) } /// Returns the length of the [Array]. diff --git a/ion/src/objects/date.rs b/ion/src/objects/date.rs index 8cca2a78..5469418d 100644 --- a/ion/src/objects/date.rs +++ b/ion/src/objects/date.rs @@ -28,7 +28,7 @@ impl Date { /// Creates a new [Date] with the given time. pub fn from_date(cx: &Context, time: DateTime) -> Date { let date = unsafe { NewDateObject(cx.as_ptr(), ClippedTime { t: time.timestamp_millis() as f64 }) }; - Date { date: cx.root_object(date) } + Date { date: cx.root(date) } } /// Creates a [Date] from an object. diff --git a/ion/src/objects/descriptor.rs b/ion/src/objects/descriptor.rs index be5963d8..914bc5e5 100644 --- a/ion/src/objects/descriptor.rs +++ b/ion/src/objects/descriptor.rs @@ -19,7 +19,7 @@ pub struct PropertyDescriptor { impl PropertyDescriptor { pub fn new(cx: &Context, value: &Value, attrs: PropertyFlags) -> PropertyDescriptor { - let mut desc = PropertyDescriptor::from(cx.root_property_descriptor(JSPropertyDescriptor::default())); + let mut desc = PropertyDescriptor::from(cx.root(JSPropertyDescriptor::default())); unsafe { SetDataPropertyDescriptor(desc.handle_mut().into(), value.handle().into(), attrs.bits() as u32) }; desc } @@ -29,7 +29,7 @@ impl PropertyDescriptor { ) -> PropertyDescriptor { let getter = getter.to_object(cx); let setter = setter.to_object(cx); - let mut desc = PropertyDescriptor::from(cx.root_property_descriptor(JSPropertyDescriptor::default())); + let mut desc = PropertyDescriptor::from(cx.root(JSPropertyDescriptor::default())); unsafe { SetAccessorPropertyDescriptor( desc.handle_mut().into(), @@ -42,7 +42,7 @@ impl PropertyDescriptor { } pub fn from_object(cx: &Context, object: &Object) -> Option { - let mut desc = PropertyDescriptor::from(cx.root_property_descriptor(JSPropertyDescriptor::default())); + let mut desc = PropertyDescriptor::from(cx.root(JSPropertyDescriptor::default())); let desc_value = Value::object(cx, object); unsafe { ObjectToCompletePropertyDescriptor( @@ -78,15 +78,15 @@ impl PropertyDescriptor { } pub fn getter(&self, cx: &Context) -> Option { - self.handle().hasGetter_().then(|| Object::from(cx.root_object(self.handle().getter_))) + self.handle().hasGetter_().then(|| Object::from(cx.root(self.handle().getter_))) } pub fn setter(&self, cx: &Context) -> Option { - self.handle().hasSetter_().then(|| Object::from(cx.root_object(self.handle().setter_))) + self.handle().hasSetter_().then(|| Object::from(cx.root(self.handle().setter_))) } pub fn value(&self, cx: &Context) -> Option { - self.handle().hasValue_().then(|| Value::from(cx.root_value(self.handle().value_))) + self.handle().hasValue_().then(|| Value::from(cx.root(self.handle().value_))) } pub fn into_root(self) -> Root>> { diff --git a/ion/src/objects/iterator.rs b/ion/src/objects/iterator.rs index 0340f266..d04f4a66 100644 --- a/ion/src/objects/iterator.rs +++ b/ion/src/objects/iterator.rs @@ -118,7 +118,7 @@ unsafe impl Traceable for Iterator { impl IntoValue for Iterator { fn into_value(self: Box, cx: &Context) -> Result { - let object = cx.root_object(Iterator::new_object(cx, self)); + let object = cx.root(Iterator::new_object(cx, self)); object.handle().get().to_value(cx) } } @@ -195,7 +195,7 @@ impl ClassDefinition for Iterator { fn parent_class_info(cx: &Context) -> Option<(&'static NativeClass, Root>>)> { Some(( &ITERATOR_CLASS, - cx.root_object(unsafe { GetRealmIteratorPrototype(cx.as_ptr()) }), + cx.root(unsafe { GetRealmIteratorPrototype(cx.as_ptr()) }), )) } diff --git a/ion/src/objects/key.rs b/ion/src/objects/key.rs index f91af2f7..9765beb2 100644 --- a/ion/src/objects/key.rs +++ b/ion/src/objects/key.rs @@ -22,7 +22,7 @@ pub struct PropertyKey { impl PropertyKey { /// Creates a [PropertyKey] from an integer. pub fn with_int(cx: &Context, int: i32) -> PropertyKey { - PropertyKey::from(cx.root_property_key(IntId(int))) + PropertyKey::from(cx.root(IntId(int))) } /// Creates a [PropertyKey] from a string. @@ -54,9 +54,9 @@ impl PropertyKey { if self.handle().is_int() { OwnedKey::Int(self.handle().to_int()) } else if self.handle().is_string() { - OwnedKey::String(String::from(cx.root_string(self.handle().to_string())).to_owned(cx)) + OwnedKey::String(String::from(cx.root(self.handle().to_string())).to_owned(cx)) } else if self.handle().is_symbol() { - OwnedKey::Symbol(cx.root_symbol(self.handle().to_symbol()).into()) + OwnedKey::Symbol(cx.root(self.handle().to_symbol()).into()) } else { OwnedKey::Void } @@ -101,7 +101,7 @@ impl OwnedKey { match self { OwnedKey::Int(i) => OwnedKey::Int(*i), OwnedKey::String(str) => OwnedKey::String(str.clone()), - OwnedKey::Symbol(symbol) => OwnedKey::Symbol(cx.root_symbol(symbol.get()).into()), + OwnedKey::Symbol(symbol) => OwnedKey::Symbol(cx.root(symbol.get()).into()), OwnedKey::Void => OwnedKey::Void, } } diff --git a/ion/src/objects/mod.rs b/ion/src/objects/mod.rs index 2434c560..f76f7b88 100644 --- a/ion/src/objects/mod.rs +++ b/ion/src/objects/mod.rs @@ -51,7 +51,7 @@ pub fn new_global>, R: Into Object { diff --git a/ion/src/objects/object.rs b/ion/src/objects/object.rs index 2c36797d..1116a032 100644 --- a/ion/src/objects/object.rs +++ b/ion/src/objects/object.rs @@ -36,19 +36,19 @@ pub struct Object { impl Object { /// Creates a plain empty [Object]. pub fn new(cx: &Context) -> Object { - Object::from(cx.root_object(unsafe { JS_NewPlainObject(cx.as_ptr()) })) + Object::from(cx.root(unsafe { JS_NewPlainObject(cx.as_ptr()) })) } /// Creates a `null` "Object". /// /// Most operations on this will result in an error, so be wary of where it is used. pub fn null(cx: &Context) -> Object { - Object::from(cx.root_object(NullValue().to_object_or_null())) + Object::from(cx.root(NullValue().to_object_or_null())) } /// Returns the current global object or `null` if one has not been initialised yet. pub fn global(cx: &Context) -> Object { - Object::from(cx.root_object(unsafe { CurrentGlobalOrNull(cx.as_ptr()) })) + Object::from(cx.root(unsafe { CurrentGlobalOrNull(cx.as_ptr()) })) } /// Checks if the [Object] has a value at the given key. @@ -178,7 +178,7 @@ impl Object { &mut self, cx: &Context, key: K, method: NativeFunction, nargs: u32, attrs: PropertyFlags, ) -> Function { let key = key.to_key(cx).unwrap(); - cx.root_function(unsafe { + cx.root(unsafe { JS_DefineFunctionById( cx.as_ptr(), self.handle().into(), @@ -343,7 +343,7 @@ impl Iterator for ObjectKeysIter<'_> { if self.index < self.count { let key = &self.slice[self.index]; self.index += 1; - Some(self.cx.root_property_key(*key).into()) + Some(self.cx.root(*key).into()) } else { None } @@ -359,7 +359,7 @@ impl DoubleEndedIterator for ObjectKeysIter<'_> { if self.index < self.count { self.count -= 1; let key = &self.keys[self.count]; - Some(self.cx.root_property_key(*key).into()) + Some(self.cx.root(*key).into()) } else { None } diff --git a/ion/src/objects/promise.rs b/ion/src/objects/promise.rs index 571a1345..ee044a6b 100644 --- a/ion/src/objects/promise.rs +++ b/ion/src/objects/promise.rs @@ -36,7 +36,7 @@ impl Promise { /// Creates a new [Promise] which never resolves. pub fn new(cx: &Context) -> Promise { Promise { - promise: cx.root_object(unsafe { NewPromiseObject(cx.as_ptr(), HandleObject::null().into()) }), + promise: cx.root(unsafe { NewPromiseObject(cx.as_ptr(), HandleObject::null().into()) }), } } @@ -73,7 +73,7 @@ impl Promise { let promise = NewPromiseObject(cx.as_ptr(), executor.handle().into()); if !promise.is_null() { - Some(Promise { promise: cx.root_object(promise) }) + Some(Promise { promise: cx.root(promise) }) } else { None } diff --git a/ion/src/objects/regexp.rs b/ion/src/objects/regexp.rs index 39f7a245..8381cd80 100644 --- a/ion/src/objects/regexp.rs +++ b/ion/src/objects/regexp.rs @@ -29,7 +29,7 @@ impl RegExp { pub fn new(cx: &Context, source: &str, flags: RegExpFlags) -> Option { let source: Vec = source.encode_utf16().collect(); let regexp = unsafe { NewUCRegExpObject(cx.as_ptr(), source.as_ptr(), source.len(), flags.into()) }; - NonNull::new(regexp).map(|re| RegExp { re: cx.root_object(re.as_ptr()) }) + NonNull::new(regexp).map(|re| RegExp { re: cx.root(re.as_ptr()) }) } /// Creates a [RegExp] from an object. @@ -51,7 +51,7 @@ impl RegExp { } pub fn source(&self, cx: &Context) -> crate::String { - crate::String::from(cx.root_string(unsafe { GetRegExpSource(cx.as_ptr(), self.handle().into()) })) + crate::String::from(cx.root(unsafe { GetRegExpSource(cx.as_ptr(), self.handle().into()) })) } pub fn flags(&self, cx: &Context) -> RegExpFlags { diff --git a/ion/src/objects/typedarray/buffer.rs b/ion/src/objects/typedarray/buffer.rs index 72d7c673..f9fc6307 100644 --- a/ion/src/objects/typedarray/buffer.rs +++ b/ion/src/objects/typedarray/buffer.rs @@ -64,7 +64,7 @@ impl ArrayBuffer { if buffer.is_null() { None } else { - Some(ArrayBuffer { buffer: cx.root_object(buffer) }) + Some(ArrayBuffer { buffer: cx.root(buffer) }) } } @@ -113,7 +113,7 @@ impl ArrayBuffer { if buffer.is_null() { None } else { - Some(ArrayBuffer { buffer: cx.root_object(buffer) }) + Some(ArrayBuffer { buffer: cx.root(buffer) }) } } @@ -144,7 +144,7 @@ impl ArrayBuffer { if data.is_null() { return Err(Error::new("ArrayBuffer transfer failed", ErrorKind::Normal)); } - let buffer = cx.root_object(unsafe { NewArrayBufferWithContents(cx.as_ptr(), len, data) }); + let buffer = cx.root(unsafe { NewArrayBufferWithContents(cx.as_ptr(), len, data) }); if buffer.handle().is_null() { return Err(Error::new("ArrayBuffer transfer failed", ErrorKind::Normal)); } diff --git a/ion/src/root.rs b/ion/src/root.rs index e72d9f3c..8035fd02 100644 --- a/ion/src/root.rs +++ b/ion/src/root.rs @@ -7,41 +7,46 @@ use std::cell::UnsafeCell; use std::fmt; use std::fmt::{Debug, Formatter}; -use std::ptr::NonNull; -use mozjs::gc::GCMethods; +use mozjs::gc::{GCMethods, Traceable}; use mozjs::jsapi::Heap; use mozjs::rust::Handle; use crate::context::{RootCollection, StableTraceable}; -pub struct Root { +pub struct Root +where + Heap: Traceable, +{ value: T, - roots: NonNull, + roots: *const RootCollection, } -impl Root { - pub(crate) unsafe fn new(value: T, roots: NonNull) -> Root { +impl Root +where + Heap: Traceable, +{ + pub(crate) unsafe fn new(value: T, roots: *const RootCollection) -> Root { Root { value, roots } } pub fn handle(&self) -> Handle { - unsafe { Handle::from_marked_location(self.value.traced()) } + unsafe { Handle::from_raw(self.value.heap().handle()) } } } impl Root where - T::Traced: Copy, + Heap: Traceable, { pub fn get(&self) -> T::Traced { self.handle().get() } } -impl Clone for Root>> +impl Clone for Root>> where - Box>: StableTraceable, + Heap: Traceable, { fn clone(&self) -> Root>> { let heap = Box::new(Heap { @@ -49,7 +54,7 @@ where }); heap.set(self.get()); unsafe { - (*self.roots.as_ptr()).root(heap.traceable()); + (*self.roots).root(heap.heap()); Root::new(heap, self.roots) } } @@ -60,16 +65,25 @@ where } } -impl Debug for Root { +impl Debug for Root +where + T::Traced: Debug, + Heap: Traceable, +{ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_struct("Root").field("value", &self.value).finish() + f.debug_struct("Root").field("value", unsafe { &*self.value.heap().get_unsafe() }).finish() } } -impl Drop for Root { +impl Drop for Root +where + Heap: Traceable, +{ fn drop(&mut self) { - unsafe { - (*self.roots.as_ptr()).unroot(self.value.traceable()); + if !self.roots.is_null() { + unsafe { + (*self.roots).unroot(self.value.heap()); + } } } } diff --git a/ion/src/script.rs b/ion/src/script.rs index 0ac37557..313561fd 100644 --- a/ion/src/script.rs +++ b/ion/src/script.rs @@ -28,7 +28,7 @@ impl Script { let script = unsafe { Compile(cx.as_ptr(), options.ptr, &mut source) }; if !script.is_null() { - Ok(Script { script: cx.root_script(script) }) + Ok(Script { script: cx.root(script) }) } else { Err(ErrorReport::new_with_exception_stack(cx).unwrap()) } diff --git a/ion/src/string/mod.rs b/ion/src/string/mod.rs index b0d2b59e..dbb6a612 100644 --- a/ion/src/string/mod.rs +++ b/ion/src/string/mod.rs @@ -67,7 +67,7 @@ pub struct String { impl String { /// Creates an empty [String]. pub fn new(cx: &Context) -> String { - String::from(cx.root_string(unsafe { JS_GetEmptyString(cx.as_ptr()) })) + String::from(cx.root(unsafe { JS_GetEmptyString(cx.as_ptr()) })) } /// Creates a new [String] with a given string, by copying it to the JS Runtime. @@ -77,7 +77,7 @@ impl String { if jsstr.is_null() { None } else { - Some(String::from(cx.root_string(jsstr))) + Some(String::from(cx.root(jsstr))) } } @@ -112,7 +112,7 @@ impl String { let vec = Vec::from(boxed); Err(WString::from_utf16_unchecked(vec)) } else { - Ok(String::from(cx.root_string(jsstr))) + Ok(String::from(cx.root(jsstr))) } } } @@ -120,15 +120,13 @@ impl String { /// Returns a slice of a [String] as a new [String]. pub fn slice(&self, cx: &Context, range: Range) -> String { let Range { start, end } = range; - String::from(cx.root_string(unsafe { JS_NewDependentString(cx.as_ptr(), self.handle().into(), start, end) })) + String::from(cx.root(unsafe { JS_NewDependentString(cx.as_ptr(), self.handle().into(), start, end) })) } /// Concatenates two [String]s into a new [String]. /// The resultant [String] is not linear. pub fn concat(&self, cx: &Context, other: &String) -> String { - String::from( - cx.root_string(unsafe { JS_ConcatStrings(cx.as_ptr(), self.handle().into(), other.handle().into()) }), - ) + String::from(cx.root(unsafe { JS_ConcatStrings(cx.as_ptr(), self.handle().into(), other.handle().into()) })) } /// Compares two [String]s. diff --git a/ion/src/symbol.rs b/ion/src/symbol.rs index c4e496c9..4743ae82 100644 --- a/ion/src/symbol.rs +++ b/ion/src/symbol.rs @@ -134,7 +134,7 @@ impl Symbol { rooted!(in(cx.as_ptr()) let description = description.handle().to_string()); let symbol = unsafe { NewSymbol(cx.as_ptr(), description.handle().into()) }; - Symbol { sym: cx.root_symbol(symbol) } + Symbol { sym: cx.root(symbol) } } /// Gets a [Symbol] from the symbol registry with the given key. @@ -143,13 +143,13 @@ impl Symbol { rooted!(in(cx.as_ptr()) let key = key.handle().to_string()); let symbol = unsafe { GetSymbolFor(cx.as_ptr(), key.handle().into()) }; - Symbol { sym: cx.root_symbol(symbol) } + Symbol { sym: cx.root(symbol) } } /// Creates a well-known symbol with its corresponding code. pub fn well_known(cx: &Context, code: WellKnownSymbolCode) -> Symbol { let symbol = unsafe { GetWellKnownSymbol(cx.as_ptr(), code.into()) }; - Symbol { sym: cx.root_symbol(symbol) } + Symbol { sym: cx.root(symbol) } } /// Returns the identifying code of a [Symbol]. diff --git a/ion/src/value.rs b/ion/src/value.rs index 5b82eb15..d25aa829 100644 --- a/ion/src/value.rs +++ b/ion/src/value.rs @@ -26,22 +26,22 @@ pub struct Value { impl Value { /// Creates a [Value] from a boolean. pub fn bool(cx: &Context, b: bool) -> Value { - Value::from(cx.root_value(BooleanValue(b))) + Value::from(cx.root(BooleanValue(b))) } /// Creates a [Value] from a 32-bit signed integer. pub fn i32(cx: &Context, i: i32) -> Value { - Value::from(cx.root_value(Int32Value(i))) + Value::from(cx.root(Int32Value(i))) } /// Creates a [Value] from a 32-bit unsigned integer. pub fn u32(cx: &Context, u: u32) -> Value { - Value::from(cx.root_value(UInt32Value(u))) + Value::from(cx.root(UInt32Value(u))) } /// Creates a [Value] from a 64-bit float. pub fn f64(cx: &Context, f: f64) -> Value { - Value::from(cx.root_value(DoubleValue(f))) + Value::from(cx.root(DoubleValue(f))) } /// Creates a [Value] from a string. @@ -51,32 +51,32 @@ impl Value { /// Creates a [Value] from a [BigInt]. pub fn bigint(cx: &Context, bi: &BigInt) -> Value { - Value::from(cx.root_value(BigIntValue(unsafe { &*bi.get() }))) + Value::from(cx.root(BigIntValue(unsafe { &*bi.get() }))) } /// Creates a [Value] from a [Symbol]. pub fn symbol(cx: &Context, sym: &Symbol) -> Value { - Value::from(cx.root_value(SymbolValue(unsafe { &*sym.get() }))) + Value::from(cx.root(SymbolValue(unsafe { &*sym.get() }))) } /// Creates a [Value] from an [Object]. pub fn object(cx: &Context, object: &Object) -> Value { - Value::from(cx.root_value(ObjectValue(object.handle().get()))) + Value::from(cx.root(ObjectValue(object.handle().get()))) } /// Creates a [Value] from an [Array]. pub fn array(cx: &Context, array: &Array) -> Value { - Value::from(cx.root_value(ObjectValue(array.handle().get()))) + Value::from(cx.root(ObjectValue(array.handle().get()))) } /// Creates an `undefined` [Value]. pub fn undefined(cx: &Context) -> Value { - Value::from(cx.root_value(UndefinedValue())) + Value::from(cx.root(UndefinedValue())) } /// Creates a `null` [Value]. pub fn null(cx: &Context) -> Value { - Value::from(cx.root_value(NullValue())) + Value::from(cx.root(NullValue())) } /// Converts a [Value] to an [Object]. @@ -84,7 +84,7 @@ impl Value { /// ### Panics /// This panics if the [Value] is not an object. pub fn to_object(&self, cx: &Context) -> Object { - cx.root_object(self.handle().to_object()).into() + cx.root(self.handle().to_object()).into() } /// Compares two values for equality using the [SameValue algorithm](https://tc39.es/ecma262/multipage/abstract-operations.html#sec-samevalue). @@ -95,7 +95,7 @@ impl Value { } pub fn to_source(&self, cx: &Context) -> crate::String { - crate::String::from(cx.root_string(unsafe { JS_ValueToSource(cx.as_ptr(), self.handle().into()) })) + crate::String::from(cx.root(unsafe { JS_ValueToSource(cx.as_ptr(), self.handle().into()) })) } } diff --git a/runtime/src/event_loop/future.rs b/runtime/src/event_loop/future.rs index a7877d23..68462774 100644 --- a/runtime/src/event_loop/future.rs +++ b/runtime/src/event_loop/future.rs @@ -37,7 +37,7 @@ impl FutureQueue { } for (result, promise) in results { - let promise = Promise::from(cx.root_object(promise)).unwrap(); + let promise = Promise::from(cx.root(promise)).unwrap(); let result = match result { Ok(o) => match o.into_value(cx) { diff --git a/runtime/src/event_loop/macrotasks.rs b/runtime/src/event_loop/macrotasks.rs index 5a4f7a3a..7b8dcffa 100644 --- a/runtime/src/event_loop/macrotasks.rs +++ b/runtime/src/event_loop/macrotasks.rs @@ -113,8 +113,8 @@ impl Macrotask { _ => unreachable!(), }; - let callback = Function::from(cx.root_function(callback)); - let args: Vec<_> = args.into_iter().map(|value| Value::from(cx.root_value(value))).collect(); + let callback = Function::from(cx.root(callback)); + let args: Vec<_> = args.into_iter().map(|value| Value::from(cx.root(value))).collect(); callback.call(cx, &Object::global(cx), args.as_slice()).map(|_| (Some(self))) } diff --git a/runtime/src/event_loop/microtasks.rs b/runtime/src/event_loop/microtasks.rs index c813ab90..3038645d 100644 --- a/runtime/src/event_loop/microtasks.rs +++ b/runtime/src/event_loop/microtasks.rs @@ -31,13 +31,13 @@ impl Microtask { pub fn run(&self, cx: &Context) -> Result<(), Option> { match self { Microtask::Promise(job) => { - let object = cx.root_object(*job); + let object = cx.root(*job); let function = Function::from_object(cx, &object).unwrap(); function.call(cx, &Object::null(cx), &[]).map(|_| ()) } Microtask::User(callback) => { - let callback = Function::from(cx.root_function(*callback)); + let callback = Function::from(cx.root(*callback)); callback.call(cx, &Object::global(cx), &[]).map(|_| ()) } Microtask::None => Ok(()), diff --git a/runtime/src/globals/fetch/mod.rs b/runtime/src/globals/fetch/mod.rs index a4a63714..4e0990c4 100644 --- a/runtime/src/globals/fetch/mod.rs +++ b/runtime/src/globals/fetch/mod.rs @@ -67,7 +67,7 @@ fn fetch(cx: &Context, resource: RequestInfo, init: Option) -> Opti let signal = AbortSignal::get_private(&request.signal); if let Some(reason) = signal.get_reason() { - promise.reject(cx, &cx.root_value(reason).into()); + promise.reject(cx, &cx.root(reason).into()); return Some(promise); } diff --git a/runtime/src/globals/fetch/response/options.rs b/runtime/src/globals/fetch/response/options.rs index acae0968..f730d975 100644 --- a/runtime/src/globals/fetch/response/options.rs +++ b/runtime/src/globals/fetch/response/options.rs @@ -20,7 +20,7 @@ pub struct ResponseInit { #[ion(default)] pub(crate) headers: HeadersInit, - #[ion(default, parser = |s| parse_status(cx, s))] + #[ion(default, parser = | s | parse_status(cx, s))] pub(crate) status: StatusCode, #[ion(default)] pub(crate) status_text: Option, diff --git a/runtime/src/runtime.rs b/runtime/src/runtime.rs index 428e8923..ac45295b 100644 --- a/runtime/src/runtime.rs +++ b/runtime/src/runtime.rs @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use std::mem::ManuallyDrop; use std::ptr; use std::ptr::NonNull; @@ -37,7 +38,7 @@ impl ContextExt for Context { } pub struct Runtime<'cx> { - global: Option, + global: ManuallyDrop, cx: &'cx Context, #[allow(dead_code)] realm: JSAutoRealm, @@ -49,11 +50,11 @@ impl<'cx> Runtime<'cx> { } pub fn global(&self) -> &Object { - self.global.as_ref().unwrap() + &self.global } pub fn global_mut(&mut self) -> &mut Object { - self.global.as_mut().unwrap() + &mut self.global } pub async fn run_event_loop(&self) -> Result<(), Option> { @@ -64,7 +65,9 @@ impl<'cx> Runtime<'cx> { impl Drop for Runtime<'_> { fn drop(&mut self) { - let _ = self.global.take(); + unsafe { + ManuallyDrop::drop(&mut self.global); + } let private = self.cx.get_private(); let _ = unsafe { Box::from_raw(private.as_ptr()) }; let inner_private = self.cx.get_inner_data(); @@ -106,7 +109,7 @@ impl RuntimeBuilder< } pub fn build(self, cx: &mut Context) -> Runtime { - let mut global = default_new_global(cx); + let mut global = ManuallyDrop::new(default_new_global(cx)); let realm = JSAutoRealm::new(cx.as_ptr(), global.handle().get()); let global_obj = global.handle().get(); @@ -157,7 +160,7 @@ impl RuntimeBuilder< } } - Runtime { global: Some(global), cx, realm } + Runtime { global, cx, realm } } }