Skip to content

Commit

Permalink
Add PermanentHeap, replace static TracedHeap with PermanentHeap
Browse files Browse the repository at this point in the history
  • Loading branch information
Arshia001 committed Feb 28, 2024
1 parent 5882c4a commit dc7409a
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 11 deletions.
2 changes: 1 addition & 1 deletion ion/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub use future::PromiseFuture;
#[cfg(feature = "macros")]
pub use ion_proc::*;
pub use object::*;
pub use root::{Local, Heap, TracedHeap, HeapPointer};
pub use root::{Local, Heap, PermanentHeap, TracedHeap, HeapPointer};
pub use stack::{Stack, StackRecord};
pub use string::{String, StringRef};
pub use symbol::Symbol;
Expand Down
76 changes: 73 additions & 3 deletions ion/src/root/heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,16 @@ where
}
}

impl<T> Clone for TracedHeap<T>
where
T: GCMethods + Copy + 'static,
JSHeap<T>: Traceable + Default,
{
fn clone(&self) -> Self {
Self::new(self.heap.get())
}
}

impl_heap_root! {
[TracedHeap]
(JSVal),
Expand All @@ -177,16 +187,66 @@ impl_heap_root! {
(*mut Symbol),
}

impl<T> Clone for TracedHeap<T>
/// Value stored on the heap and traced permanently. There is
/// no need to trace [PermanentHeap] instances, and thus there
/// is no [Traceable] implementation for this type. This can be
/// considered the rust parallel to PersistentRooted. This type
/// is mainly useful for use in thread statics, since dropping a
/// [TracedHeap] after [RootedTraceableSet] is dropped can cause
/// threads to panic.
#[derive(Debug)]
pub struct PermanentHeap<T>
where
T: GCMethods + Copy + 'static,
JSHeap<T>: Traceable,
{
heap: Box<JSHeap<T>>,
}

impl<T> PermanentHeap<T>
where
T: GCMethods + Copy + 'static,
JSHeap<T>: Traceable + Default,
{
fn clone(&self) -> Self {
Self::new(self.heap.get())
pub fn new(ptr: T) -> Self {
let heap = JSHeap::boxed(ptr);
unsafe { RootedTraceableSet::add(&*heap) };
Self { heap }
}

pub fn get(&self) -> T {
self.heap.get()
}
}

impl<T> PermanentHeap<T>
where
T: GCMethods + Copy + RootKind + 'static,
JSHeap<T>: Traceable + Default,
{
pub fn from_local(local: &Local<'_, T>) -> Self {
Self::new(local.get())
}

/// This constructs a Local from the Heap directly as opposed to rooting on the stack.
/// The returned Local cannot be used to construct a HandleMut.
pub fn to_local(&self) -> Local<'_, T> {
unsafe { Local::from_heap(&self.heap) }
}
}

impl_heap_root! {
[PermanentHeap]
(JSVal),
(*mut JSObject),
(*mut JSString),
(*mut JSScript),
(PropertyKey),
(*mut JSFunction),
(*mut BigInt),
(*mut Symbol),
}

pub trait HeapPointer<T> {
fn to_ptr(&self) -> T;
}
Expand All @@ -210,3 +270,13 @@ where
self.heap.get()
}
}

impl<T> HeapPointer<T> for PermanentHeap<T>
where
T: GCMethods + Copy + 'static,
JSHeap<T>: Traceable + Default,
{
fn to_ptr(&self) -> T {
self.heap.get()
}
}
2 changes: 1 addition & 1 deletion ion/src/root/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

pub use heap::{Heap, HeapPointer, TracedHeap};
pub use heap::{Heap, HeapPointer, PermanentHeap, TracedHeap};
pub use local::Local;

mod heap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use std::cell::RefCell;

use ion::{
conversions::ToValue, flags::PropertyFlags, function::Opt, js_fn, object::WritableStream, Context, Error,
ErrorKind, Function, Object, Promise, ReadableStream, Result, TracedHeap, Value,
ErrorKind, Function, Object, Promise, ReadableStream, Result, PermanentHeap, Value,
};
use mozjs::jsapi::JSFunction;

thread_local! {
static STREAM_PIPE_TO: RefCell<Option<TracedHeap<*mut JSFunction>>> = RefCell::new(None);
static STREAM_PIPE_TO: RefCell<Option<PermanentHeap<*mut JSFunction>>> = RefCell::new(None);
}

#[js_fn]
Expand Down Expand Up @@ -116,7 +116,7 @@ pub(super) fn define(cx: &Context, global: &Object) -> bool {
return false;
};

STREAM_PIPE_TO.with(move |l| l.replace(Some(TracedHeap::from_local(&pipe_to_fn))));
STREAM_PIPE_TO.with(move |l| l.replace(Some(PermanentHeap::from_local(&pipe_to_fn))));

readable_stream_prototype.define_method(cx, "pipeThrough", pipe_through, 1, PropertyFlags::ENUMERATE);

Expand Down
7 changes: 4 additions & 3 deletions runtime/src/globals/streams/readable_stream_extensions/tee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use ion::{
conversions::{FromValue, ToValue},
flags::PropertyFlags,
typedarray::Uint8Array,
Array, Context, Error, ErrorKind, Exception, Function, Heap, Object, Promise, Result, TracedHeap, Value,
Array, Context, Error, ErrorKind, Exception, Function, Heap, Object, PermanentHeap, Promise, Result, TracedHeap,
Value,
};
use mozjs::{
jsapi::{IsReadableByteStreamController, JSFunction, JSObject, ReadableStreamGetController},
Expand All @@ -20,7 +21,7 @@ use crate::{
use super::readable_stream_from_callbacks;

thread_local! {
static STREAM_TEE: RefCell<Option<TracedHeap<*mut JSFunction>>> = RefCell::new(None);
static STREAM_TEE: RefCell<Option<PermanentHeap<*mut JSFunction>>> = RefCell::new(None);
}

pub(super) fn define(cx: &Context, global: &Object) -> bool {
Expand Down Expand Up @@ -53,7 +54,7 @@ pub(super) fn define(cx: &Context, global: &Object) -> bool {
return false;
};

STREAM_TEE.with(move |l| l.replace(Some(TracedHeap::from_local(&tee_fn))));
STREAM_TEE.with(move |l| l.replace(Some(PermanentHeap::from_local(&tee_fn))));

let new_tee_fn = readable_stream_prototype.define_method(cx, "tee", self::tee, 2, PropertyFlags::ENUMERATE);

Expand Down

0 comments on commit dc7409a

Please sign in to comment.