Support objects in WebIDL unions

Fixes #17011
This commit is contained in:
Igor Matuszewski 2018-03-10 14:35:09 +01:00
parent 725f9cbefa
commit 17ecbaf8ff
2 changed files with 19 additions and 13 deletions

View file

@ -1075,20 +1075,24 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if type.isObject(): if type.isObject():
assert not isEnforceRange and not isClamp assert not isEnforceRange and not isClamp
# TODO: Need to root somehow templateBody = "${val}.get().to_object()"
# https://github.com/servo/servo/issues/6382
default = "ptr::null_mut()" default = "ptr::null_mut()"
templateBody = wrapObjectTemplate("${val}.get().to_object()",
default,
isDefinitelyObject, type, failureCode)
if isMember in ("Dictionary", "Union"): # TODO: Do we need to do the same for dictionaries?
if isMember == "Union":
templateBody = "RootedTraceableBox::from_box(Heap::boxed(%s))" % templateBody
default = "RootedTraceableBox::new(Heap::default())"
declType = CGGeneric("RootedTraceableBox<Heap<*mut JSObject>>")
elif isMember == "Dictionary":
declType = CGGeneric("Heap<*mut JSObject>") declType = CGGeneric("Heap<*mut JSObject>")
else: else:
# TODO: Need to root somehow # TODO: Need to root somehow
# https://github.com/servo/servo/issues/6382 # https://github.com/servo/servo/issues/6382
declType = CGGeneric("*mut JSObject") declType = CGGeneric("*mut JSObject")
templateBody = wrapObjectTemplate(templateBody, default,
isDefinitelyObject, type, failureCode)
return handleOptional(templateBody, declType, return handleOptional(templateBody, declType,
handleDefaultNull(default)) handleDefaultNull(default))
@ -4291,11 +4295,13 @@ class CGUnionConversionStruct(CGThing):
else: else:
mozMapObject = None mozMapObject = None
hasObjectTypes = interfaceObject or arrayObject or dateObject or object or mozMapObject hasObjectTypes = object or interfaceObject or arrayObject or dateObject or mozMapObject
if hasObjectTypes: if hasObjectTypes:
# "object" is not distinguishable from other types # "object" is not distinguishable from other types
assert not object or not (interfaceObject or arrayObject or dateObject or callbackObject or mozMapObject) assert not object or not (interfaceObject or arrayObject or dateObject or callbackObject or mozMapObject)
templateBody = CGList([], "\n") templateBody = CGList([], "\n")
if object:
templateBody.append(object)
if interfaceObject: if interfaceObject:
templateBody.append(interfaceObject) templateBody.append(interfaceObject)
if arrayObject: if arrayObject:
@ -4363,11 +4369,6 @@ class CGUnionConversionStruct(CGThing):
returnType = "Result<Option<%s>, ()>" % actualType returnType = "Result<Option<%s>, ()>" % actualType
jsConversion = templateVars["jsConversion"] jsConversion = templateVars["jsConversion"]
# Any code to convert to Object is unused, since we're already converting
# from an Object value.
if t.name == 'Object':
return CGGeneric('')
return CGWrapper( return CGWrapper(
CGIndenter(jsConversion, 4), CGIndenter(jsConversion, 4),
pre="unsafe fn TryConvertTo%s(cx: *mut JSContext, value: HandleValue) -> %s {\n" pre="unsafe fn TryConvertTo%s(cx: *mut JSContext, value: HandleValue) -> %s {\n"

View file

@ -765,7 +765,12 @@ unsafe impl<T: JSTraceable + 'static> JSTraceable for RootedTraceableBox<T> {
impl<T: JSTraceable + 'static> RootedTraceableBox<T> { impl<T: JSTraceable + 'static> RootedTraceableBox<T> {
/// DomRoot a JSTraceable thing for the life of this RootedTraceable /// DomRoot a JSTraceable thing for the life of this RootedTraceable
pub fn new(traceable: T) -> RootedTraceableBox<T> { pub fn new(traceable: T) -> RootedTraceableBox<T> {
let traceable = Box::into_raw(Box::new(traceable)); Self::from_box(Box::new(traceable))
}
/// Consumes a boxed JSTraceable and roots it for the life of this RootedTraceable.
pub fn from_box(boxed_traceable: Box<T>) -> RootedTraceableBox<T> {
let traceable = Box::into_raw(boxed_traceable);
unsafe { unsafe {
RootedTraceableSet::add(traceable); RootedTraceableSet::add(traceable);
} }