Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a safe, mostly-sound rooting rooting strategy. #2101

Merged
merged 16 commits into from May 3, 2014
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Make dictionaries contain Root<T> values instead of JS<T>, ensuring t…

…hat they will not be collected while the dictionary is alive.
  • Loading branch information
jdm committed May 3, 2014
commit 895e9ee37fb572f7750c02de4fc51060990c51be
@@ -602,6 +602,8 @@ def wrapObjectTemplate(templateBody, isDefinitelyObject, type,
failureCode)
return handleOptional(template, declType, isOptional)

descriptorType = descriptor.memberType if isMember else descriptor.nativeType

templateBody = ""
if descriptor.interface.isConsequential():
raise TypeError("Consequential interface %s being used as an "
@@ -617,11 +619,14 @@ def wrapObjectTemplate(templateBody, isDefinitelyObject, type,
descriptor,
"(${val}).to_object()"))

declType = CGGeneric(descriptor.nativeType)
declType = CGGeneric(descriptorType)
if type.nullable():
templateBody = "Some(%s)" % templateBody
declType = CGWrapper(declType, pre="Option<", post=">")

if isMember:
templateBody += ".root()"

templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
type, failureCode)

@@ -4069,7 +4074,7 @@ def define(self):
def struct(self):
d = self.dictionary
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))
else:
inheritance = ""
@@ -4078,7 +4083,7 @@ def struct(self):
for m in self.memberInfo]

return (string.Template(
"pub struct ${selfName} {\n" +
"pub struct ${selfName}<'a, 'b> {\n" +
"${inheritance}" +
"\n".join(memberDecls) + "\n" +
"}").substitute( { "selfName": self.makeClassName(d),
@@ -4104,7 +4109,7 @@ def memberInit(memberInfo):
memberInits = CGList([memberInit(m) for m in self.memberInfo])

return string.Template(
"impl ${selfName} {\n"
"impl<'a, 'b> ${selfName}<'a, 'b> {\n"
" pub fn new(cx: *JSContext, val: JSVal) -> Result<${selfName}, ()> {\n"
" let object = if val.is_null_or_undefined() {\n"
" ptr::null()\n"
@@ -4305,7 +4310,7 @@ def __init__(self, config, prefix, webIDLFile):
'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}',
'dom::types::*',
'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::{ConstantSpec, cx_for_dom_object, Default}',
'dom::bindings::utils::{dom_object_slot, DOM_OBJECT_SLOT, DOMClass}',
@@ -135,6 +135,7 @@ def __init__(self, config, interface, desc):

self.returnType = "Temporary<%s>" % ifaceName
self.argumentType = "JSRef<%s>" % ifaceName
self.memberType = "Root<'a, 'b, %s>" % ifaceName
self.nativeType = desc.get('nativeType', nativeTypeDefault)
self.concreteType = desc.get('concreteType', ifaceName)
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
/// 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.
@@ -61,13 +61,11 @@ impl MouseEvent {
type_: DOMString,
init: &MouseEventBinding::MouseEventInit) -> Fallible<Temporary<MouseEvent>> {
let mut ev = MouseEvent::new(owner).root();
let view = init.view.as_ref().map(|view| view.root());
let related_target = init.relatedTarget.as_ref().map(|relatedTarget| relatedTarget.root());
ev.InitMouseEvent(type_, init.bubbles, init.cancelable, view.root_ref(),
ev.InitMouseEvent(type_, init.bubbles, init.cancelable, init.view.root_ref(),
init.detail, init.screenX, init.screenY,
init.clientX, init.clientY, init.ctrlKey,
init.altKey, init.shiftKey, init.metaKey,
init.button, related_target.root_ref());
init.button, init.relatedTarget.root_ref());
Ok(Temporary::from_rooted(&*ev))
}
}
@@ -46,9 +46,8 @@ impl UIEvent {
type_: DOMString,
init: &UIEventBinding::UIEventInit) -> Fallible<Temporary<UIEvent>> {
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,
view.root_ref(), init.detail);
init.view.root_ref(), init.detail);
Ok(Temporary::from_rooted(&*ev))
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.