aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMs2ger <Ms2ger@gmail.com>2017-02-14 16:45:36 +0100
committerMs2ger <Ms2ger@gmail.com>2017-02-16 11:03:26 +0100
commitf7e2f0e641967ba78a0b6b057aec760f9a9ca519 (patch)
treebcc391aba306ce52e66ad1227238c866ad33dba3
parentf1605ab149032adb20aec667d7660a4e433824e8 (diff)
downloadservo-f7e2f0e641967ba78a0b6b057aec760f9a9ca519.tar.gz
servo-f7e2f0e641967ba78a0b6b057aec760f9a9ca519.zip
Use RootedTraceableBox for dictionaries.
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py53
-rw-r--r--components/script/dom/customevent.rs3
-rw-r--r--components/script/dom/errorevent.rs9
-rw-r--r--components/script/dom/extendablemessageevent.rs6
-rw-r--r--components/script/dom/messageevent.rs8
-rw-r--r--components/script/dom/popstateevent.rs3
-rw-r--r--components/script/dom/request.rs5
-rw-r--r--components/script/dom/testbinding.rs3
-rw-r--r--components/script/dom/window.rs3
-rw-r--r--components/script/dom/workerglobalscope.rs3
-rw-r--r--components/script/fetch.rs3
11 files changed, 75 insertions, 24 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 2d188d41104..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,
@@ -1090,6 +1091,12 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
typeName = "%s::%s" % (CGDictionary.makeModuleName(type.inner),
CGDictionary.makeDictionaryName(type.inner))
declType = CGGeneric(typeName)
+ 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"
@@ -1098,7 +1105,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
" _ => { %s },\n"
"}" % (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
@@ -3147,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))
@@ -5577,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',
@@ -6163,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)
@@ -6176,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/customevent.rs b/components/script/dom/customevent.rs
index 942253c30dc..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,7 +52,7 @@ 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_),
diff --git a/components/script/dom/errorevent.rs b/components/script/dom/errorevent.rs
index a89a7b7e527..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.get());
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 b070007f831..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.get());
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/messageevent.rs b/components/script/dom/messageevent.rs
index b066cf810fe..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.get());
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 7db2eea8fe6..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};
@@ -55,7 +56,7 @@ impl PopStateEvent {
pub fn Constructor(window: &Window,
type_: DOMString,
- init: &PopStateEventBinding::PopStateEventInit)
+ init: RootedTraceableBox<PopStateEventBinding::PopStateEventInit>)
-> Fallible<Root<PopStateEvent>> {
Ok(PopStateEvent::new(window,
Atom::from(type_),
diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs
index bf4914f8255..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;
@@ -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 677d5c611db..1582647ca33 100644
--- a/components/script/dom/testbinding.rs
+++ b/components/script/dom/testbinding.rs
@@ -27,6 +27,7 @@ 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;
@@ -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)
}
}
diff --git a/components/script/fetch.rs b/components/script/fetch.rs
index f1fd49147b7..0e7cacdfc1a 100644
--- a/components/script/fetch.rs
+++ b/components/script/fetch.rs
@@ -10,6 +10,7 @@ use dom::bindings::error::Error;
use dom::bindings::js::Root;
use dom::bindings::refcounted::{Trusted, TrustedPromise};
use dom::bindings::reflector::DomObject;
+use dom::bindings::trace::RootedTraceableBox;
use dom::globalscope::GlobalScope;
use dom::headers::Guard;
use dom::promise::Promise;
@@ -68,7 +69,7 @@ fn request_init_from_request(request: NetTraitsRequest) -> NetTraitsRequestInit
// https://fetch.spec.whatwg.org/#fetch-method
#[allow(unrooted_must_root)]
-pub fn Fetch(global: &GlobalScope, input: RequestInfo, init: &RequestInit) -> Rc<Promise> {
+pub fn Fetch(global: &GlobalScope, input: RequestInfo, init: RootedTraceableBox<RequestInit>) -> Rc<Promise> {
let core_resource_thread = global.core_resource_thread();
// Step 1