mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Use a stack guard and a macro for RootedVec instead of return_address.
This commit is contained in:
parent
0db1faf876
commit
b79a7d468e
8 changed files with 77 additions and 71 deletions
|
@ -1166,23 +1166,22 @@ class CGArgumentConverter(CGThing):
|
|||
template, variadicConversion, declType, "slot")]
|
||||
|
||||
arg = "arg%d" % index
|
||||
|
||||
if argument.type.isGeckoInterface():
|
||||
vec = "RootedVec::new()"
|
||||
init = "rooted_vec!(let mut %s)" % arg
|
||||
innerConverter.append(CGGeneric("%s.push(JS::from_ref(&*slot));" % arg))
|
||||
else:
|
||||
vec = "vec![]"
|
||||
init = "let mut %s = vec![]" % arg
|
||||
innerConverter.append(CGGeneric("%s.push(slot);" % arg))
|
||||
inner = CGIndenter(CGList(innerConverter, "\n"), 8).define()
|
||||
|
||||
self.converter = CGGeneric("""\
|
||||
let mut %(arg)s = %(vec)s;
|
||||
%(init)s;
|
||||
if %(argc)s > %(index)s {
|
||||
%(arg)s.reserve(%(argc)s as usize - %(index)s);
|
||||
for variadicArg in %(index)s..%(argc)s {
|
||||
%(inner)s
|
||||
}
|
||||
}""" % {'arg': arg, 'argc': argc, 'index': index, 'inner': inner, 'vec': vec})
|
||||
}""" % {'arg': arg, 'argc': argc, 'index': index, 'inner': inner, 'init': init})
|
||||
|
||||
def define(self):
|
||||
return self.converter.define()
|
||||
|
@ -5603,7 +5602,6 @@ class CGBindingRoot(CGThing):
|
|||
'dom::bindings::proxyhandler::{get_expando_object, get_property_descriptor}',
|
||||
'dom::bindings::num::Finite',
|
||||
'dom::bindings::str::{ByteString, DOMString, USVString}',
|
||||
'dom::bindings::trace::RootedVec',
|
||||
'dom::bindings::weakref::{DOM_WEAK_SLOT, WeakBox, WeakReferenceable}',
|
||||
'dom::browsingcontext::BrowsingContext',
|
||||
'mem::heap_size_of_raw_self_and_children',
|
||||
|
|
|
@ -77,8 +77,6 @@ use std::boxed::FnBox;
|
|||
use std::cell::{Cell, UnsafeCell};
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use std::hash::{BuildHasher, Hash};
|
||||
use std::intrinsics::return_address;
|
||||
use std::iter::{FromIterator, IntoIterator};
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::rc::Rc;
|
||||
|
@ -466,7 +464,7 @@ impl RootedTraceableSet {
|
|||
///
|
||||
/// If you have a valid Reflectable, use Root.
|
||||
/// If you have GC things like *mut JSObject or JSVal, use rooted!.
|
||||
/// If you have an arbitrary number of Reflectables to root, use RootedVec<JS<T>>
|
||||
/// If you have an arbitrary number of Reflectables to root, use rooted_vec!.
|
||||
/// If you know what you're doing, use this.
|
||||
#[derive(JSTraceable)]
|
||||
pub struct RootedTraceable<'a, T: 'a + JSTraceable> {
|
||||
|
@ -493,73 +491,73 @@ impl<'a, T: JSTraceable> Drop for RootedTraceable<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A vector of items that are rooted for the lifetime of this struct.
|
||||
/// A vector of items to be rooted with `RootedVec`.
|
||||
/// Guaranteed to be empty when not rooted.
|
||||
/// Usage: `rooted_vec!(let mut v);` or if you have an
|
||||
/// iterator of `Root`s, `rooted_vec!(let v <- iterator);`.
|
||||
#[allow(unrooted_must_root)]
|
||||
#[no_move]
|
||||
#[derive(JSTraceable)]
|
||||
#[allow_unrooted_interior]
|
||||
pub struct RootedVec<T: JSTraceable> {
|
||||
pub struct RootableVec<T: JSTraceable> {
|
||||
v: Vec<T>,
|
||||
}
|
||||
|
||||
|
||||
impl<T: JSTraceable> RootedVec<T> {
|
||||
/// Create a vector of items of type T that is rooted for
|
||||
/// the lifetime of this struct
|
||||
pub fn new() -> RootedVec<T> {
|
||||
let addr = unsafe { return_address() as *const libc::c_void };
|
||||
|
||||
unsafe { RootedVec::new_with_destination_address(addr) }
|
||||
}
|
||||
|
||||
/// Create a vector of items of type T. This constructor is specific
|
||||
/// for RootTraceableSet.
|
||||
pub unsafe fn new_with_destination_address(addr: *const libc::c_void) -> RootedVec<T> {
|
||||
RootedTraceableSet::add::<RootedVec<T>>(&*(addr as *const _));
|
||||
RootedVec::<T> {
|
||||
impl<T: JSTraceable> RootableVec<T> {
|
||||
/// Create a vector of items of type T that can be rooted later.
|
||||
pub fn new_unrooted() -> RootableVec<T> {
|
||||
RootableVec {
|
||||
v: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: JSTraceable + Reflectable> RootedVec<JS<T>> {
|
||||
/// Obtain a safe slice of references that can't outlive that RootedVec.
|
||||
pub fn r(&self) -> &[&T] {
|
||||
unsafe { mem::transmute(&self.v[..]) }
|
||||
}
|
||||
/// A vector of items that are rooted for the lifetime 'a.
|
||||
#[allow_unrooted_interior]
|
||||
pub struct RootedVec<'a, T: 'a + JSTraceable> {
|
||||
root: &'a mut RootableVec<T>,
|
||||
}
|
||||
|
||||
impl<T: JSTraceable> Drop for RootedVec<T> {
|
||||
fn drop(&mut self) {
|
||||
impl<'a, T: JSTraceable + Reflectable> RootedVec<'a, JS<T>> {
|
||||
/// Create a vector of items of type T that is rooted for
|
||||
/// the lifetime of this struct
|
||||
pub fn new<I: Iterator<Item = Root<T>>>(root: &'a mut RootableVec<JS<T>>, iter: I)
|
||||
-> RootedVec<'a, JS<T>> {
|
||||
unsafe {
|
||||
RootedTraceableSet::remove(self);
|
||||
RootedTraceableSet::add(root);
|
||||
}
|
||||
root.v.extend(iter.map(|item| JS::from_ref(&*item)));
|
||||
RootedVec {
|
||||
root: root,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: JSTraceable> Deref for RootedVec<T> {
|
||||
impl<'a, T: JSTraceable + Reflectable> RootedVec<'a, JS<T>> {
|
||||
/// Obtain a safe slice of references that can't outlive that RootedVec.
|
||||
pub fn r(&self) -> &[&T] {
|
||||
unsafe { mem::transmute(&self[..]) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: JSTraceable> Drop for RootedVec<'a, T> {
|
||||
fn drop(&mut self) {
|
||||
self.clear();
|
||||
unsafe {
|
||||
RootedTraceableSet::remove(self.root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: JSTraceable> Deref for RootedVec<'a, T> {
|
||||
type Target = Vec<T>;
|
||||
fn deref(&self) -> &Vec<T> {
|
||||
&self.v
|
||||
&self.root.v
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: JSTraceable> DerefMut for RootedVec<T> {
|
||||
impl<'a, T: JSTraceable> DerefMut for RootedVec<'a, T> {
|
||||
fn deref_mut(&mut self) -> &mut Vec<T> {
|
||||
&mut self.v
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: JSTraceable + Reflectable> FromIterator<Root<A>> for RootedVec<JS<A>> {
|
||||
#[allow(moved_no_move)]
|
||||
fn from_iter<T>(iterable: T) -> RootedVec<JS<A>>
|
||||
where T: IntoIterator<Item = Root<A>>
|
||||
{
|
||||
let mut vec = unsafe {
|
||||
RootedVec::new_with_destination_address(return_address() as *const libc::c_void)
|
||||
};
|
||||
vec.extend(iterable.into_iter().map(|item| JS::from_ref(&*item)));
|
||||
vec
|
||||
&mut self.root.v
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue