diff options
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r-- | components/script/dom/bindings/callback.rs | 7 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 8 | ||||
-rw-r--r-- | components/script/dom/bindings/global.rs | 1 | ||||
-rw-r--r-- | components/script/dom/bindings/js.rs | 39 | ||||
-rw-r--r-- | components/script/dom/bindings/refcounted.rs | 83 | ||||
-rw-r--r-- | components/script/dom/bindings/utils.rs | 32 |
6 files changed, 103 insertions, 67 deletions
diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs index ec6071e0700..29741117383 100644 --- a/components/script/dom/bindings/callback.rs +++ b/components/script/dom/bindings/callback.rs @@ -16,6 +16,7 @@ use js::jsval::{JSVal, UndefinedValue}; use std::ptr; /// The exception handling used for a call. +#[deriving(Copy)] pub enum ExceptionHandling { /// Report any exception and don't throw it to the caller code. ReportExceptions, @@ -28,7 +29,7 @@ pub enum ExceptionHandling { } /// A common base class for representing IDL callback function types. -#[deriving(Clone,PartialEq)] +#[deriving(Copy, Clone,PartialEq)] #[jstraceable] pub struct CallbackFunction { object: CallbackObject @@ -46,7 +47,7 @@ impl CallbackFunction { } /// A common base class for representing IDL callback interface types. -#[deriving(Clone,PartialEq)] +#[deriving(Copy, Clone,PartialEq)] #[jstraceable] pub struct CallbackInterface { object: CallbackObject @@ -55,7 +56,7 @@ pub struct CallbackInterface { /// A common base class for representing IDL callback function and /// callback interface types. #[allow(raw_pointer_deriving)] -#[deriving(Clone,PartialEq)] +#[deriving(Copy, Clone,PartialEq)] #[jstraceable] struct CallbackObject { /// The underlying `JSObject`. diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 6dab989a86f..a256432f762 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -2763,7 +2763,7 @@ class CGEnum(CGThing): decl = """\ #[repr(uint)] -#[deriving(PartialEq)] +#[deriving(PartialEq, Copy)] #[jstraceable] pub enum %s { %s @@ -4694,7 +4694,7 @@ class CGCallback(CGClass): bases=[ClassBase(baseName)], constructors=self.getConstructors(), methods=realMethods+getters+setters, - decorators="#[deriving(PartialEq,Clone)]#[jstraceable]") + decorators="#[deriving(PartialEq,Copy,Clone)]#[jstraceable]") def getConstructors(self): return [ClassConstructor( @@ -5190,8 +5190,8 @@ class GlobalGenRoots(): return CGList([ CGGeneric(AUTOGENERATED_WARNING_COMMENT), CGGeneric("pub const MAX_PROTO_CHAIN_LENGTH: uint = %d;\n\n" % config.maxProtoChainLength), - CGNonNamespacedEnum('ID', protos, [0], deriving="PartialEq"), - CGNonNamespacedEnum('Proxies', proxies, [0], deriving="PartialEq"), + CGNonNamespacedEnum('ID', protos, [0], deriving="PartialEq, Copy"), + CGNonNamespacedEnum('Proxies', proxies, [0], deriving="PartialEq, Copy"), ]) diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index 8079c796094..0b65fabfec0 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -26,6 +26,7 @@ use url::Url; use std::ptr; /// A freely-copyable reference to a rooted global object. +#[deriving(Copy)] pub enum GlobalRef<'a> { Window(JSRef<'a, window::Window>), Worker(JSRef<'a, WorkerGlobalScope>), diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index f7208237cc1..a0c099769f0 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -70,6 +70,15 @@ pub struct Temporary<T> { _js_ptr: *mut JSObject, } +impl<T> Clone for Temporary<T> { + fn clone(&self) -> Temporary<T> { + Temporary { + inner: self.inner, + _js_ptr: self._js_ptr, + } + } +} + impl<T> PartialEq for Temporary<T> { fn eq(&self, other: &Temporary<T>) -> bool { self.inner == other.inner @@ -92,10 +101,12 @@ impl<T: Reflectable> Temporary<T> { /// Create a stack-bounded root for this value. pub fn root(self) -> Root<T> { - let collection = StackRoots.get().unwrap(); - unsafe { - Root::new(&**collection, &self.inner) - } + StackRoots.with(|ref collection| { + let RootCollectionPtr(collection) = collection.get().unwrap(); + unsafe { + Root::new(&*collection, &self.inner) + } + }) } unsafe fn inner(&self) -> JS<T> { @@ -114,6 +125,8 @@ pub struct JS<T> { ptr: *const T } +impl<T> Copy for JS<T> {} + impl<T> PartialEq for JS<T> { #[allow(unrooted_must_root)] fn eq(&self, other: &JS<T>) -> bool { @@ -151,10 +164,12 @@ impl<T: Reflectable> JS<T> { /// Root this JS-owned value to prevent its collection as garbage. pub fn root(&self) -> Root<T> { - let collection = StackRoots.get().unwrap(); - unsafe { - Root::new(&**collection, self) - } + StackRoots.with(|ref collection| { + let RootCollectionPtr(collection) = collection.get().unwrap(); + unsafe { + Root::new(&*collection, self) + } + }) } } @@ -270,7 +285,7 @@ impl<T: Reflectable> MutNullableJS<T> { Some(inner) => inner, None => { let inner = cb(); - self.assign(Some(inner)); + self.assign(Some(inner.clone())); inner }, } @@ -450,6 +465,10 @@ pub struct RootCollection { roots: UnsafeCell<SmallVec16<*mut JSObject>>, } +pub struct RootCollectionPtr(pub *const RootCollection); + +impl Copy for RootCollectionPtr {} + impl RootCollection { /// Create an empty collection of roots pub fn new() -> RootCollection { @@ -548,6 +567,8 @@ pub struct JSRef<'a, T> { chain: ContravariantLifetime<'a>, } +impl<'a, T> Copy for JSRef<'a, T> {} + impl<'a, T> Clone for JSRef<'a, T> { fn clone(&self) -> JSRef<'a, T> { JSRef { diff --git a/components/script/dom/bindings/refcounted.rs b/components/script/dom/bindings/refcounted.rs index 7bffda2153d..1f6149394f2 100644 --- a/components/script/dom/bindings/refcounted.rs +++ b/components/script/dom/bindings/refcounted.rs @@ -33,9 +33,11 @@ use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot, JSContext}; use libc; use std::cell::RefCell; use std::collections::hash_map::{HashMap, Vacant, Occupied}; +use std::rc::Rc; use std::sync::{Arc, Mutex}; -local_data_key!(pub LiveReferences: LiveDOMReferences) +thread_local!(pub static LiveReferences: Rc<RefCell<Option<LiveDOMReferences>>> = Rc::new(RefCell::new(None))) + /// A safe wrapper around a raw pointer to a DOM object that can be /// shared among tasks for use in asynchronous operations. The underlying @@ -55,24 +57,28 @@ impl<T: Reflectable> Trusted<T> { /// be prevented from being GCed for the duration of the resulting `Trusted<T>` object's /// lifetime. pub fn new(cx: *mut JSContext, ptr: JSRef<T>, script_chan: Box<ScriptChan + Send>) -> Trusted<T> { - let live_references = LiveReferences.get().unwrap(); - let refcount = live_references.addref(cx, &*ptr as *const T); - Trusted { - ptr: &*ptr as *const T as *const libc::c_void, - refcount: refcount, - script_chan: script_chan, - owner_thread: (&*live_references) as *const _ as *const libc::c_void, - } + LiveReferences.with(|ref r| { + let r = r.borrow(); + let live_references = r.as_ref().unwrap(); + let refcount = live_references.addref(cx, &*ptr as *const T); + Trusted { + ptr: &*ptr as *const T as *const libc::c_void, + refcount: refcount, + script_chan: script_chan.clone(), + owner_thread: (&*live_references) as *const _ as *const libc::c_void, + } + }) } /// Obtain a usable DOM pointer from a pinned `Trusted<T>` value. Fails if used on /// a different thread than the original value from which this `Trusted<T>` was /// obtained. pub fn to_temporary(&self) -> Temporary<T> { - assert!({ - let live_references = LiveReferences.get().unwrap(); + assert!(LiveReferences.with(|ref r| { + let r = r.borrow(); + let live_references = r.as_ref().unwrap(); self.owner_thread == (&*live_references) as *const _ as *const libc::c_void - }); + })); unsafe { Temporary::new(JS::from_raw(self.ptr as *const T)) } @@ -117,9 +123,11 @@ pub struct LiveDOMReferences { impl LiveDOMReferences { /// Set up the task-local data required for storing the outstanding DOM references. pub fn initialize() { - LiveReferences.replace(Some(LiveDOMReferences { - table: RefCell::new(HashMap::new()), - })); + LiveReferences.with(|ref r| { + *r.borrow_mut() = Some(LiveDOMReferences { + table: RefCell::new(HashMap::new()), + }) + }); } fn addref<T: Reflectable>(&self, cx: *mut JSContext, ptr: *const T) -> Arc<Mutex<uint>> { @@ -144,30 +152,33 @@ impl LiveDOMReferences { /// Unpin the given DOM object if its refcount is 0. pub fn cleanup(cx: *mut JSContext, raw_reflectable: *const libc::c_void) { - let live_references = LiveReferences.get().unwrap(); - let reflectable = raw_reflectable as *const Reflector; - let mut table = live_references.table.borrow_mut(); - match table.entry(raw_reflectable) { - Occupied(entry) => { - if *entry.get().lock() != 0 { - // there could have been a new reference taken since - // this message was dispatched. - return; + LiveReferences.with(|ref r| { + let r = r.borrow(); + let live_references = r.as_ref().unwrap(); + let reflectable = raw_reflectable as *const Reflector; + let mut table = live_references.table.borrow_mut(); + match table.entry(raw_reflectable) { + Occupied(entry) => { + if *entry.get().lock() != 0 { + // there could have been a new reference taken since + // this message was dispatched. + return; + } + + unsafe { + JS_RemoveObjectRoot(cx, (*reflectable).rootable()); + } + let _ = entry.take(); } - - unsafe { - JS_RemoveObjectRoot(cx, (*reflectable).rootable()); + Vacant(_) => { + // there could be a cleanup message dispatched, then a new + // pinned reference obtained and released before the message + // is processed, at which point there would be no matching + // hashtable entry. + info!("attempt to cleanup an unrecognized reflector"); } - let _ = entry.take(); - } - Vacant(_) => { - // there could be a cleanup message dispatched, then a new - // pinned reference obtained and released before the message - // is processed, at which point there would be no matching - // hashtable entry. - info!("attempt to cleanup an unrecognized reflector"); } - } + }) } } diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 8119978cff9..13d662ae5f7 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -130,6 +130,7 @@ pub struct NativePropertyHooks { } /// The struct that holds inheritance information for DOM object reflectors. +#[deriving(Copy)] pub struct DOMClass { /// A list of interfaces that this object implements, in order of decreasing /// derivedness. @@ -140,6 +141,7 @@ pub struct DOMClass { } /// The JSClass used for DOM object reflectors. +#[deriving(Copy)] pub struct DOMJSClass { /// The actual JSClass. pub base: js::Class, @@ -609,18 +611,18 @@ pub fn xml_name_type(name: &str) -> XMLName { 'A' ... 'Z' | '_' | 'a' ... 'z' | - '\u00C0' ... '\u00D6' | - '\u00D8' ... '\u00F6' | - '\u00F8' ... '\u02FF' | - '\u0370' ... '\u037D' | - '\u037F' ... '\u1FFF' | - '\u200C' ... '\u200D' | - '\u2070' ... '\u218F' | - '\u2C00' ... '\u2FEF' | - '\u3001' ... '\uD7FF' | - '\uF900' ... '\uFDCF' | - '\uFDF0' ... '\uFFFD' | - '\U00010000' ... '\U000EFFFF' => true, + '\u{C0}' ... '\u{D6}' | + '\u{D8}' ... '\u{F6}' | + '\u{F8}' ... '\u{2FF}' | + '\u{370}' ... '\u{37D}' | + '\u{37F}' ... '\u{1FFF}' | + '\u{200C}' ... '\u{200D}' | + '\u{2070}' ... '\u{218F}' | + '\u{2C00}' ... '\u{2FEF}' | + '\u{3001}' ... '\u{D7FF}' | + '\u{F900}' ... '\u{FDCF}' | + '\u{FDF0}' ... '\u{FFFD}' | + '\u{10000}' ... '\u{EFFFF}' => true, _ => false, } } @@ -630,9 +632,9 @@ pub fn xml_name_type(name: &str) -> XMLName { '-' | '.' | '0' ... '9' | - '\u00B7' | - '\u0300' ... '\u036F' | - '\u203F' ... '\u2040' => true, + '\u{B7}' | + '\u{300}' ... '\u{36F}' | + '\u{203F}' ... '\u{2040}' => true, _ => false, } } |