diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2015-11-13 06:22:40 +0530 |
---|---|---|
committer | bors-servo <lbergstrom+bors@mozilla.com> | 2015-11-13 06:22:40 +0530 |
commit | e63b1e83d4acd272cdf293292f2a496455405098 (patch) | |
tree | 2c2b65ed064f843aeee27b5f2b413e05e1905177 /components/script/dom/bindings/codegen | |
parent | 9eaa8e7b1f2e462f62b73477c30183c836a18399 (diff) | |
parent | 72c67efe9631153a015af4a8d5b01bfbaa92068d (diff) | |
download | servo-e63b1e83d4acd272cdf293292f2a496455405098.tar.gz servo-e63b1e83d4acd272cdf293292f2a496455405098.zip |
Auto merge of #8147 - nox:weakref, r=Ms2ger
Implement weak-referenceable JS-managed objects
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8147)
<!-- Reviewable:end -->
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 226587b5283..aef047285ed 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -1761,12 +1761,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 { @@ -2171,6 +2175,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 @@ -4517,8 +4524,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): @@ -4537,6 +4544,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);\ @@ -4714,6 +4739,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) @@ -4822,6 +4857,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), @@ -5212,7 +5249,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::*', @@ -5226,6 +5263,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. |