aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen
diff options
context:
space:
mode:
authorAnthony Ramine <n.oxyde@gmail.com>2015-10-18 13:53:12 +0200
committerAnthony Ramine <n.oxyde@gmail.com>2015-11-12 12:51:50 +0100
commit72c67efe9631153a015af4a8d5b01bfbaa92068d (patch)
treecd62fff1fd2599616b9a9048153e9555039674e5 /components/script/dom/bindings/codegen
parent12f6ba29a74029fa8c83cc7274181d441e1e52dd (diff)
downloadservo-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.conf4
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py46
-rw-r--r--components/script/dom/bindings/codegen/Configuration.py1
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.