aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen/CodegenRust.py
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings/codegen/CodegenRust.py')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py83
1 files changed, 58 insertions, 25 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 86ee03d7ddd..39e8bfa275d 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -836,6 +836,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
descriptorType = descriptor.nativeType
elif isArgument:
descriptorType = descriptor.argumentType
+ elif descriptor.interface.identifier.name == "WindowProxy":
+ conversionFunction = "windowproxy_from_handlevalue"
if failureCode is None:
substitutions = {
@@ -2409,7 +2411,9 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
'crate::dom::bindings::conversions::ConversionBehavior',
'crate::dom::bindings::conversions::StringificationBehavior',
'crate::dom::bindings::conversions::root_from_handlevalue',
+ 'crate::dom::bindings::conversions::windowproxy_from_handlevalue',
'std::ptr::NonNull',
+ 'std::rc::Rc',
'crate::dom::bindings::record::Record',
'crate::dom::bindings::num::Finite',
'crate::dom::bindings::root::DomRoot',
@@ -2419,10 +2423,12 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
'crate::dom::bindings::trace::RootedTraceableBox',
'crate::dom::bindings::utils::find_enum_value',
'crate::dom::types::*',
+ 'crate::dom::windowproxy::WindowProxy',
'crate::script_runtime::JSContext as SafeJSContext',
'js::error::throw_type_error',
'js::rust::HandleValue',
'js::jsapi::Heap',
+ 'js::jsapi::IsCallable',
'js::jsapi::JSContext',
'js::jsapi::JSObject',
'js::rust::MutableHandleValue',
@@ -2438,9 +2444,10 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
if not t.isUnion():
continue
for memberType in t.flatMemberTypes:
- if memberType.isDictionary() or memberType.isEnum():
+ if memberType.isDictionary() or memberType.isEnum() or memberType.isCallback():
memberModule = getModuleFromObject(memberType)
- memberName = memberType.inner.identifier.name
+ memberName = (memberType.callback.identifier.name
+ if memberType.isCallback() else memberType.inner.identifier.name)
imports.append("%s::%s" % (memberModule, memberName))
if memberType.isEnum():
imports.append("%s::%sValues" % (memberModule, memberName))
@@ -4380,6 +4387,9 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
elif is_typed_array(type):
name = type.name
typeName = "typedarray::Heap" + name
+ elif type.isCallback():
+ name = type.name
+ typeName = name
else:
raise TypeError("Can't handle %s in unions yet" % type)
@@ -4418,12 +4428,19 @@ class CGUnionStruct(CGThing):
return False
def define(self):
+ def getTypeWrapper(t):
+ if type_needs_tracing(t):
+ return "RootedTraceableBox"
+ if t.isCallback():
+ return "Rc"
+ return ""
+
templateVars = map(lambda t: (getUnionTypeTemplateVars(t, self.descriptorProvider),
- type_needs_tracing(t)),
+ getTypeWrapper(t)),
self.type.flatMemberTypes)
enumValues = [
- " %s(%s)," % (v["name"], "RootedTraceableBox<%s>" % v["typeName"] if trace else v["typeName"])
- for (v, trace) in templateVars
+ " %s(%s)," % (v["name"], "%s<%s>" % (wrapper, v["typeName"]) if wrapper else v["typeName"])
+ for (v, wrapper) in templateVars
]
enumConversions = [
" %s::%s(ref inner) => inner.to_jsval(cx, rval),"
@@ -4506,7 +4523,8 @@ class CGUnionConversionStruct(CGThing):
callbackMemberTypes = filter(lambda t: t.isCallback() or t.isCallbackInterface(), memberTypes)
if len(callbackMemberTypes) > 0:
assert len(callbackMemberTypes) == 1
- raise TypeError("Can't handle callbacks in unions.")
+ typeName = callbackMemberTypes[0].name
+ callbackObject = CGGeneric(get_match(typeName))
else:
callbackObject = None
@@ -4537,7 +4555,7 @@ class CGUnionConversionStruct(CGThing):
else:
mozMapObject = None
- hasObjectTypes = object or interfaceObject or arrayObject or dateObject or mozMapObject
+ hasObjectTypes = object or interfaceObject or arrayObject or dateObject or callbackObject or mozMapObject
if hasObjectTypes:
# "object" is not distinguishable from other types
assert not object or not (interfaceObject or arrayObject or dateObject or callbackObject or mozMapObject)
@@ -4548,6 +4566,8 @@ class CGUnionConversionStruct(CGThing):
templateBody.append(interfaceObject)
if arrayObject:
templateBody.append(arrayObject)
+ if callbackObject:
+ templateBody.append(callbackObject)
if mozMapObject:
templateBody.append(mozMapObject)
conversions.append(CGIfWrapper("value.get().is_object()", templateBody))
@@ -4608,6 +4628,8 @@ class CGUnionConversionStruct(CGThing):
actualType = templateVars["typeName"]
if type_needs_tracing(t):
actualType = "RootedTraceableBox<%s>" % actualType
+ if t.isCallback():
+ actualType = "Rc<%s>" % actualType
returnType = "Result<Option<%s>, ()>" % actualType
jsConversion = templateVars["jsConversion"]
@@ -6388,8 +6410,11 @@ class CGDictionary(CGThing):
def struct(self):
d = self.dictionary
if d.parent:
- inheritance = " pub parent: %s::%s,\n" % (self.makeModuleName(d.parent),
- self.makeClassName(d.parent))
+ typeName = "%s::%s" % (self.makeModuleName(d.parent),
+ self.makeClassName(d.parent))
+ if type_needs_tracing(d.parent):
+ typeName = "RootedTraceableBox<%s>" % typeName
+ inheritance = " pub parent: %s,\n" % typeName
else:
inheritance = ""
memberDecls = [" pub %s: %s," %
@@ -6399,8 +6424,9 @@ class CGDictionary(CGThing):
derive = ["JSTraceable"]
mustRoot = ""
if self.membersNeedTracing():
- mustRoot = "#[must_root]\n"
- derive += ["Default"]
+ mustRoot = "#[unrooted_must_root_lint::must_root]\n"
+ if not self.hasRequiredFields(self.dictionary):
+ derive += ["Default"]
return (string.Template(
"#[derive(${derive})]\n"
@@ -6460,16 +6486,14 @@ class CGDictionary(CGThing):
selfName = self.makeClassName(d)
if self.membersNeedTracing():
actualType = "RootedTraceableBox<%s>" % selfName
- preInitial = "let mut dictionary = RootedTraceableBox::new(%s::default());\n" % selfName
- initParent = initParent = ("dictionary.parent = %s;\n" % initParent) if initParent else ""
- memberInits = CGList([memberInit(m, False) for m in self.memberInfo])
- postInitial = ""
+ preInitial = "let dictionary = RootedTraceableBox::new(%s {\n" % selfName
+ postInitial = "});\n"
else:
actualType = selfName
preInitial = "let dictionary = %s {\n" % selfName
postInitial = "};\n"
- initParent = ("parent: %s,\n" % initParent) if initParent else ""
- memberInits = CGList([memberInit(m, True) for m in self.memberInfo])
+ initParent = ("parent: %s,\n" % initParent) if initParent else ""
+ memberInits = CGList([memberInit(m, True) for m in self.memberInfo])
return string.Template(
"impl ${selfName} {\n"
@@ -6515,15 +6539,12 @@ class CGDictionary(CGThing):
"initParent": CGIndenter(CGGeneric(initParent), indentLevel=16).define(),
"initMembers": CGIndenter(memberInits, indentLevel=16).define(),
"insertMembers": CGIndenter(memberInserts, indentLevel=8).define(),
- "preInitial": CGIndenter(CGGeneric(preInitial), indentLevel=16).define(),
- "postInitial": CGIndenter(CGGeneric(postInitial), indentLevel=16).define(),
+ "preInitial": CGIndenter(CGGeneric(preInitial), indentLevel=8).define(),
+ "postInitial": CGIndenter(CGGeneric(postInitial), indentLevel=8).define(),
})
def membersNeedTracing(self):
- for member, _ in self.memberInfo:
- if type_needs_tracing(member.type):
- return True
- return False
+ return type_needs_tracing(self.dictionary)
@staticmethod
def makeDictionaryName(dictionary):
@@ -6923,7 +6944,8 @@ class CGCallback(CGClass):
bases=[ClassBase(baseName)],
constructors=self.getConstructors(),
methods=realMethods,
- decorators="#[derive(JSTraceable, PartialEq)]\n#[allow_unrooted_interior]")
+ decorators="#[derive(JSTraceable, PartialEq)]\n"
+ "#[unrooted_must_root_lint::allow_unrooted_interior]")
def getConstructors(self):
return [ClassConstructor(
@@ -7386,7 +7408,16 @@ class CGIterableMethodGenerator(CGGeneric):
rooted!(in(*cx) let mut call_arg2 = UndefinedValue());
let mut call_args = vec![UndefinedValue(), UndefinedValue(), ObjectValue(*_obj)];
rooted!(in(*cx) let mut ignoredReturnVal = UndefinedValue());
- for i in 0..(*this).get_iterable_length() {
+
+ // This has to be a while loop since get_iterable_length() may change during
+ // the callback, and we need to avoid iterator invalidation.
+ //
+ // It is possible for this to loop infinitely, but that matches the spec
+ // and other browsers.
+ //
+ // https://heycam.github.io/webidl/#es-forEach
+ let mut i = 0;
+ while i < (*this).get_iterable_length() {
(*this).get_value_at_index(i).to_jsval(*cx, call_arg1.handle_mut());
(*this).get_key_at_index(i).to_jsval(*cx, call_arg2.handle_mut());
call_args[0] = call_arg1.handle().get();
@@ -7396,6 +7427,8 @@ class CGIterableMethodGenerator(CGGeneric):
ignoredReturnVal.handle_mut()) {
return false;
}
+
+ i += 1;
}
let result = ();