aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen/CodegenRust.py
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2017-05-26 12:29:31 -0400
committerJosh Matthews <josh@joshmatthews.net>2017-09-25 16:10:58 -0400
commitda65698c5c5934220b82493b3f7bb2ab05a2e512 (patch)
treeebb8646bbbde4b988d55758598b6ea724149b79f /components/script/dom/bindings/codegen/CodegenRust.py
parente481e8934a0c37a4b1eba19862ff732ec9bf19c9 (diff)
downloadservo-da65698c5c5934220b82493b3f7bb2ab05a2e512.tar.gz
servo-da65698c5c5934220b82493b3f7bb2ab05a2e512.zip
Be more conservative about safety of dictionary and union values.
Mark dictionaries containing GC values as must_root, and wrap them in RootedTraceableBox in automatically-generated APIs. To accommodate union variants that are now flagged as unsafe, add RootedTraceableBox to union variants that need to be rooted, rather than wrapping the entire union value.
Diffstat (limited to 'components/script/dom/bindings/codegen/CodegenRust.py')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py43
1 files changed, 35 insertions, 8 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 208d4b1d923..4d31da25efe 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -723,9 +723,6 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if type.nullable():
declType = CGWrapper(declType, pre="Option<", post=" >")
- if isMember != "Dictionary" and type_needs_tracing(type):
- declType = CGTemplatedType("RootedTraceableBox", declType)
-
templateBody = ("match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n"
" Ok(ConversionResult::Success(value)) => value,\n"
" Ok(ConversionResult::Failure(error)) => {\n"
@@ -1427,6 +1424,8 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
nullable = returnType.nullable()
dictName = returnType.inner.name if nullable else returnType.name
result = CGGeneric(dictName)
+ if type_needs_tracing(returnType):
+ result = CGWrapper(result, pre="RootedTraceableBox<", post=">")
if nullable:
result = CGWrapper(result, pre="Option<", post=">")
return result
@@ -2262,6 +2261,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
'dom::bindings::str::ByteString',
'dom::bindings::str::DOMString',
'dom::bindings::str::USVString',
+ 'dom::bindings::trace::RootedTraceableBox',
'dom::types::*',
'js::error::throw_type_error',
'js::jsapi::HandleValue',
@@ -4132,15 +4132,23 @@ class CGUnionStruct(CGThing):
self.type = type
self.descriptorProvider = descriptorProvider
+ def membersNeedTracing(self):
+ for t in self.type.flatMemberTypes:
+ if type_needs_tracing(t):
+ return True
+ return False
+
def define(self):
- templateVars = map(lambda t: getUnionTypeTemplateVars(t, self.descriptorProvider),
+ templateVars = map(lambda t: (getUnionTypeTemplateVars(t, self.descriptorProvider),
+ type_needs_tracing(t)),
self.type.flatMemberTypes)
enumValues = [
- " %s(%s)," % (v["name"], v["typeName"]) for v in templateVars
+ " %s(%s)," % (v["name"], "RootedTraceableBox<%s>" % v["typeName"] if trace else v["typeName"])
+ for (v, trace) in templateVars
]
enumConversions = [
" %s::%s(ref inner) => inner.to_jsval(cx, rval),"
- % (self.type, v["name"]) for v in templateVars
+ % (self.type, v["name"]) for (v, _) in templateVars
]
return ("""\
#[derive(JSTraceable)]
@@ -4167,6 +4175,12 @@ class CGUnionConversionStruct(CGThing):
self.type = type
self.descriptorProvider = descriptorProvider
+ def membersNeedTracing(self):
+ for t in self.type.flatMemberTypes:
+ if type_needs_tracing(t):
+ return True
+ return False
+
def from_jsval(self):
memberTypes = self.type.flatMemberTypes
names = []
@@ -4310,7 +4324,10 @@ class CGUnionConversionStruct(CGThing):
def try_method(self, t):
templateVars = getUnionTypeTemplateVars(t, self.descriptorProvider)
- returnType = "Result<Option<%s>, ()>" % templateVars["typeName"]
+ actualType = templateVars["typeName"]
+ if type_needs_tracing(t):
+ actualType = "RootedTraceableBox<%s>" % actualType
+ returnType = "Result<Option<%s>, ()>" % actualType
jsConversion = templateVars["jsConversion"]
# Any code to convert to Object is unused, since we're already converting
@@ -6022,13 +6039,17 @@ class CGDictionary(CGThing):
(self.makeMemberName(m[0].identifier.name), self.getMemberType(m))
for m in self.memberInfo]
+ mustRoot = "#[must_root]\n" if self.membersNeedTracing() else ""
+
return (string.Template(
"#[derive(JSTraceable)]\n"
+ "${mustRoot}" +
"pub struct ${selfName} {\n" +
"${inheritance}" +
"\n".join(memberDecls) + "\n" +
"}").substitute({"selfName": self.makeClassName(d),
- "inheritance": inheritance}))
+ "inheritance": inheritance,
+ "mustRoot": mustRoot}))
def impl(self):
d = self.dictionary
@@ -6120,6 +6141,12 @@ class CGDictionary(CGThing):
"insertMembers": CGIndenter(memberInserts, indentLevel=8).define(),
})
+ def membersNeedTracing(self):
+ for member, _ in self.memberInfo:
+ if type_needs_tracing(member.type):
+ return True
+ return False
+
@staticmethod
def makeDictionaryName(dictionary):
return dictionary.identifier.name