diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-02-16 02:03:54 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-16 02:03:54 -0800 |
commit | 0cc6d3e99781394b76ad2725661ae8f6bb895f7b (patch) | |
tree | bcc391aba306ce52e66ad1227238c866ad33dba3 /components/script/dom | |
parent | 84a44a401424852bc44ef5e751e84544ed892e70 (diff) | |
parent | f7e2f0e641967ba78a0b6b057aec760f9a9ca519 (diff) | |
download | servo-0cc6d3e99781394b76ad2725661ae8f6bb895f7b.tar.gz servo-0cc6d3e99781394b76ad2725661ae8f6bb895f7b.zip |
Auto merge of #15544 - servo:RootedTraceable-dict, r=nox
Root dictionaries that contain any or object.
<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15544)
<!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 120 | ||||
-rw-r--r-- | components/script/dom/bindings/conversions.rs | 17 | ||||
-rw-r--r-- | components/script/dom/bindings/iterable.rs | 6 | ||||
-rw-r--r-- | components/script/dom/bindings/js.rs | 6 | ||||
-rw-r--r-- | components/script/dom/bindings/mozmap.rs | 2 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 55 | ||||
-rw-r--r-- | components/script/dom/customevent.rs | 5 | ||||
-rw-r--r-- | components/script/dom/errorevent.rs | 9 | ||||
-rw-r--r-- | components/script/dom/extendablemessageevent.rs | 6 | ||||
-rw-r--r-- | components/script/dom/filereader.rs | 2 | ||||
-rw-r--r-- | components/script/dom/messageevent.rs | 8 | ||||
-rw-r--r-- | components/script/dom/popstateevent.rs | 6 | ||||
-rw-r--r-- | components/script/dom/request.rs | 11 | ||||
-rw-r--r-- | components/script/dom/testbinding.rs | 11 | ||||
-rw-r--r-- | components/script/dom/window.rs | 3 | ||||
-rw-r--r-- | components/script/dom/workerglobalscope.rs | 3 |
16 files changed, 203 insertions, 67 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index b1f188a7b45..e4448ff834c 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -19,6 +19,7 @@ from WebIDL import ( IDLBuiltinType, IDLNullValue, IDLNullableType, + IDLObject, IDLType, IDLInterfaceMember, IDLUndefinedValue, @@ -581,11 +582,9 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, If isDefinitelyObject is True, that means we know the value isObject() and we have no need to recheck that. - if isMember is True, we're being converted from a property of some - JS object, not from an actual method argument, so we can't rely on - our jsval being rooted or outliving us in any way. Any caller - passing true needs to ensure that it is handled correctly in - typeIsSequenceOrHasSequenceMember. + isMember is `False`, "Dictionary", "Union" or "Variadic", and affects + whether this function returns code suitable for an on-stack rooted binding + or suitable for storing in an appropriate larger structure. invalidEnumValueFatal controls whether an invalid enum value conversion attempt will throw (if true) or simply return without doing anything (if @@ -1033,33 +1032,33 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, if type.isAny(): assert not isEnforceRange and not isClamp + assert isMember != "Union" - declType = "" - default = "" if isMember == "Dictionary": # TODO: Need to properly root dictionaries # https://github.com/servo/servo/issues/6381 - declType = CGGeneric("JSVal") + declType = CGGeneric("Heap<JSVal>") if defaultValue is None: default = None elif isinstance(defaultValue, IDLNullValue): - default = "NullValue()" + default = "Heap::new(NullValue())" elif isinstance(defaultValue, IDLUndefinedValue): - default = "UndefinedValue()" + default = "Heap::new(UndefinedValue())" else: raise TypeError("Can't handle non-null, non-undefined default value here") - else: - declType = CGGeneric("HandleValue") + return handleOptional("Heap::new(${val}.get())", declType, default) - if defaultValue is None: - default = None - elif isinstance(defaultValue, IDLNullValue): - default = "HandleValue::null()" - elif isinstance(defaultValue, IDLUndefinedValue): - default = "HandleValue::undefined()" - else: - raise TypeError("Can't handle non-null, non-undefined default value here") + declType = CGGeneric("HandleValue") + + if defaultValue is None: + default = None + elif isinstance(defaultValue, IDLNullValue): + default = "HandleValue::null()" + elif isinstance(defaultValue, IDLUndefinedValue): + default = "HandleValue::undefined()" + else: + raise TypeError("Can't handle non-null, non-undefined default value here") return handleOptional("${val}", declType, default) @@ -1068,13 +1067,22 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, # TODO: Need to root somehow # https://github.com/servo/servo/issues/6382 - declType = CGGeneric("*mut JSObject") + default = "ptr::null_mut()" templateBody = wrapObjectTemplate("${val}.get().to_object()", - "ptr::null_mut()", + default, isDefinitelyObject, type, failureCode) + if isMember in ("Dictionary", "Union"): + declType = CGGeneric("Heap<*mut JSObject>") + templateBody = "Heap::new(%s)" % templateBody + default = "Heap::new(%s)" % default + else: + # TODO: Need to root somehow + # https://github.com/servo/servo/issues/6382 + declType = CGGeneric("*mut JSObject") + return handleOptional(templateBody, declType, - handleDefaultNull("ptr::null_mut()")) + handleDefaultNull(default)) if type.isDictionary(): # There are no nullable dictionaries @@ -1083,15 +1091,21 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, typeName = "%s::%s" % (CGDictionary.makeModuleName(type.inner), CGDictionary.makeDictionaryName(type.inner)) declType = CGGeneric(typeName) - template = ("match %s::new(cx, ${val}) {\n" + empty = "%s::empty(cx)" % typeName + + if isMember != "Dictionary" and type_needs_tracing(type): + declType = CGTemplatedType("RootedTraceableBox", declType) + empty = "RootedTraceableBox::new(%s)" % empty + + template = ("match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n" " Ok(ConversionResult::Success(dictionary)) => dictionary,\n" " Ok(ConversionResult::Failure(error)) => {\n" "%s\n" " }\n" " _ => { %s },\n" - "}" % (typeName, indent(failOrPropagate, 8), exceptionCode)) + "}" % (indent(failOrPropagate, 8), exceptionCode)) - return handleOptional(template, declType, handleDefaultNull("%s::empty(cx)" % typeName)) + return handleOptional(template, declType, handleDefaultNull(empty)) if type.isVoid(): # This one only happens for return values, and its easy: Just @@ -2233,6 +2247,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config): 'dom::types::*', 'js::error::throw_type_error', 'js::jsapi::HandleValue', + 'js::jsapi::Heap', 'js::jsapi::JSContext', 'js::jsapi::JSObject', 'js::jsapi::MutableHandleValue', @@ -3139,7 +3154,7 @@ class CGCallGenerator(CGThing): args = CGList([CGGeneric(arg) for arg in argsPre], ", ") for (a, name) in arguments: # XXXjdm Perhaps we should pass all nontrivial types by borrowed pointer - if a.type.isDictionary(): + if a.type.isDictionary() and not type_needs_tracing(a.type): name = "&" + name args.append(CGGeneric(name)) @@ -4052,14 +4067,15 @@ def getUnionTypeTemplateVars(type, descriptorProvider): typeName = builtinNames[type.tag()] elif type.isObject(): name = type.name - typeName = "*mut JSObject" + typeName = "Heap<*mut JSObject>" else: raise TypeError("Can't handle %s in unions yet" % type) info = getJSToNativeConversionInfo( type, descriptorProvider, failureCode="return Ok(None);", exceptionCode='return Err(());', - isDefinitelyObject=True) + isDefinitelyObject=True, + isMember="Union") template = info.template jsConversion = string.Template(template).substitute({ @@ -4094,6 +4110,7 @@ class CGUnionStruct(CGThing): % (self.type, v["name"]) for v in templateVars ] return ("""\ +#[derive(JSTraceable)] pub enum %s { %s } @@ -5567,6 +5584,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries 'dom::bindings::utils::trace_global', 'dom::bindings::trace::JSTraceable', 'dom::bindings::trace::RootedTraceable', + 'dom::bindings::trace::RootedTraceableBox', 'dom::bindings::callback::CallSetup', 'dom::bindings::callback::CallbackContainer', 'dom::bindings::callback::CallbackInterface', @@ -5872,6 +5890,7 @@ class CGDictionary(CGThing): for m in self.memberInfo] return (string.Template( + "#[derive(JSTraceable)]\n" "pub struct ${selfName} {\n" + "${inheritance}" + "\n".join(memberDecls) + "\n" + @@ -5995,8 +6014,6 @@ class CGDictionary(CGThing): default = info.default replacements = {"val": "rval.handle()"} conversion = string.Template(templateBody).substitute(replacements) - if memberType.isAny(): - conversion = "%s.get()" % conversion assert (member.defaultValue is None) == (default is None) if not member.optional: @@ -6154,6 +6171,45 @@ class CGBindingRoot(CGThing): return stripTrailingWhitespace(self.root.define()) +def type_needs_tracing(t): + assert isinstance(t, IDLObject), (t, type(t)) + + if t.isType(): + if isinstance(t, IDLWrapperType): + return type_needs_tracing(t.inner) + + if t.nullable(): + return type_needs_tracing(t.inner) + + if t.isAny(): + return True + + if t.isObject(): + return True + + if t.isSequence(): + return type_needs_tracing(t.inner) + + return False + + if t.isDictionary(): + if t.parent and type_needs_tracing(t.parent): + return True + + if any(type_needs_tracing(member.type) for member in t.members): + return True + + return False + + if t.isInterface(): + return False + + if t.isEnum(): + return False + + assert False, (t, type(t)) + + def argument_type(descriptorProvider, ty, optional=False, defaultValue=None, variadic=False): info = getJSToNativeConversionInfo( ty, descriptorProvider, isArgument=True) @@ -6167,7 +6223,7 @@ def argument_type(descriptorProvider, ty, optional=False, defaultValue=None, var elif optional and not defaultValue: declType = CGWrapper(declType, pre="Option<", post=">") - if ty.isDictionary(): + if ty.isDictionary() and not type_needs_tracing(ty): declType = CGWrapper(declType, pre="&") return declType.define() diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index 747573cec05..0cbb49bea3e 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -37,6 +37,7 @@ use dom::bindings::js::Root; use dom::bindings::num::Finite; use dom::bindings::reflector::{DomObject, Reflector}; use dom::bindings::str::{ByteString, DOMString, USVString}; +use dom::bindings::trace::{JSTraceable, RootedTraceableBox}; use dom::bindings::utils::DOMClass; use js; pub use js::conversions::{FromJSValConvertible, ToJSValConvertible, ConversionResult}; @@ -117,6 +118,22 @@ impl <T: DomObject + IDLInterface> FromJSValConvertible for Root<T> { } } +impl <T: FromJSValConvertible + JSTraceable> FromJSValConvertible for RootedTraceableBox<T> { + type Config = T::Config; + + unsafe fn from_jsval(cx: *mut JSContext, + value: HandleValue, + config: Self::Config) + -> Result<ConversionResult<Self>, ()> { + T::from_jsval(cx, value, config).map(|result| { + match result { + ConversionResult::Success(v) => ConversionResult::Success(RootedTraceableBox::new(v)), + ConversionResult::Failure(e) => ConversionResult::Failure(e), + } + }) + } +} + /// Convert `id` to a `DOMString`, assuming it is string-valued. /// /// Handling of invalid UTF-16 in strings depends on the relevant option. diff --git a/components/script/dom/bindings/iterable.rs b/components/script/dom/bindings/iterable.rs index 08439d16517..f10bd320b85 100644 --- a/components/script/dom/bindings/iterable.rs +++ b/components/script/dom/bindings/iterable.rs @@ -15,7 +15,7 @@ use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::trace::JSTraceable; use dom::globalscope::GlobalScope; use js::conversions::ToJSValConvertible; -use js::jsapi::{HandleValue, JSContext, JSObject, MutableHandleObject}; +use js::jsapi::{HandleValue, Heap, JSContext, JSObject, MutableHandleObject}; use js::jsval::UndefinedValue; use std::cell::Cell; use std::ptr; @@ -116,7 +116,7 @@ fn dict_return(cx: *mut JSContext, value: HandleValue) -> Fallible<()> { let mut dict = unsafe { IterableKeyOrValueResult::empty(cx) }; dict.done = done; - dict.value = value.get(); + dict.value.set(value.get()); rooted!(in(cx) let mut dict_value = UndefinedValue()); unsafe { dict.to_jsval(cx, dict_value.handle_mut()); @@ -131,7 +131,7 @@ fn key_and_value_return(cx: *mut JSContext, value: HandleValue) -> Fallible<()> { let mut dict = unsafe { IterableKeyAndValueResult::empty(cx) }; dict.done = false; - dict.value = Some(vec![key.get(), value.get()]); + dict.value = Some(vec![Heap::new(key.get()), Heap::new(value.get())]); rooted!(in(cx) let mut dict_value = UndefinedValue()); unsafe { dict.to_jsval(cx, dict_value.handle_mut()); diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index bdd2b81ce37..e63177e3bd8 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -642,3 +642,9 @@ impl<T: DomObject> Drop for Root<T> { } } } + +unsafe impl<T: DomObject> JSTraceable for Root<T> { + unsafe fn trace(&self, _: *mut JSTracer) { + // Already traced. + } +} diff --git a/components/script/dom/bindings/mozmap.rs b/components/script/dom/bindings/mozmap.rs index 5ef102539b7..abfedf02caf 100644 --- a/components/script/dom/bindings/mozmap.rs +++ b/components/script/dom/bindings/mozmap.rs @@ -23,7 +23,7 @@ use std::collections::HashMap; use std::ops::Deref; /// The `MozMap` (open-ended dictionary) type. -#[derive(Clone)] +#[derive(Clone, JSTraceable)] pub struct MozMap<T> { map: HashMap<DOMString, T>, } diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 763ccb9b22b..aeddcdabe4b 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -653,6 +653,61 @@ impl<'a, T: JSTraceable + 'static> Drop for RootedTraceable<'a, T> { } } +/// Roots any JSTraceable thing +/// +/// If you have a valid DomObject, use Root. +/// If you have GC things like *mut JSObject or JSVal, use rooted!. +/// If you have an arbitrary number of DomObjects to root, use rooted_vec!. +/// If you know what you're doing, use this. +pub struct RootedTraceableBox<T: 'static + JSTraceable> { + ptr: *mut T, +} + +unsafe impl<T: JSTraceable + 'static> JSTraceable for RootedTraceableBox<T> { + unsafe fn trace(&self, tracer: *mut JSTracer) { + (*self.ptr).trace(tracer); + } +} + +impl<T: JSTraceable + 'static> RootedTraceableBox<T> { + /// Root a JSTraceable thing for the life of this RootedTraceable + pub fn new(traceable: T) -> RootedTraceableBox<T> { + let traceable = Box::into_raw(box traceable); + unsafe { + RootedTraceableSet::add(traceable); + } + RootedTraceableBox { + ptr: traceable, + } + } +} + +impl<T: JSTraceable> Deref for RootedTraceableBox<T> { + type Target = T; + fn deref(&self) -> &T { + unsafe { + &*self.ptr + } + } +} + +impl<T: JSTraceable> DerefMut for RootedTraceableBox<T> { + fn deref_mut(&mut self) -> &mut T { + unsafe { + &mut *self.ptr + } + } +} + +impl<T: JSTraceable + 'static> Drop for RootedTraceableBox<T> { + fn drop(&mut self) { + unsafe { + RootedTraceableSet::remove(self.ptr); + let _ = Box::from_raw(self.ptr); + } + } +} + /// 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 diff --git a/components/script/dom/customevent.rs b/components/script/dom/customevent.rs index f4346280cb7..f11f2643dad 100644 --- a/components/script/dom/customevent.rs +++ b/components/script/dom/customevent.rs @@ -10,6 +10,7 @@ use dom::bindings::inheritance::Castable; use dom::bindings::js::{MutHeapJSVal, Root}; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; +use dom::bindings::trace::RootedTraceableBox; use dom::event::Event; use dom::globalscope::GlobalScope; use js::jsapi::{HandleValue, JSContext}; @@ -51,13 +52,13 @@ impl CustomEvent { #[allow(unsafe_code)] pub fn Constructor(global: &GlobalScope, type_: DOMString, - init: &CustomEventBinding::CustomEventInit) + init: RootedTraceableBox<CustomEventBinding::CustomEventInit>) -> Fallible<Root<CustomEvent>> { Ok(CustomEvent::new(global, Atom::from(type_), init.parent.bubbles, init.parent.cancelable, - unsafe { HandleValue::from_marked_location(&init.detail) })) + init.detail.handle())) } fn init_custom_event(&self, diff --git a/components/script/dom/errorevent.rs b/components/script/dom/errorevent.rs index 3739d5732f3..37197b6125a 100644 --- a/components/script/dom/errorevent.rs +++ b/components/script/dom/errorevent.rs @@ -11,6 +11,7 @@ use dom::bindings::inheritance::Castable; use dom::bindings::js::{MutHeapJSVal, Root}; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; +use dom::bindings::trace::RootedTraceableBox; use dom::event::{Event, EventBubbles, EventCancelable}; use dom::globalscope::GlobalScope; use js::jsapi::{HandleValue, JSContext}; @@ -72,7 +73,8 @@ impl ErrorEvent { pub fn Constructor(global: &GlobalScope, type_: DOMString, - init: &ErrorEventBinding::ErrorEventInit) -> Fallible<Root<ErrorEvent>>{ + init: RootedTraceableBox<ErrorEventBinding::ErrorEventInit>) + -> Fallible<Root<ErrorEvent>>{ let msg = match init.message.as_ref() { Some(message) => message.clone(), None => DOMString::new(), @@ -91,9 +93,6 @@ impl ErrorEvent { let cancelable = EventCancelable::from(init.parent.cancelable); - // Dictionaries need to be rooted - // https://github.com/servo/servo/issues/6381 - rooted!(in(global.get_cx()) let error = init.error); let event = ErrorEvent::new( global, Atom::from(type_), @@ -103,7 +102,7 @@ impl ErrorEvent { file_name, line_num, col_num, - error.handle()); + init.error.handle()); Ok(event) } diff --git a/components/script/dom/extendablemessageevent.rs b/components/script/dom/extendablemessageevent.rs index a7ee5f797af..dd0360cb408 100644 --- a/components/script/dom/extendablemessageevent.rs +++ b/components/script/dom/extendablemessageevent.rs @@ -9,6 +9,7 @@ use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; +use dom::bindings::trace::RootedTraceableBox; use dom::event::Event; use dom::eventtarget::EventTarget; use dom::extendableevent::ExtendableEvent; @@ -47,15 +48,14 @@ impl ExtendableMessageEvent { pub fn Constructor(worker: &ServiceWorkerGlobalScope, type_: DOMString, - init: &ExtendableMessageEventBinding::ExtendableMessageEventInit) + init: RootedTraceableBox<ExtendableMessageEventBinding::ExtendableMessageEventInit>) -> Fallible<Root<ExtendableMessageEvent>> { let global = worker.upcast::<GlobalScope>(); - rooted!(in(global.get_cx()) let data = init.data); let ev = ExtendableMessageEvent::new(global, Atom::from(type_), init.parent.parent.bubbles, init.parent.parent.cancelable, - data.handle(), + init.data.handle(), init.origin.clone().unwrap(), init.lastEventId.clone().unwrap()); Ok(ev) diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs index f97f14480c3..0c303010656 100644 --- a/components/script/dom/filereader.rs +++ b/components/script/dom/filereader.rs @@ -344,7 +344,7 @@ impl FileReaderMethods for FileReader { FileReaderResult::String(ref string) => StringOrObject::String(string.clone()), FileReaderResult::ArrayBuffer(ref arr_buffer) => { - StringOrObject::Object((*arr_buffer.ptr.get()).to_object()) + StringOrObject::Object(Heap::new((*arr_buffer.ptr.get()).to_object())) } }) } diff --git a/components/script/dom/messageevent.rs b/components/script/dom/messageevent.rs index 5b36b14f6ce..3df960d0882 100644 --- a/components/script/dom/messageevent.rs +++ b/components/script/dom/messageevent.rs @@ -10,6 +10,7 @@ use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; +use dom::bindings::trace::RootedTraceableBox; use dom::event::Event; use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; @@ -60,16 +61,13 @@ impl MessageEvent { pub fn Constructor(global: &GlobalScope, type_: DOMString, - init: &MessageEventBinding::MessageEventInit) + init: RootedTraceableBox<MessageEventBinding::MessageEventInit>) -> Fallible<Root<MessageEvent>> { - // Dictionaries need to be rooted - // https://github.com/servo/servo/issues/6381 - 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.data.handle(), init.origin.clone(), init.lastEventId.clone()); Ok(ev) diff --git a/components/script/dom/popstateevent.rs b/components/script/dom/popstateevent.rs index fde05e30394..1282d847d7c 100644 --- a/components/script/dom/popstateevent.rs +++ b/components/script/dom/popstateevent.rs @@ -10,6 +10,7 @@ use dom::bindings::inheritance::Castable; use dom::bindings::js::{MutHeapJSVal, Root}; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; +use dom::bindings::trace::RootedTraceableBox; use dom::event::Event; use dom::window::Window; use js::jsapi::{HandleValue, JSContext}; @@ -53,16 +54,15 @@ impl PopStateEvent { ev } - #[allow(unsafe_code)] pub fn Constructor(window: &Window, type_: DOMString, - init: &PopStateEventBinding::PopStateEventInit) + init: RootedTraceableBox<PopStateEventBinding::PopStateEventInit>) -> Fallible<Root<PopStateEvent>> { Ok(PopStateEvent::new(window, Atom::from(type_), init.parent.bubbles, init.parent.cancelable, - unsafe { HandleValue::from_marked_location(&init.state) })) + init.state.handle())) } } diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs index 2b26d5e1e8c..a81d9f767b6 100644 --- a/components/script/dom/request.rs +++ b/components/script/dom/request.rs @@ -20,6 +20,7 @@ use dom::bindings::error::{Error, Fallible}; use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::str::{ByteString, DOMString, USVString}; +use dom::bindings::trace::RootedTraceableBox; use dom::globalscope::GlobalScope; use dom::headers::{Guard, Headers}; use dom::promise::Promise; @@ -80,7 +81,7 @@ impl Request { // https://fetch.spec.whatwg.org/#dom-request pub fn Constructor(global: &GlobalScope, input: RequestInfo, - init: &RequestInit) + init: RootedTraceableBox<RequestInit>) -> Fallible<Root<Request>> { // Step 1 let temporary_request: NetTraitsRequest; @@ -139,12 +140,12 @@ impl Request { // TODO: `environment settings object` is not implemented in Servo yet. // Step 10 - if !init.window.is_undefined() && !init.window.is_null() { + if !init.window.handle().is_null_or_undefined() { return Err(Error::Type("Window is present and is not null".to_string())) } // Step 11 - if !init.window.is_undefined() { + if !init.window.handle().is_undefined() { window = Window::NoWindow; } @@ -179,7 +180,7 @@ impl Request { init.redirect.is_some() || init.referrer.is_some() || init.referrerPolicy.is_some() || - !init.window.is_undefined() { + !init.window.handle().is_undefined() { // Step 13.1 if request.mode == NetTraitsRequestMode::Navigate { return Err(Error::Type( @@ -311,7 +312,7 @@ impl Request { if let Some(possible_header) = init.headers.as_ref() { match possible_header { &HeadersInit::Headers(ref init_headers) => { - headers_copy = init_headers.clone(); + headers_copy = Root::from_ref(&*init_headers); } &HeadersInit::ByteStringSequenceSequence(ref init_sequence) => { try!(headers_copy.fill(Some( diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index 4726b82d900..1582647ca33 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -27,13 +27,14 @@ use dom::bindings::num::Finite; use dom::bindings::refcounted::TrustedPromise; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::str::{ByteString, DOMString, USVString}; +use dom::bindings::trace::RootedTraceableBox; use dom::bindings::weakref::MutableWeakRef; use dom::blob::{Blob, BlobImpl}; use dom::globalscope::GlobalScope; use dom::promise::Promise; use dom::promisenativehandler::{PromiseNativeHandler, Callback}; use dom::url::URL; -use js::jsapi::{HandleObject, HandleValue, JSContext, JSObject, JSAutoCompartment}; +use js::jsapi::{HandleObject, HandleValue, Heap, JSContext, JSObject, JSAutoCompartment}; use js::jsapi::{JS_NewPlainObject, JS_NewUint8ClampedArray}; use js::jsval::{JSVal, NullValue}; use script_traits::MsDuration; @@ -338,12 +339,12 @@ impl TestBindingMethods for TestBinding { fn ReceiveNullableSequence(&self) -> Option<Vec<i32>> { Some(vec![1]) } fn ReceiveTestDictionaryWithSuccessOnKeyword(&self) -> TestDictionary { TestDictionary { - anyValue: NullValue(), + anyValue: Heap::new(NullValue()), booleanValue: None, byteValue: None, dict: TestDictionaryDefaults { UnrestrictedDoubleValue: 0.0, - anyValue: NullValue(), + anyValue: Heap::new(NullValue()), booleanValue: false, bytestringValue: ByteString::new(vec![]), byteValue: 0, @@ -359,7 +360,7 @@ impl TestBindingMethods for TestBinding { nullableFloatValue: None, nullableLongLongValue: None, nullableLongValue: None, - nullableObjectValue: ptr::null_mut(), + nullableObjectValue: Heap::new(ptr::null_mut()), nullableOctetValue: None, nullableShortValue: None, nullableStringValue: None, @@ -402,7 +403,7 @@ impl TestBindingMethods for TestBinding { } } - fn DictMatchesPassedValues(&self, arg: &TestDictionary) -> bool { + fn DictMatchesPassedValues(&self, arg: RootedTraceableBox<TestDictionary>) -> bool { arg.type_.as_ref().map(|s| s == "success").unwrap_or(false) && arg.nonRequiredNullable.is_none() && arg.nonRequiredNullable2 == Some(None) diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index b68bd492fd0..d1eba0245e0 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -26,6 +26,7 @@ use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::DomObject; use dom::bindings::str::DOMString; use dom::bindings::structuredclone::StructuredCloneData; +use dom::bindings::trace::RootedTraceableBox; use dom::bindings::utils::{GlobalStaticData, WindowProxyHandler}; use dom::bluetooth::BluetoothExtraPermissionData; use dom::browsingcontext::BrowsingContext; @@ -921,7 +922,7 @@ impl WindowMethods for Window { #[allow(unrooted_must_root)] // https://fetch.spec.whatwg.org/#fetch-method - fn Fetch(&self, input: RequestOrUSVString, init: &RequestInit) -> Rc<Promise> { + fn Fetch(&self, input: RequestOrUSVString, init: RootedTraceableBox<RequestInit>) -> Rc<Promise> { fetch::Fetch(&self.upcast(), input, init) } diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 16bd699da7c..03e531c5f16 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -14,6 +14,7 @@ use dom::bindings::js::{MutNullableJS, Root}; use dom::bindings::reflector::DomObject; use dom::bindings::settings_stack::AutoEntryScript; use dom::bindings::str::DOMString; +use dom::bindings::trace::RootedTraceableBox; use dom::crypto::Crypto; use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope; use dom::globalscope::GlobalScope; @@ -314,7 +315,7 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { #[allow(unrooted_must_root)] // https://fetch.spec.whatwg.org/#fetch-method - fn Fetch(&self, input: RequestOrUSVString, init: &RequestInit) -> Rc<Promise> { + fn Fetch(&self, input: RequestOrUSVString, init: RootedTraceableBox<RequestInit>) -> Rc<Promise> { fetch::Fetch(self.upcast(), input, init) } } |