mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Backed out 4 changesets (bug 1541684) for bustages on xpcprivate.h . CLOSED TREE
Backed out changeset b021ea89cf04 (bug 1541684) Backed out changeset 16d5f0b792d4 (bug 1541684) Backed out changeset a37029984f13 (bug 1541684) Backed out changeset 900f639d72a3 (bug 1541684)
This commit is contained in:
parent
4be669f520
commit
ed1878b2ce
@ -47,6 +47,25 @@ 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) {
|
||||
|
@ -250,7 +250,7 @@ MozExternalRefCountType nsXPCWrappedJS::AddRef(void) {
|
||||
|
||||
if (2 == cnt && IsValid()) {
|
||||
GetJSObject(); // Unmark gray JSObject.
|
||||
XPCJSRuntime::Get()->AddWrappedJSRoot(this);
|
||||
mClass->GetRuntime()->AddWrappedJSRoot(this);
|
||||
}
|
||||
|
||||
return cnt;
|
||||
|
@ -33,6 +33,9 @@ using namespace mozilla::dom;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsXPCWrappedJSClass, nsIXPCWrappedJSClass)
|
||||
|
||||
// the value of this variable is never used - we use its address as a sentinel
|
||||
static uint32_t zero_methods_descriptor;
|
||||
|
||||
bool AutoScriptEvaluate::StartEvaluating(HandleObject scope) {
|
||||
MOZ_ASSERT(!mEvaluated,
|
||||
"AutoScriptEvaluate::Evaluate should only be called once");
|
||||
@ -108,20 +111,50 @@ already_AddRefed<nsXPCWrappedJSClass> nsXPCWrappedJSClass::GetNewOrUsed(
|
||||
const nsXPTInterfaceInfo* info = nsXPTInterfaceInfo::ByIID(aIID);
|
||||
if (info) {
|
||||
if (!info->IsBuiltinClass() && nsXPConnect::IsISupportsDescendant(info)) {
|
||||
clasp = new nsXPCWrappedJSClass(info);
|
||||
clasp = new nsXPCWrappedJSClass(aIID, info);
|
||||
if (!clasp->mDescriptors) {
|
||||
clasp = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return clasp.forget();
|
||||
}
|
||||
|
||||
nsXPCWrappedJSClass::nsXPCWrappedJSClass(const nsXPTInterfaceInfo* aInfo)
|
||||
: mInfo(aInfo) {
|
||||
XPCJSRuntime::Get()->GetWrappedJSClassMap()->Add(this);
|
||||
nsXPCWrappedJSClass::nsXPCWrappedJSClass(REFNSIID aIID,
|
||||
const nsXPTInterfaceInfo* aInfo)
|
||||
: mRuntime(nsXPConnect::GetRuntimeInstance()),
|
||||
mInfo(aInfo),
|
||||
mIID(aIID),
|
||||
mDescriptors(nullptr) {
|
||||
mRuntime->GetWrappedJSClassMap()->Add(this);
|
||||
|
||||
uint16_t methodCount = mInfo->MethodCount();
|
||||
if (methodCount) {
|
||||
int wordCount = (methodCount / 32) + 1;
|
||||
if (nullptr != (mDescriptors = new uint32_t[wordCount])) {
|
||||
int i;
|
||||
// init flags to 0;
|
||||
for (i = wordCount - 1; i >= 0; i--) {
|
||||
mDescriptors[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < methodCount; i++) {
|
||||
SetReflectable(i, XPCConvert::IsMethodReflectable(mInfo->Method(i)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mDescriptors = &zero_methods_descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
nsXPCWrappedJSClass::~nsXPCWrappedJSClass() {
|
||||
XPCJSRuntime::Get()->GetWrappedJSClassMap()->Remove(this);
|
||||
if (mDescriptors && mDescriptors != &zero_methods_descriptor) {
|
||||
delete[] mDescriptors;
|
||||
}
|
||||
if (mRuntime) {
|
||||
mRuntime->GetWrappedJSClassMap()->Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
JSObject* nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(JSContext* cx,
|
||||
@ -158,8 +191,7 @@ JSObject* nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(JSContext* cx,
|
||||
}
|
||||
|
||||
// check upfront for the existence of the function property
|
||||
HandleId funid =
|
||||
XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_QUERY_INTERFACE);
|
||||
HandleId funid = mRuntime->GetStringID(XPCJSContext::IDX_QUERY_INTERFACE);
|
||||
if (!JS_GetPropertyById(cx, jsobj, funid, &fun) || fun.isPrimitive()) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -772,7 +804,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
|
||||
|
||||
JSContext* cx = ccx.GetJSContext();
|
||||
|
||||
if (!cx || !info->IsReflectable()) {
|
||||
if (!cx || !IsReflectable(methodIndex)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -813,7 +845,6 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
|
||||
RootedValueVector args(cx);
|
||||
AutoScriptEvaluate scriptEval(cx);
|
||||
|
||||
XPCJSRuntime* xpcrt = XPCJSRuntime::Get();
|
||||
XPCJSContext* xpccx = ccx.GetContext();
|
||||
AutoSavePendingResult apr(xpccx);
|
||||
|
||||
@ -923,7 +954,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
|
||||
|
||||
if (param.IsIn()) {
|
||||
if (!JS_SetPropertyById(cx, out_obj,
|
||||
xpcrt->GetStringID(XPCJSContext::IDX_VALUE),
|
||||
mRuntime->GetStringID(XPCJSContext::IDX_VALUE),
|
||||
val)) {
|
||||
goto pre_call_clean_up;
|
||||
}
|
||||
@ -1018,9 +1049,8 @@ pre_call_clean_up:
|
||||
} else {
|
||||
RootedObject obj(cx, &argv[i].toObject());
|
||||
if (!JS_GetPropertyById(
|
||||
cx, obj, xpcrt->GetStringID(XPCJSContext::IDX_VALUE), &val)) {
|
||||
cx, obj, mRuntime->GetStringID(XPCJSContext::IDX_VALUE), &val))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// setup allocator and/or iid
|
||||
@ -1060,9 +1090,8 @@ pre_call_clean_up:
|
||||
} else {
|
||||
RootedObject obj(cx, &argv[i].toObject());
|
||||
if (!JS_GetPropertyById(
|
||||
cx, obj, xpcrt->GetStringID(XPCJSContext::IDX_VALUE), &val)) {
|
||||
cx, obj, mRuntime->GetStringID(XPCJSContext::IDX_VALUE), &val))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// setup allocator and/or iid
|
||||
@ -1111,7 +1140,7 @@ nsXPCWrappedJSClass::DebugDump(int16_t depth) {
|
||||
XPC_LOG_INDENT();
|
||||
const char* name = mInfo->Name();
|
||||
XPC_LOG_ALWAYS(("interface name is %s", name));
|
||||
char* iid = mInfo->IID().ToString();
|
||||
char* iid = mIID.ToString();
|
||||
XPC_LOG_ALWAYS(("IID number is %s", iid ? iid : "invalid"));
|
||||
if (iid) {
|
||||
free(iid);
|
||||
@ -1126,13 +1155,13 @@ nsXPCWrappedJSClass::DebugDump(int16_t depth) {
|
||||
XPC_LOG_ALWAYS(("ConstantCount = %d", mInfo->ConstantCount()));
|
||||
XPC_LOG_OUTDENT();
|
||||
}
|
||||
XPC_LOG_ALWAYS(("method count = %d", methodCount));
|
||||
if (depth && methodCount) {
|
||||
XPC_LOG_ALWAYS(("mRuntime @ %p", mRuntime));
|
||||
XPC_LOG_ALWAYS(("mDescriptors @ %p count = %d", mDescriptors, methodCount));
|
||||
if (depth && mDescriptors && methodCount) {
|
||||
depth--;
|
||||
XPC_LOG_INDENT();
|
||||
for (uint16_t i = 0; i < methodCount; i++) {
|
||||
XPC_LOG_ALWAYS(("Method %d is %s%s", i,
|
||||
mInfo->Method(i).IsReflectable() ? "" : " NOT ",
|
||||
XPC_LOG_ALWAYS(("Method %d is %s%s", i, IsReflectable(i) ? "" : " NOT ",
|
||||
"reflectable"));
|
||||
}
|
||||
XPC_LOG_OUTDENT();
|
||||
|
@ -280,7 +280,7 @@ already_AddRefed<XPCNativeInterface> XPCNativeInterface::NewInstance(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!info.IsReflectable()) {
|
||||
if (!XPCConvert::IsMethodReflectable(info)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1615,7 +1615,8 @@ class nsXPCWrappedJSClass final : public nsIXPCWrappedJSClass {
|
||||
public:
|
||||
static already_AddRefed<nsXPCWrappedJSClass> GetNewOrUsed(REFNSIID aIID);
|
||||
|
||||
REFNSIID GetIID() const { return mInfo->IID(); }
|
||||
REFNSIID GetIID() const { return mIID; }
|
||||
XPCJSRuntime* GetRuntime() const { return mRuntime; }
|
||||
const nsXPTInterfaceInfo* GetInterfaceInfo() const { return mInfo; }
|
||||
const char* GetInterfaceName();
|
||||
|
||||
@ -1644,7 +1645,17 @@ class nsXPCWrappedJSClass final : public nsIXPCWrappedJSClass {
|
||||
virtual ~nsXPCWrappedJSClass();
|
||||
|
||||
nsXPCWrappedJSClass() = delete;
|
||||
nsXPCWrappedJSClass(const nsXPTInterfaceInfo* aInfo);
|
||||
nsXPCWrappedJSClass(REFNSIID aIID, const nsXPTInterfaceInfo* aInfo);
|
||||
|
||||
bool IsReflectable(uint16_t i) const {
|
||||
return (bool)(mDescriptors[i / 32] & (1U << (i % 32)));
|
||||
}
|
||||
void SetReflectable(uint16_t i, bool b) {
|
||||
if (b)
|
||||
mDescriptors[i / 32] |= (1U << (i % 32));
|
||||
else
|
||||
mDescriptors[i / 32] &= ~(1U << (i % 32));
|
||||
}
|
||||
|
||||
bool GetArraySizeFromParam(const nsXPTMethodInfo* method,
|
||||
const nsXPTType& type, nsXPTCMiniVariant* params,
|
||||
@ -1659,7 +1670,10 @@ class nsXPCWrappedJSClass final : public nsIXPCWrappedJSClass {
|
||||
uint8_t n) const;
|
||||
|
||||
private:
|
||||
XPCJSRuntime* mRuntime;
|
||||
const nsXPTInterfaceInfo* mInfo;
|
||||
nsIID mIID;
|
||||
uint32_t* mDescriptors;
|
||||
};
|
||||
|
||||
/*************************/
|
||||
@ -1817,6 +1831,8 @@ 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.
|
||||
*
|
||||
|
@ -79,7 +79,8 @@ nsXPTMethodInfo = mkstruct(
|
||||
"mNumParams",
|
||||
"mGetter",
|
||||
"mSetter",
|
||||
"mReflectable",
|
||||
"mNotXPCOM",
|
||||
"mHidden",
|
||||
"mOptArgc",
|
||||
"mContext",
|
||||
"mHasRetval",
|
||||
@ -274,10 +275,6 @@ 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'])
|
||||
@ -319,28 +316,13 @@ 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 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
|
||||
if 'notxpcom' in method['flags'] or 'hidden' in method['flags']:
|
||||
paramidx = name = numparams = 0 # hide parameters
|
||||
else:
|
||||
if isSymbol:
|
||||
name = lower_symbol(method['name'])
|
||||
@ -360,6 +342,8 @@ 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,
|
||||
@ -367,7 +351,8 @@ def link_to_cpp(interfaces, fd):
|
||||
# Flags
|
||||
mGetter='getter' in method['flags'],
|
||||
mSetter='setter' in method['flags'],
|
||||
mReflectable=reflectable,
|
||||
mNotXPCOM='notxpcom' in method['flags'],
|
||||
mHidden='hidden' in method['flags'],
|
||||
mOptArgc='optargc' in method['flags'],
|
||||
mContext='jscontext' in method['flags'],
|
||||
mHasRetval='hasretval' in method['flags'],
|
||||
|
@ -413,7 +413,8 @@ static_assert(sizeof(nsXPTParamInfo) == 3, "wrong size");
|
||||
struct nsXPTMethodInfo {
|
||||
bool IsGetter() const { return mGetter; }
|
||||
bool IsSetter() const { return mSetter; }
|
||||
bool IsReflectable() const { return mReflectable; }
|
||||
bool IsNotXPCOM() const { return mNotXPCOM; }
|
||||
bool IsHidden() const { return mHidden; }
|
||||
bool IsSymbol() const { return mIsSymbol; }
|
||||
bool WantsOptArgc() const { return mOptArgc; }
|
||||
bool WantsContext() const { return mContext; }
|
||||
@ -479,7 +480,8 @@ struct nsXPTMethodInfo {
|
||||
|
||||
uint8_t mGetter : 1;
|
||||
uint8_t mSetter : 1;
|
||||
uint8_t mReflectable : 1;
|
||||
uint8_t mNotXPCOM : 1;
|
||||
uint8_t mHidden : 1;
|
||||
uint8_t mOptArgc : 1;
|
||||
uint8_t mContext : 1;
|
||||
uint8_t mHasRetval : 1;
|
||||
|
Loading…
Reference in New Issue
Block a user