Introduce LayoutJS<T>

This commit is contained in:
Tetsuharu OHZEKI 2015-01-11 04:25:10 +09:00
parent 1d7b1e5c31
commit a5d7240534
2 changed files with 67 additions and 4 deletions

View file

@ -129,8 +129,25 @@ pub struct JS<T> {
ptr: NonZero<*const T>
}
impl<T> JS<T> {
/// Returns `LayoutJS<T>` containing the same pointer.
fn to_layout(self) -> LayoutJS<T> {
LayoutJS {
ptr: self.ptr.clone()
}
}
}
/// This is specialized `JS<T>` to use in under `layout` crate.
/// `Layout*Helpers` traits must be implemented on this.
pub struct LayoutJS<T> {
ptr: NonZero<*const T>
}
impl<T> Copy for JS<T> {}
impl<T> Copy for LayoutJS<T> {}
impl<T> PartialEq for JS<T> {
#[allow(unrooted_must_root)]
fn eq(&self, other: &JS<T>) -> bool {
@ -138,6 +155,13 @@ impl<T> PartialEq for JS<T> {
}
}
impl<T> PartialEq for LayoutJS<T> {
#[allow(unrooted_must_root)]
fn eq(&self, other: &LayoutJS<T>) -> bool {
self.ptr == other.ptr
}
}
impl <T> Clone for JS<T> {
#[inline]
fn clone(&self) -> JS<T> {
@ -147,6 +171,15 @@ impl <T> Clone for JS<T> {
}
}
impl <T> Clone for LayoutJS<T> {
#[inline]
fn clone(&self) -> LayoutJS<T> {
LayoutJS {
ptr: self.ptr.clone()
}
}
}
impl JS<Node> {
/// Create a new JS-owned value wrapped from an address known to be a `Node` pointer.
pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<Node> {
@ -198,6 +231,15 @@ impl<T: Reflectable> Reflectable for JS<T> {
}
}
// XXXjdm same above
impl<T: Reflectable> Reflectable for LayoutJS<T> {
fn reflector<'a>(&'a self) -> &'a Reflector {
unsafe {
(*self.unsafe_get()).reflector()
}
}
}
/// A trait to be implemented for JS-managed types that can be stored in
/// mutable member fields.
///
@ -296,6 +338,12 @@ impl<T: Reflectable> MutNullableJS<T> {
self.ptr.get()
}
/// Retrieve a copy of the inner optional `JS<T>` as `LayoutJS<T>`.
/// For use by layout, which can't use safe types like Temporary.
pub unsafe fn get_inner_as_layout(&self) -> Option<LayoutJS<T>> {
self.get_inner().map(|js| js.to_layout())
}
/// Retrieve a copy of the current inner value. If it is `None`, it is
/// initialized with the result of `cb` first.
pub fn or_init<F>(&self, cb: F) -> Temporary<T>
@ -313,9 +361,8 @@ impl<T: Reflectable> MutNullableJS<T> {
}
impl<T: Reflectable> JS<T> {
/// Returns an unsafe pointer to the interior of this object. This is the
/// only method that be safely accessed from layout. (The fact that this is
/// unsafe is what necessitates the layout wrappers.)
/// Returns an unsafe pointer to the interior of this object.
/// This should only be used by the DOM bindings.
pub unsafe fn unsafe_get(&self) -> *const T {
*self.ptr
}
@ -328,6 +375,15 @@ impl<T: Reflectable> JS<T> {
}
}
impl<T: Reflectable> LayoutJS<T> {
/// Returns an unsafe pointer to the interior of this JS object without touching the borrow
/// flags. This is the only method that be safely accessed from layout. (The fact that this
/// is unsafe is what necessitates the layout wrappers.)
pub unsafe fn unsafe_get(&self) -> *const T {
*self.ptr
}
}
impl<From> JS<From> {
/// Return `self` as a `JS` of another type.
//XXXjdm It would be lovely if this could be private.
@ -341,6 +397,12 @@ impl<From> JS<From> {
}
}
impl<From> LayoutJS<From> {
/// Return `self` as a `LayoutJS` of another type.
pub unsafe fn transmute_copy<To>(&self) -> LayoutJS<To> {
mem::transmute_copy(self)
}
}
/// Get an `Option<JSRef<T>>` out of an `Option<Root<T>>`
pub trait RootedReference<T> {