mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
Bug 1474369
- Part 6: Use RefPtr for Array<T> of interface and WebIDL types, r=mccr8
Summary:
This means that using these types involves many fewer footguns, while not
requiring any changes to the actual XPConnect implementation!
Depends on D2111
Reviewers: mccr8!
Tags: #secure-revision
Bug #: 1474369
Differential Revision: https://phabricator.services.mozilla.com/D2334
This commit is contained in:
parent
5b6ca0e475
commit
f900f5239d
@ -334,13 +334,12 @@ nsXPCTestParams::TestDoubleSequence(const nsTArray<double>& a, nsTArray<double>&
|
|||||||
SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
|
SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX(nika): Consider generating the exposed type 'nsTArray<RefPtr<nsIXPCTestInterfaceA>>` here instead?
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXPCTestParams::TestInterfaceSequence(const nsTArray<nsIXPCTestInterfaceA*>& a,
|
nsXPCTestParams::TestInterfaceSequence(const nsTArray<RefPtr<nsIXPCTestInterfaceA>>& a,
|
||||||
nsTArray<nsIXPCTestInterfaceA*>& b,
|
nsTArray<RefPtr<nsIXPCTestInterfaceA>>& b,
|
||||||
nsTArray<nsIXPCTestInterfaceA*>& _retval)
|
nsTArray<RefPtr<nsIXPCTestInterfaceA>>& _retval)
|
||||||
{
|
{
|
||||||
SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_INTERFACE);
|
SEQUENCE_METHOD_IMPL(TAKE_OWNERSHIP_NOOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -132,6 +132,9 @@ class Builtin(object):
|
|||||||
return self.nativename.endswith('*')
|
return self.nativename.endswith('*')
|
||||||
|
|
||||||
def nativeType(self, calltype, shared=False, const=False):
|
def nativeType(self, calltype, shared=False, const=False):
|
||||||
|
if self.name in ["string", "wstring"] and calltype == 'element':
|
||||||
|
raise IDLError("Use string class types for string Sequence elements", self.location)
|
||||||
|
|
||||||
if const:
|
if const:
|
||||||
print >>sys.stderr, IDLError(
|
print >>sys.stderr, IDLError(
|
||||||
"[const] doesn't make sense on builtin types.", self.location, warning=True)
|
"[const] doesn't make sense on builtin types.", self.location, warning=True)
|
||||||
@ -409,6 +412,9 @@ class Typedef(object):
|
|||||||
parent.setName(self)
|
parent.setName(self)
|
||||||
self.realtype = parent.getName(self.type, self.location)
|
self.realtype = parent.getName(self.type, self.location)
|
||||||
|
|
||||||
|
if not isinstance(self.realtype, (Builtin, Native, Typedef)):
|
||||||
|
raise IDLError("Unsupported typedef target type", self.location)
|
||||||
|
|
||||||
def isScriptable(self):
|
def isScriptable(self):
|
||||||
return self.realtype.isScriptable()
|
return self.realtype.isScriptable()
|
||||||
|
|
||||||
@ -452,6 +458,8 @@ class Forward(object):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def nativeType(self, calltype):
|
def nativeType(self, calltype):
|
||||||
|
if calltype == 'element':
|
||||||
|
return 'RefPtr<%s>' % self.name
|
||||||
return "%s *%s" % (self.name, '*' if 'out' in calltype else '')
|
return "%s *%s" % (self.name, '*' if 'out' in calltype else '')
|
||||||
|
|
||||||
def rustType(self, calltype):
|
def rustType(self, calltype):
|
||||||
@ -534,7 +542,7 @@ class Native(object):
|
|||||||
def nativeType(self, calltype, const=False, shared=False):
|
def nativeType(self, calltype, const=False, shared=False):
|
||||||
if shared:
|
if shared:
|
||||||
if calltype != 'out':
|
if calltype != 'out':
|
||||||
raise IDLError("[shared] only applies to out parameters.")
|
raise IDLError("[shared] only applies to out parameters.", self.location)
|
||||||
const = True
|
const = True
|
||||||
|
|
||||||
if isinstance(self.nativename, tuple):
|
if isinstance(self.nativename, tuple):
|
||||||
@ -549,6 +557,21 @@ class Native(object):
|
|||||||
if self.specialtype == 'nsid' and calltype == 'in':
|
if self.specialtype == 'nsid' and calltype == 'in':
|
||||||
const = True
|
const = True
|
||||||
|
|
||||||
|
if calltype == 'element':
|
||||||
|
if self.isRef(calltype):
|
||||||
|
raise IDLError("[ref] qualified type unsupported in Sequence<T>", self.location)
|
||||||
|
|
||||||
|
# Promises should be held in RefPtr<T> in Sequence<T>s
|
||||||
|
if self.specialtype == 'promise':
|
||||||
|
return 'RefPtr<mozilla::dom::Promise>'
|
||||||
|
|
||||||
|
# We don't support nsIDPtr, in Sequence<T> currently, although
|
||||||
|
# this or support for Sequence<nsID> will be needed to replace
|
||||||
|
# [array] completely.
|
||||||
|
if self.specialtype == 'nsid':
|
||||||
|
raise IDLError("Sequence<nsIDPtr> not yet supported. "
|
||||||
|
"File an XPConnect bug if you need it.", self.location)
|
||||||
|
|
||||||
if self.isRef(calltype):
|
if self.isRef(calltype):
|
||||||
m = '& ' # [ref] is always passed with a single indirection
|
m = '& ' # [ref] is always passed with a single indirection
|
||||||
else:
|
else:
|
||||||
@ -575,11 +598,11 @@ class Native(object):
|
|||||||
if self.specialtype == 'nsid':
|
if self.specialtype == 'nsid':
|
||||||
return prefix + self.nativename
|
return prefix + self.nativename
|
||||||
if self.specialtype in ['cstring', 'utf8string']:
|
if self.specialtype in ['cstring', 'utf8string']:
|
||||||
if calltype == 'element':
|
if 'element' in calltype:
|
||||||
return '::nsstring::nsCString'
|
return '::nsstring::nsCString'
|
||||||
return prefix + '::nsstring::nsACString'
|
return prefix + '::nsstring::nsACString'
|
||||||
if self.specialtype in ['astring', 'domstring']:
|
if self.specialtype in ['astring', 'domstring']:
|
||||||
if calltype == 'element':
|
if 'element' in calltype:
|
||||||
return '::nsstring::nsString'
|
return '::nsstring::nsString'
|
||||||
return prefix + '::nsstring::nsAString'
|
return prefix + '::nsstring::nsAString'
|
||||||
if self.nativename == 'void':
|
if self.nativename == 'void':
|
||||||
@ -627,6 +650,8 @@ class WebIDL(object):
|
|||||||
return True # All DOM objects are script exposed.
|
return True # All DOM objects are script exposed.
|
||||||
|
|
||||||
def nativeType(self, calltype):
|
def nativeType(self, calltype):
|
||||||
|
if calltype == 'element':
|
||||||
|
return 'RefPtr<%s>' % self.native
|
||||||
return "%s *%s" % (self.native, '*' if 'out' in calltype else '')
|
return "%s *%s" % (self.native, '*' if 'out' in calltype else '')
|
||||||
|
|
||||||
def rustType(self, calltype):
|
def rustType(self, calltype):
|
||||||
@ -727,6 +752,8 @@ class Interface(object):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def nativeType(self, calltype, const=False):
|
def nativeType(self, calltype, const=False):
|
||||||
|
if calltype == 'element':
|
||||||
|
return 'RefPtr<%s>' % self.name
|
||||||
return "%s%s *%s" % ('const ' if const else '', self.name,
|
return "%s%s *%s" % ('const ' if const else '', self.name,
|
||||||
'*' if 'out' in calltype else '')
|
'*' if 'out' in calltype else '')
|
||||||
|
|
||||||
@ -752,7 +779,7 @@ class Interface(object):
|
|||||||
while name not in iface.namemap and iface is not None:
|
while name not in iface.namemap and iface is not None:
|
||||||
iface = self.idl.getName(TypeId(self.base), self.location)
|
iface = self.idl.getName(TypeId(self.base), self.location)
|
||||||
if iface is None:
|
if iface is None:
|
||||||
raise IDLError("cannot find symbol '%s'" % name)
|
raise IDLError("cannot find symbol '%s'" % name, self.location)
|
||||||
c = iface.namemap.get(name, location)
|
c = iface.namemap.get(name, location)
|
||||||
if c.kind != 'const':
|
if c.kind != 'const':
|
||||||
raise IDLError("symbol '%s' is not a constant", c.location)
|
raise IDLError("symbol '%s' is not a constant", c.location)
|
||||||
@ -1227,24 +1254,28 @@ class Param(object):
|
|||||||
class Array(object):
|
class Array(object):
|
||||||
def __init__(self, basetype):
|
def __init__(self, basetype):
|
||||||
self.type = basetype
|
self.type = basetype
|
||||||
|
self.location = self.type.location
|
||||||
|
|
||||||
def isScriptable(self):
|
def isScriptable(self):
|
||||||
return self.type.isScriptable()
|
return self.type.isScriptable()
|
||||||
|
|
||||||
def nativeType(self, calltype, const=False):
|
def nativeType(self, calltype, const=False):
|
||||||
|
if 'element' in calltype:
|
||||||
|
raise IDLError("nested [array] unsupported", self.location)
|
||||||
|
|
||||||
# For legacy reasons, we have to add a 'const ' to builtin pointer array
|
# For legacy reasons, we have to add a 'const ' to builtin pointer array
|
||||||
# types. (`[array] in string` and `[array] in wstring` parameters)
|
# types. (`[array] in string` and `[array] in wstring` parameters)
|
||||||
if calltype == 'in' and isinstance(self.type, Builtin) and self.type.isPointer():
|
if calltype == 'in' and isinstance(self.type, Builtin) and self.type.isPointer():
|
||||||
const = True
|
const = True
|
||||||
|
|
||||||
return "%s%s*%s" % ('const ' if const else '',
|
return "%s%s*%s" % ('const ' if const else '',
|
||||||
self.type.nativeType('element'),
|
self.type.nativeType('legacyelement'),
|
||||||
'*' if 'out' in calltype else '')
|
'*' if 'out' in calltype else '')
|
||||||
|
|
||||||
def rustType(self, calltype, const=False):
|
def rustType(self, calltype, const=False):
|
||||||
return "%s%s%s" % ('*mut ' if 'out' in calltype else '',
|
return "%s%s%s" % ('*mut ' if 'out' in calltype else '',
|
||||||
'*const ' if const else '*mut ',
|
'*const ' if const else '*mut ',
|
||||||
self.type.rustType('element'))
|
self.type.rustType('legacyelement'))
|
||||||
|
|
||||||
|
|
||||||
class Sequence(object):
|
class Sequence(object):
|
||||||
@ -1265,6 +1296,9 @@ class Sequence(object):
|
|||||||
return self.type.isScriptable()
|
return self.type.isScriptable()
|
||||||
|
|
||||||
def nativeType(self, calltype):
|
def nativeType(self, calltype):
|
||||||
|
if calltype == 'legacyelement':
|
||||||
|
raise IDLError("[array] Sequence<T> is unsupported", self.location)
|
||||||
|
|
||||||
base = 'nsTArray<%s>' % self.type.nativeType('element')
|
base = 'nsTArray<%s>' % self.type.nativeType('element')
|
||||||
if 'out' in calltype:
|
if 'out' in calltype:
|
||||||
return '%s& ' % base
|
return '%s& ' % base
|
||||||
@ -1274,6 +1308,8 @@ class Sequence(object):
|
|||||||
return base
|
return base
|
||||||
|
|
||||||
def rustType(self, calltype):
|
def rustType(self, calltype):
|
||||||
|
# NOTE: To add Rust support, ensure 'element' is handled correctly in
|
||||||
|
# all rustType callees.
|
||||||
raise RustNoncompat("Sequence<...> types")
|
raise RustNoncompat("Sequence<...> types")
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user