Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make (dictionary)::empty() safe #21131

Merged
merged 1 commit into from Jul 6, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -744,7 +744,7 @@ def wrapObjectTemplate(templateBody, nullValue, isDefinitelyObject, type,
if defaultValue:
assert isinstance(defaultValue, IDLNullValue)
dictionary, = dictionaries
default = "%s::%s(%s::%s::empty(cx))" % (
default = "%s::%s(%s::%s::empty())" % (
union_native_type(type),
dictionary.name,
CGDictionary.makeModuleName(dictionary.inner),
@@ -1148,7 +1148,7 @@ def wrapObjectTemplate(templateBody, nullValue, isDefinitelyObject, type,
typeName = "%s::%s" % (CGDictionary.makeModuleName(type.inner),
CGDictionary.makeDictionaryName(type.inner))
declType = CGGeneric(typeName)
empty = "%s::empty(cx)" % typeName
empty = "%s::empty()" % typeName

if type_needs_tracing(type):
declType = CGTemplatedType("RootedTraceableBox", declType)
@@ -6274,12 +6274,7 @@ def memberInsert(memberInfo):

return string.Template(
"impl ${selfName} {\n"
" pub unsafe fn empty(cx: *mut JSContext) -> ${actualType} {\n"
" match ${selfName}::new(cx, HandleValue::null()) {\n"
" Ok(ConversionResult::Success(v)) => v,\n"
" _ => unreachable!(),\n"
" }\n"
" }\n"
"${empty}\n"
" pub unsafe fn new(cx: *mut JSContext, val: HandleValue) \n"
" -> Result<ConversionResult<${actualType}>, ()> {\n"
" let object = if val.get().is_null_or_undefined() {\n"
@@ -6315,6 +6310,7 @@ def memberInsert(memberInfo):
"}\n").substitute({
"selfName": selfName,
"actualType": actualType,
"empty": CGIndenter(CGGeneric(self.makeEmpty()), indentLevel=4).define(),
"initParent": CGIndenter(CGGeneric(initParent), indentLevel=12).define(),
"initMembers": CGIndenter(memberInits, indentLevel=12).define(),
"insertMembers": CGIndenter(memberInserts, indentLevel=8).define(),
@@ -6380,6 +6376,50 @@ def indent(s):

return CGGeneric(conversion)

def makeEmpty(self):
if self.hasRequiredFields(self.dictionary):
return ""
parentTemplate = "parent: %s::%s::empty(),\n"
fieldTemplate = "%s: %s,\n"
functionTemplate = (
"pub fn empty() -> Self {\n"
" Self {\n"
"%s"
" }\n"
"}"
)
if self.membersNeedTracing():
parentTemplate = "dictionary.parent = %s::%s::empty();\n"
fieldTemplate = "dictionary.%s = %s;\n"
functionTemplate = (
"pub fn empty() -> RootedTraceableBox<Self> {\n"
" let mut dictionary = RootedTraceableBox::new(Self::default());\n"
"%s"
" dictionary\n"
"}"
)
s = ""
if self.dictionary.parent:
s += parentTemplate % (self.makeModuleName(self.dictionary.parent),
self.makeClassName(self.dictionary.parent))
for member, info in self.memberInfo:
if not member.optional:
return ""
default = info.default
if not default:
default = "None"
s += fieldTemplate % (self.makeMemberName(member.identifier.name), default)
return functionTemplate % CGIndenter(CGGeneric(s), 12).define()

def hasRequiredFields(self, dictionary):
if dictionary.parent:
if self.hasRequiredFields(dictionary.parent):
return True
for member in dictionary.members:
if not member.optional:
return True
return False

@staticmethod
def makeMemberName(name):
# Can't use Rust keywords as member names.
@@ -115,7 +115,7 @@ fn dict_return(cx: *mut JSContext,
mut result: MutableHandleObject,
done: bool,
value: HandleValue) -> Fallible<()> {
let mut dict = unsafe { IterableKeyOrValueResult::empty(cx) };
let mut dict = IterableKeyOrValueResult::empty();
dict.done = done;
dict.value.set(value.get());
rooted!(in(cx) let mut dict_value = UndefinedValue());
@@ -130,7 +130,7 @@ fn key_and_value_return(cx: *mut JSContext,
mut result: MutableHandleObject,
key: HandleValue,
value: HandleValue) -> Fallible<()> {
let mut dict = unsafe { IterableKeyAndValueResult::empty(cx) };
let mut dict = IterableKeyAndValueResult::empty();
dict.done = false;
dict.value = Some(vec![key, value]
.into_iter()
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.