First steps of &JSRef -> JSRef conversion

Replace &JSRef with JSRef in the bulk of the generated code. This will
remove a level of indirection throughout all DOM code.

This patch doesn't change methods implemented on JSRef<T> to take `self`
rather than `&self`, and it leaves a few other uses of &JSRef, but those
changes can be made incrementally.
This commit is contained in:
Cameron Zwarich 2014-09-18 13:43:15 -07:00
parent b8f34bbc51
commit 4fa8725111
126 changed files with 994 additions and 992 deletions

View file

@ -115,7 +115,7 @@ impl CallbackInterface {
/// Wraps the reflector for `p` into the compartment of `cx`.
pub fn WrapCallThisObject<T: Reflectable>(cx: *mut JSContext,
p: &JSRef<T>) -> *mut JSObject {
p: JSRef<T>) -> *mut JSObject {
let mut obj = p.reflector().get_jsobject();
assert!(obj.is_not_null());
@ -140,7 +140,7 @@ pub struct CallSetup {
impl CallSetup {
/// Performs the setup needed to make a call.
#[allow(unrooted_must_root)]
pub fn new<T: CallbackContainer>(callback: &T, handling: ExceptionHandling) -> CallSetup {
pub fn new<T: CallbackContainer>(callback: T, handling: ExceptionHandling) -> CallSetup {
let global = global_object_for_js_object(callback.callback());
let global = global.root();
let cx = global.root_ref().get_cx();

View file

@ -2170,10 +2170,7 @@ class CGCallGenerator(CGThing):
args = CGList([CGGeneric(arg) for arg in argsPre], ", ")
for (a, name) in arguments:
#XXXjdm Perhaps we should pass all nontrivial types by borrowed pointer
if a.type.isGeckoInterface():
if not (a.type.nullable() or a.optional):
name = "&" + name
elif a.type.isDictionary():
if a.type.isDictionary():
name = "&" + name
args.append(CGGeneric(name))
@ -3996,9 +3993,7 @@ class CGInterfaceTrait(CGThing):
elif optional and not defaultValue:
declType = CGWrapper(declType, pre="Option<", post=">")
if ty.isGeckoInterface() and not (ty.nullable() or optional):
declType = CGWrapper(declType, pre="&")
elif ty.isDictionary():
if ty.isDictionary():
declType = CGWrapper(declType, pre="&")
return declType.define()
@ -4854,27 +4849,22 @@ class CGNativeMember(ClassMethod):
decl = CGGeneric(decl)
if handleNullable and type.nullable():
decl = CGTemplatedType("Nullable", decl)
ref = True
if isMember == "Variadic":
arrayType = "Sequence" if self.variadicIsSequence else "nsTArray"
decl = CGTemplatedType(arrayType, decl)
ref = True
elif optional:
# Note: All variadic args claim to be optional, but we can just use
# empty arrays to represent them not being present.
decl = CGTemplatedType("Option", decl)
ref = False
return (decl, ref)
return decl
def getArg(self, arg):
"""
Get the full argument declaration for an argument
"""
(decl, ref) = self.getArgType(arg.type,
arg.optional and not arg.defaultValue,
"Variadic" if arg.variadic else False)
if ref:
decl = CGWrapper(decl, pre="&")
decl = self.getArgType(arg.type,
arg.optional and not arg.defaultValue,
"Variadic" if arg.variadic else False)
return Argument(decl.define(), arg.identifier.name)
@ -4931,17 +4921,17 @@ class CGCallback(CGClass):
args.append(Argument("ExceptionHandling", "aExceptionHandling",
"ReportExceptions"))
args[0] = Argument('&' + args[0].argType, args[0].name, args[0].default)
args[0] = Argument(args[0].argType, args[0].name, args[0].default)
method.args[2] = args[0]
# And now insert our template argument.
argsWithoutThis = list(args)
args.insert(0, Argument("&JSRef<T>", "thisObj"))
args.insert(0, Argument("JSRef<T>", "thisObj"))
# And the self argument
method.args.insert(0, Argument(None, "&self"))
args.insert(0, Argument(None, "&self"))
argsWithoutThis.insert(0, Argument(None, "&self"))
method.args.insert(0, Argument(None, "self"))
args.insert(0, Argument(None, "self"))
argsWithoutThis.insert(0, Argument(None, "self"))
setupCall = ("let s = CallSetup::new(self, aExceptionHandling);\n"
"if s.GetContext().is_null() {\n"
@ -5471,7 +5461,7 @@ class GlobalGenRoots():
cast = [CGGeneric(string.Template('''pub trait ${castTraitName} {
#[inline(always)]
fn to_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a JSRef<'b, T>) -> Option<&'a JSRef<'b, Self>> {
fn to_ref<'a, T: ${toBound}+Reflectable>(base: JSRef<'a, T>) -> Option<JSRef<'a, Self>> {
match base.deref().${checkFn}() {
true => unsafe { Some(base.transmute()) },
false => None
@ -5479,10 +5469,23 @@ class GlobalGenRoots():
}
#[inline(always)]
fn from_ref<'a, 'b, T: ${fromBound}>(derived: &'a JSRef<'b, T>) -> &'a JSRef<'b, Self> {
fn to_borrowed_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a JSRef<'b, T>) -> Option<&'a JSRef<'b, Self>> {
match base.deref().${checkFn}() {
true => unsafe { Some(base.transmute_borrowed()) },
false => None
}
}
#[inline(always)]
fn from_ref<'a, T: ${fromBound}>(derived: JSRef<'a, T>) -> JSRef<'a, Self> {
unsafe { derived.transmute() }
}
#[inline(always)]
fn from_borrowed_ref<'a, 'b, T: ${fromBound}>(derived: &'a JSRef<'b, T>) -> &'a JSRef<'b, Self> {
unsafe { derived.transmute_borrowed() }
}
#[inline(always)]
fn from_temporary<T: ${fromBound}+Reflectable>(derived: Temporary<T>) -> Temporary<Self> {
unsafe { derived.transmute() }

View file

@ -52,9 +52,9 @@ impl<'a> GlobalRef<'a> {
/// Extract a `Window`, causing task failure if the global object is not
/// a `Window`.
pub fn as_window<'b>(&'b self) -> &'b JSRef<'b, Window> {
pub fn as_window<'b>(&'b self) -> JSRef<'b, Window> {
match *self {
Window(ref window) => window,
Window(window) => window,
Worker(_) => fail!("expected a Window scope"),
}
}
@ -107,8 +107,8 @@ impl GlobalField {
/// Create a new `GlobalField` from a rooted reference.
pub fn from_rooted(global: &GlobalRef) -> GlobalField {
match *global {
Window(ref window) => WindowField(JS::from_rooted(window)),
Worker(ref worker) => WorkerField(JS::from_rooted(worker)),
Window(window) => WindowField(JS::from_rooted(window)),
Worker(worker) => WorkerField(JS::from_rooted(worker)),
}
}

View file

@ -21,7 +21,7 @@
//!
//! - All methods return `Temporary<T>`, to ensure the value remains alive until it is stored
//! somewhere that is reachable by the GC.
//! - All functions take `&JSRef<T>` arguments, to ensure that they will remain uncollected for
//! - All functions take `JSRef<T>` arguments, to ensure that they will remain uncollected for
//! the duration of their usage.
//! - All types contain `JS<T>` fields and derive the `Encodable` trait, to ensure that they are
//! transitively marked as reachable by the GC if the enclosing value is reachable.
@ -84,7 +84,7 @@ impl<T: Reflectable> Temporary<T> {
}
/// Create a new `Temporary` value from a rooted value.
pub fn from_rooted<'a>(root: &JSRef<'a, T>) -> Temporary<T> {
pub fn from_rooted<'a>(root: JSRef<'a, T>) -> Temporary<T> {
Temporary::new(JS::from_rooted(root))
}
@ -175,7 +175,7 @@ impl<T: Reflectable> JS<T> {
}
impl<T: Assignable<U>, U: Reflectable> JS<U> {
pub fn from_rooted(root: &T) -> JS<U> {
pub fn from_rooted(root: T) -> JS<U> {
unsafe {
root.get_js()
}
@ -298,7 +298,7 @@ pub trait OptionalUnrootable<T> {
impl<'a, T: Reflectable> OptionalUnrootable<T> for Option<JSRef<'a, T>> {
fn unrooted(&self) -> Option<JS<T>> {
self.as_ref().map(|inner| JS::from_rooted(inner))
self.as_ref().map(|inner| JS::from_rooted(*inner))
}
}
@ -477,12 +477,12 @@ impl<'a, T> PartialEq for JSRef<'a, T> {
impl<'a,T> JSRef<'a,T> {
//XXXjdm It would be lovely if this could be private.
pub unsafe fn transmute<'b, To>(&'b self) -> &'b JSRef<'a, To> {
pub unsafe fn transmute<To>(self) -> JSRef<'a, To> {
mem::transmute(self)
}
//XXXjdm It would be lovely if this could be private.
pub unsafe fn transmute_mut<'b, To>(&'b mut self) -> &'b mut JSRef<'a, To> {
// FIXME(zwarich): It would be nice to get rid of this entirely.
pub unsafe fn transmute_borrowed<'b, To>(&'b self) -> &'b JSRef<'a, To> {
mem::transmute(self)
}