aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/bindings/callback.rs35
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py204
-rw-r--r--components/script/dom/bindings/error.rs4
-rw-r--r--components/script/dom/bindings/guard.rs4
-rw-r--r--components/script/dom/bindings/interface.rs34
-rw-r--r--components/script/dom/bindings/proxyhandler.rs13
-rw-r--r--components/script/dom/bindings/trace.rs87
-rw-r--r--components/script/dom/bindings/utils.rs37
-rw-r--r--components/script/dom/blob.rs267
-rw-r--r--components/script/dom/browsingcontext.rs38
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs6
-rw-r--r--components/script/dom/dedicatedworkerglobalscope.rs4
-rw-r--r--components/script/dom/document.rs17
-rw-r--r--components/script/dom/domtokenlist.rs2
-rw-r--r--components/script/dom/element.rs6
-rw-r--r--components/script/dom/errorevent.rs4
-rw-r--r--components/script/dom/eventdispatcher.rs5
-rw-r--r--components/script/dom/eventtarget.rs14
-rw-r--r--components/script/dom/file.rs7
-rw-r--r--components/script/dom/filereader.rs16
-rw-r--r--components/script/dom/formdata.rs5
-rw-r--r--components/script/dom/htmlanchorelement.rs4
-rw-r--r--components/script/dom/htmlcollection.rs2
-rw-r--r--components/script/dom/htmlfontelement.rs2
-rw-r--r--components/script/dom/htmlformelement.rs6
-rw-r--r--components/script/dom/htmliframeelement.rs54
-rw-r--r--components/script/dom/htmlinputelement.rs27
-rw-r--r--components/script/dom/htmllinkelement.rs6
-rw-r--r--components/script/dom/htmlmediaelement.rs5
-rw-r--r--components/script/dom/htmlmetaelement.rs4
-rw-r--r--components/script/dom/htmloptionelement.rs2
-rw-r--r--components/script/dom/htmlscriptelement.rs5
-rw-r--r--components/script/dom/macros.rs15
-rw-r--r--components/script/dom/messageevent.rs4
-rw-r--r--components/script/dom/mouseevent.rs4
-rw-r--r--components/script/dom/node.rs14
-rw-r--r--components/script/dom/range.rs4
-rw-r--r--components/script/dom/serviceworker.rs3
-rw-r--r--components/script/dom/serviceworkerglobalscope.rs8
-rw-r--r--components/script/dom/testbinding.rs16
-rw-r--r--components/script/dom/url.rs55
-rw-r--r--components/script/dom/webglrenderingcontext.rs17
-rw-r--r--components/script/dom/webidls/BrowserElement.webidl1
-rw-r--r--components/script/dom/websocket.rs11
-rw-r--r--components/script/dom/window.rs14
-rw-r--r--components/script/dom/worker.rs6
-rw-r--r--components/script/dom/workerglobalscope.rs6
-rw-r--r--components/script/dom/xmlhttprequest.rs32
48 files changed, 602 insertions, 534 deletions
diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs
index c9424adf5b2..cc1266d27ab 100644
--- a/components/script/dom/bindings/callback.rs
+++ b/components/script/dom/bindings/callback.rs
@@ -9,14 +9,14 @@ use dom::bindings::global::global_root_from_object;
use dom::bindings::reflector::Reflectable;
use js::jsapi::GetGlobalForObjectCrossCompartment;
use js::jsapi::JSAutoCompartment;
-use js::jsapi::{Heap, MutableHandleObject, RootedObject, RootedValue};
+use js::jsapi::{Heap, MutableHandleObject, RootedObject};
use js::jsapi::{IsCallable, JSContext, JSObject, JS_WrapObject};
use js::jsapi::{JSCompartment, JS_EnterCompartment, JS_LeaveCompartment};
use js::jsapi::{JS_GetProperty, JS_IsExceptionPending, JS_ReportPendingException};
use js::jsval::{JSVal, UndefinedValue};
+use js::rust::RootedGuard;
use std::default::Default;
use std::ffi::CString;
-use std::intrinsics::return_address;
use std::ptr;
use std::rc::Rc;
@@ -114,20 +114,20 @@ impl CallbackInterface {
/// Returns the property with the given `name`, if it is a callable object,
/// or an error otherwise.
pub fn get_callable_property(&self, cx: *mut JSContext, name: &str) -> Fallible<JSVal> {
- let mut callable = RootedValue::new(cx, UndefinedValue());
- let obj = RootedObject::new(cx, self.callback());
+ rooted!(in(cx) let mut callable = UndefinedValue());
+ rooted!(in(cx) let obj = self.callback());
unsafe {
let c_name = CString::new(name).unwrap();
if !JS_GetProperty(cx, obj.handle(), c_name.as_ptr(), callable.handle_mut()) {
return Err(Error::JSFailed);
}
- if !callable.ptr.is_object() || !IsCallable(callable.ptr.to_object()) {
+ if !callable.is_object() || !IsCallable(callable.to_object()) {
return Err(Error::Type(format!("The value of the {} property is not callable",
name)));
}
}
- Ok(callable.ptr)
+ Ok(callable.get())
}
}
@@ -147,11 +147,9 @@ pub fn wrap_call_this_object<T: Reflectable>(cx: *mut JSContext,
/// A class that performs whatever setup we need to safely make a call while
/// this class is on the stack. After `new` returns, the call is safe to make.
-pub struct CallSetup {
+pub struct CallSetup<'a> {
/// The compartment for reporting exceptions.
- /// As a RootedObject, this must be the first field in order to
- /// determine the final address on the stack correctly.
- exception_compartment: RootedObject,
+ exception_compartment: RootedGuard<'a, *mut JSObject>,
/// The `JSContext` used for the call.
cx: *mut JSContext,
/// The compartment we were in before the call.
@@ -160,20 +158,21 @@ pub struct CallSetup {
handling: ExceptionHandling,
}
-impl CallSetup {
+impl<'a> CallSetup<'a> {
/// 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>(exception_compartment: &'a mut RootedObject,
+ callback: &T,
+ handling: ExceptionHandling)
+ -> CallSetup<'a> {
let global = unsafe { global_root_from_object(callback.callback()) };
let cx = global.r().get_cx();
- let exception_compartment = unsafe {
+ exception_compartment.ptr = unsafe {
GetGlobalForObjectCrossCompartment(callback.callback())
};
CallSetup {
- exception_compartment: RootedObject::new_with_addr(cx,
- exception_compartment,
- unsafe { return_address() }),
+ exception_compartment: RootedGuard::new(cx, exception_compartment),
cx: cx,
old_compartment: unsafe { JS_EnterCompartment(cx, callback.callback()) },
handling: handling,
@@ -186,7 +185,7 @@ impl CallSetup {
}
}
-impl Drop for CallSetup {
+impl<'a> Drop for CallSetup<'a> {
fn drop(&mut self) {
unsafe {
JS_LeaveCompartment(self.cx, self.old_compartment);
@@ -195,7 +194,7 @@ impl Drop for CallSetup {
unsafe { JS_IsExceptionPending(self.cx) };
if need_to_deal_with_exception {
unsafe {
- let _ac = JSAutoCompartment::new(self.cx, self.exception_compartment.ptr);
+ let _ac = JSAutoCompartment::new(self.cx, *self.exception_compartment);
JS_ReportPendingException(self.cx);
}
}
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 76aab6b9b53..e6e95ab1cb8 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -1166,23 +1166,22 @@ class CGArgumentConverter(CGThing):
template, variadicConversion, declType, "slot")]
arg = "arg%d" % index
-
if argument.type.isGeckoInterface():
- vec = "RootedVec::new()"
+ init = "rooted_vec!(let mut %s)" % arg
innerConverter.append(CGGeneric("%s.push(JS::from_ref(&*slot));" % arg))
else:
- vec = "vec![]"
+ init = "let mut %s = vec![]" % arg
innerConverter.append(CGGeneric("%s.push(slot);" % arg))
inner = CGIndenter(CGList(innerConverter, "\n"), 8).define()
self.converter = CGGeneric("""\
-let mut %(arg)s = %(vec)s;
+%(init)s;
if %(argc)s > %(index)s {
%(arg)s.reserve(%(argc)s as usize - %(index)s);
for variadicArg in %(index)s..%(argc)s {
%(inner)s
}
-}""" % {'arg': arg, 'argc': argc, 'index': index, 'inner': inner, 'vec': vec})
+}""" % {'arg': arg, 'argc': argc, 'index': index, 'inner': inner, 'init': init})
def define(self):
return self.converter.define()
@@ -2250,7 +2249,7 @@ class CGConstructorEnabled(CGAbstractMethod):
pref = iface.getExtendedAttribute("Pref")
if pref:
assert isinstance(pref, list) and len(pref) == 1
- conditions.append('prefs::get_pref("%s").as_boolean().unwrap_or(false)' % pref[0])
+ conditions.append('PREFS.get("%s").as_boolean().unwrap_or(false)' % pref[0])
func = iface.getExtendedAttribute("Func")
if func:
assert isinstance(func, list) and len(func) == 1
@@ -2278,34 +2277,33 @@ def CreateBindingJSObject(descriptor, parent=None):
assert not descriptor.isGlobal()
create += """
let handler = RegisterBindings::proxy_handlers[PrototypeList::Proxies::%s as usize];
-let private = RootedValue::new(cx, PrivateValue(raw as *const libc::c_void));
+rooted!(in(cx) let private = PrivateValue(raw as *const libc::c_void));
let obj = NewProxyObject(cx, handler,
private.handle(),
- proto.ptr, %s.get(),
+ proto.get(), %s.get(),
ptr::null_mut(), ptr::null_mut());
assert!(!obj.is_null());
-let obj = RootedObject::new(cx, obj);\
+rooted!(in(cx) let obj = obj);\
""" % (descriptor.name, parent)
elif descriptor.isGlobal():
- create += ("let obj = RootedObject::new(\n"
- " cx,\n"
+ create += ("rooted!(in(cx) let obj =\n"
" create_dom_global(\n"
" cx,\n"
" &Class.base as *const js::jsapi::Class as *const JSClass,\n"
" raw as *const libc::c_void,\n"
" Some(%s))\n"
");\n"
- "assert!(!obj.ptr.is_null());" % TRACE_HOOK_NAME)
+ "assert!(!obj.is_null());" % TRACE_HOOK_NAME)
else:
- create += ("let obj = RootedObject::new(cx, JS_NewObjectWithGivenProto(\n"
+ create += ("rooted!(in(cx) let obj = JS_NewObjectWithGivenProto(\n"
" cx, &Class.base as *const js::jsapi::Class as *const JSClass, proto.handle()));\n"
- "assert!(!obj.ptr.is_null());\n"
+ "assert!(!obj.is_null());\n"
"\n"
- "JS_SetReservedSlot(obj.ptr, DOM_OBJECT_SLOT,\n"
+ "JS_SetReservedSlot(obj.get(), 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()));"""
+JS_SetReservedSlot(obj.get(), DOM_WEAK_SLOT, PrivateValue(ptr::null()));"""
return create
@@ -2344,7 +2342,7 @@ def CopyUnforgeablePropertiesToInstance(descriptor):
# reflector, so we can make sure we don't get confused by named getters.
if descriptor.proxy:
copyCode += """\
-let expando = RootedObject::new(cx, ensure_expando_object(cx, obj.handle()));
+rooted!(in(cx) let expando = ensure_expando_object(cx, obj.handle()));
"""
obj = "expando"
else:
@@ -2358,9 +2356,9 @@ let expando = RootedObject::new(cx, ensure_expando_object(cx, obj.handle()));
else:
copyFunc = "JS_InitializePropertiesFromCompatibleNativeObject"
copyCode += """\
-let mut unforgeable_holder = RootedObject::new(cx, ptr::null_mut());
+rooted!(in(cx) let mut unforgeable_holder = ptr::null_mut());
unforgeable_holder.handle_mut().set(
- JS_GetReservedSlot(proto.ptr, DOM_PROTO_UNFORGEABLE_HOLDER_SLOT).to_object());
+ JS_GetReservedSlot(proto.get(), DOM_PROTO_UNFORGEABLE_HOLDER_SLOT).to_object());
assert!(%(copyFunc)s(cx, %(obj)s.handle(), unforgeable_holder.handle()));
""" % {'copyFunc': copyFunc, 'obj': obj}
@@ -2393,25 +2391,25 @@ let scope = scope.reflector().get_jsobject();
assert!(!scope.get().is_null());
assert!(((*JS_GetClass(scope.get())).flags & JSCLASS_IS_GLOBAL) != 0);
-let mut proto = RootedObject::new(cx, ptr::null_mut());
+rooted!(in(cx) let mut proto = ptr::null_mut());
let _ac = JSAutoCompartment::new(cx, scope.get());
GetProtoObject(cx, scope, proto.handle_mut());
-assert!(!proto.ptr.is_null());
+assert!(!proto.is_null());
%(createObject)s
%(copyUnforgeable)s
-(*raw).init_reflector(obj.ptr);
+(*raw).init_reflector(obj.get());
Root::from_ref(&*raw)""" % {'copyUnforgeable': unforgeable, 'createObject': create})
else:
create = CreateBindingJSObject(self.descriptor)
return CGGeneric("""\
%(createObject)s
-(*raw).init_reflector(obj.ptr);
+(*raw).init_reflector(obj.get());
-let _ac = JSAutoCompartment::new(cx, obj.ptr);
-let mut proto = RootedObject::new(cx, ptr::null_mut());
+let _ac = JSAutoCompartment::new(cx, obj.get());
+rooted!(in(cx) let mut proto = ptr::null_mut());
GetProtoObject(cx, obj.handle(), proto.handle_mut());
JS_SetPrototype(cx, obj.handle(), proto.handle());
@@ -2525,29 +2523,29 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
if self.descriptor.interface.isCallback():
assert not self.descriptor.interface.ctor() and self.descriptor.interface.hasConstants()
return CGGeneric("""\
-let mut interface = RootedObject::new(cx, ptr::null_mut());
+rooted!(in(cx) let mut interface = ptr::null_mut());
create_callback_interface_object(cx, global, sConstants, %(name)s, interface.handle_mut());
-assert!(!interface.ptr.is_null());
+assert!(!interface.is_null());
assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null());
-(*cache)[PrototypeList::Constructor::%(id)s as usize] = interface.ptr;
+(*cache)[PrototypeList::Constructor::%(id)s as usize] = interface.get();
<*mut JSObject>::post_barrier((*cache).as_mut_ptr().offset(PrototypeList::Constructor::%(id)s as isize),
ptr::null_mut(),
- interface.ptr);
+ interface.get());
""" % {"id": name, "name": str_to_const_array(name)})
if len(self.descriptor.prototypeChain) == 1:
if self.descriptor.interface.getExtendedAttribute("ExceptionClass"):
- getPrototypeProto = "prototype_proto.ptr = JS_GetErrorPrototype(cx)"
+ getPrototypeProto = "prototype_proto.set(JS_GetErrorPrototype(cx))"
else:
- getPrototypeProto = "prototype_proto.ptr = JS_GetObjectPrototype(cx, global)"
+ getPrototypeProto = "prototype_proto.set(JS_GetObjectPrototype(cx, global))"
else:
getPrototypeProto = ("%s::GetProtoObject(cx, global, prototype_proto.handle_mut())" %
toBindingNamespace(self.descriptor.prototypeChain[-2]))
code = [CGGeneric("""\
-let mut prototype_proto = RootedObject::new(cx, ptr::null_mut());
+rooted!(in(cx) let mut prototype_proto = ptr::null_mut());
%s;
-assert!(!prototype_proto.ptr.is_null());""" % getPrototypeProto)]
+assert!(!prototype_proto.is_null());""" % getPrototypeProto)]
properties = {
"id": name,
@@ -2561,7 +2559,7 @@ assert!(!prototype_proto.ptr.is_null());""" % getPrototypeProto)]
properties[arrayName] = "&[]"
code.append(CGGeneric("""
-let mut prototype = RootedObject::new(cx, ptr::null_mut());
+rooted!(in(cx) let mut prototype = ptr::null_mut());
create_interface_prototype_object(cx,
prototype_proto.handle(),
&PrototypeClass,
@@ -2570,12 +2568,12 @@ create_interface_prototype_object(cx,
%(consts)s,
%(unscopables)s,
prototype.handle_mut());
-assert!(!prototype.ptr.is_null());
+assert!(!prototype.is_null());
assert!((*cache)[PrototypeList::ID::%(id)s as usize].is_null());
-(*cache)[PrototypeList::ID::%(id)s as usize] = prototype.ptr;
+(*cache)[PrototypeList::ID::%(id)s as usize] = prototype.get();
<*mut JSObject>::post_barrier((*cache).as_mut_ptr().offset(PrototypeList::ID::%(id)s as isize),
ptr::null_mut(),
- prototype.ptr);
+ prototype.get());
""" % properties))
if self.descriptor.interface.hasInterfaceObject():
@@ -2587,15 +2585,15 @@ assert!((*cache)[PrototypeList::ID::%(id)s as usize].is_null());
if self.descriptor.interface.parent:
parentName = toBindingNamespace(self.descriptor.getParentName())
code.append(CGGeneric("""
-let mut interface_proto = RootedObject::new(cx, ptr::null_mut());
+rooted!(in(cx) let mut interface_proto = ptr::null_mut());
%s::GetConstructorObject(cx, global, interface_proto.handle_mut());""" % parentName))
else:
code.append(CGGeneric("""
-let interface_proto = RootedObject::new(cx, JS_GetFunctionPrototype(cx, global));"""))
+rooted!(in(cx) let interface_proto = JS_GetFunctionPrototype(cx, global));"""))
code.append(CGGeneric("""\
-assert!(!interface_proto.ptr.is_null());
+assert!(!interface_proto.is_null());
-let mut interface = RootedObject::new(cx, ptr::null_mut());
+rooted!(in(cx) let mut interface = ptr::null_mut());
create_noncallback_interface_object(cx,
global,
interface_proto.handle(),
@@ -2607,14 +2605,14 @@ create_noncallback_interface_object(cx,
%(name)s,
%(length)s,
interface.handle_mut());
-assert!(!interface.ptr.is_null());""" % properties))
+assert!(!interface.is_null());""" % properties))
if self.descriptor.hasDescendants():
code.append(CGGeneric("""\
assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null());
-(*cache)[PrototypeList::Constructor::%(id)s as usize] = interface.ptr;
+(*cache)[PrototypeList::Constructor::%(id)s as usize] = interface.get();
<*mut JSObject>::post_barrier((*cache).as_mut_ptr().offset(PrototypeList::Constructor::%(id)s as isize),
ptr::null_mut(),
- interface.ptr);
+ interface.get());
""" % properties))
constructors = self.descriptor.interface.namedConstructors
@@ -2649,15 +2647,15 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null());
holderClass = "&Class.base as *const js::jsapi::Class as *const JSClass"
holderProto = "prototype.handle()"
code.append(CGGeneric("""
-let mut unforgeable_holder = RootedObject::new(cx, ptr::null_mut());
+rooted!(in(cx) let mut unforgeable_holder = ptr::null_mut());
unforgeable_holder.handle_mut().set(
JS_NewObjectWithoutMetadata(cx, %(holderClass)s, %(holderProto)s));
-assert!(!unforgeable_holder.ptr.is_null());
+assert!(!unforgeable_holder.is_null());
""" % {'holderClass': holderClass, 'holderProto': holderProto}))
code.append(InitUnforgeablePropertiesOnHolder(self.descriptor, self.properties))
code.append(CGGeneric("""\
-JS_SetReservedSlot(prototype.ptr, DOM_PROTO_UNFORGEABLE_HOLDER_SLOT,
- ObjectValue(&*unforgeable_holder.ptr))"""))
+JS_SetReservedSlot(prototype.get(), DOM_PROTO_UNFORGEABLE_HOLDER_SLOT,
+ ObjectValue(&*unforgeable_holder.get()))"""))
return CGList(code, "\n")
@@ -2826,9 +2824,9 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
return CGGeneric("""\
assert!(!global.get().is_null());
%s
-let mut proto = RootedObject::new(cx, ptr::null_mut());
+rooted!(in(cx) let mut proto = ptr::null_mut());
%s(cx, global, proto.handle_mut());
-assert!(!proto.ptr.is_null());""" % (getCheck(self.descriptor), function))
+assert!(!proto.is_null());""" % (getCheck(self.descriptor), function))
def needCx(returnType, arguments, considerTypes):
@@ -3277,15 +3275,15 @@ class CGSpecializedForwardingSetter(CGSpecializedSetter):
assert all(ord(c) < 128 for c in attrName)
assert all(ord(c) < 128 for c in forwardToAttrName)
return CGGeneric("""\
-let mut v = RootedValue::new(cx, UndefinedValue());
+rooted!(in(cx) let mut v = UndefinedValue());
if !JS_GetProperty(cx, obj, %s as *const u8 as *const libc::c_char, v.handle_mut()) {
return false;
}
-if !v.ptr.is_object() {
+if !v.is_object() {
throw_type_error(cx, "Value.%s is not an object.");
return false;
}
-let target_obj = RootedObject::new(cx, v.ptr.to_object());
+rooted!(in(cx) let target_obj = v.to_object());
JS_SetProperty(cx, target_obj.handle(), %s as *const u8 as *const libc::c_char, args.get(0))
""" % (str_to_const_array(attrName), attrName, str_to_const_array(forwardToAttrName)))
@@ -4342,7 +4340,7 @@ class CGProxySpecialOperation(CGPerSignatureCall):
}
self.cgRoot.prepend(instantiateJSToNativeConversionTemplate(
template, templateValues, declType, argument.identifier.name))
- self.cgRoot.prepend(CGGeneric("let value = RootedValue::new(cx, desc.get().value);"))
+ self.cgRoot.prepend(CGGeneric("rooted!(in(cx) let value = desc.value);"))
elif operation.isGetter():
self.cgRoot.prepend(CGGeneric("let mut found = false;"))
@@ -4450,7 +4448,7 @@ class CGProxyUnwrap(CGAbstractMethod):
obj = js::UnwrapObject(obj);
}*/
//MOZ_ASSERT(IsProxy(obj));
-let box_ = GetProxyPrivate(*obj.ptr).to_private() as *const %s;
+let box_ = GetProxyPrivate(obj.get()).to_private() as *const %s;
return box_;""" % self.descriptor.concreteType)
@@ -4458,7 +4456,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
def __init__(self, descriptor):
args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'),
Argument('HandleId', 'id'),
- Argument('MutableHandle<PropertyDescriptor>', 'desc')]
+ Argument('MutableHandle<PropertyDescriptor>', 'desc', mutable=True)]
CGAbstractExternMethod.__init__(self, descriptor, "getOwnPropertyDescriptor",
"bool", args)
self.descriptor = descriptor
@@ -4475,13 +4473,14 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
attrs = "JSPROP_ENUMERATE"
if self.descriptor.operations['IndexedSetter'] is None:
attrs += " | JSPROP_READONLY"
- fillDescriptor = ("desc.get().value = result_root.ptr;\n"
- "fill_property_descriptor(&mut *desc.ptr, *proxy.ptr, %s);\n"
+ # FIXME(#11868) Should assign to desc.value, desc.get() is a copy.
+ fillDescriptor = ("desc.get().value = result_root.get();\n"
+ "fill_property_descriptor(&mut desc, proxy.get(), %s);\n"
"return true;" % attrs)
templateValues = {
'jsvalRef': 'result_root.handle_mut()',
'successCode': fillDescriptor,
- 'pre': 'let mut result_root = RootedValue::new(cx, UndefinedValue());'
+ 'pre': 'rooted!(in(cx) let mut result_root = UndefinedValue());'
}
get += ("if let Some(index) = index {\n" +
" let this = UnwrapProxy(proxy);\n" +
@@ -4500,13 +4499,14 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
attrs = " | ".join(attrs)
else:
attrs = "0"
- fillDescriptor = ("desc.get().value = result_root.ptr;\n"
- "fill_property_descriptor(&mut *desc.ptr, *proxy.ptr, %s);\n"
+ # FIXME(#11868) Should assign to desc.value, desc.get() is a copy.
+ fillDescriptor = ("desc.get().value = result_root.get();\n"
+ "fill_property_descriptor(&mut desc, proxy.get(), %s);\n"
"return true;" % attrs)
templateValues = {
'jsvalRef': 'result_root.handle_mut()',
'successCode': fillDescriptor,
- 'pre': 'let mut result_root = RootedValue::new(cx, UndefinedValue());'
+ 'pre': 'rooted!(in(cx) let mut result_root = UndefinedValue());'
}
# Once we start supporting OverrideBuiltins we need to make
# ResolveOwnProperty or EnumerateOwnProperties filter out named
@@ -4518,16 +4518,17 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
else:
namedGet = ""
+ # FIXME(#11868) Should assign to desc.obj, desc.get() is a copy.
return get + """\
-let expando = RootedObject::new(cx, get_expando_object(proxy));
+rooted!(in(cx) let expando = get_expando_object(proxy));
//if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {
-if !expando.ptr.is_null() {
+if !expando.is_null() {
if !JS_GetPropertyDescriptorById(cx, expando.handle(), id, desc) {
return false;
}
- if !desc.get().obj.is_null() {
+ if !desc.obj.is_null() {
// Pretend the property lives on the wrapper.
- desc.get().obj = *proxy.ptr;
+ desc.get().obj = proxy.get();
return true;
}
}
@@ -4637,7 +4638,7 @@ class CGDOMJSProxyHandler_ownPropertyKeys(CGAbstractExternMethod):
body += dedent(
"""
for i in 0..(*unwrapped_proxy).Length() {
- let rooted_jsid = RootedId::new(cx, int_to_jsid(i as i32));
+ rooted!(in(cx) let rooted_jsid = int_to_jsid(i as i32));
AppendToAutoIdVector(props, rooted_jsid.handle().get());
}
""")
@@ -4648,9 +4649,9 @@ class CGDOMJSProxyHandler_ownPropertyKeys(CGAbstractExternMethod):
for name in (*unwrapped_proxy).SupportedPropertyNames() {
let cstring = CString::new(name).unwrap();
let jsstring = JS_AtomizeAndPinString(cx, cstring.as_ptr());
- let rooted = RootedString::new(cx, jsstring);
+ rooted!(in(cx) let rooted = jsstring);
let jsid = INTERNED_STRING_TO_JSID(cx, rooted.handle().get());
- let rooted_jsid = RootedId::new(cx, jsid);
+ rooted!(in(cx) let rooted_jsid = jsid);
AppendToAutoIdVector(props, rooted_jsid.handle().get());
}
""")
@@ -4659,7 +4660,7 @@ class CGDOMJSProxyHandler_ownPropertyKeys(CGAbstractExternMethod):
"""
let expando = get_expando_object(proxy);
if !expando.is_null() {
- let rooted_expando = RootedObject::new(cx, expando);
+ rooted!(in(cx) let rooted_expando = expando);
GetPropertyKeys(cx, rooted_expando.handle(), JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props);
}
@@ -4693,7 +4694,7 @@ class CGDOMJSProxyHandler_getOwnEnumerablePropertyKeys(CGAbstractExternMethod):
body += dedent(
"""
for i in 0..(*unwrapped_proxy).Length() {
- let rooted_jsid = RootedId::new(cx, int_to_jsid(i as i32));
+ rooted!(in(cx) let rooted_jsid = int_to_jsid(i as i32));
AppendToAutoIdVector(props, rooted_jsid.handle().get());
}
""")
@@ -4702,7 +4703,7 @@ class CGDOMJSProxyHandler_getOwnEnumerablePropertyKeys(CGAbstractExternMethod):
"""
let expando = get_expando_object(proxy);
if !expando.is_null() {
- let rooted_expando = RootedObject::new(cx, expando);
+ rooted!(in(cx) let rooted_expando = expando);
GetPropertyKeys(cx, rooted_expando.handle(), JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props);
}
@@ -4748,8 +4749,8 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod):
named = ""
return indexed + """\
-let expando = RootedObject::new(cx, get_expando_object(proxy));
-if !expando.ptr.is_null() {
+rooted!(in(cx) let expando = get_expando_object(proxy));
+if !expando.is_null() {
let ok = JS_HasPropertyById(cx, expando.handle(), id, bp);
if !ok || *bp {
return ok;
@@ -4773,8 +4774,8 @@ class CGDOMJSProxyHandler_get(CGAbstractExternMethod):
def getBody(self):
getFromExpando = """\
-let expando = RootedObject::new(cx, get_expando_object(proxy));
-if !expando.ptr.is_null() {
+rooted!(in(cx) let expando = get_expando_object(proxy));
+if !expando.is_null() {
let mut hasProp = false;
if !JS_HasPropertyById(cx, expando.handle(), id, &mut hasProp) {
return false;
@@ -4829,7 +4830,7 @@ if found {
return true;
}
%s
-*vp.ptr = UndefinedValue();
+vp.set(UndefinedValue());
return true;""" % (getIndexedOrExpando, getNamed)
def definition_body(self):
@@ -5297,7 +5298,7 @@ class CGDictionary(CGThing):
return CGGeneric("%s: %s,\n" % (name, conversion.define()))
def varInsert(varName, dictionaryName):
- insertion = ("let mut %s_js = RootedValue::new(cx, UndefinedValue());\n"
+ insertion = ("rooted!(in(cx) let mut %s_js = UndefinedValue());\n"
"%s.to_jsval(cx, %s_js.handle_mut());\n"
"set_dictionary_property(cx, obj.handle(), \"%s\", %s_js.handle()).unwrap();"
% (varName, varName, varName, dictionaryName, varName))
@@ -5324,13 +5325,14 @@ class CGDictionary(CGThing):
" }\n"
" pub unsafe fn new(cx: *mut JSContext, val: HandleValue) -> Result<${selfName}, ()> {\n"
" let object = if val.get().is_null_or_undefined() {\n"
- " RootedObject::new(cx, ptr::null_mut())\n"
+ " ptr::null_mut()\n"
" } else if val.get().is_object() {\n"
- " RootedObject::new(cx, val.get().to_object())\n"
+ " val.get().to_object()\n"
" } else {\n"
" throw_type_error(cx, \"Value not an object.\");\n"
" return Err(());\n"
" };\n"
+ " rooted!(in(cx) let object = object);\n"
" Ok(${selfName} {\n"
"${initParent}"
"${initMembers}"
@@ -5348,9 +5350,9 @@ class CGDictionary(CGThing):
"\n"
"impl ToJSValConvertible for ${selfName} {\n"
" unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {\n"
- " let obj = RootedObject::new(cx, JS_NewObject(cx, ptr::null()));\n"
+ " rooted!(in(cx) let obj = JS_NewObject(cx, ptr::null()));\n"
"${insertMembers}"
- " rval.set(ObjectOrNullValue(obj.ptr))\n"
+ " rval.set(ObjectOrNullValue(obj.get()))\n"
" }\n"
"}\n").substitute({
"selfName": self.makeClassName(d),
@@ -5400,7 +5402,7 @@ class CGDictionary(CGThing):
conversion = (
"{\n"
- "let mut rval = RootedValue::new(cx, UndefinedValue());\n"
+ "rooted!(in(cx) let mut rval = UndefinedValue());\n"
"match try!(get_dictionary_property(cx, object.handle(), \"%s\", rval.handle_mut())) {\n"
" true => {\n"
"%s\n"
@@ -5548,8 +5550,8 @@ class CGBindingRoot(CGThing):
'js::jsapi::{JSNative, JSObject, JSNativeWrapper, JSPropertySpec}',
'js::jsapi::{JSString, JSTracer, JSType, JSTypedMethodJitInfo, JSValueType}',
'js::jsapi::{ObjectOpResult, JSJitInfo_OpType, MutableHandle, MutableHandleObject}',
- 'js::jsapi::{MutableHandleValue, PropertyDescriptor, RootedId, RootedObject}',
- 'js::jsapi::{RootedString, RootedValue, SymbolCode, jsid}',
+ 'js::jsapi::{MutableHandleValue, PropertyDescriptor, RootedObject}',
+ 'js::jsapi::{SymbolCode, jsid}',
'js::jsval::JSVal',
'js::jsval::{ObjectValue, ObjectOrNullValue, PrivateValue}',
'js::jsval::{NullValue, UndefinedValue}',
@@ -5600,12 +5602,11 @@ class CGBindingRoot(CGThing):
'dom::bindings::proxyhandler::{get_expando_object, get_property_descriptor}',
'dom::bindings::num::Finite',
'dom::bindings::str::{ByteString, DOMString, USVString}',
- 'dom::bindings::trace::RootedVec',
'dom::bindings::weakref::{DOM_WEAK_SLOT, WeakBox, WeakReferenceable}',
'dom::browsingcontext::BrowsingContext',
'mem::heap_size_of_raw_self_and_children',
'libc',
- 'util::prefs',
+ 'util::prefs::PREFS',
'script_runtime::{store_panic_result, maybe_take_panic_result}',
'std::borrow::ToOwned',
'std::cmp',
@@ -5769,16 +5770,17 @@ class CGCallback(CGClass):
args.insert(0, Argument(None, "&self"))
argsWithoutThis.insert(0, Argument(None, "&self"))
- setupCall = ("let s = CallSetup::new(self, aExceptionHandling);\n"
+ setupCall = ("let mut s_ec = RootedObject::new_unrooted(ptr::null_mut());\n"
+ "let s = CallSetup::new(&mut s_ec, self, aExceptionHandling);\n"
"if s.get_context().is_null() {\n"
" return Err(JSFailed);\n"
"}\n")
bodyWithThis = string.Template(
setupCall +
- "let mut thisObjJS = RootedObject::new(s.get_context(), ptr::null_mut());\n"
+ "rooted!(in(s.get_context()) let mut thisObjJS = ptr::null_mut());\n"
"wrap_call_this_object(s.get_context(), thisObj, thisObjJS.handle_mut());\n"
- "if thisObjJS.ptr.is_null() {\n"
+ "if thisObjJS.is_null() {\n"
" return Err(JSFailed);\n"
"}\n"
"return ${methodName}(${callArgs});").substitute({
@@ -5787,7 +5789,7 @@ class CGCallback(CGClass):
})
bodyWithoutThis = string.Template(
setupCall +
- "let thisObjJS = RootedObject::new(s.get_context(), ptr::null_mut());"
+ "rooted!(in(s.get_context()) let thisObjJS = ptr::null_mut());"
"return ${methodName}(${callArgs});").substitute({
"callArgs": ", ".join(argnamesWithoutThis),
"methodName": 'self.' + method.name,
@@ -6006,8 +6008,8 @@ class CallbackMember(CGNativeMember):
conversion = wrapForType(
"argv_root.handle_mut()", result=argval,
- successCode="argv[%s] = argv_root.ptr;" % jsvalIndex,
- pre="let mut argv_root = RootedValue::new(cx, UndefinedValue());")
+ successCode="argv[%s] = argv_root.get();" % jsvalIndex,
+ pre="rooted!(in(cx) let mut argv_root = UndefinedValue());")
if arg.variadic:
conversion = string.Template(
"for idx in 0..${arg}.len() {\n" +
@@ -6077,7 +6079,7 @@ class CallbackMethod(CallbackMember):
needThisHandling)
def getRvalDecl(self):
- return "let mut rval = RootedValue::new(cx, UndefinedValue());\n"
+ return "rooted!(in(cx) let mut rval = UndefinedValue());\n"
def getCall(self):
replacements = {
@@ -6092,7 +6094,7 @@ class CallbackMethod(CallbackMember):
replacements["argc"] = "0"
return string.Template(
"${getCallable}"
- "let rootedThis = RootedObject::new(cx, ${thisObj});\n"
+ "rooted!(in(cx) let rootedThis = ${thisObj});\n"
"let ok = JS_CallFunctionValue(\n"
" cx, rootedThis.handle(), callable.handle(),\n"
" &HandleValueArray {\n"
@@ -6116,7 +6118,7 @@ class CallCallback(CallbackMethod):
return "aThisObj.get()"
def getCallableDecl(self):
- return "let callable = RootedValue::new(cx, ObjectValue(&*self.parent.callback()));\n"
+ return "rooted!(in(cx) let callable = ObjectValue(&*self.parent.callback()));\n"
class CallbackOperationBase(CallbackMethod):
@@ -6141,17 +6143,17 @@ class CallbackOperationBase(CallbackMethod):
"methodName": self.methodName
}
getCallableFromProp = string.Template(
- 'RootedValue::new(cx, try!(self.parent.get_callable_property(cx, "${methodName}")))'
+ 'try!(self.parent.get_callable_property(cx, "${methodName}"))'
).substitute(replacements)
if not self.singleOperation:
- return 'JS::Rooted<JS::Value> callable(cx);\n' + getCallableFromProp
+ return 'rooted!(in(cx) let callable =\n' + getCallableFromProp + ');\n'
return (
'let isCallable = IsCallable(self.parent.callback());\n'
- 'let callable =\n' +
+ 'rooted!(in(cx) let callable =\n' +
CGIndenter(
CGIfElseWrapper('isCallable',
- CGGeneric('RootedValue::new(cx, ObjectValue(&*self.parent.callback()))'),
- CGGeneric(getCallableFromProp))).define() + ';\n')
+ CGGeneric('ObjectValue(&*self.parent.callback())'),
+ CGGeneric(getCallableFromProp))).define() + ');\n')
class CallbackOperation(CallbackOperationBase):
diff --git a/components/script/dom/bindings/error.rs b/components/script/dom/bindings/error.rs
index ed0b81c4d64..161e477a85a 100644
--- a/components/script/dom/bindings/error.rs
+++ b/components/script/dom/bindings/error.rs
@@ -10,7 +10,7 @@ use dom::bindings::global::GlobalRef;
use dom::domexception::{DOMErrorName, DOMException};
use js::error::{throw_range_error, throw_type_error};
use js::jsapi::JSAutoCompartment;
-use js::jsapi::{JSContext, JSObject, RootedValue};
+use js::jsapi::{JSContext, JSObject};
use js::jsapi::{JS_IsExceptionPending, JS_ReportPendingException, JS_SetPendingException};
use js::jsval::UndefinedValue;
@@ -115,7 +115,7 @@ pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef, result:
assert!(!JS_IsExceptionPending(cx));
let exception = DOMException::new(global, code);
- let mut thrown = RootedValue::new(cx, UndefinedValue());
+ rooted!(in(cx) let mut thrown = UndefinedValue());
exception.to_jsval(cx, thrown.handle_mut());
JS_SetPendingException(cx, thrown.handle());
}
diff --git a/components/script/dom/bindings/guard.rs b/components/script/dom/bindings/guard.rs
index 40faebbd4f2..114045a62e8 100644
--- a/components/script/dom/bindings/guard.rs
+++ b/components/script/dom/bindings/guard.rs
@@ -5,7 +5,7 @@
//! Machinery to conditionally expose things.
use js::jsapi::{HandleObject, JSContext};
-use util::prefs::get_pref;
+use util::prefs::PREFS;
/// A container with a condition.
pub struct Guard<T: Clone + Copy> {
@@ -47,7 +47,7 @@ pub enum Condition {
impl Condition {
unsafe fn is_satisfied(&self, cx: *mut JSContext, obj: HandleObject) -> bool {
match *self {
- Condition::Pref(name) => get_pref(name).as_boolean().unwrap_or(false),
+ Condition::Pref(name) => PREFS.get(name).as_boolean().unwrap_or(false),
Condition::Func(f) => f(cx, obj),
Condition::Satisfied => true,
}
diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs
index 500f262f3af..c61a3f211c4 100644
--- a/components/script/dom/bindings/interface.rs
+++ b/components/script/dom/bindings/interface.rs
@@ -19,8 +19,8 @@ use js::jsapi::{JS_DefineProperty2, JS_DefineProperty4, JS_DefinePropertyById3};
use js::jsapi::{JS_GetClass, JS_GetFunctionObject, JS_GetPrototype, JS_LinkConstructorAndPrototype};
use js::jsapi::{JS_NewFunction, JS_NewObject, JS_NewObjectWithUniqueType};
use js::jsapi::{JS_NewPlainObject, JS_NewStringCopyN, MutableHandleObject};
-use js::jsapi::{MutableHandleValue, ObjectOps, RootedId, RootedObject};
-use js::jsapi::{RootedString, RootedValue, SymbolCode, TrueHandleValue, Value};
+use js::jsapi::{MutableHandleValue, ObjectOps};
+use js::jsapi::{SymbolCode, TrueHandleValue, Value};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UInt32Value};
use js::rust::{define_methods, define_properties};
use libc;
@@ -74,7 +74,7 @@ fn define_constants(
obj: HandleObject,
constants: &[ConstantSpec]) {
for spec in constants {
- let value = RootedValue::new(cx, spec.get_value());
+ rooted!(in(cx) let value = spec.get_value());
unsafe {
assert!(JS_DefineProperty(cx,
obj,
@@ -243,13 +243,13 @@ pub unsafe fn create_interface_prototype_object(
create_object(cx, proto, class, regular_methods, regular_properties, constants, rval);
if !unscopable_names.is_empty() {
- let mut unscopable_obj = RootedObject::new(cx, ptr::null_mut());
+ rooted!(in(cx) let mut unscopable_obj = ptr::null_mut());
create_unscopable_object(cx, unscopable_names, unscopable_obj.handle_mut());
let unscopable_symbol = GetWellKnownSymbol(cx, SymbolCode::unscopables);
assert!(!unscopable_symbol.is_null());
- let unscopable_id = RootedId::new(cx, RUST_SYMBOL_TO_JSID(unscopable_symbol));
+ rooted!(in(cx) let unscopable_id = RUST_SYMBOL_TO_JSID(unscopable_symbol));
assert!(JS_DefinePropertyById3(
cx, rval.handle(), unscopable_id.handle(), unscopable_obj.handle(),
JSPROP_READONLY, None, None))
@@ -288,7 +288,7 @@ pub unsafe fn create_named_constructors(
global: HandleObject,
named_constructors: &[(NonNullJSNative, &[u8], u32)],
interface_prototype_object: HandleObject) {
- let mut constructor = RootedObject::new(cx, ptr::null_mut());
+ rooted!(in(cx) let mut constructor = ptr::null_mut());
for &(native, name, arity) in named_constructors {
assert!(*name.last().unwrap() == b'\0');
@@ -299,8 +299,8 @@ pub unsafe fn create_named_constructors(
JSFUN_CONSTRUCTOR,
name.as_ptr() as *const libc::c_char);
assert!(!fun.is_null());
- constructor.ptr = JS_GetFunctionObject(fun);
- assert!(!constructor.ptr.is_null());
+ constructor.set(JS_GetFunctionObject(fun));
+ assert!(!constructor.is_null());
assert!(JS_DefineProperty1(cx,
constructor.handle(),
@@ -339,12 +339,13 @@ unsafe fn has_instance(
// Step 1.
return Ok(false);
}
- let mut value = RootedObject::new(cx, value.to_object());
+ rooted!(in(cx) let mut value = value.to_object());
let js_class = JS_GetClass(interface_object.get());
let object_class = &*(js_class as *const NonCallbackInterfaceObjectClass);
- if let Ok(dom_class) = get_dom_class(UncheckedUnwrapObject(value.ptr, /* stopAtWindowProxy = */ 0)) {
+ if let Ok(dom_class) = get_dom_class(UncheckedUnwrapObject(value.get(),
+ /* stopAtWindowProxy = */ 0)) {
if dom_class.interface_chain[object_class.proto_depth as usize] == object_class.proto_id {
// Step 4.
return Ok(true);
@@ -355,15 +356,15 @@ unsafe fn has_instance(
let global = GetGlobalForObjectCrossCompartment(interface_object.get());
assert!(!global.is_null());
let proto_or_iface_array = get_proto_or_iface_array(global);
- let prototype = RootedObject::new(cx, (*proto_or_iface_array)[object_class.proto_id as usize]);
- assert!(!prototype.ptr.is_null());
+ rooted!(in(cx) let prototype = (*proto_or_iface_array)[object_class.proto_id as usize]);
+ assert!(!prototype.is_null());
// Step 3 only concern legacy callback interface objects (i.e. NodeFilter).
while JS_GetPrototype(cx, value.handle(), value.handle_mut()) {
- if value.ptr.is_null() {
+ if value.is_null() {
// Step 5.2.
return Ok(false);
- } else if value.ptr as *const _ == prototype.ptr {
+ } else if value.get() as *const _ == prototype.get() {
// Step 5.3.
return Ok(true);
}
@@ -433,9 +434,8 @@ pub unsafe fn define_guarded_properties(
unsafe fn define_name(cx: *mut JSContext, obj: HandleObject, name: &[u8]) {
assert!(*name.last().unwrap() == b'\0');
- let name = RootedString::new(
- cx, JS_AtomizeAndPinString(cx, name.as_ptr() as *const libc::c_char));
- assert!(!name.ptr.is_null());
+ rooted!(in(cx) let name = JS_AtomizeAndPinString(cx, name.as_ptr() as *const libc::c_char));
+ assert!(!name.is_null());
assert!(JS_DefineProperty2(cx,
obj,
b"name\0".as_ptr() as *const libc::c_char,
diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs
index f7505b77fc7..9db30d8835c 100644
--- a/components/script/dom/bindings/proxyhandler.rs
+++ b/components/script/dom/bindings/proxyhandler.rs
@@ -13,7 +13,7 @@ use js::glue::InvokeGetOwnPropertyDescriptor;
use js::glue::{GetProxyHandler, SetProxyExtra};
use js::jsapi::GetObjectProto;
use js::jsapi::JS_GetPropertyDescriptorById;
-use js::jsapi::{Handle, HandleId, HandleObject, MutableHandle, ObjectOpResult, RootedObject};
+use js::jsapi::{Handle, HandleId, HandleObject, MutableHandle, ObjectOpResult};
use js::jsapi::{JSContext, JSObject, JSPROP_GETTER, PropertyDescriptor};
use js::jsapi::{JSErrNum, JS_StrictPropertyStub};
use js::jsapi::{JS_DefinePropertyById, JS_NewObjectWithGivenProto};
@@ -36,12 +36,13 @@ pub unsafe extern "C" fn get_property_descriptor(cx: *mut JSContext,
if !InvokeGetOwnPropertyDescriptor(handler, cx, proxy, id, desc) {
return false;
}
- if !desc.get().obj.is_null() {
+ if !desc.obj.is_null() {
return true;
}
- let mut proto = RootedObject::new(cx, ptr::null_mut());
+ rooted!(in(cx) let mut proto = ptr::null_mut());
if !GetObjectProto(cx, proxy, proto.handle_mut()) {
+ // FIXME(#11868) Should assign to desc.obj, desc.get() is a copy.
desc.get().obj = ptr::null_mut();
return true;
}
@@ -65,7 +66,7 @@ pub unsafe extern "C" fn define_property(cx: *mut JSContext,
return true;
}
- let expando = RootedObject::new(cx, ensure_expando_object(cx, proxy));
+ rooted!(in(cx) let expando = ensure_expando_object(cx, proxy));
JS_DefinePropertyById(cx, expando.handle(), id, desc, result)
}
@@ -75,8 +76,8 @@ pub unsafe extern "C" fn delete(cx: *mut JSContext,
id: HandleId,
bp: *mut ObjectOpResult)
-> bool {
- let expando = RootedObject::new(cx, get_expando_object(proxy));
- if expando.ptr.is_null() {
+ rooted!(in(cx) let expando = get_expando_object(proxy));
+ if expando.is_null() {
(*bp).code_ = 0 /* OkCode */;
return true;
}
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 1d1433b2693..7404e96b95d 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -56,8 +56,8 @@ use js::jsapi::{GCTraceKindToAscii, Heap, TraceKind, JSObject, JSTracer};
use js::jsval::JSVal;
use js::rust::Runtime;
use libc;
-use msg::constellation_msg::{FrameType, PipelineId, SubpageId, WindowSizeData, WindowSizeType, ReferrerPolicy};
-use net_traits::filemanager_thread::SelectedFileId;
+use msg::constellation_msg::{FrameType, PipelineId, SubpageId, WindowSizeType, ReferrerPolicy};
+use net_traits::filemanager_thread::{SelectedFileId, RelativePos};
use net_traits::image::base::{Image, ImageMetadata};
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread};
use net_traits::response::HttpsState;
@@ -70,15 +70,13 @@ use script_layout_interface::OpaqueStyleAndLayoutData;
use script_layout_interface::reporter::CSSErrorReporter;
use script_layout_interface::rpc::LayoutRPC;
use script_runtime::ScriptChan;
-use script_traits::{TimerEventId, TimerSource, TouchpadPressurePhase, UntrustedNodeAddress};
+use script_traits::{TimerEventId, TimerSource, TouchpadPressurePhase, UntrustedNodeAddress, WindowSizeData};
use serde::{Deserialize, Serialize};
use smallvec::SmallVec;
use std::boxed::FnBox;
use std::cell::{Cell, UnsafeCell};
use std::collections::{BTreeMap, HashMap, HashSet};
use std::hash::{BuildHasher, Hash};
-use std::intrinsics::return_address;
-use std::iter::{FromIterator, IntoIterator};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
@@ -331,6 +329,7 @@ no_jsmanaged_fields!(ReferrerPolicy);
no_jsmanaged_fields!(ResourceThreads);
no_jsmanaged_fields!(SystemTime);
no_jsmanaged_fields!(SelectedFileId);
+no_jsmanaged_fields!(RelativePos);
no_jsmanaged_fields!(OpaqueStyleAndLayoutData);
no_jsmanaged_fields!(CSSErrorReporter);
no_jsmanaged_fields!(WebGLBufferId);
@@ -465,8 +464,8 @@ impl RootedTraceableSet {
/// Roots any JSTraceable thing
///
/// If you have a valid Reflectable, use Root.
-/// If you have GC things like *mut JSObject or JSVal, use jsapi::Rooted.
-/// If you have an arbitrary number of Reflectables to root, use RootedVec<JS<T>>
+/// If you have GC things like *mut JSObject or JSVal, use rooted!.
+/// If you have an arbitrary number of Reflectables to root, use rooted_vec!.
/// If you know what you're doing, use this.
#[derive(JSTraceable)]
pub struct RootedTraceable<'a, T: 'a + JSTraceable> {
@@ -493,73 +492,73 @@ impl<'a, T: JSTraceable> Drop for RootedTraceable<'a, T> {
}
}
-/// A vector of items that are rooted for the lifetime of this struct.
+/// A vector of items to be rooted with `RootedVec`.
+/// Guaranteed to be empty when not rooted.
+/// Usage: `rooted_vec!(let mut v);` or if you have an
+/// iterator of `Root`s, `rooted_vec!(let v <- iterator);`.
#[allow(unrooted_must_root)]
-#[no_move]
#[derive(JSTraceable)]
#[allow_unrooted_interior]
-pub struct RootedVec<T: JSTraceable> {
+pub struct RootableVec<T: JSTraceable> {
v: Vec<T>,
}
+impl<T: JSTraceable> RootableVec<T> {
+ /// Create a vector of items of type T that can be rooted later.
+ pub fn new_unrooted() -> RootableVec<T> {
+ RootableVec {
+ v: vec![],
+ }
+ }
+}
+
+/// A vector of items that are rooted for the lifetime 'a.
+#[allow_unrooted_interior]
+pub struct RootedVec<'a, T: 'a + JSTraceable> {
+ root: &'a mut RootableVec<T>,
+}
-impl<T: JSTraceable> RootedVec<T> {
+impl<'a, T: JSTraceable + Reflectable> RootedVec<'a, JS<T>> {
/// Create a vector of items of type T that is rooted for
/// the lifetime of this struct
- pub fn new() -> RootedVec<T> {
- let addr = unsafe { return_address() as *const libc::c_void };
-
- unsafe { RootedVec::new_with_destination_address(addr) }
- }
-
- /// Create a vector of items of type T. This constructor is specific
- /// for RootTraceableSet.
- pub unsafe fn new_with_destination_address(addr: *const libc::c_void) -> RootedVec<T> {
- RootedTraceableSet::add::<RootedVec<T>>(&*(addr as *const _));
- RootedVec::<T> {
- v: vec![],
+ pub fn new<I: Iterator<Item = Root<T>>>(root: &'a mut RootableVec<JS<T>>, iter: I)
+ -> RootedVec<'a, JS<T>> {
+ unsafe {
+ RootedTraceableSet::add(root);
+ }
+ root.v.extend(iter.map(|item| JS::from_ref(&*item)));
+ RootedVec {
+ root: root,
}
}
}
-impl<T: JSTraceable + Reflectable> RootedVec<JS<T>> {
+impl<'a, T: JSTraceable + Reflectable> RootedVec<'a, JS<T>> {
/// Obtain a safe slice of references that can't outlive that RootedVec.
pub fn r(&self) -> &[&T] {
- unsafe { mem::transmute(&self.v[..]) }
+ unsafe { mem::transmute(&self[..]) }
}
}
-impl<T: JSTraceable> Drop for RootedVec<T> {
+impl<'a, T: JSTraceable> Drop for RootedVec<'a, T> {
fn drop(&mut self) {
+ self.clear();
unsafe {
- RootedTraceableSet::remove(self);
+ RootedTraceableSet::remove(self.root);
}
}
}
-impl<T: JSTraceable> Deref for RootedVec<T> {
+impl<'a, T: JSTraceable> Deref for RootedVec<'a, T> {
type Target = Vec<T>;
fn deref(&self) -> &Vec<T> {
- &self.v
+ &self.root.v
}
}
-impl<T: JSTraceable> DerefMut for RootedVec<T> {
+impl<'a, T: JSTraceable> DerefMut for RootedVec<'a, T> {
fn deref_mut(&mut self) -> &mut Vec<T> {
- &mut self.v
- }
-}
-
-impl<A: JSTraceable + Reflectable> FromIterator<Root<A>> for RootedVec<JS<A>> {
- #[allow(moved_no_move)]
- fn from_iter<T>(iterable: T) -> RootedVec<JS<A>>
- where T: IntoIterator<Item = Root<A>>
- {
- let mut vec = unsafe {
- RootedVec::new_with_destination_address(return_address() as *const libc::c_void)
- };
- vec.extend(iterable.into_iter().map(|item| JS::from_ref(&*item)));
- vec
+ &mut self.root.v
}
}
diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs
index 0f0d5bcf00e..e7085bf424a 100644
--- a/components/script/dom/bindings/utils.rs
+++ b/components/script/dom/bindings/utils.rs
@@ -29,8 +29,8 @@ use js::jsapi::{JS_ForwardGetPropertyTo, JS_GetClass, JS_GetLatin1StringCharsAnd
use js::jsapi::{JS_GetProperty, JS_GetPrototype, JS_GetReservedSlot, JS_HasProperty};
use js::jsapi::{JS_HasPropertyById, JS_IsExceptionPending, JS_IsGlobalObject, JS_NewGlobalObject};
use js::jsapi::{JS_ResolveStandardClass, JS_SetProperty, ToWindowProxyIfWindow};
-use js::jsapi::{JS_SetReservedSlot, JS_StringHasLatin1Chars, MutableHandleValue, ObjectOpResult};
-use js::jsapi::{OnNewGlobalHookOption, RootedObject, RootedValue};
+use js::jsapi::{JS_SetReservedSlot, JS_StringHasLatin1Chars, MutableHandleValue};
+use js::jsapi::{ObjectOpResult, OnNewGlobalHookOption};
use js::jsval::{JSVal, ObjectValue, PrivateValue, UndefinedValue};
use js::rust::{GCMethods, ToString};
use libc;
@@ -135,8 +135,8 @@ pub fn get_property_on_prototype(cx: *mut JSContext,
-> bool {
unsafe {
// let proto = GetObjectProto(proxy);
- let mut proto = RootedObject::new(cx, ptr::null_mut());
- if !JS_GetPrototype(cx, proxy, proto.handle_mut()) || proto.ptr.is_null() {
+ rooted!(in(cx) let mut proto = ptr::null_mut());
+ if !JS_GetPrototype(cx, proxy, proto.handle_mut()) || proto.is_null() {
*found = false;
return true;
}
@@ -150,7 +150,7 @@ pub fn get_property_on_prototype(cx: *mut JSContext,
return true;
}
- let receiver = RootedValue::new(cx, ObjectValue(&**proxy.ptr));
+ rooted!(in(cx) let receiver = ObjectValue(&*proxy.get()));
JS_ForwardGetPropertyTo(cx, proto.handle(), id, receiver.handle(), vp)
}
}
@@ -305,29 +305,28 @@ pub fn create_dom_global(cx: *mut JSContext,
options.creationOptions_.traceGlobal_ = trace;
options.creationOptions_.sharedMemoryAndAtomics_ = true;
- let obj =
- RootedObject::new(cx,
- JS_NewGlobalObject(cx,
- class,
- ptr::null_mut(),
- OnNewGlobalHookOption::DontFireOnNewGlobalHook,
- &options));
- if obj.ptr.is_null() {
+ rooted!(in(cx) let obj =
+ JS_NewGlobalObject(cx,
+ class,
+ ptr::null_mut(),
+ OnNewGlobalHookOption::DontFireOnNewGlobalHook,
+ &options));
+ if obj.is_null() {
return ptr::null_mut();
}
// Initialize the reserved slots before doing amything that can GC, to
// avoid getting trace hooks called on a partially initialized object.
- JS_SetReservedSlot(obj.ptr, DOM_OBJECT_SLOT, PrivateValue(private));
+ JS_SetReservedSlot(obj.get(), DOM_OBJECT_SLOT, PrivateValue(private));
let proto_array: Box<ProtoOrIfaceArray> =
box [0 as *mut JSObject; PROTO_OR_IFACE_LENGTH];
- JS_SetReservedSlot(obj.ptr,
+ JS_SetReservedSlot(obj.get(),
DOM_PROTOTYPE_SLOT,
PrivateValue(Box::into_raw(proto_array) as *const libc::c_void));
- let _ac = JSAutoCompartment::new(cx, obj.ptr);
+ let _ac = JSAutoCompartment::new(cx, obj.get());
JS_FireOnNewGlobalObject(cx, obj.handle());
- obj.ptr
+ obj.get()
}
}
@@ -459,14 +458,14 @@ unsafe fn generic_call(cx: *mut JSContext,
} else {
GetGlobalForObjectCrossCompartment(JS_CALLEE(cx, vp).to_object_or_null())
};
- let obj = RootedObject::new(cx, obj);
+ rooted!(in(cx) let obj = obj);
let info = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));
let proto_id = (*info).protoID;
let depth = (*info).depth;
let proto_check = |class: &'static DOMClass| {
class.interface_chain[depth as usize] as u16 == proto_id
};
- let this = match private_from_proto_check(obj.ptr, proto_check) {
+ let this = match private_from_proto_check(obj.get(), proto_check) {
Ok(val) => val,
Err(()) => {
if is_lenient {
diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs
index dcb4c68f34a..8e9e96322d9 100644
--- a/components/script/dom/blob.rs
+++ b/components/script/dom/blob.rs
@@ -8,111 +8,43 @@ use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
use dom::bindings::codegen::UnionTypes::BlobOrString;
use dom::bindings::error::{Error, Fallible};
use dom::bindings::global::GlobalRef;
-use dom::bindings::js::Root;
+use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use encoding::all::UTF_8;
use encoding::types::{EncoderTrap, Encoding};
use ipc_channel::ipc;
-use net_traits::filemanager_thread::{FileManagerThreadMsg, SelectedFileId};
-use num_traits::ToPrimitive;
+use net_traits::IpcSend;
+use net_traits::blob_url_store::BlobURLStoreEntry;
+use net_traits::filemanager_thread::{FileManagerThreadMsg, SelectedFileId, RelativePos};
use std::ascii::AsciiExt;
use std::cell::Cell;
-use std::cmp::{max, min};
-use std::sync::Arc;
-
-#[derive(Clone, JSTraceable)]
-pub struct DataSlice {
- bytes: Arc<Vec<u8>>,
- bytes_start: usize,
- bytes_end: usize
-}
-
-impl DataSlice {
- /// Construct DataSlice from reference counted bytes
- pub fn new(bytes: Arc<Vec<u8>>, start: Option<i64>, end: Option<i64>) -> DataSlice {
- let size = bytes.len() as i64;
- let relativeStart: i64 = match start {
- None => 0,
- Some(start) => {
- if start < 0 {
- max(size + start, 0)
- } else {
- min(start, size)
- }
- }
- };
- let relativeEnd: i64 = match end {
- None => size,
- Some(end) => {
- if end < 0 {
- max(size + end, 0)
- } else {
- min(end, size)
- }
- }
- };
-
- let span: i64 = max(relativeEnd - relativeStart, 0);
- let start = relativeStart.to_usize().unwrap();
- let end = (relativeStart + span).to_usize().unwrap();
-
- DataSlice {
- bytes: bytes,
- bytes_start: start,
- bytes_end: end
- }
- }
-
- /// Construct data slice from a vector of bytes
- pub fn from_bytes(bytes: Vec<u8>) -> DataSlice {
- DataSlice::new(Arc::new(bytes), None, None)
- }
-
- /// Construct an empty data slice
- pub fn empty() -> DataSlice {
- DataSlice {
- bytes: Arc::new(Vec::new()),
- bytes_start: 0,
- bytes_end: 0,
- }
- }
+use std::ops::Index;
- /// Get sliced bytes
- pub fn get_bytes(&self) -> &[u8] {
- &self.bytes[self.bytes_start..self.bytes_end]
- }
-
- /// Get length of sliced bytes
- pub fn size(&self) -> u64 {
- (self.bytes_end as u64) - (self.bytes_start as u64)
- }
-}
-
-
-#[derive(Clone, JSTraceable)]
+#[must_root]
+#[derive(JSTraceable)]
pub enum BlobImpl {
- /// File-based, cached backend
- File(SelectedFileId, DOMRefCell<Option<DataSlice>>),
- /// Memory-based backend
- Memory(DataSlice),
+ /// File-based blob, including id and possibly cached content
+ File(SelectedFileId, DOMRefCell<Option<Vec<u8>>>),
+ /// Memory-based blob
+ Memory(Vec<u8>),
+ /// Sliced blob, including parent blob and
+ /// relative positions representing current slicing range,
+ /// it is leaf of a two-layer fat tree
+ Sliced(JS<Blob>, RelativePos),
}
impl BlobImpl {
- /// Construct memory-backed BlobImpl from DataSlice
- pub fn new_from_slice(slice: DataSlice) -> BlobImpl {
- BlobImpl::Memory(slice)
+ /// Construct memory-backed BlobImpl
+ #[allow(unrooted_must_root)]
+ pub fn new_from_bytes(bytes: Vec<u8>) -> BlobImpl {
+ BlobImpl::Memory(bytes)
}
/// Construct file-backed BlobImpl from File ID
pub fn new_from_file(file_id: SelectedFileId) -> BlobImpl {
BlobImpl::File(file_id, DOMRefCell::new(None))
}
-
- /// Construct empty, memory-backed BlobImpl
- pub fn new_from_empty_slice() -> BlobImpl {
- BlobImpl::new_from_slice(DataSlice::empty())
- }
}
// https://w3c.github.io/FileAPI/#blob
@@ -120,26 +52,58 @@ impl BlobImpl {
pub struct Blob {
reflector_: Reflector,
#[ignore_heap_size_of = "No clear owner"]
- blob_impl: BlobImpl,
+ blob_impl: DOMRefCell<BlobImpl>,
typeString: String,
isClosed_: Cell<bool>,
}
impl Blob {
+ #[allow(unrooted_must_root)]
pub fn new(global: GlobalRef, blob_impl: BlobImpl, typeString: String) -> Root<Blob> {
let boxed_blob = box Blob::new_inherited(blob_impl, typeString);
reflect_dom_object(boxed_blob, global, BlobBinding::Wrap)
}
+ #[allow(unrooted_must_root)]
pub fn new_inherited(blob_impl: BlobImpl, typeString: String) -> Blob {
Blob {
reflector_: Reflector::new(),
- blob_impl: blob_impl,
+ blob_impl: DOMRefCell::new(blob_impl),
typeString: typeString,
isClosed_: Cell::new(false),
}
}
+ #[allow(unrooted_must_root)]
+ fn new_sliced(parent: &Blob, rel_pos: RelativePos,
+ relativeContentType: DOMString) -> Root<Blob> {
+ let global = parent.global();
+ let blob_impl = match *parent.blob_impl.borrow() {
+ BlobImpl::File(ref id, _) => {
+ inc_ref_id(global.r(), id.clone());
+
+ // Create new parent node
+ BlobImpl::Sliced(JS::from_ref(parent), rel_pos)
+ }
+ BlobImpl::Memory(_) => {
+ // Create new parent node
+ BlobImpl::Sliced(JS::from_ref(parent), rel_pos)
+ }
+ BlobImpl::Sliced(ref grandparent, ref old_rel_pos) => {
+ // Adjust the slicing position, using same parent
+ let new_rel_pos = old_rel_pos.slice_inner(&rel_pos);
+
+ if let BlobImpl::File(ref id, _) = *grandparent.blob_impl.borrow() {
+ inc_ref_id(global.r(), id.clone());
+ }
+
+ BlobImpl::Sliced(grandparent.clone(), new_rel_pos)
+ }
+ };
+
+ Blob::new(global.r(), blob_impl, relativeContentType.into())
+ }
+
// https://w3c.github.io/FileAPI/#constructorBlob
pub fn Constructor(global: GlobalRef,
blobParts: Option<Vec<BlobOrString>>,
@@ -154,38 +118,110 @@ impl Blob {
}
};
- let slice = DataSlice::from_bytes(bytes);
- Ok(Blob::new(global, BlobImpl::new_from_slice(slice), blobPropertyBag.get_typestring()))
+ Ok(Blob::new(global, BlobImpl::new_from_bytes(bytes), blobPropertyBag.get_typestring()))
}
/// Get a slice to inner data, this might incur synchronous read and caching
- pub fn get_slice(&self) -> Result<DataSlice, ()> {
- match self.blob_impl {
- BlobImpl::File(ref id, ref slice) => {
- match *slice.borrow() {
+ pub fn get_bytes(&self) -> Result<Vec<u8>, ()> {
+ match *self.blob_impl.borrow() {
+ BlobImpl::File(ref id, ref cached) => {
+ let buffer = match *cached.borrow() {
Some(ref s) => Ok(s.clone()),
None => {
let global = self.global();
let s = read_file(global.r(), id.clone())?;
- *slice.borrow_mut() = Some(s.clone()); // Cached
Ok(s)
}
+ };
+
+ // Cache
+ if let Ok(buf) = buffer.clone() {
+ *cached.borrow_mut() = Some(buf);
}
+
+ buffer
+ }
+ BlobImpl::Memory(ref s) => Ok(s.clone()),
+ BlobImpl::Sliced(ref parent, ref rel_pos) => {
+ parent.get_bytes().map(|v| {
+ let range = rel_pos.to_abs_range(v.len());
+ v.index(range).to_vec()
+ })
}
- BlobImpl::Memory(ref s) => Ok(s.clone())
}
}
- /// Try to get a slice, and if any exception happens, return the empty slice
- pub fn get_slice_or_empty(&self) -> DataSlice {
- self.get_slice().unwrap_or(DataSlice::empty())
+ pub fn get_id(&self) -> SelectedFileId {
+ match *self.blob_impl.borrow() {
+ BlobImpl::File(ref id, _) => id.clone(),
+ BlobImpl::Memory(ref slice) => self.promote_to_file(slice),
+ BlobImpl::Sliced(ref parent, ref rel_pos) => {
+ match *parent.blob_impl.borrow() {
+ BlobImpl::Sliced(_, _) => {
+ debug!("Sliced can't have a sliced parent");
+ // Return dummy id
+ SelectedFileId("".to_string())
+ }
+ BlobImpl::File(ref parent_id, _) =>
+ self.create_sliced_id(parent_id, rel_pos),
+ BlobImpl::Memory(ref bytes) => {
+ let parent_id = parent.promote_to_file(bytes);
+ *self.blob_impl.borrow_mut() = BlobImpl::Sliced(parent.clone(), rel_pos.clone());
+ self.create_sliced_id(&parent_id, rel_pos)
+ }
+ }
+ }
+ }
+ }
+
+ /// Promite memory-based Blob to file-based,
+ /// The bytes in data slice will be transferred to file manager thread
+ fn promote_to_file(&self, bytes: &[u8]) -> SelectedFileId {
+ let global = self.global();
+ let origin = global.r().get_url().origin().unicode_serialization();
+ let filemanager = global.r().resource_threads().sender();
+
+ let entry = BlobURLStoreEntry {
+ type_string: self.typeString.clone(),
+ size: self.Size(),
+ bytes: bytes.to_vec(),
+ };
+
+ let (tx, rx) = ipc::channel().unwrap();
+ let _ = filemanager.send(FileManagerThreadMsg::TransferMemory(entry, tx, origin.clone()));
+
+ match rx.recv().unwrap() {
+ Ok(new_id) => SelectedFileId(new_id.0),
+ // Dummy id
+ Err(_) => SelectedFileId("".to_string()),
+ }
+ }
+
+ fn create_sliced_id(&self, parent_id: &SelectedFileId,
+ rel_pos: &RelativePos) -> SelectedFileId {
+ let global = self.global();
+
+ let origin = global.r().get_url().origin().unicode_serialization();
+
+ let filemanager = global.r().resource_threads().sender();
+ let (tx, rx) = ipc::channel().unwrap();
+ let msg = FileManagerThreadMsg::AddSlicedEntry(parent_id.clone(),
+ rel_pos.clone(),
+ tx, origin.clone());
+ let _ = filemanager.send(msg);
+ let new_id = rx.recv().unwrap().unwrap();
+
+ // Return the indirect id reference
+ SelectedFileId(new_id.0)
}
}
-fn read_file(global: GlobalRef, id: SelectedFileId) -> Result<DataSlice, ()> {
+fn read_file(global: GlobalRef, id: SelectedFileId) -> Result<Vec<u8>, ()> {
let file_manager = global.filemanager_thread();
let (chan, recv) = ipc::channel().map_err(|_|())?;
- let _ = file_manager.send(FileManagerThreadMsg::ReadFile(chan, id));
+ let origin = global.get_url().origin().unicode_serialization();
+ let msg = FileManagerThreadMsg::ReadFile(chan, id, origin);
+ let _ = file_manager.send(msg);
let result = match recv.recv() {
Ok(ret) => ret,
@@ -195,8 +231,7 @@ fn read_file(global: GlobalRef, id: SelectedFileId) -> Result<DataSlice, ()> {
}
};
- let bytes = result.map_err(|_|())?;
- Ok(DataSlice::from_bytes(bytes))
+ result.map_err(|_|())
}
/// Extract bytes from BlobParts, used by Blob and File constructor
@@ -211,7 +246,8 @@ pub fn blob_parts_to_bytes(blobparts: Vec<BlobOrString>) -> Result<Vec<u8>, ()>
ret.append(&mut bytes);
},
&BlobOrString::Blob(ref b) => {
- ret.append(&mut b.get_slice_or_empty().bytes.to_vec());
+ let mut bytes = b.get_bytes().unwrap_or(vec![]);
+ ret.append(&mut bytes);
},
}
}
@@ -222,7 +258,11 @@ pub fn blob_parts_to_bytes(blobparts: Vec<BlobOrString>) -> Result<Vec<u8>, ()>
impl BlobMethods for Blob {
// https://w3c.github.io/FileAPI/#dfn-size
fn Size(&self) -> u64 {
- self.get_slice_or_empty().size()
+ // XXX: This will incur reading if file-based
+ match self.get_bytes() {
+ Ok(s) => s.len() as u64,
+ _ => 0,
+ }
}
// https://w3c.github.io/FileAPI/#dfn-type
@@ -248,10 +288,8 @@ impl BlobMethods for Blob {
}
};
- let global = self.global();
- let bytes = self.get_slice_or_empty().bytes.clone();
- let slice = DataSlice::new(bytes, start, end);
- Blob::new(global.r(), BlobImpl::new_from_slice(slice), relativeContentType.into())
+ let rel_pos = RelativePos::from_opts(start, end);
+ Blob::new_sliced(self, rel_pos, relativeContentType)
}
// https://w3c.github.io/FileAPI/#dfn-isClosed
@@ -274,7 +312,6 @@ impl BlobMethods for Blob {
}
}
-
impl BlobBinding::BlobPropertyBag {
/// Get the normalized inner type string
/// https://w3c.github.io/FileAPI/#dfn-type
@@ -292,3 +329,11 @@ fn is_ascii_printable(string: &str) -> bool {
// https://w3c.github.io/FileAPI/#constructorBlob
string.chars().all(|c| c >= '\x20' && c <= '\x7E')
}
+
+/// Bump the reference counter in file manager thread
+fn inc_ref_id(global: GlobalRef, id: SelectedFileId) {
+ let file_manager = global.filemanager_thread();
+ let origin = global.get_url().origin().unicode_serialization();
+ let msg = FileManagerThreadMsg::IncRef(id, origin);
+ let _ = file_manager.send(msg);
+}
diff --git a/components/script/dom/browsingcontext.rs b/components/script/dom/browsingcontext.rs
index 1b78fb7572d..4c0914ddf3c 100644
--- a/components/script/dom/browsingcontext.rs
+++ b/components/script/dom/browsingcontext.rs
@@ -22,7 +22,7 @@ use js::jsapi::{Handle, HandleId, HandleObject, HandleValue, JSAutoCompartment};
use js::jsapi::{JSContext, JSPROP_READONLY, JSErrNum, JSObject, PropertyDescriptor, JS_DefinePropertyById};
use js::jsapi::{JS_ForwardGetPropertyTo, JS_ForwardSetPropertyTo, JS_GetClass, JSTracer, FreeOp};
use js::jsapi::{JS_GetOwnPropertyDescriptorById, JS_HasPropertyById, MutableHandle};
-use js::jsapi::{MutableHandleValue, ObjectOpResult, RootedObject, RootedValue};
+use js::jsapi::{MutableHandleValue, ObjectOpResult};
use js::jsval::{UndefinedValue, PrivateValue};
use msg::constellation_msg::{PipelineId, SubpageId};
use std::cell::Cell;
@@ -74,16 +74,15 @@ impl BrowsingContext {
assert!(!parent.get().is_null());
assert!(((*JS_GetClass(parent.get())).flags & JSCLASS_IS_GLOBAL) != 0);
let _ac = JSAutoCompartment::new(cx, parent.get());
- let window_proxy = RootedObject::new(cx,
- NewWindowProxy(cx, parent, handler));
- assert!(!window_proxy.ptr.is_null());
+ rooted!(in(cx) let window_proxy = NewWindowProxy(cx, parent, handler));
+ assert!(!window_proxy.is_null());
let object = box BrowsingContext::new_inherited(frame_element, id);
let raw = Box::into_raw(object);
- SetProxyExtra(window_proxy.ptr, 0, &PrivateValue(raw as *const _));
+ SetProxyExtra(window_proxy.get(), 0, &PrivateValue(raw as *const _));
- (*raw).init_reflector(window_proxy.ptr);
+ (*raw).init_reflector(window_proxy.get());
Root::from_ref(&*raw)
}
@@ -235,7 +234,7 @@ unsafe fn GetSubframeWindow(cx: *mut JSContext,
-> Option<Root<Window>> {
let index = get_array_index_from_id(cx, id);
if let Some(index) = index {
- let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object());
+ rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object());
let win = root_from_handleobject::<Window>(target.handle()).unwrap();
let mut found = false;
return win.IndexedGetter(index, &mut found);
@@ -248,25 +247,26 @@ unsafe fn GetSubframeWindow(cx: *mut JSContext,
unsafe extern "C" fn getOwnPropertyDescriptor(cx: *mut JSContext,
proxy: HandleObject,
id: HandleId,
- desc: MutableHandle<PropertyDescriptor>)
+ mut desc: MutableHandle<PropertyDescriptor>)
-> bool {
let window = GetSubframeWindow(cx, proxy, id);
if let Some(window) = window {
- let mut val = RootedValue::new(cx, UndefinedValue());
+ rooted!(in(cx) let mut val = UndefinedValue());
window.to_jsval(cx, val.handle_mut());
- (*desc.ptr).value = val.ptr;
- fill_property_descriptor(&mut *desc.ptr, *proxy.ptr, JSPROP_READONLY);
+ desc.value = val.get();
+ fill_property_descriptor(&mut desc, proxy.get(), JSPROP_READONLY);
return true;
}
- let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object());
+ rooted!(in(cx) let target = GetProxyPrivate(proxy.get()).to_object());
if !JS_GetOwnPropertyDescriptorById(cx, target.handle(), id, desc) {
return false;
}
- assert!(desc.get().obj.is_null() || desc.get().obj == target.ptr);
- if desc.get().obj == target.ptr {
- desc.get().obj = *proxy.ptr;
+ assert!(desc.obj.is_null() || desc.obj == target.get());
+ if desc.obj == target.get() {
+ // FIXME(#11868) Should assign to desc.obj, desc.get() is a copy.
+ desc.get().obj = proxy.get();
}
true
@@ -288,7 +288,7 @@ unsafe extern "C" fn defineProperty(cx: *mut JSContext,
return true;
}
- let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object());
+ rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object());
JS_DefinePropertyById(cx, target.handle(), id, desc, res)
}
@@ -304,7 +304,7 @@ unsafe extern "C" fn has(cx: *mut JSContext,
return true;
}
- let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object());
+ rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object());
let mut found = false;
if !JS_HasPropertyById(cx, target.handle(), id, &mut found) {
return false;
@@ -327,7 +327,7 @@ unsafe extern "C" fn get(cx: *mut JSContext,
return true;
}
- let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object());
+ rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object());
JS_ForwardGetPropertyTo(cx, target.handle(), id, receiver, vp)
}
@@ -345,7 +345,7 @@ unsafe extern "C" fn set(cx: *mut JSContext,
return true;
}
- let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object());
+ rooted!(in(cx) let target = GetProxyPrivate(*proxy.ptr).to_object());
JS_ForwardSetPropertyTo(cx,
target.handle(),
id,
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index fc6afdc2b25..1c6f83651d1 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -3,8 +3,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use canvas_traits::{Canvas2dMsg, CanvasCommonMsg, CanvasMsg};
-use canvas_traits::{CompositionOrBlending, LineCapStyle, LineJoinStyle};
-use canvas_traits::{FillOrStrokeStyle, FillRule, LinearGradientStyle, RadialGradientStyle, RepetitionStyle};
+use canvas_traits::{CompositionOrBlending, FillOrStrokeStyle, FillRule};
+use canvas_traits::{LineCapStyle, LineJoinStyle, LinearGradientStyle};
+use canvas_traits::{RadialGradientStyle, RepetitionStyle, byte_swap};
use cssparser::Color as CSSColor;
use cssparser::{Parser, RGBA};
use dom::bindings::cell::DOMRefCell;
@@ -46,7 +47,6 @@ use std::str::FromStr;
use std::{cmp, fmt};
use unpremultiplytable::UNPREMULTIPLY_TABLE;
use url::Url;
-use util::vec::byte_swap;
#[must_root]
#[derive(JSTraceable, Clone, HeapSizeOf)]
diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs
index dfa1672715b..87ac897a4e4 100644
--- a/components/script/dom/dedicatedworkerglobalscope.rs
+++ b/components/script/dom/dedicatedworkerglobalscope.rs
@@ -25,7 +25,7 @@ use dom::workerglobalscope::WorkerGlobalScopeInit;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use ipc_channel::router::ROUTER;
use js::jsapi::{HandleValue, JS_SetInterruptCallback};
-use js::jsapi::{JSAutoCompartment, JSContext, RootedValue};
+use js::jsapi::{JSAutoCompartment, JSContext};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
use msg::constellation_msg::PipelineId;
@@ -290,7 +290,7 @@ impl DedicatedWorkerGlobalScope {
let target = self.upcast();
let _ac = JSAutoCompartment::new(scope.get_cx(),
scope.reflector().get_jsobject().get());
- let mut message = RootedValue::new(scope.get_cx(), UndefinedValue());
+ rooted!(in(scope.get_cx()) let mut message = UndefinedValue());
data.read(GlobalRef::Worker(scope), message.handle_mut());
MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message.handle());
},
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 23c50075068..2160a3a4556 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -28,7 +28,6 @@ use dom::bindings::num::Finite;
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::str::{DOMString, USVString};
-use dom::bindings::trace::RootedVec;
use dom::bindings::xmlname::XMLName::InvalidXMLName;
use dom::bindings::xmlname::{validate_and_extract, namespace_from_domstring, xml_name_type};
use dom::browsingcontext::BrowsingContext;
@@ -115,6 +114,7 @@ use std::cell::{Cell, Ref, RefMut};
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::default::Default;
+use std::iter::once;
use std::mem;
use std::ptr;
use std::rc::Rc;
@@ -124,11 +124,11 @@ use style::attr::AttrValue;
use style::context::ReflowGoal;
use style::restyle_hints::ElementSnapshot;
use style::servo::Stylesheet;
+use style::str::{split_html_space_chars, str_join};
use time;
use url::Url;
use url::percent_encoding::percent_decode;
-use util::prefs::mozbrowser_enabled;
-use util::str::{split_html_space_chars, str_join};
+use util::prefs::PREFS;
#[derive(JSTraceable, PartialEq, HeapSizeOf)]
pub enum IsHTMLDocument {
@@ -1009,18 +1009,15 @@ impl Document {
}
}
- let mut touches = RootedVec::new();
+ rooted_vec!(let mut touches);
touches.extend(self.active_touch_points.borrow().iter().cloned());
-
- let mut changed_touches = RootedVec::new();
- changed_touches.push(JS::from_ref(&*touch));
-
- let mut target_touches = RootedVec::new();
+ rooted_vec!(let mut target_touches);
target_touches.extend(self.active_touch_points
.borrow()
.iter()
.filter(|t| t.Target() == target)
.cloned());
+ rooted_vec!(let changed_touches <- once(touch));
let event = TouchEvent::new(window,
DOMString::from(event_name),
@@ -1262,7 +1259,7 @@ impl Document {
}
pub fn trigger_mozbrowser_event(&self, event: MozBrowserEvent) {
- if mozbrowser_enabled() {
+ if PREFS.is_mozbrowser_enabled() {
if let Some((containing_pipeline_id, subpage_id, _)) = self.window.parent_info() {
let event = ConstellationMsg::MozBrowserEvent(containing_pipeline_id,
subpage_id,
diff --git a/components/script/dom/domtokenlist.rs b/components/script/dom/domtokenlist.rs
index 1fb53e6ce06..364b6366282 100644
--- a/components/script/dom/domtokenlist.rs
+++ b/components/script/dom/domtokenlist.rs
@@ -13,7 +13,7 @@ use dom::bindings::str::DOMString;
use dom::element::Element;
use dom::node::window_from_node;
use string_cache::Atom;
-use util::str::HTML_SPACE_CHARACTERS;
+use style::str::HTML_SPACE_CHARACTERS;
#[dom_struct]
pub struct DOMTokenList {
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 479a73dee86..d9535663d46 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -75,7 +75,6 @@ use selectors::matching::{DeclarationBlock, ElementFlags, matches};
use selectors::matching::{HAS_SLOW_SELECTOR, HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
use selectors::matching::{common_style_affecting_attributes, rare_style_affecting_attributes};
use selectors::parser::{AttrSelector, NamespaceConstraint, parse_author_origin_selector_list_from_str};
-use smallvec::VecLike;
use std::ascii::AsciiExt;
use std::borrow::Cow;
use std::cell::{Cell, Ref};
@@ -91,6 +90,7 @@ use style::properties::DeclaredValue;
use style::properties::longhands::{self, background_image, border_spacing, font_family, overflow_x, font_size};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl};
+use style::sink::Push;
use style::values::CSSFloat;
use style::values::specified::{self, CSSColor, CSSRGBA, LengthOrPercentage};
@@ -275,7 +275,7 @@ pub trait LayoutElementHelpers {
#[allow(unsafe_code)]
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, &mut V)
- where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>;
+ where V: Push<DeclarationBlock<Vec<PropertyDeclaration>>>;
#[allow(unsafe_code)]
unsafe fn get_colspan(self) -> u32;
#[allow(unsafe_code)]
@@ -308,7 +308,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
#[allow(unsafe_code)]
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
- where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>
+ where V: Push<DeclarationBlock<Vec<PropertyDeclaration>>>
{
#[inline]
fn from_declaration(rule: PropertyDeclaration) -> DeclarationBlock<Vec<PropertyDeclaration>> {
diff --git a/components/script/dom/errorevent.rs b/components/script/dom/errorevent.rs
index f6c5802ca29..61db675f551 100644
--- a/components/script/dom/errorevent.rs
+++ b/components/script/dom/errorevent.rs
@@ -13,7 +13,7 @@ use dom::bindings::js::{MutHeapJSVal, Root};
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::event::{Event, EventBubbles, EventCancelable};
-use js::jsapi::{RootedValue, HandleValue, JSContext};
+use js::jsapi::{HandleValue, JSContext};
use js::jsval::JSVal;
use std::cell::Cell;
use string_cache::Atom;
@@ -93,7 +93,7 @@ impl ErrorEvent {
// Dictionaries need to be rooted
// https://github.com/servo/servo/issues/6381
- let error = RootedValue::new(global.get_cx(), init.error);
+ rooted!(in(global.get_cx()) let error = init.error);
let event = ErrorEvent::new(global, Atom::from(type_),
bubbles, cancelable,
msg, file_name,
diff --git a/components/script/dom/eventdispatcher.rs b/components/script/dom/eventdispatcher.rs
index cef67d2d18c..7509df2ef13 100644
--- a/components/script/dom/eventdispatcher.rs
+++ b/components/script/dom/eventdispatcher.rs
@@ -9,7 +9,6 @@ use dom::bindings::global::GlobalRoot;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root, RootedReference};
use dom::bindings::reflector::Reflectable;
-use dom::bindings::trace::RootedVec;
use dom::document::Document;
use dom::event::{Event, EventPhase};
use dom::eventtarget::{CompiledEventListener, EventTarget, ListenerPhase};
@@ -128,12 +127,12 @@ pub fn dispatch_event(target: &EventTarget,
// Step 3. The "invoke" algorithm is only used on `target` separately,
// so we don't put it in the path.
- let mut event_path: RootedVec<JS<EventTarget>> = RootedVec::new();
+ rooted_vec!(let mut event_path);
// Step 4.
if let Some(target_node) = target.downcast::<Node>() {
for ancestor in target_node.ancestors() {
- event_path.push(JS::from_ref(ancestor.upcast()));
+ event_path.push(JS::from_ref(ancestor.upcast::<EventTarget>()));
}
let top_most_ancestor_or_target =
Root::from_ref(event_path.r().last().cloned().unwrap_or(target));
diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs
index 9f41abee7d7..0175023deb1 100644
--- a/components/script/dom/eventtarget.rs
+++ b/components/script/dom/eventtarget.rs
@@ -29,7 +29,7 @@ use dom::virtualmethods::VirtualMethods;
use dom::window::Window;
use fnv::FnvHasher;
use heapsize::HeapSizeOf;
-use js::jsapi::{CompileFunction, JS_GetFunctionObject, RootedValue, RootedFunction, JSAutoCompartment};
+use js::jsapi::{CompileFunction, JS_GetFunctionObject, JSAutoCompartment};
use js::rust::{AutoObjectVectorWrapper, CompileOptionsWrapper};
use libc::{c_char, size_t};
use std::collections::HashMap;
@@ -156,7 +156,7 @@ impl CompiledEventListener {
if let Some(event) = event.downcast::<ErrorEvent>() {
let global = object.global();
let cx = global.r().get_cx();
- let error = RootedValue::new(cx, event.Error(cx));
+ rooted!(in(cx) let error = event.Error(cx));
let return_value = handler.Call_(object,
EventOrString::String(event.Message()),
Some(event.Filename()),
@@ -166,7 +166,7 @@ impl CompiledEventListener {
exception_handle);
// Step 4
if let Ok(return_value) = return_value {
- let return_value = RootedValue::new(cx, return_value);
+ rooted!(in(cx) let return_value = return_value);
if return_value.handle().is_boolean() && return_value.handle().to_boolean() == true {
event.upcast::<Event>().PreventDefault();
}
@@ -203,7 +203,7 @@ impl CompiledEventListener {
if let Ok(value) = handler.Call_(object, event, exception_handle) {
let global = object.global();
let cx = global.r().get_cx();
- let value = RootedValue::new(cx, value);
+ rooted!(in(cx) let value = value);
let value = value.handle();
//Step 4
@@ -411,7 +411,7 @@ impl EventTarget {
let scopechain = AutoObjectVectorWrapper::new(cx);
let _ac = JSAutoCompartment::new(cx, window.reflector().get_jsobject().get());
- let mut handler = RootedFunction::new(cx, ptr::null_mut());
+ rooted!(in(cx) let mut handler = ptr::null_mut());
let rv = unsafe {
CompileFunction(cx,
scopechain.ptr,
@@ -423,7 +423,7 @@ impl EventTarget {
body.len() as size_t,
handler.handle_mut())
};
- if !rv || handler.ptr.is_null() {
+ if !rv || handler.get().is_null() {
// Step 1.8.2
unsafe {
report_pending_exception(cx, self.reflector().get_jsobject().get());
@@ -433,7 +433,7 @@ impl EventTarget {
}
// TODO step 1.11-13
- let funobj = unsafe { JS_GetFunctionObject(handler.ptr) };
+ let funobj = unsafe { JS_GetFunctionObject(handler.get()) };
assert!(!funobj.is_null());
// Step 1.14
if is_error {
diff --git a/components/script/dom/file.rs b/components/script/dom/file.rs
index 86e8888a88f..75f73aeda59 100644
--- a/components/script/dom/file.rs
+++ b/components/script/dom/file.rs
@@ -10,7 +10,7 @@ use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
-use dom::blob::{Blob, BlobImpl, DataSlice, blob_parts_to_bytes};
+use dom::blob::{Blob, BlobImpl, blob_parts_to_bytes};
use dom::window::Window;
use net_traits::filemanager_thread::SelectedFile;
use time;
@@ -23,6 +23,7 @@ pub struct File {
}
impl File {
+ #[allow(unrooted_must_root)]
fn new_inherited(blob_impl: BlobImpl, name: DOMString,
modified: Option<i64>, typeString: &str) -> File {
File {
@@ -39,6 +40,7 @@ impl File {
}
}
+ #[allow(unrooted_must_root)]
pub fn new(global: GlobalRef, blob_impl: BlobImpl,
name: DOMString, modified: Option<i64>, typeString: &str) -> Root<File> {
reflect_dom_object(box File::new_inherited(blob_impl, name, modified, typeString),
@@ -69,9 +71,8 @@ impl File {
let ref blobPropertyBag = filePropertyBag.parent;
let typeString = blobPropertyBag.get_typestring();
- let slice = DataSlice::from_bytes(bytes);
let modified = filePropertyBag.lastModified;
- Ok(File::new(global, BlobImpl::new_from_slice(slice), filename, modified, &typeString))
+ Ok(File::new(global, BlobImpl::new_from_bytes(bytes), filename, modified, &typeString))
}
pub fn name(&self) -> &DOMString {
diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs
index 9e3f4674fa1..634f2facafe 100644
--- a/components/script/dom/filereader.rs
+++ b/components/script/dom/filereader.rs
@@ -13,7 +13,7 @@ use dom::bindings::js::{JS, MutNullableHeap, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::str::DOMString;
-use dom::blob::{Blob, DataSlice};
+use dom::blob::Blob;
use dom::domexception::{DOMErrorName, DOMException};
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventtarget::EventTarget;
@@ -27,6 +27,7 @@ use script_runtime::ScriptThreadEventCategory::FileRead;
use script_runtime::{ScriptChan, CommonScriptMsg};
use script_thread::Runnable;
use std::cell::Cell;
+use std::sync::Arc;
use string_cache::Atom;
use util::thread::spawn_named;
@@ -160,7 +161,7 @@ impl FileReader {
// https://w3c.github.io/FileAPI/#dfn-readAsText
pub fn process_read_eof(filereader: TrustedFileReader, gen_id: GenerationId,
- data: ReadMetaData, blob_contents: DataSlice) {
+ data: ReadMetaData, blob_contents: Arc<Vec<u8>>) {
let fr = filereader.root();
macro_rules! return_on_abort(
@@ -176,12 +177,11 @@ impl FileReader {
fr.change_ready_state(FileReaderReadyState::Done);
// Step 8.2
- let bytes = blob_contents.get_bytes();
let output = match data.function {
FileReaderFunction::ReadAsDataUrl =>
- FileReader::perform_readasdataurl(data, bytes),
+ FileReader::perform_readasdataurl(data, &blob_contents),
FileReaderFunction::ReadAsText =>
- FileReader::perform_readastext(data, bytes),
+ FileReader::perform_readastext(data, &blob_contents),
};
*fr.result.borrow_mut() = Some(output);
@@ -349,7 +349,7 @@ impl FileReader {
self.change_ready_state(FileReaderReadyState::Loading);
// Step 4
- let blob_contents = blob.get_slice_or_empty();
+ let blob_contents = Arc::new(blob.get_bytes().unwrap_or(vec![]));
let type_ = blob.Type();
@@ -376,7 +376,7 @@ pub enum FileReaderEvent {
ProcessRead(TrustedFileReader, GenerationId),
ProcessReadData(TrustedFileReader, GenerationId),
ProcessReadError(TrustedFileReader, GenerationId, DOMErrorName),
- ProcessReadEOF(TrustedFileReader, GenerationId, ReadMetaData, DataSlice)
+ ProcessReadEOF(TrustedFileReader, GenerationId, ReadMetaData, Arc<Vec<u8>>)
}
impl Runnable for FileReaderEvent {
@@ -400,7 +400,7 @@ impl Runnable for FileReaderEvent {
}
// https://w3c.github.io/FileAPI/#thread-read-operation
-fn perform_annotated_read_operation(gen_id: GenerationId, data: ReadMetaData, blob_contents: DataSlice,
+fn perform_annotated_read_operation(gen_id: GenerationId, data: ReadMetaData, blob_contents: Arc<Vec<u8>>,
filereader: TrustedFileReader, script_chan: Box<ScriptChan + Send>) {
let chan = &script_chan;
// Step 4
diff --git a/components/script/dom/formdata.rs b/components/script/dom/formdata.rs
index 6d5b1900ec5..41168495847 100644
--- a/components/script/dom/formdata.rs
+++ b/components/script/dom/formdata.rs
@@ -126,8 +126,9 @@ impl FormData {
Some(fname) => {
let global = self.global();
let name = DOMString::from(fname.0);
- let slice = blob.get_slice_or_empty();
- Root::upcast(File::new(global.r(), BlobImpl::new_from_slice(slice), name, None, ""))
+ let bytes = blob.get_bytes().unwrap_or(vec![]);
+
+ Root::upcast(File::new(global.r(), BlobImpl::new_from_bytes(bytes), name, None, ""))
}
None => Root::from_ref(blob)
}
diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs
index 161a7d43eaf..713aa0a92cb 100644
--- a/components/script/dom/htmlanchorelement.rs
+++ b/components/script/dom/htmlanchorelement.rs
@@ -29,7 +29,7 @@ use std::default::Default;
use string_cache::Atom;
use style::attr::AttrValue;
use url::Url;
-use util::prefs::mozbrowser_enabled;
+use util::prefs::PREFS;
#[dom_struct]
pub struct HTMLAnchorElement {
@@ -575,7 +575,7 @@ fn follow_hyperlink(subject: &Element, hyperlink_suffix: Option<String>) {
// Step 8: navigate to the URL.
if let Some(target) = target {
- if mozbrowser_enabled() && !is_current_browsing_context(target.Value()) {
+ if PREFS.is_mozbrowser_enabled() && !is_current_browsing_context(target.Value()) {
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowseropenwindow
// TODO: referrer and opener
// TODO: should we send the normalized url or the non-normalized href?
diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs
index bbacf5c7a0d..798d0731b2c 100644
--- a/components/script/dom/htmlcollection.rs
+++ b/components/script/dom/htmlcollection.rs
@@ -17,7 +17,7 @@ use dom::window::Window;
use std::ascii::AsciiExt;
use std::cell::Cell;
use string_cache::{Atom, Namespace, QualName};
-use util::str::split_html_space_chars;
+use style::str::split_html_space_chars;
pub trait CollectionFilter : JSTraceable {
fn filter<'a>(&self, elem: &'a Element, root: &'a Node) -> bool;
diff --git a/components/script/dom/htmlfontelement.rs b/components/script/dom/htmlfontelement.rs
index 5968efc7948..85dd000d183 100644
--- a/components/script/dom/htmlfontelement.rs
+++ b/components/script/dom/htmlfontelement.rs
@@ -15,8 +15,8 @@ use dom::node::Node;
use dom::virtualmethods::VirtualMethods;
use string_cache::Atom;
use style::attr::AttrValue;
+use style::str::{HTML_SPACE_CHARACTERS, read_numbers};
use style::values::specified;
-use util::str::{HTML_SPACE_CHARACTERS, read_numbers};
#[dom_struct]
pub struct HTMLFontElement {
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 515d49c0f7c..b31d33d5685 100644
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -51,10 +51,10 @@ use std::cell::Cell;
use std::sync::mpsc::Sender;
use string_cache::Atom;
use style::attr::AttrValue;
+use style::str::split_html_space_chars;
use task_source::TaskSource;
use task_source::dom_manipulation::DOMManipulationTask;
use url::form_urlencoded;
-use util::str::split_html_space_chars;
#[derive(JSTraceable, PartialEq, Clone, Copy, HeapSizeOf)]
pub struct GenerationId(u32);
@@ -324,9 +324,9 @@ impl HTMLFormElement {
content_disposition,
content_type));
- let slice = f.upcast::<Blob>().get_slice_or_empty();
+ let bytes = &f.upcast::<Blob>().get_bytes().unwrap_or(vec![])[..];
- let decoded = encoding.decode(&slice.get_bytes(), DecoderTrap::Replace)
+ let decoded = encoding.decode(bytes, DecoderTrap::Replace)
.expect("Invalid encoding in file");
result.push_str(&decoded);
}
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index 3c5377b8c98..dccba5846cc 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -36,7 +36,7 @@ use dom::urlhelper::UrlHelper;
use dom::virtualmethods::VirtualMethods;
use dom::window::{ReflowReason, Window};
use ipc_channel::ipc;
-use js::jsapi::{JSAutoCompartment, RootedValue, JSContext, MutableHandleValue};
+use js::jsapi::{JSAutoCompartment, JSContext, MutableHandleValue};
use js::jsval::{UndefinedValue, NullValue};
use msg::constellation_msg::{FrameType, LoadData, NavigationDirection, PipelineId, SubpageId};
use net_traits::response::HttpsState;
@@ -48,17 +48,20 @@ use string_cache::Atom;
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
use style::context::ReflowGoal;
use url::Url;
-use util::prefs::mozbrowser_enabled;
-
-#[derive(HeapSizeOf)]
-enum SandboxAllowance {
- AllowNothing = 0x00,
- AllowSameOrigin = 0x01,
- AllowTopNavigation = 0x02,
- AllowForms = 0x04,
- AllowScripts = 0x08,
- AllowPointerLock = 0x10,
- AllowPopups = 0x20
+use util::prefs::PREFS;
+use util::servo_version;
+
+bitflags! {
+ #[derive(JSTraceable, HeapSizeOf)]
+ flags SandboxAllowance: u8 {
+ const ALLOW_NOTHING = 0x00,
+ const ALLOW_SAME_ORIGIN = 0x01,
+ const ALLOW_TOP_NAVIGATION = 0x02,
+ const ALLOW_FORMS = 0x04,
+ const ALLOW_SCRIPTS = 0x08,
+ const ALLOW_POINTER_LOCK = 0x10,
+ const ALLOW_POPUPS = 0x20
+ }
}
#[dom_struct]
@@ -67,7 +70,7 @@ pub struct HTMLIFrameElement {
pipeline_id: Cell<Option<PipelineId>>,
subpage_id: Cell<Option<SubpageId>>,
sandbox: MutNullableHeap<JS<DOMTokenList>>,
- sandbox_allowance: Cell<Option<u8>>,
+ sandbox_allowance: Cell<Option<SandboxAllowance>>,
load_blocker: DOMRefCell<Option<LoadBlocker>>,
visibility: Cell<bool>,
}
@@ -142,7 +145,7 @@ impl HTMLIFrameElement {
.send(ConstellationMsg::ScriptLoadedURLInIFrame(load_info))
.unwrap();
- if mozbrowser_enabled() {
+ if PREFS.is_mozbrowser_enabled() {
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadstart
self.dispatch_mozbrowser_event(MozBrowserEvent::LoadStart);
}
@@ -161,14 +164,14 @@ impl HTMLIFrameElement {
// TODO(gw): Support mozbrowser event types that have detail which is not a string.
// See https://developer.mozilla.org/en-US/docs/Web/API/Using_the_Browser_API
// for a list of mozbrowser events.
- assert!(mozbrowser_enabled());
+ assert!(PREFS.is_mozbrowser_enabled());
if self.Mozbrowser() {
let window = window_from_node(self);
let custom_event = unsafe {
let cx = window.get_cx();
let _ac = JSAutoCompartment::new(cx, window.reflector().get_jsobject().get());
- let mut detail = RootedValue::new(cx, UndefinedValue());
+ rooted!(in(cx) let mut detail = UndefinedValue());
let event_name = Atom::from(event.name());
self.build_mozbrowser_event_detail(event, cx, detail.handle_mut());
CustomEvent::new(GlobalRef::Window(window.r()),
@@ -358,6 +361,7 @@ impl MozBrowserEventDetailBuilder for HTMLIFrameElement {
type_: Some(DOMString::from(error_type.name())),
description: description.map(DOMString::from),
report: report.map(DOMString::from),
+ version: Some(DOMString::from_string(servo_version().into())),
}.to_jsval(cx, rval);
},
MozBrowserEvent::SecurityChange(https_state) => {
@@ -589,17 +593,17 @@ impl VirtualMethods for HTMLIFrameElement {
match attr.local_name() {
&atom!("sandbox") => {
self.sandbox_allowance.set(mutation.new_value(attr).map(|value| {
- let mut modes = SandboxAllowance::AllowNothing as u8;
+ let mut modes = ALLOW_NOTHING;
for token in value.as_tokens() {
modes |= match &*token.to_ascii_lowercase() {
- "allow-same-origin" => SandboxAllowance::AllowSameOrigin,
- "allow-forms" => SandboxAllowance::AllowForms,
- "allow-pointer-lock" => SandboxAllowance::AllowPointerLock,
- "allow-popups" => SandboxAllowance::AllowPopups,
- "allow-scripts" => SandboxAllowance::AllowScripts,
- "allow-top-navigation" => SandboxAllowance::AllowTopNavigation,
- _ => SandboxAllowance::AllowNothing
- } as u8;
+ "allow-same-origin" => ALLOW_SAME_ORIGIN,
+ "allow-forms" => ALLOW_FORMS,
+ "allow-pointer-lock" => ALLOW_POINTER_LOCK,
+ "allow-popups" => ALLOW_POPUPS,
+ "allow-scripts" => ALLOW_SCRIPTS,
+ "allow-top-navigation" => ALLOW_TOP_NAVIGATION,
+ _ => ALLOW_NOTHING
+ };
}
modes
}));
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 6c3b008bfc8..0ee2023e44a 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -42,10 +42,10 @@ use std::ops::Range;
use string_cache::Atom;
use style::attr::AttrValue;
use style::element_state::*;
+use style::str::split_commas;
use textinput::KeyReaction::{DispatchInput, Nothing, RedrawSelection, TriggerDefaultAction};
use textinput::Lines::Single;
use textinput::{TextInput, SelectionDirection};
-use util::str::split_commas;
const DEFAULT_SUBMIT_VALUE: &'static str = "Submit";
const DEFAULT_RESET_VALUE: &'static str = "Reset";
@@ -1150,17 +1150,20 @@ impl Activatable for HTMLInputElement {
EventCancelable::NotCancelable);
},
InputType::InputFile => {
+ // https://html.spec.whatwg.org/multipage/#file-upload-state-(type=file)
let window = window_from_node(self);
+ let origin = window.get_url().origin().unicode_serialization();
let filemanager = window.resource_threads().sender();
let mut files: Vec<Root<File>> = vec![];
let mut error = None;
let filter = filter_from_accept(&self.Accept());
+ let target = self.upcast::<EventTarget>();
if self.Multiple() {
let (chan, recv) = ipc::channel().expect("Error initializing channel");
- let msg = FileManagerThreadMsg::SelectFiles(filter, chan);
+ let msg = FileManagerThreadMsg::SelectFiles(filter, chan, origin);
let _ = filemanager.send(msg).unwrap();
match recv.recv().expect("IpcSender side error") {
@@ -1168,16 +1171,32 @@ impl Activatable for HTMLInputElement {
for selected in selected_files {
files.push(File::new_from_selected(window.r(), selected));
}
+
+ target.fire_event("input",
+ EventBubbles::Bubbles,
+ EventCancelable::NotCancelable);
+ target.fire_event("change",
+ EventBubbles::Bubbles,
+ EventCancelable::NotCancelable);
},
Err(err) => error = Some(err),
};
} else {
let (chan, recv) = ipc::channel().expect("Error initializing channel");
- let msg = FileManagerThreadMsg::SelectFile(filter, chan);
+ let msg = FileManagerThreadMsg::SelectFile(filter, chan, origin);
let _ = filemanager.send(msg).unwrap();
match recv.recv().expect("IpcSender side error") {
- Ok(selected) => files.push(File::new_from_selected(window.r(), selected)),
+ Ok(selected) => {
+ files.push(File::new_from_selected(window.r(), selected));
+
+ target.fire_event("input",
+ EventBubbles::Bubbles,
+ EventCancelable::NotCancelable);
+ target.fire_event("change",
+ EventBubbles::Bubbles,
+ EventCancelable::NotCancelable);
+ },
Err(err) => error = Some(err),
};
}
diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs
index 0af076950b3..ed6754afde6 100644
--- a/components/script/dom/htmllinkelement.rs
+++ b/components/script/dom/htmllinkelement.rs
@@ -40,9 +40,9 @@ use style::attr::AttrValue;
use style::media_queries::{MediaQueryList, parse_media_query_list};
use style::parser::ParserContextExtraData;
use style::servo::Stylesheet;
+use style::str::HTML_SPACE_CHARACTERS;
use style::stylesheets::Origin;
use url::Url;
-use util::str::HTML_SPACE_CHARACTERS;
no_jsmanaged_fields!(Stylesheet);
@@ -194,6 +194,10 @@ impl VirtualMethods for HTMLLinkElement {
impl HTMLLinkElement {
fn handle_stylesheet_url(&self, href: &str) {
let document = document_from_node(self);
+ if document.browsing_context().is_none() {
+ return;
+ }
+
match document.base_url().join(href) {
Ok(url) => {
let element = self.upcast::<Element>();
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index 70563ec95c7..49d42c31f1a 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -133,9 +133,8 @@ impl AsyncResponseListener for HTMLMediaElementContext {
// Step 5
elem.fire_simple_event("error");
- }
- // => "If the media data cannot be fetched at all..."
- else {
+ } else {
+ // => "If the media data cannot be fetched at all..."
elem.queue_dedicated_media_source_failure_steps();
}
diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs
index 160b4a9c68e..14d8d300bb6 100644
--- a/components/script/dom/htmlmetaelement.rs
+++ b/components/script/dom/htmlmetaelement.rs
@@ -21,9 +21,9 @@ use std::sync::Arc;
use string_cache::Atom;
use style::attr::AttrValue;
use style::servo::Stylesheet;
+use style::str::HTML_SPACE_CHARACTERS;
use style::stylesheets::{CSSRule, Origin};
use style::viewport::ViewportRule;
-use util::str::HTML_SPACE_CHARACTERS;
#[dom_struct]
pub struct HTMLMetaElement {
@@ -70,7 +70,7 @@ impl HTMLMetaElement {
}
fn apply_viewport(&self) {
- if !::util::prefs::get_pref("layout.viewport.enabled").as_boolean().unwrap_or(false) {
+ if !::util::prefs::PREFS.get("layout.viewport.enabled").as_boolean().unwrap_or(false) {
return;
}
let element = self.upcast::<Element>();
diff --git a/components/script/dom/htmloptionelement.rs b/components/script/dom/htmloptionelement.rs
index 67cb4983258..7d0eeb45752 100644
--- a/components/script/dom/htmloptionelement.rs
+++ b/components/script/dom/htmloptionelement.rs
@@ -22,7 +22,7 @@ use dom::virtualmethods::VirtualMethods;
use std::cell::Cell;
use string_cache::Atom;
use style::element_state::*;
-use util::str::{split_html_space_chars, str_join};
+use style::str::{split_html_space_chars, str_join};
#[dom_struct]
pub struct HTMLOptionElement {
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index f280f670e4b..e4ce7fb068f 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -30,7 +30,6 @@ use html5ever::tree_builder::NextParserState;
use hyper::http::RawStatus;
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
-use js::jsapi::RootedValue;
use js::jsval::UndefinedValue;
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError};
use network_listener::{NetworkListener, PreInvoke};
@@ -39,8 +38,8 @@ use std::cell::Cell;
use std::mem;
use std::sync::{Arc, Mutex};
use string_cache::Atom;
+use style::str::{HTML_SPACE_CHARACTERS, StaticStringVec};
use url::Url;
-use util::str::{HTML_SPACE_CHARACTERS, StaticStringVec};
#[dom_struct]
pub struct HTMLScriptElement {
@@ -441,7 +440,7 @@ impl HTMLScriptElement {
// Step 2.b.6.
// TODO: Create a script...
let window = window_from_node(self);
- let mut rval = RootedValue::new(window.get_cx(), UndefinedValue());
+ rooted!(in(window.get_cx()) let mut rval = UndefinedValue());
window.evaluate_script_on_global_with_result(&*source,
url.as_str(),
rval.handle_mut());
diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs
index 3ad9713fb70..58af2b28ac6 100644
--- a/components/script/dom/macros.rs
+++ b/components/script/dom/macros.rs
@@ -503,3 +503,18 @@ macro_rules! document_and_element_event_handlers(
event_handler!(paste, GetOnpaste, SetOnpaste);
)
);
+
+#[macro_export]
+macro_rules! rooted_vec {
+ (let mut $name:ident) => {
+ rooted_vec!(let mut $name <- ::std::iter::empty())
+ };
+ (let $name:ident <- $iter:expr) => {
+ let mut __root = $crate::dom::bindings::trace::RootableVec::new_unrooted();
+ let $name = $crate::dom::bindings::trace::RootedVec::new(&mut __root, $iter);
+ };
+ (let mut $name:ident <- $iter:expr) => {
+ let mut __root = $crate::dom::bindings::trace::RootableVec::new_unrooted();
+ let mut $name = $crate::dom::bindings::trace::RootedVec::new(&mut __root, $iter);
+ }
+}
diff --git a/components/script/dom/messageevent.rs b/components/script/dom/messageevent.rs
index 8d638adae06..b5b46fba5d8 100644
--- a/components/script/dom/messageevent.rs
+++ b/components/script/dom/messageevent.rs
@@ -13,7 +13,7 @@ use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::event::Event;
use dom::eventtarget::EventTarget;
-use js::jsapi::{RootedValue, HandleValue, Heap, JSContext};
+use js::jsapi::{HandleValue, Heap, JSContext};
use js::jsval::JSVal;
use std::default::Default;
use string_cache::Atom;
@@ -66,7 +66,7 @@ impl MessageEvent {
-> Fallible<Root<MessageEvent>> {
// Dictionaries need to be rooted
// https://github.com/servo/servo/issues/6381
- let data = RootedValue::new(global.get_cx(), init.data);
+ rooted!(in(global.get_cx()) let data = init.data);
let ev = MessageEvent::new(global, Atom::from(type_), init.parent.bubbles, init.parent.cancelable,
data.handle(),
init.origin.clone(), init.lastEventId.clone());
diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs
index d6b5316f2d2..78b1a33005f 100644
--- a/components/script/dom/mouseevent.rs
+++ b/components/script/dom/mouseevent.rs
@@ -17,7 +17,7 @@ use dom::uievent::UIEvent;
use dom::window::Window;
use std::cell::Cell;
use std::default::Default;
-use util::prefs;
+use util::prefs::PREFS;
#[dom_struct]
pub struct MouseEvent {
@@ -157,7 +157,7 @@ impl MouseEventMethods for MouseEvent {
// This returns the same result as current gecko.
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/which
fn Which(&self) -> i32 {
- if prefs::get_pref("dom.mouseevent.which.enabled").as_boolean().unwrap_or(false) {
+ if PREFS.get("dom.mouseevent.which.enabled").as_boolean().unwrap_or(false) {
(self.button.get() + 1) as i32
} else {
0
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index ec370dff293..811716088b6 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -28,7 +28,6 @@ use dom::bindings::js::RootedReference;
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::str::{DOMString, USVString};
-use dom::bindings::trace::RootedVec;
use dom::bindings::xmlname::namespace_from_domstring;
use dom::characterdata::{CharacterData, LayoutCharacterDataHelpers};
use dom::document::{Document, DocumentSource, IsHTMLDocument};
@@ -740,7 +739,10 @@ impl Node {
Err(()) => Err(Error::Syntax),
// Step 3.
Ok(selectors) => {
- Ok(QuerySelectorIterator::new(self.traverse_preorder(), selectors))
+ let mut descendants = self.traverse_preorder();
+ // Skip the root of the tree.
+ assert!(&*descendants.next().unwrap() == self);
+ Ok(QuerySelectorIterator::new(descendants, selectors))
}
}
}
@@ -1559,7 +1561,7 @@ impl Node {
parent.ranges.increase_above(parent, index, count);
}
}
- let mut new_nodes = RootedVec::new();
+ rooted_vec!(let mut new_nodes);
let new_nodes = if let NodeTypeId::DocumentFragment = node.type_id() {
// Step 3.
new_nodes.extend(node.children().map(|kid| JS::from_ref(&*kid)));
@@ -1603,9 +1605,9 @@ impl Node {
Node::adopt(node, &*parent.owner_doc());
}
// Step 2.
- let removed_nodes = parent.children().collect::<RootedVec<_>>();
+ rooted_vec!(let removed_nodes <- parent.children());
// Step 3.
- let mut added_nodes = RootedVec::new();
+ rooted_vec!(let mut added_nodes);
let added_nodes = if let Some(node) = node.as_ref() {
if let NodeTypeId::DocumentFragment = node.type_id() {
added_nodes.extend(node.children().map(|child| JS::from_ref(&*child)));
@@ -2149,7 +2151,7 @@ impl NodeMethods for Node {
};
// Step 12.
- let mut nodes = RootedVec::new();
+ rooted_vec!(let mut nodes);
let nodes = if node.type_id() == NodeTypeId::DocumentFragment {
nodes.extend(node.children().map(|node| JS::from_ref(&*node)));
nodes.r()
diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs
index bde5515238b..b8cb72c4dc4 100644
--- a/components/script/dom/range.rs
+++ b/components/script/dom/range.rs
@@ -17,7 +17,7 @@ use dom::bindings::inheritance::{CharacterDataTypeId, NodeTypeId};
use dom::bindings::js::{JS, MutHeap, Root, RootedReference};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
-use dom::bindings::trace::{JSTraceable, RootedVec};
+use dom::bindings::trace::JSTraceable;
use dom::bindings::weakref::{WeakRef, WeakRefVec};
use dom::characterdata::CharacterData;
use dom::document::Document;
@@ -762,7 +762,7 @@ impl RangeMethods for Range {
}
// Step 4.
- let mut contained_children: RootedVec<JS<Node>> = RootedVec::new();
+ rooted_vec!(let mut contained_children);
let ancestor = self.CommonAncestorContainer();
let mut iter = start_node.following_nodes(ancestor.r());
diff --git a/components/script/dom/serviceworker.rs b/components/script/dom/serviceworker.rs
index 5122bcf5f0d..ad303d45915 100644
--- a/components/script/dom/serviceworker.rs
+++ b/components/script/dom/serviceworker.rs
@@ -20,7 +20,6 @@ use dom::eventtarget::EventTarget;
use dom::serviceworkerglobalscope::ServiceWorkerGlobalScope;
use dom::workerglobalscope::prepare_workerscope_init;
use ipc_channel::ipc;
-use js::jsapi::RootedValue;
use js::jsval::UndefinedValue;
use script_thread::Runnable;
use std::cell::Cell;
@@ -91,7 +90,7 @@ impl ServiceWorker {
}
let global = worker.r().global();
- let error = RootedValue::new(global.r().get_cx(), UndefinedValue());
+ rooted!(in(global.r().get_cx()) let error = UndefinedValue());
let errorevent = ErrorEvent::new(global.r(), atom!("error"),
EventBubbles::Bubbles, EventCancelable::Cancelable,
message, filename, lineno, colno, error.handle());
diff --git a/components/script/dom/serviceworkerglobalscope.rs b/components/script/dom/serviceworkerglobalscope.rs
index 4039be05403..cbe195d1b8e 100644
--- a/components/script/dom/serviceworkerglobalscope.rs
+++ b/components/script/dom/serviceworkerglobalscope.rs
@@ -23,7 +23,7 @@ use dom::workerglobalscope::WorkerGlobalScope;
use dom::workerglobalscope::WorkerGlobalScopeInit;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use ipc_channel::router::ROUTER;
-use js::jsapi::{JS_SetInterruptCallback, JSAutoCompartment, JSContext, RootedValue};
+use js::jsapi::{JS_SetInterruptCallback, JSAutoCompartment, JSContext};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
use msg::constellation_msg::PipelineId;
@@ -37,7 +37,7 @@ use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
use std::sync::{Arc, Mutex};
use std::time::Instant;
use url::Url;
-use util::prefs;
+use util::prefs::PREFS;
use util::thread::spawn_named;
use util::thread_state;
use util::thread_state::{IN_WORKER, SCRIPT};
@@ -225,7 +225,7 @@ impl ServiceWorkerGlobalScope {
scope.mem_profiler_chan().run_with_memory_reporting(|| {
// Service workers are time limited
let sw_lifetime = Instant::now();
- let sw_lifetime_timeout = prefs::get_pref("dom.serviceworker.timeout_seconds").as_u64().unwrap();
+ let sw_lifetime_timeout = PREFS.get("dom.serviceworker.timeout_seconds").as_u64().unwrap();
while let Ok(event) = global.receive_event() {
if scope.is_closing() {
break;
@@ -283,7 +283,7 @@ impl ServiceWorkerGlobalScope {
let target = self.upcast();
let _ac = JSAutoCompartment::new(scope.get_cx(),
scope.reflector().get_jsobject().get());
- let mut message = RootedValue::new(scope.get_cx(), UndefinedValue());
+ rooted!(in(scope.get_cx()) let mut message = UndefinedValue());
data.read(GlobalRef::Worker(scope), message.handle_mut());
MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message.handle());
},
diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs
index 8cd53ee57fb..64fb6fb7578 100644
--- a/components/script/dom/testbinding.rs
+++ b/components/script/dom/testbinding.rs
@@ -29,7 +29,7 @@ use js::jsval::{JSVal, NullValue};
use std::borrow::ToOwned;
use std::ptr;
use std::rc::Rc;
-use util::prefs::get_pref;
+use util::prefs::PREFS;
#[dom_struct]
pub struct TestBinding {
@@ -101,7 +101,7 @@ impl TestBindingMethods for TestBinding {
fn EnumAttribute(&self) -> TestEnum { TestEnum::_empty }
fn SetEnumAttribute(&self, _: TestEnum) {}
fn InterfaceAttribute(&self) -> Root<Blob> {
- Blob::new(self.global().r(), BlobImpl::new_from_empty_slice(), "".to_owned())
+ Blob::new(self.global().r(), BlobImpl::new_from_bytes(vec![]), "".to_owned())
}
fn SetInterfaceAttribute(&self, _: &Blob) {}
fn UnionAttribute(&self) -> HTMLElementOrLong { HTMLElementOrLong::Long(0) }
@@ -179,7 +179,7 @@ impl TestBindingMethods for TestBinding {
fn SetAttr_to_automatically_rename(&self, _: DOMString) {}
fn GetEnumAttributeNullable(&self) -> Option<TestEnum> { Some(TestEnum::_empty) }
fn GetInterfaceAttributeNullable(&self) -> Option<Root<Blob>> {
- Some(Blob::new(self.global().r(), BlobImpl::new_from_empty_slice(), "".to_owned()))
+ Some(Blob::new(self.global().r(), BlobImpl::new_from_bytes(vec![]), "".to_owned()))
}
fn SetInterfaceAttributeNullable(&self, _: Option<&Blob>) {}
fn GetInterfaceAttributeWeak(&self) -> Option<Root<URL>> {
@@ -230,7 +230,7 @@ impl TestBindingMethods for TestBinding {
fn ReceiveByteString(&self) -> ByteString { ByteString::new(vec!()) }
fn ReceiveEnum(&self) -> TestEnum { TestEnum::_empty }
fn ReceiveInterface(&self) -> Root<Blob> {
- Blob::new(self.global().r(), BlobImpl::new_from_empty_slice(), "".to_owned())
+ Blob::new(self.global().r(), BlobImpl::new_from_bytes(vec![]), "".to_owned())
}
fn ReceiveAny(&self, _: *mut JSContext) -> JSVal { NullValue() }
fn ReceiveObject(&self, _: *mut JSContext) -> *mut JSObject { panic!() }
@@ -247,7 +247,7 @@ impl TestBindingMethods for TestBinding {
}
fn ReceiveSequence(&self) -> Vec<i32> { vec![1] }
fn ReceiveInterfaceSequence(&self) -> Vec<Root<Blob>> {
- vec![Blob::new(self.global().r(), BlobImpl::new_from_empty_slice(), "".to_owned())]
+ vec![Blob::new(self.global().r(), BlobImpl::new_from_bytes(vec![]), "".to_owned())]
}
fn ReceiveNullableBoolean(&self) -> Option<bool> { Some(false) }
@@ -268,7 +268,7 @@ impl TestBindingMethods for TestBinding {
fn ReceiveNullableByteString(&self) -> Option<ByteString> { Some(ByteString::new(vec!())) }
fn ReceiveNullableEnum(&self) -> Option<TestEnum> { Some(TestEnum::_empty) }
fn ReceiveNullableInterface(&self) -> Option<Root<Blob>> {
- Some(Blob::new(self.global().r(), BlobImpl::new_from_empty_slice(), "".to_owned()))
+ Some(Blob::new(self.global().r(), BlobImpl::new_from_bytes(vec![]), "".to_owned()))
}
fn ReceiveNullableObject(&self, _: *mut JSContext) -> *mut JSObject { ptr::null_mut() }
fn ReceiveNullableUnion(&self) -> Option<HTMLElementOrLong> {
@@ -558,10 +558,10 @@ impl TestBindingMethods for TestBinding {
fn PassVariadicAny(&self, _: *mut JSContext, _: Vec<HandleValue>) {}
fn PassVariadicObject(&self, _: *mut JSContext, _: Vec<*mut JSObject>) {}
fn BooleanMozPreference(&self, pref_name: DOMString) -> bool {
- get_pref(pref_name.as_ref()).as_boolean().unwrap_or(false)
+ PREFS.get(pref_name.as_ref()).as_boolean().unwrap_or(false)
}
fn StringMozPreference(&self, pref_name: DOMString) -> DOMString {
- get_pref(pref_name.as_ref()).as_string().map(|s| DOMString::from(s)).unwrap_or_else(|| DOMString::new())
+ PREFS.get(pref_name.as_ref()).as_string().map(|s| DOMString::from(s)).unwrap_or_else(|| DOMString::new())
}
fn PrefControlledAttributeDisabled(&self) -> bool { false }
fn PrefControlledAttributeEnabled(&self) -> bool { false }
diff --git a/components/script/dom/url.rs b/components/script/dom/url.rs
index c6d23bd7d4c..9a47be034f8 100644
--- a/components/script/dom/url.rs
+++ b/components/script/dom/url.rs
@@ -13,10 +13,9 @@ use dom::bindings::str::{DOMString, USVString};
use dom::blob::Blob;
use dom::urlhelper::UrlHelper;
use dom::urlsearchparams::URLSearchParams;
-use ipc_channel::ipc;
use net_traits::IpcSend;
-use net_traits::blob_url_store::{BlobURLStoreEntry, BlobURLStoreMsg, parse_blob_url};
-use net_traits::filemanager_thread::FileManagerThreadMsg;
+use net_traits::blob_url_store::parse_blob_url;
+use net_traits::filemanager_thread::{SelectedFileId, FileManagerThreadMsg};
use std::borrow::ToOwned;
use std::default::Default;
use url::quirks::domain_to_unicode;
@@ -117,7 +116,7 @@ impl URL {
pub fn CreateObjectURL(global: GlobalRef, blob: &Blob) -> DOMString {
/// XXX: Second field is an unicode-serialized Origin, it is a temporary workaround
/// and should not be trusted. See issue https://github.com/servo/servo/issues/11722
- let origin = global.get_url().origin().unicode_serialization();
+ let origin = URL::get_blob_origin(&global.get_url());
if blob.IsClosed() {
// Generate a dummy id
@@ -125,34 +124,9 @@ impl URL {
return DOMString::from(URL::unicode_serialization_blob_url(&origin, &id));
}
- let filemanager = global.resource_threads().sender();
-
- let slice = blob.get_slice_or_empty();
- let bytes = slice.get_bytes();
-
- let entry = BlobURLStoreEntry {
- type_string: blob.Type().to_string(),
- filename: None, // XXX: the filename is currently only in File object now
- size: blob.Size(),
- bytes: bytes.to_vec(),
- };
-
- let (tx, rx) = ipc::channel().unwrap();
-
- let msg = BlobURLStoreMsg::AddEntry(entry, origin.clone(), tx);
+ let id = blob.get_id();
- let _ = filemanager.send(FileManagerThreadMsg::BlobURLStoreMsg(msg));
-
- match rx.recv().unwrap() {
- Ok(id) => {
- DOMString::from(URL::unicode_serialization_blob_url(&origin, &id))
- }
- Err(_) => {
- // Generate a dummy id
- let id = Uuid::new_v4().simple().to_string();
- DOMString::from(URL::unicode_serialization_blob_url(&origin, &id))
- }
- }
+ DOMString::from(URL::unicode_serialization_blob_url(&origin, &id.0))
}
// https://w3c.github.io/FileAPI/#dfn-revokeObjectURL
@@ -166,13 +140,15 @@ impl URL {
NOTE: The first step is unnecessary, since closed blobs do not exist in the store
*/
+ let origin = global.get_url().origin().unicode_serialization();
match Url::parse(&url) {
Ok(url) => match parse_blob_url(&url) {
Some((id, _)) => {
let filemanager = global.resource_threads().sender();
- let msg = BlobURLStoreMsg::DeleteEntry(id.simple().to_string());
- let _ = filemanager.send(FileManagerThreadMsg::BlobURLStoreMsg(msg));
+ let id = SelectedFileId(id.simple().to_string());
+ let msg = FileManagerThreadMsg::DecRef(id, origin);
+ let _ = filemanager.send(msg);
}
None => {}
},
@@ -196,6 +172,19 @@ impl URL {
result
}
+
+ // XXX: change String to FileOrigin
+ /* NOTE(izgzhen): WebKit will return things like blob:file:///XXX
+ while Chrome will return blob:null/XXX
+ This is not well-specified, and I prefer the WebKit way here
+ */
+ fn get_blob_origin(url: &Url) -> String {
+ if url.scheme() == "file" {
+ "file://".to_string()
+ } else {
+ url.origin().unicode_serialization()
+ }
+ }
}
impl URLMethods for URL {
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 686bf43178f..dbb774ad87b 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::{CanvasCommonMsg, CanvasMsg};
+use canvas_traits::{CanvasCommonMsg, CanvasMsg, byte_swap};
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes};
@@ -33,14 +33,13 @@ use dom::webgltexture::{TexParameterValue, WebGLTexture};
use dom::webgluniformlocation::WebGLUniformLocation;
use euclid::size::Size2D;
use ipc_channel::ipc::{self, IpcSender};
-use js::jsapi::{JSContext, JS_GetArrayBufferViewType, JSObject, RootedValue, Type};
+use js::jsapi::{JSContext, JS_GetArrayBufferViewType, JSObject, Type};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue};
use net_traits::image::base::PixelFormat;
use net_traits::image_cache_thread::ImageResponse;
use offscreen_gl_context::{GLContextAttributes, GLLimits};
use script_traits::ScriptMsg as ConstellationMsg;
use std::cell::Cell;
-use util::vec::byte_swap;
use webrender_traits::WebGLError::*;
use webrender_traits::{WebGLCommand, WebGLError, WebGLFramebufferBindingRequest, WebGLParameter};
@@ -522,11 +521,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
WebGLParameter::Float(val) => DoubleValue(val as f64),
WebGLParameter::FloatArray(_) => panic!("Parameter should not be float array"),
WebGLParameter::String(val) => {
- let mut rval = RootedValue::new(cx, UndefinedValue());
+ rooted!(in(cx) let mut rval = UndefinedValue());
unsafe {
val.to_jsval(cx, rval.handle_mut());
}
- rval.ptr
+ rval.get()
}
WebGLParameter::Invalid => NullValue(),
}
@@ -1267,13 +1266,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
fn GetVertexAttrib(&self, cx: *mut JSContext, index: u32, pname: u32) -> JSVal {
if index == 0 && pname == constants::CURRENT_VERTEX_ATTRIB {
- let mut result = RootedValue::new(cx, UndefinedValue());
+ rooted!(in(cx) let mut result = UndefinedValue());
let (x, y, z, w) = self.current_vertex_attrib_0.get();
let attrib = vec![x, y, z, w];
unsafe {
attrib.to_jsval(cx, result.handle_mut());
}
- return result.ptr
+ return result.get()
}
let (sender, receiver) = ipc::channel().unwrap();
@@ -1285,11 +1284,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
WebGLParameter::String(_) => panic!("Vertex attrib should not be string"),
WebGLParameter::Float(_) => panic!("Vertex attrib should not be float"),
WebGLParameter::FloatArray(val) => {
- let mut result = RootedValue::new(cx, UndefinedValue());
+ rooted!(in(cx) let mut result = UndefinedValue());
unsafe {
val.to_jsval(cx, result.handle_mut());
}
- result.ptr
+ result.get()
}
WebGLParameter::Invalid => NullValue(),
}
diff --git a/components/script/dom/webidls/BrowserElement.webidl b/components/script/dom/webidls/BrowserElement.webidl
index 6105811666b..44790d33070 100644
--- a/components/script/dom/webidls/BrowserElement.webidl
+++ b/components/script/dom/webidls/BrowserElement.webidl
@@ -61,6 +61,7 @@ dictionary BrowserElementErrorEventDetail {
DOMString type;
DOMString description;
DOMString report;
+ DOMString version;
};
dictionary BrowserElementLocationChangeEventDetail {
diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs
index 1409936c6c7..1a34096f26b 100644
--- a/components/script/dom/websocket.rs
+++ b/components/script/dom/websocket.rs
@@ -16,14 +16,14 @@ use dom::bindings::js::Root;
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::str::{DOMString, USVString, is_token};
-use dom::blob::{Blob, BlobImpl, DataSlice};
+use dom::blob::{Blob, BlobImpl};
use dom::closeevent::CloseEvent;
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventtarget::EventTarget;
use dom::messageevent::MessageEvent;
use dom::urlhelper::UrlHelper;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
-use js::jsapi::{JSAutoCompartment, RootedValue};
+use js::jsapi::JSAutoCompartment;
use js::jsapi::{JS_GetArrayBufferData, JS_NewArrayBuffer};
use js::jsval::UndefinedValue;
use libc::{uint32_t, uint8_t};
@@ -405,7 +405,7 @@ impl WebSocketMethods for WebSocket {
if send_data {
let mut other_sender = self.sender.borrow_mut();
let my_sender = other_sender.as_mut().unwrap();
- let bytes = blob.get_slice_or_empty().get_bytes().to_vec();
+ let bytes = blob.get_bytes().unwrap_or(vec![]);
let _ = my_sender.send(WebSocketDomAction::SendMessage(MessageData::Binary(bytes)));
}
@@ -585,14 +585,13 @@ impl Runnable for MessageReceivedTask {
unsafe {
let cx = global.r().get_cx();
let _ac = JSAutoCompartment::new(cx, ws.reflector().get_jsobject().get());
- let mut message = RootedValue::new(cx, UndefinedValue());
+ rooted!(in(cx) let mut message = UndefinedValue());
match self.message {
MessageData::Text(text) => text.to_jsval(cx, message.handle_mut()),
MessageData::Binary(data) => {
match ws.binary_type.get() {
BinaryType::Blob => {
- let slice = DataSlice::from_bytes(data);
- let blob = Blob::new(global.r(), BlobImpl::new_from_slice(slice), "".to_owned());
+ let blob = Blob::new(global.r(), BlobImpl::new_from_bytes(data), "".to_owned());
blob.to_jsval(cx, message.handle_mut());
}
BinaryType::Arraybuffer => {
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index b58fc901316..a098edcb43c 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -43,9 +43,7 @@ use js::jsapi::{JS_GetRuntime, JS_GC, MutableHandleValue, SetWindowProxy};
use js::rust::CompileOptionsWrapper;
use js::rust::Runtime;
use libc;
-use msg::constellation_msg::{FrameType, LoadData, PanicMsg, PipelineId, SubpageId};
-use msg::constellation_msg::{WindowSizeData, WindowSizeType};
-use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
+use msg::constellation_msg::{FrameType, LoadData, PanicMsg, PipelineId, SubpageId, WindowSizeType};
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread};
use net_traits::storage_thread::StorageType;
@@ -64,9 +62,10 @@ use script_layout_interface::rpc::{MarginStyleResponse, ResolvedStyleResponse};
use script_runtime::{ScriptChan, ScriptPort, maybe_take_panic_result};
use script_thread::SendableMainThreadScriptChan;
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, RunnableWrapper};
+use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
use script_traits::{ConstellationControlMsg, UntrustedNodeAddress};
use script_traits::{DocumentState, MsDuration, TimerEvent, TimerEventId};
-use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, TimerSource};
+use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, TimerSource, WindowSizeData};
use std::ascii::AsciiExt;
use std::borrow::ToOwned;
use std::cell::Cell;
@@ -85,6 +84,7 @@ use style::context::ReflowGoal;
use style::error_reporting::ParseErrorReporter;
use style::properties::longhands::overflow_x;
use style::selector_impl::PseudoElement;
+use style::str::HTML_SPACE_CHARACTERS;
use task_source::dom_manipulation::DOMManipulationTaskSource;
use task_source::file_reading::FileReadingTaskSource;
use task_source::history_traversal::HistoryTraversalTaskSource;
@@ -96,8 +96,7 @@ use timers::{IsInterval, OneshotTimerCallback, OneshotTimerHandle, OneshotTimers
use tinyfiledialogs::{self, MessageBoxIcon};
use url::Url;
use util::geometry::{self, MAX_RECT};
-use util::prefs::mozbrowser_enabled;
-use util::str::HTML_SPACE_CHARACTERS;
+use util::prefs::PREFS;
use util::{breakpoint, opts};
use webdriver_handlers::jsval_to_webdriver;
@@ -1581,7 +1580,7 @@ impl Window {
/// Returns whether this window is mozbrowser.
pub fn is_mozbrowser(&self) -> bool {
- mozbrowser_enabled() && self.parent_info().is_none()
+ PREFS.is_mozbrowser_enabled() && self.parent_info().is_none()
}
/// Returns whether mozbrowser is enabled and `obj` has been created
@@ -1757,4 +1756,3 @@ fn debug_reflow_events(id: PipelineId, goal: &ReflowGoal, query_type: &ReflowQue
println!("{}", debug_msg);
}
-
diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs
index a136f4ec8ca..2cf1d1c4e46 100644
--- a/components/script/dom/worker.rs
+++ b/components/script/dom/worker.rs
@@ -23,7 +23,7 @@ use dom::eventtarget::EventTarget;
use dom::messageevent::MessageEvent;
use dom::workerglobalscope::prepare_workerscope_init;
use ipc_channel::ipc;
-use js::jsapi::{HandleValue, JSContext, RootedValue, JSAutoCompartment};
+use js::jsapi::{HandleValue, JSContext, JSAutoCompartment};
use js::jsval::UndefinedValue;
use script_thread::Runnable;
use std::sync::atomic::{AtomicBool, Ordering};
@@ -115,7 +115,7 @@ impl Worker {
let global = worker.r().global();
let target = worker.upcast();
let _ac = JSAutoCompartment::new(global.r().get_cx(), target.reflector().get_jsobject().get());
- let mut message = RootedValue::new(global.r().get_cx(), UndefinedValue());
+ rooted!(in(global.r().get_cx()) let mut message = UndefinedValue());
data.read(global.r(), message.handle_mut());
MessageEvent::dispatch_jsval(target, global.r(), message.handle());
}
@@ -134,7 +134,7 @@ impl Worker {
}
let global = worker.r().global();
- let error = RootedValue::new(global.r().get_cx(), UndefinedValue());
+ rooted!(in(global.r().get_cx()) let error = UndefinedValue());
let errorevent = ErrorEvent::new(global.r(), atom!("error"),
EventBubbles::Bubbles, EventCancelable::Cancelable,
message, filename, lineno, colno, error.handle());
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index a9106d36206..2e1c983bfd4 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -21,7 +21,7 @@ use dom::workerlocation::WorkerLocation;
use dom::workernavigator::WorkerNavigator;
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
-use js::jsapi::{HandleValue, JSContext, JSRuntime, RootedValue};
+use js::jsapi::{HandleValue, JSContext, JSRuntime};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
use msg::constellation_msg::{PipelineId, ReferrerPolicy, PanicMsg};
@@ -309,7 +309,7 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
};
}
- let mut rval = RootedValue::new(self.runtime.cx(), UndefinedValue());
+ rooted!(in(self.runtime.cx()) let mut rval = UndefinedValue());
for url in urls {
let (url, source) = match load_whole_resource(LoadContext::Script,
&self.resource_threads.sender(),
@@ -420,7 +420,7 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
impl WorkerGlobalScope {
#[allow(unsafe_code)]
pub fn execute_script(&self, source: DOMString) {
- let mut rval = RootedValue::new(self.runtime.cx(), UndefinedValue());
+ rooted!(in(self.runtime.cx()) let mut rval = UndefinedValue());
match self.runtime.evaluate_script(
self.reflector().get_jsobject(), &source, self.worker_url.as_str(), 1, rval.handle_mut()) {
Ok(_) => (),
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index af424fb83d7..e76bbd0c7b3 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -20,7 +20,7 @@ use dom::bindings::js::{Root, RootedReference};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::str::{ByteString, DOMString, USVString, is_token};
-use dom::blob::{Blob, DataSlice, BlobImpl};
+use dom::blob::{Blob, BlobImpl};
use dom::document::DocumentSource;
use dom::document::{Document, IsHTMLDocument};
use dom::event::{Event, EventBubbles, EventCancelable};
@@ -40,7 +40,7 @@ use hyper::mime::{self, Mime, Attr as MimeAttr, Value as MimeValue};
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use js::jsapi::JS_ClearPendingException;
-use js::jsapi::{JSContext, JS_ParseJSON, RootedValue};
+use js::jsapi::{JSContext, JS_ParseJSON};
use js::jsval::{JSVal, NullValue, UndefinedValue};
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use net_traits::CoreResourceMsg::Fetch;
@@ -62,7 +62,7 @@ use string_cache::Atom;
use time;
use timers::{OneshotTimerCallback, OneshotTimerHandle};
use url::{Url, Position};
-use util::prefs::mozbrowser_enabled;
+use util::prefs::PREFS;
#[derive(JSTraceable, PartialEq, Copy, Clone, HeapSizeOf)]
enum XMLHttpRequestState {
@@ -581,8 +581,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
// story. See https://github.com/servo/servo/issues/9582
if let GlobalRoot::Window(win) = self.global() {
let is_root_pipeline = win.parent_info().is_none();
- let is_mozbrowser_enabled = mozbrowser_enabled();
- is_root_pipeline && is_mozbrowser_enabled
+ is_root_pipeline && PREFS.is_mozbrowser_enabled()
} else {
false
}
@@ -772,7 +771,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
// https://xhr.spec.whatwg.org/#the-response-attribute
fn Response(&self, cx: *mut JSContext) -> JSVal {
unsafe {
- let mut rval = RootedValue::new(cx, UndefinedValue());
+ rooted!(in(cx) let mut rval = UndefinedValue());
match self.response_type.get() {
XMLHttpRequestResponseType::_empty | XMLHttpRequestResponseType::Text => {
let ready_state = self.ready_state.get();
@@ -809,7 +808,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
self.response.borrow().to_jsval(cx, rval.handle_mut());
}
}
- rval.ptr
+ rval.get()
}
}
@@ -1106,8 +1105,8 @@ impl XMLHttpRequest {
let mime = self.final_mime_type().as_ref().map(Mime::to_string).unwrap_or("".to_owned());
// Step 3, 4
- let slice = DataSlice::from_bytes(self.response.borrow().to_vec());
- let blob = Blob::new(self.global().r(), BlobImpl::new_from_slice(slice), mime);
+ let bytes = self.response.borrow().to_vec();
+ let blob = Blob::new(self.global().r(), BlobImpl::new_from_bytes(bytes), mime);
self.response_blob.set(Some(blob.r()));
blob
}
@@ -1129,9 +1128,8 @@ impl XMLHttpRequest {
// Step 5
if self.response_type.get() == XMLHttpRequestResponseType::_empty {
return None;
- }
- // Step 6
- else {
+ } else {
+ // Step 6
temp_doc = self.document_text_html();
}
},
@@ -1144,8 +1142,7 @@ impl XMLHttpRequest {
Some(Mime(_, mime::SubLevel::Ext(sub), _)) => {
if sub.ends_with("+xml") {
temp_doc = self.handle_xml();
- }
- else {
+ } else {
return None;
}
},
@@ -1177,7 +1174,7 @@ impl XMLHttpRequest {
let json_text = UTF_8.decode(&bytes, DecoderTrap::Replace).unwrap();
let json_text: Vec<u16> = json_text.encode_utf16().collect();
// Step 5
- let mut rval = RootedValue::new(cx, UndefinedValue());
+ rooted!(in(cx) let mut rval = UndefinedValue());
unsafe {
if !JS_ParseJSON(cx,
json_text.as_ptr(),
@@ -1188,7 +1185,7 @@ impl XMLHttpRequest {
}
}
// Step 6
- self.response_json.set(rval.ptr);
+ self.response_json.set(rval.get());
self.response_json.get()
}
@@ -1378,7 +1375,8 @@ impl Extractable for BodyInit {
} else {
Some(b.Type())
};
- (b.get_slice_or_empty().get_bytes().to_vec(), content_type)
+ let bytes = b.get_bytes().unwrap_or(vec![]);
+ (bytes, content_type)
},
}
}