Bug 1541684, part 3 - Statically compute if a method is reflectable. r=nika

XPCConvert::IsMethodReflectable() is derived entirely from
nsXPTMethodInfo, so we can compute it at build time and include it in
nsXPTMethodInfo. It is the only use of mNotXPCOM and mHidden, so we
can get rid of those fields at the same time.

This paves the way for getting rid of XPCWrappedJSClass::mDescriptors
in the next patch.

Differential Revision: https://phabricator.services.mozilla.com/D26070

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrew McCreight 2019-04-05 23:48:18 +00:00
parent a8dbd5d65f
commit 8f597c742f
6 changed files with 27 additions and 35 deletions

View File

@ -47,25 +47,6 @@ using namespace JS;
/***********************************************************/
// static
bool XPCConvert::IsMethodReflectable(const nsXPTMethodInfo& info) {
if (info.IsNotXPCOM() || info.IsHidden()) {
return false;
}
for (int i = info.GetParamCount() - 1; i >= 0; i--) {
const nsXPTParamInfo& param = info.GetParam(i);
const nsXPTType& type = param.GetType();
// Reflected methods can't use native types. All native types end up
// getting tagged as void*, so this check is easy.
if (type.Tag() == nsXPTType::T_VOID) {
return false;
}
}
return true;
}
static JSObject* UnwrapNativeCPOW(nsISupports* wrapper) {
nsCOMPtr<nsIXPConnectWrappedJS> underware = do_QueryInterface(wrapper);
if (underware) {

View File

@ -136,7 +136,7 @@ nsXPCWrappedJSClass::nsXPCWrappedJSClass(const nsXPTInterfaceInfo* aInfo)
}
for (i = 0; i < methodCount; i++) {
SetReflectable(i, XPCConvert::IsMethodReflectable(mInfo->Method(i)));
SetReflectable(i, mInfo->Method(i).IsReflectable());
}
}
} else {

View File

@ -280,7 +280,7 @@ already_AddRefed<XPCNativeInterface> XPCNativeInterface::NewInstance(
continue;
}
if (!XPCConvert::IsMethodReflectable(info)) {
if (!info.IsReflectable()) {
continue;
}

View File

@ -1838,8 +1838,6 @@ class XPCWrappedJSIterator final : public nsISimpleEnumerator {
// class here just for static methods
class XPCConvert {
public:
static bool IsMethodReflectable(const nsXPTMethodInfo& info);
/**
* Convert a native object into a JS::Value.
*

View File

@ -79,8 +79,7 @@ nsXPTMethodInfo = mkstruct(
"mNumParams",
"mGetter",
"mSetter",
"mNotXPCOM",
"mHidden",
"mReflectable",
"mOptArgc",
"mContext",
"mHasRetval",
@ -275,6 +274,10 @@ def link_to_cpp(interfaces, fd):
tag = type['tag']
d1 = d2 = 0
# TD_VOID is used for types that can't be represented in JS, so they
# should not be represented in the XPT info.
assert tag != 'TD_VOID'
if tag == 'TD_LEGACY_ARRAY':
d1 = type['size_is']
d2 = lower_extra_type(type['element'])
@ -316,13 +319,28 @@ def link_to_cpp(interfaces, fd):
optional='optional' in param['flags'])
))
def is_method_reflectable(method):
if 'notxpcom' in method['flags'] or 'hidden' in method['flags']:
return False
for param in method['params']:
# Reflected methods can't use native types. All native types end up
# getting tagged as void*, so this check is easy.
if param['type']['tag'] == 'TD_VOID':
return False
return True
def lower_method(method, ifacename):
methodname = "%s::%s" % (ifacename, method['name'])
isSymbol = 'symbol' in method['flags']
reflectable = is_method_reflectable(method)
if 'notxpcom' in method['flags'] or 'hidden' in method['flags']:
paramidx = name = numparams = 0 # hide parameters
if not reflectable:
# Hide the parameters of methods that can't be called from JS to
# reduce the size of the file.
paramidx = name = numparams = 0
else:
if isSymbol:
name = lower_symbol(method['name'])
@ -342,8 +360,6 @@ def link_to_cpp(interfaces, fd):
methods.append(nsXPTMethodInfo(
"%d = %s" % (len(methods), methodname),
# If our method is hidden, we can save some memory by not
# generating parameter info about it.
mName=name,
mParams=paramidx,
mNumParams=numparams,
@ -351,8 +367,7 @@ def link_to_cpp(interfaces, fd):
# Flags
mGetter='getter' in method['flags'],
mSetter='setter' in method['flags'],
mNotXPCOM='notxpcom' in method['flags'],
mHidden='hidden' in method['flags'],
mReflectable=reflectable,
mOptArgc='optargc' in method['flags'],
mContext='jscontext' in method['flags'],
mHasRetval='hasretval' in method['flags'],

View File

@ -415,8 +415,7 @@ static_assert(sizeof(nsXPTParamInfo) == 3, "wrong size");
struct nsXPTMethodInfo {
bool IsGetter() const { return mGetter; }
bool IsSetter() const { return mSetter; }
bool IsNotXPCOM() const { return mNotXPCOM; }
bool IsHidden() const { return mHidden; }
bool IsReflectable() const { return mReflectable; }
bool IsSymbol() const { return mIsSymbol; }
bool WantsOptArgc() const { return mOptArgc; }
bool WantsContext() const { return mContext; }
@ -482,8 +481,7 @@ struct nsXPTMethodInfo {
uint8_t mGetter : 1;
uint8_t mSetter : 1;
uint8_t mNotXPCOM : 1;
uint8_t mHidden : 1;
uint8_t mReflectable : 1;
uint8_t mOptArgc : 1;
uint8_t mContext : 1;
uint8_t mHasRetval : 1;