diff options
Diffstat (limited to 'src/components/script/dom/bindings')
-rw-r--r-- | src/components/script/dom/bindings/codegen/CodegenRust.py | 10 | ||||
-rw-r--r-- | src/components/script/dom/bindings/js.rs | 3 | ||||
-rw-r--r-- | src/components/script/dom/bindings/trace.rs | 69 | ||||
-rw-r--r-- | src/components/script/dom/bindings/utils.rs | 8 |
4 files changed, 80 insertions, 10 deletions
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 9470b61fab2..8d89fe1b879 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1864,7 +1864,7 @@ def CreateBindingJSObject(descriptor, parent=None): assert not descriptor.createGlobal handler = """ let js_info = aScope.get().page().js_info(); - let handler = js_info.get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint)); + let handler = js_info.get_ref().dom_static.proxy_handlers.deref().get(&(PrototypeList::id::%s as uint)); """ % descriptor.name create += handler + """ let obj = NewProxyObject(aCx, *handler, &PrivateValue(squirrel_away_unique(aObject) as *libc::c_void), @@ -2204,7 +2204,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): ('Some(%s)' % TRACE_HOOK_NAME), self.descriptor.name) - return (body + """ let cx = js_info.js_context.deref().ptr; + return (body + """ let cx = (*js_info.js_context).deref().ptr; let receiver = js_info.js_compartment.global_obj; let global: *JSObject = JS_GetGlobalForObject(cx, receiver); assert!(%s(cx, global, receiver).is_not_null());""" % (getter)) @@ -4517,7 +4517,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}', 'dom::bindings::utils::{VoidVal, with_gc_disabled}', 'dom::bindings::utils::{with_gc_enabled}', - 'dom::bindings::trace::Traceable', + 'dom::bindings::trace::JSTraceable', 'dom::bindings::callback::{CallbackContainer,CallbackInterface}', 'dom::bindings::callback::{CallSetup,ExceptionHandling}', 'dom::bindings::callback::{WrapCallThisObject}', @@ -5472,7 +5472,7 @@ class GlobalGenRoots(): allprotos = [CGGeneric("#[allow(unused_imports)];\n"), CGGeneric("use dom::types::*;\n"), CGGeneric("use dom::bindings::js::JS;\n"), - CGGeneric("use dom::bindings::trace::Traceable;\n"), + CGGeneric("use dom::bindings::trace::JSTraceable;\n"), CGGeneric("use serialize::{Encodable, Encoder};\n"), CGGeneric("use js::jsapi::JSTracer;\n\n")] for descriptor in descriptors: @@ -5523,7 +5523,7 @@ class GlobalGenRoots(): 'toBound': name + 'Derived'})), CGGeneric("impl %s for %s {}\n\n" % (name + 'Cast', name))] - trace = [CGGeneric(string.Template('''impl Traceable for ${name} { + trace = [CGGeneric(string.Template('''impl JSTraceable for ${name} { fn trace(&self, tracer: *mut JSTracer) { unsafe { self.encode(&mut *tracer); diff --git a/src/components/script/dom/bindings/js.rs b/src/components/script/dom/bindings/js.rs index 71ca2d7ac86..5d2640a2bdf 100644 --- a/src/components/script/dom/bindings/js.rs +++ b/src/components/script/dom/bindings/js.rs @@ -44,8 +44,9 @@ impl<T: Reflectable> JS<T> { pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<T> { + let TrustedNodeAddress(addr) = inner; JS { - ptr: RefCell::new(inner as *mut T) + ptr: RefCell::new(addr as *mut T) } } } diff --git a/src/components/script/dom/bindings/trace.rs b/src/components/script/dom/bindings/trace.rs index 1cedf246728..4e32bacec68 100644 --- a/src/components/script/dom/bindings/trace.rs +++ b/src/components/script/dom/bindings/trace.rs @@ -8,6 +8,7 @@ use dom::bindings::utils::{Reflectable, Reflector}; use js::jsapi::{JSTracer, JS_CallTracer, JSTRACE_OBJECT}; use std::cast; +use std::cell::RefCell; use std::libc; use std::ptr; use std::ptr::null; @@ -30,7 +31,7 @@ impl<S: Encoder> Encodable<S> for Reflector { } } -pub trait Traceable { +pub trait JSTraceable { fn trace(&self, trc: *mut JSTracer); } @@ -46,3 +47,69 @@ pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Ref }); } } + +/// Encapsulates a type that cannot easily have Encodable derived automagically, +/// but also does not need to be made known to the SpiderMonkey garbage collector. +/// Use only with types that are not associated with a JS reflector and do not contain +/// fields of types associated with JS reflectors. +pub struct Untraceable<T> { + priv inner: T, +} + +impl<T> Untraceable<T> { + pub fn new(val: T) -> Untraceable<T> { + Untraceable { + inner: val + } + } +} + +impl<S: Encoder, T> Encodable<S> for Untraceable<T> { + fn encode(&self, _s: &mut S) { + } +} + +impl<T> Deref<T> for Untraceable<T> { + fn deref<'a>(&'a self) -> &'a T { + &self.inner + } +} + +impl<T> DerefMut<T> for Untraceable<T> { + fn deref_mut<'a>(&'a mut self) -> &'a mut T { + &mut self.inner + } +} + +/// Encapsulates a type that can be traced but is boxed in a type we don't control +/// (such as RefCell). Wrap a field in Traceable and implement the Encodable trait +/// for that new concrete type to achieve magic compiler-derived trace hooks. +pub struct Traceable<T> { + priv inner: T +} + +impl<T> Traceable<T> { + pub fn new(val: T) -> Traceable<T> { + Traceable { + inner: val + } + } +} + +impl<T> Deref<T> for Traceable<T> { + fn deref<'a>(&'a self) -> &'a T { + &self.inner + } +} + +impl<T> DerefMut<T> for Traceable<T> { + fn deref_mut<'a>(&'a mut self) -> &'a mut T { + &mut self.inner + } +} + +impl<S: Encoder, T: Encodable<S>> Encodable<S> for Traceable<RefCell<T>> { + fn encode(&self, s: &mut S) { + self.borrow().encode(s) + } +}
\ No newline at end of file diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index ec1472bac28..71c82ae86dc 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -6,6 +6,7 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH; use dom::bindings::conversions::FromJSValConvertible; use dom::bindings::js::JS; +use dom::bindings::trace::Untraceable; use dom::window; use servo_util::str::DOMString; @@ -42,13 +43,14 @@ use js::JSPROP_PERMANENT; use js::{JSFUN_CONSTRUCTOR, JSPROP_READONLY}; use js; +#[deriving(Encodable)] pub struct GlobalStaticData { - proxy_handlers: HashMap<uint, *libc::c_void> + proxy_handlers: Untraceable<HashMap<uint, *libc::c_void>> } pub fn GlobalStaticData() -> GlobalStaticData { GlobalStaticData { - proxy_handlers: HashMap::new() + proxy_handlers: Untraceable::new(HashMap::new()) } } @@ -533,7 +535,7 @@ fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext { let win = global_object_for_js_object(obj); let js_info = win.get().page().js_info(); match *js_info { - Some(ref info) => info.js_context.deref().ptr, + Some(ref info) => info.js_context.deref().deref().ptr, None => fail!("no JS context for DOM global") } } |