mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Make dictionaries contain Root<T> values instead of JS<T>, ensuring that they will not be collected while the dictionary is alive.
This commit is contained in:
parent
0f2d0b1dc3
commit
895e9ee37f
5 changed files with 20 additions and 11 deletions
|
@ -602,6 +602,8 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
|
||||||
failureCode)
|
failureCode)
|
||||||
return handleOptional(template, declType, isOptional)
|
return handleOptional(template, declType, isOptional)
|
||||||
|
|
||||||
|
descriptorType = descriptor.memberType if isMember else descriptor.nativeType
|
||||||
|
|
||||||
templateBody = ""
|
templateBody = ""
|
||||||
if descriptor.interface.isConsequential():
|
if descriptor.interface.isConsequential():
|
||||||
raise TypeError("Consequential interface %s being used as an "
|
raise TypeError("Consequential interface %s being used as an "
|
||||||
|
@ -617,11 +619,14 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
|
||||||
descriptor,
|
descriptor,
|
||||||
"(${val}).to_object()"))
|
"(${val}).to_object()"))
|
||||||
|
|
||||||
declType = CGGeneric(descriptor.nativeType)
|
declType = CGGeneric(descriptorType)
|
||||||
if type.nullable():
|
if type.nullable():
|
||||||
templateBody = "Some(%s)" % templateBody
|
templateBody = "Some(%s)" % templateBody
|
||||||
declType = CGWrapper(declType, pre="Option<", post=">")
|
declType = CGWrapper(declType, pre="Option<", post=">")
|
||||||
|
|
||||||
|
if isMember:
|
||||||
|
templateBody += ".root()"
|
||||||
|
|
||||||
templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
|
templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
|
||||||
type, failureCode)
|
type, failureCode)
|
||||||
|
|
||||||
|
@ -4069,7 +4074,7 @@ class CGDictionary(CGThing):
|
||||||
def struct(self):
|
def struct(self):
|
||||||
d = self.dictionary
|
d = self.dictionary
|
||||||
if d.parent:
|
if d.parent:
|
||||||
inheritance = " pub parent: %s::%s,\n" % (self.makeModuleName(d.parent),
|
inheritance = " pub parent: %s::%s<'a, 'b>,\n" % (self.makeModuleName(d.parent),
|
||||||
self.makeClassName(d.parent))
|
self.makeClassName(d.parent))
|
||||||
else:
|
else:
|
||||||
inheritance = ""
|
inheritance = ""
|
||||||
|
@ -4078,7 +4083,7 @@ class CGDictionary(CGThing):
|
||||||
for m in self.memberInfo]
|
for m in self.memberInfo]
|
||||||
|
|
||||||
return (string.Template(
|
return (string.Template(
|
||||||
"pub struct ${selfName} {\n" +
|
"pub struct ${selfName}<'a, 'b> {\n" +
|
||||||
"${inheritance}" +
|
"${inheritance}" +
|
||||||
"\n".join(memberDecls) + "\n" +
|
"\n".join(memberDecls) + "\n" +
|
||||||
"}").substitute( { "selfName": self.makeClassName(d),
|
"}").substitute( { "selfName": self.makeClassName(d),
|
||||||
|
@ -4104,7 +4109,7 @@ class CGDictionary(CGThing):
|
||||||
memberInits = CGList([memberInit(m) for m in self.memberInfo])
|
memberInits = CGList([memberInit(m) for m in self.memberInfo])
|
||||||
|
|
||||||
return string.Template(
|
return string.Template(
|
||||||
"impl ${selfName} {\n"
|
"impl<'a, 'b> ${selfName}<'a, 'b> {\n"
|
||||||
" pub fn new(cx: *JSContext, val: JSVal) -> Result<${selfName}, ()> {\n"
|
" pub fn new(cx: *JSContext, val: JSVal) -> Result<${selfName}, ()> {\n"
|
||||||
" let object = if val.is_null_or_undefined() {\n"
|
" let object = if val.is_null_or_undefined() {\n"
|
||||||
" ptr::null()\n"
|
" ptr::null()\n"
|
||||||
|
@ -4305,7 +4310,7 @@ class CGBindingRoot(CGThing):
|
||||||
'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}',
|
'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}',
|
||||||
'dom::types::*',
|
'dom::types::*',
|
||||||
'dom::bindings',
|
'dom::bindings',
|
||||||
'dom::bindings::js::{JS, JSRef, RootedReference, Temporary, OptionalRootable, OptionalRootedRootable}',
|
'dom::bindings::js::{JS, JSRef, Root, RootedReference, Temporary, OptionalRootable, OptionalRootedRootable, ResultRootable}',
|
||||||
'dom::bindings::utils::{CreateDOMGlobal, CreateInterfaceObjects2}',
|
'dom::bindings::utils::{CreateDOMGlobal, CreateInterfaceObjects2}',
|
||||||
'dom::bindings::utils::{ConstantSpec, cx_for_dom_object, Default}',
|
'dom::bindings::utils::{ConstantSpec, cx_for_dom_object, Default}',
|
||||||
'dom::bindings::utils::{dom_object_slot, DOM_OBJECT_SLOT, DOMClass}',
|
'dom::bindings::utils::{dom_object_slot, DOM_OBJECT_SLOT, DOMClass}',
|
||||||
|
|
|
@ -135,6 +135,7 @@ class Descriptor(DescriptorProvider):
|
||||||
|
|
||||||
self.returnType = "Temporary<%s>" % ifaceName
|
self.returnType = "Temporary<%s>" % ifaceName
|
||||||
self.argumentType = "JSRef<%s>" % ifaceName
|
self.argumentType = "JSRef<%s>" % ifaceName
|
||||||
|
self.memberType = "Root<'a, 'b, %s>" % ifaceName
|
||||||
self.nativeType = desc.get('nativeType', nativeTypeDefault)
|
self.nativeType = desc.get('nativeType', nativeTypeDefault)
|
||||||
self.concreteType = desc.get('concreteType', ifaceName)
|
self.concreteType = desc.get('concreteType', ifaceName)
|
||||||
self.createGlobal = desc.get('createGlobal', False)
|
self.createGlobal = desc.get('createGlobal', False)
|
||||||
|
|
|
@ -284,6 +284,12 @@ impl<T: Reflectable, U> ResultRootable<T, U> for Result<Temporary<T>, U> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Reflectable, U> ResultRootable<T, U> for Result<JS<T>, U> {
|
||||||
|
fn root<'a, 'b>(self) -> Result<Root<'a, 'b, T>, U> {
|
||||||
|
self.map(|inner| inner.root())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Provides a facility to push unrooted values onto lists of rooted values. This is safe
|
/// Provides a facility to push unrooted values onto lists of rooted values. This is safe
|
||||||
/// under the assumption that said lists are reachable via the GC graph, and therefore the
|
/// under the assumption that said lists are reachable via the GC graph, and therefore the
|
||||||
/// new values are transitively rooted for the lifetime of their new owner.
|
/// new values are transitively rooted for the lifetime of their new owner.
|
||||||
|
|
|
@ -61,13 +61,11 @@ impl MouseEvent {
|
||||||
type_: DOMString,
|
type_: DOMString,
|
||||||
init: &MouseEventBinding::MouseEventInit) -> Fallible<Temporary<MouseEvent>> {
|
init: &MouseEventBinding::MouseEventInit) -> Fallible<Temporary<MouseEvent>> {
|
||||||
let mut ev = MouseEvent::new(owner).root();
|
let mut ev = MouseEvent::new(owner).root();
|
||||||
let view = init.view.as_ref().map(|view| view.root());
|
ev.InitMouseEvent(type_, init.bubbles, init.cancelable, init.view.root_ref(),
|
||||||
let related_target = init.relatedTarget.as_ref().map(|relatedTarget| relatedTarget.root());
|
|
||||||
ev.InitMouseEvent(type_, init.bubbles, init.cancelable, view.root_ref(),
|
|
||||||
init.detail, init.screenX, init.screenY,
|
init.detail, init.screenX, init.screenY,
|
||||||
init.clientX, init.clientY, init.ctrlKey,
|
init.clientX, init.clientY, init.ctrlKey,
|
||||||
init.altKey, init.shiftKey, init.metaKey,
|
init.altKey, init.shiftKey, init.metaKey,
|
||||||
init.button, related_target.root_ref());
|
init.button, init.relatedTarget.root_ref());
|
||||||
Ok(Temporary::from_rooted(&*ev))
|
Ok(Temporary::from_rooted(&*ev))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,9 +46,8 @@ impl UIEvent {
|
||||||
type_: DOMString,
|
type_: DOMString,
|
||||||
init: &UIEventBinding::UIEventInit) -> Fallible<Temporary<UIEvent>> {
|
init: &UIEventBinding::UIEventInit) -> Fallible<Temporary<UIEvent>> {
|
||||||
let mut ev = UIEvent::new(owner).root();
|
let mut ev = UIEvent::new(owner).root();
|
||||||
let view = init.view.as_ref().map(|view| view.root());
|
|
||||||
ev.InitUIEvent(type_, init.parent.bubbles, init.parent.cancelable,
|
ev.InitUIEvent(type_, init.parent.bubbles, init.parent.cancelable,
|
||||||
view.root_ref(), init.detail);
|
init.view.root_ref(), init.detail);
|
||||||
Ok(Temporary::from_rooted(&*ev))
|
Ok(Temporary::from_rooted(&*ev))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue