diff options
author | Anthony Ramine <n.oxyde@gmail.com> | 2015-10-18 13:53:12 +0200 |
---|---|---|
committer | Anthony Ramine <n.oxyde@gmail.com> | 2015-11-12 12:51:50 +0100 |
commit | 72c67efe9631153a015af4a8d5b01bfbaa92068d (patch) | |
tree | cd62fff1fd2599616b9a9048153e9555039674e5 /components/script/dom/bindings/codegen | |
parent | 12f6ba29a74029fa8c83cc7274181d441e1e52dd (diff) | |
download | servo-72c67efe9631153a015af4a8d5b01bfbaa92068d.tar.gz servo-72c67efe9631153a015af4a8d5b01bfbaa92068d.zip |
Introduce trait WeakReferenceable
This allows to take weak references of JS-managed DOM objects.
Diffstat (limited to 'components/script/dom/bindings/codegen')
-rw-r--r-- | components/script/dom/bindings/codegen/Bindings.conf | 4 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 46 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/Configuration.py | 1 |
3 files changed, 47 insertions, 4 deletions
diff --git a/components/script/dom/bindings/codegen/Bindings.conf b/components/script/dom/bindings/codegen/Bindings.conf index 48b6067d00c..00ccea7fb63 100644 --- a/components/script/dom/bindings/codegen/Bindings.conf +++ b/components/script/dom/bindings/codegen/Bindings.conf @@ -21,4 +21,8 @@ DOMInterfaces = { #FIXME(jdm): This should be 'register': False, but then we don't generate enum types 'TestBinding': {}, +'URL': { + 'weakReferenceable': True, +} + } diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 260ef1e9006..d9894dad386 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -1765,12 +1765,16 @@ class CGDOMJSClass(CGThing): def define(self): traceHook = 'Some(%s)' % TRACE_HOOK_NAME if self.descriptor.isGlobal(): + assert not self.descriptor.weakReferenceable traceHook = "Some(js::jsapi::JS_GlobalObjectTraceHook)" flags = "JSCLASS_IS_GLOBAL | JSCLASS_DOM_GLOBAL" slots = "JSCLASS_GLOBAL_SLOT_COUNT + 1" else: flags = "0" - slots = "1" + if self.descriptor.weakReferenceable: + slots = "2" + else: + slots = "1" return """\ static Class: DOMJSClass = DOMJSClass { base: js::jsapi::Class { @@ -2175,6 +2179,9 @@ let obj = RootedObject::new(cx, obj);\ "\n" "JS_SetReservedSlot(obj.ptr, DOM_OBJECT_SLOT,\n" " PrivateValue(raw as *const libc::c_void));") + if descriptor.weakReferenceable: + create += """ +JS_SetReservedSlot(obj.ptr, DOM_WEAK_SLOT, PrivateValue(ptr::null()));""" return create @@ -4521,8 +4528,8 @@ class CGAbstractClassHook(CGAbstractExternMethod): args) def definition_body_prologue(self): - return CGGeneric("""\ -let this = private_from_object(obj) as *const %s; + return CGGeneric(""" +let this = native_from_object::<%s>(obj).unwrap(); """ % self.descriptor.concreteType) def definition_body(self): @@ -4541,6 +4548,24 @@ def finalizeHook(descriptor, hookName, context): release += """\ finalize_global(obj); """ + elif descriptor.weakReferenceable: + release += """\ +let weak_box_ptr = JS_GetReservedSlot(obj, DOM_WEAK_SLOT).to_private() as *mut WeakBox<%s>; +if !weak_box_ptr.is_null() { + let count = { + let weak_box = &*weak_box_ptr; + assert!(weak_box.value.get().is_some()); + assert!(weak_box.count.get() > 0); + weak_box.value.set(None); + let count = weak_box.count.get() - 1; + weak_box.count.set(count); + count + }; + if count == 0 { + mem::drop(Box::from_raw(weak_box_ptr)); + } +} +""" % descriptor.concreteType release += """\ let _ = Box::from_raw(this as *mut %s); debug!("%s finalize: {:p}", this);\ @@ -4718,6 +4743,16 @@ class CGInterfaceTrait(CGThing): return self.cgRoot.define() +class CGWeakReferenceableTrait(CGThing): + def __init__(self, descriptor): + CGThing.__init__(self) + assert descriptor.weakReferenceable + self.code = "impl WeakReferenceable for %s {}" % descriptor.interface.identifier.name + + def define(self): + return self.code + + class CGDescriptor(CGThing): def __init__(self, descriptor): CGThing.__init__(self) @@ -4826,6 +4861,8 @@ class CGDescriptor(CGThing): if not descriptor.interface.isCallback(): cgThings.append(CGIDLInterface(descriptor)) cgThings.append(CGInterfaceTrait(descriptor)) + if descriptor.weakReferenceable: + cgThings.append(CGWeakReferenceableTrait(descriptor)) cgThings = CGList(cgThings, "\n") # self.cgRoot = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name), @@ -5215,7 +5252,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::conversions::{ConversionBehavior, DOM_OBJECT_SLOT, IDLInterface}', 'dom::bindings::conversions::{FromJSValConvertible, StringificationBehavior}', 'dom::bindings::conversions::{ToJSValConvertible, jsid_to_str, native_from_handlevalue}', - 'dom::bindings::conversions::{private_from_object, root_from_object}', + 'dom::bindings::conversions::{native_from_object, private_from_object, root_from_object}', 'dom::bindings::conversions::{root_from_handleobject, root_from_handlevalue}', 'dom::bindings::codegen::{PrototypeList, RegisterBindings, UnionTypes}', 'dom::bindings::codegen::Bindings::*', @@ -5230,6 +5267,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::str::ByteString', 'dom::bindings::str::USVString', 'dom::bindings::trace::RootedVec', + 'dom::bindings::weakref::{DOM_WEAK_SLOT, WeakBox, WeakReferenceable}', 'mem::heap_size_of_raw_self_and_children', 'libc', 'util::str::DOMString', diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py index 715719aae60..4f59ff09f5b 100644 --- a/components/script/dom/bindings/codegen/Configuration.py +++ b/components/script/dom/bindings/codegen/Configuration.py @@ -168,6 +168,7 @@ class Descriptor(DescriptorProvider): self.register = desc.get('register', True) self.outerObjectHook = desc.get('outerObjectHook', 'None') self.proxy = False + self.weakReferenceable = desc.get('weakReferenceable', False) # If we're concrete, we need to crawl our ancestor interfaces and mark # them as having a concrete descendant. |