mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
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 -->
This commit is contained in:
commit
0cc6d3e997
18 changed files with 206 additions and 69 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1303,7 +1303,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "js"
|
||||
version = "0.1.4"
|
||||
source = "git+https://github.com/servo/rust-mozjs#b391ec674babe4a3955f562635ea936180c7eea3"
|
||||
source = "git+https://github.com/servo/rust-mozjs#93e59ef1263e451143d0ed431f1aa564ea101ab8"
|
||||
dependencies = [
|
||||
"cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -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")
|
||||
return handleOptional("Heap::new(${val}.get())", declType, default)
|
||||
|
||||
declType = CGGeneric("HandleValue")
|
||||
|
||||
if defaultValue is None:
|
||||
default = None
|
||||
elif isinstance(defaultValue, IDLNullValue):
|
||||
default = "HandleValue::null()"
|
||||
elif isinstance(defaultValue, IDLUndefinedValue):
|
||||
default = "HandleValue::undefined()"
|
||||
else:
|
||||
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")
|
||||
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()
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>,
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue