mirror of
https://github.com/servo/servo.git
synced 2025-07-29 18:20:24 +01:00
Make (dictionary)::empty() safe
It currently works by constructing from null (which will throw a runtime error if there are non-defaultable members). This changes it so that we no longer need a JSContext to construct this, so it can be safely constructed. In the case of non-defaultable members, this method simply does not exist.
This commit is contained in:
parent
c90737e6c8
commit
cceaede96a
2 changed files with 50 additions and 10 deletions
|
@ -744,7 +744,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
if defaultValue:
|
if defaultValue:
|
||||||
assert isinstance(defaultValue, IDLNullValue)
|
assert isinstance(defaultValue, IDLNullValue)
|
||||||
dictionary, = dictionaries
|
dictionary, = dictionaries
|
||||||
default = "%s::%s(%s::%s::empty(cx))" % (
|
default = "%s::%s(%s::%s::empty())" % (
|
||||||
union_native_type(type),
|
union_native_type(type),
|
||||||
dictionary.name,
|
dictionary.name,
|
||||||
CGDictionary.makeModuleName(dictionary.inner),
|
CGDictionary.makeModuleName(dictionary.inner),
|
||||||
|
@ -1148,7 +1148,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
typeName = "%s::%s" % (CGDictionary.makeModuleName(type.inner),
|
typeName = "%s::%s" % (CGDictionary.makeModuleName(type.inner),
|
||||||
CGDictionary.makeDictionaryName(type.inner))
|
CGDictionary.makeDictionaryName(type.inner))
|
||||||
declType = CGGeneric(typeName)
|
declType = CGGeneric(typeName)
|
||||||
empty = "%s::empty(cx)" % typeName
|
empty = "%s::empty()" % typeName
|
||||||
|
|
||||||
if type_needs_tracing(type):
|
if type_needs_tracing(type):
|
||||||
declType = CGTemplatedType("RootedTraceableBox", declType)
|
declType = CGTemplatedType("RootedTraceableBox", declType)
|
||||||
|
@ -6274,12 +6274,7 @@ class CGDictionary(CGThing):
|
||||||
|
|
||||||
return string.Template(
|
return string.Template(
|
||||||
"impl ${selfName} {\n"
|
"impl ${selfName} {\n"
|
||||||
" pub unsafe fn empty(cx: *mut JSContext) -> ${actualType} {\n"
|
"${empty}\n"
|
||||||
" match ${selfName}::new(cx, HandleValue::null()) {\n"
|
|
||||||
" Ok(ConversionResult::Success(v)) => v,\n"
|
|
||||||
" _ => unreachable!(),\n"
|
|
||||||
" }\n"
|
|
||||||
" }\n"
|
|
||||||
" pub unsafe fn new(cx: *mut JSContext, val: HandleValue) \n"
|
" pub unsafe fn new(cx: *mut JSContext, val: HandleValue) \n"
|
||||||
" -> Result<ConversionResult<${actualType}>, ()> {\n"
|
" -> Result<ConversionResult<${actualType}>, ()> {\n"
|
||||||
" let object = if val.get().is_null_or_undefined() {\n"
|
" let object = if val.get().is_null_or_undefined() {\n"
|
||||||
|
@ -6315,6 +6310,7 @@ class CGDictionary(CGThing):
|
||||||
"}\n").substitute({
|
"}\n").substitute({
|
||||||
"selfName": selfName,
|
"selfName": selfName,
|
||||||
"actualType": actualType,
|
"actualType": actualType,
|
||||||
|
"empty": CGIndenter(CGGeneric(self.makeEmpty()), indentLevel=4).define(),
|
||||||
"initParent": CGIndenter(CGGeneric(initParent), indentLevel=12).define(),
|
"initParent": CGIndenter(CGGeneric(initParent), indentLevel=12).define(),
|
||||||
"initMembers": CGIndenter(memberInits, indentLevel=12).define(),
|
"initMembers": CGIndenter(memberInits, indentLevel=12).define(),
|
||||||
"insertMembers": CGIndenter(memberInserts, indentLevel=8).define(),
|
"insertMembers": CGIndenter(memberInserts, indentLevel=8).define(),
|
||||||
|
@ -6380,6 +6376,50 @@ class CGDictionary(CGThing):
|
||||||
|
|
||||||
return CGGeneric(conversion)
|
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
|
@staticmethod
|
||||||
def makeMemberName(name):
|
def makeMemberName(name):
|
||||||
# Can't use Rust keywords as member names.
|
# Can't use Rust keywords as member names.
|
||||||
|
|
|
@ -115,7 +115,7 @@ fn dict_return(cx: *mut JSContext,
|
||||||
mut result: MutableHandleObject,
|
mut result: MutableHandleObject,
|
||||||
done: bool,
|
done: bool,
|
||||||
value: HandleValue) -> Fallible<()> {
|
value: HandleValue) -> Fallible<()> {
|
||||||
let mut dict = unsafe { IterableKeyOrValueResult::empty(cx) };
|
let mut dict = IterableKeyOrValueResult::empty();
|
||||||
dict.done = done;
|
dict.done = done;
|
||||||
dict.value.set(value.get());
|
dict.value.set(value.get());
|
||||||
rooted!(in(cx) let mut dict_value = UndefinedValue());
|
rooted!(in(cx) let mut dict_value = UndefinedValue());
|
||||||
|
@ -130,7 +130,7 @@ fn key_and_value_return(cx: *mut JSContext,
|
||||||
mut result: MutableHandleObject,
|
mut result: MutableHandleObject,
|
||||||
key: HandleValue,
|
key: HandleValue,
|
||||||
value: HandleValue) -> Fallible<()> {
|
value: HandleValue) -> Fallible<()> {
|
||||||
let mut dict = unsafe { IterableKeyAndValueResult::empty(cx) };
|
let mut dict = IterableKeyAndValueResult::empty();
|
||||||
dict.done = false;
|
dict.done = false;
|
||||||
dict.value = Some(vec![key, value]
|
dict.value = Some(vec![key, value]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue