Fix for bug 519614 (Having to QI javascript scriptable helpers to nsIXPCScriptable is silly). r=mrbkap.

--HG--
extra : rebase_source : 10d46903d75cecff0f47f3bd483f849ea740e446
This commit is contained in:
Peter Van der Beken 2009-09-28 23:00:35 +02:00
Родитель bf91872d12
Коммит 11bf9bf420
16 изменённых файлов: 190 добавлений и 166 удалений

Просмотреть файл

@ -57,7 +57,7 @@
#include "nsNodeInfoManager.h" #include "nsNodeInfoManager.h"
#include "nsContentList.h" #include "nsContentList.h"
#include "nsDOMClassInfoID.h" #include "nsDOMClassInfoID.h"
#include "nsIClassInfo.h" #include "nsIXPCScriptable.h"
#include "nsIDOM3Node.h" #include "nsIDOM3Node.h"
#include "nsDataHashtable.h" #include "nsDataHashtable.h"
#include "nsIScriptRuntime.h" #include "nsIScriptRuntime.h"

Просмотреть файл

@ -1108,7 +1108,8 @@ NS_NewHTML##_elementName##Element(nsINodeInfo *aNodeInfo, PRBool aFromParser)\
#define NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_IF_TAG(_class, _tag) \ #define NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_IF_TAG(_class, _tag) \
if (mNodeInfo->Equals(nsGkAtoms::_tag) && \ if (mNodeInfo->Equals(nsGkAtoms::_tag) && \
aIID.Equals(NS_GET_IID(nsIClassInfo))) { \ (aIID.Equals(NS_GET_IID(nsIClassInfo)) || \
aIID.Equals(NS_GET_IID(nsXPCClassInfo)))) { \
foundInterface = NS_GetDOMClassInfoInstance(eDOMClassInfo_##_class##_id); \ foundInterface = NS_GetDOMClassInfoInstance(eDOMClassInfo_##_class##_id); \
if (!foundInterface) { \ if (!foundInterface) { \
*aInstancePtr = nsnull; \ *aInstancePtr = nsnull; \

Просмотреть файл

@ -1743,20 +1743,17 @@ nsDOMClassInfo::~nsDOMClassInfo()
} }
} }
NS_DEFINE_STATIC_IID_ACCESSOR(nsDOMClassInfo, NS_DOMCLASSINFO_IID)
NS_IMPL_ADDREF(nsDOMClassInfo) NS_IMPL_ADDREF(nsDOMClassInfo)
NS_IMPL_RELEASE(nsDOMClassInfo) NS_IMPL_RELEASE(nsDOMClassInfo)
NS_INTERFACE_MAP_BEGIN(nsDOMClassInfo) NS_INTERFACE_MAP_BEGIN(nsDOMClassInfo)
if (aIID.Equals(NS_GET_IID(nsXPCClassInfo)))
foundInterface = static_cast<nsIClassInfo*>(
static_cast<nsXPCClassInfo*>(this));
else
NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
NS_INTERFACE_MAP_ENTRY(nsIClassInfo) NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCScriptable) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIClassInfo)
if (aIID.Equals(NS_GET_IID(nsDOMClassInfo))) {
*aInstancePtr = static_cast<nsIXPCScriptable*>(this);
return NS_OK;
}
else
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
@ -4425,20 +4422,6 @@ nsDOMClassInfo::GetClassInfoInstance(nsDOMClassInfoData* aData)
return GET_CLEAN_CI_PTR(aData->mCachedClassInfo); return GET_CLEAN_CI_PTR(aData->mCachedClassInfo);
} }
// static
void
nsDOMClassInfo::PreserveNodeWrapper(nsIXPConnectWrappedNative *aWrapper)
{
nsCOMPtr<nsIClassInfo> ci = do_QueryInterface(aWrapper->Native());
if (ci) {
nsDOMClassInfo* domci = nsnull;
CallQueryInterface(ci, &domci);
if (domci) {
domci->PreserveWrapper(aWrapper->Native());
}
}
}
// static // static
void void

Просмотреть файл

@ -101,16 +101,9 @@ typedef PRUptrdiff PtrBits;
#define IS_EXTERNAL(_ptr) (PtrBits(_ptr) & 0x1) #define IS_EXTERNAL(_ptr) (PtrBits(_ptr) & 0x1)
#define NS_DOMCLASSINFO_IID \ class nsDOMClassInfo : public nsXPCClassInfo
{ 0x7da6858c, 0x5c12, 0x4588, \
{ 0x82, 0xbe, 0x01, 0xa2, 0x45, 0xc5, 0xc0, 0xb0 } }
class nsDOMClassInfo : public nsIXPCScriptable,
public nsIClassInfo
{ {
public: public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOMCLASSINFO_IID)
nsDOMClassInfo(nsDOMClassInfoData* aData); nsDOMClassInfo(nsDOMClassInfoData* aData);
virtual ~nsDOMClassInfo(); virtual ~nsDOMClassInfo();
@ -203,8 +196,6 @@ public:
::JS_GET_CLASS(cx, obj)->getProperty == sXPCNativeWrapperGetPropertyOp; ::JS_GET_CLASS(cx, obj)->getProperty == sXPCNativeWrapperGetPropertyOp;
} }
static void PreserveNodeWrapper(nsIXPConnectWrappedNative *aWrapper);
static nsISupports *GetNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj); static nsISupports *GetNative(nsIXPConnectWrappedNative *wrapper, JSObject *obj);
static nsIXPConnect *XPConnect() static nsIXPConnect *XPConnect()

Просмотреть файл

@ -488,15 +488,17 @@ enum nsDOMClassInfoID {
* nsIClassInfo helper macros * nsIClassInfo helper macros
*/ */
class nsIClassInfo;
#ifdef _IMPL_NS_LAYOUT #ifdef _IMPL_NS_LAYOUT
class nsIClassInfo;
class nsXPCClassInfo;
extern nsIClassInfo* extern nsIClassInfo*
NS_GetDOMClassInfoInstance(nsDOMClassInfoID aID); NS_GetDOMClassInfoInstance(nsDOMClassInfoID aID);
#define NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(_class) \ #define NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(_class) \
if (aIID.Equals(NS_GET_IID(nsIClassInfo))) { \ if (aIID.Equals(NS_GET_IID(nsIClassInfo)) || \
aIID.Equals(NS_GET_IID(nsXPCClassInfo))) { \
foundInterface = NS_GetDOMClassInfoInstance(eDOMClassInfo_##_class##_id); \ foundInterface = NS_GetDOMClassInfoInstance(eDOMClassInfo_##_class##_id); \
if (!foundInterface) { \ if (!foundInterface) { \
*aInstancePtr = nsnull; \ *aInstancePtr = nsnull; \

Просмотреть файл

@ -74,7 +74,8 @@
#else #else
#define NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(_class) \ #define NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(_class) \
if (aIID.Equals(NS_GET_IID(nsIClassInfo))) { \ if (aIID.Equals(NS_GET_IID(nsIClassInfo)) || \
aIID.Equals(NS_GET_IID(nsXPCClassInfo))) { \
static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID); \ static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID); \
\ \
nsresult rv; \ nsresult rv; \
@ -95,7 +96,8 @@
// nsScriptNamespaceManager. Remember to release NS_CLASSINFO_NAME(_class) // nsScriptNamespaceManager. Remember to release NS_CLASSINFO_NAME(_class)
// (eg. when your module unloads). // (eg. when your module unloads).
#define NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO(_class) \ #define NS_INTERFACE_MAP_ENTRY_EXTERNAL_DOM_CLASSINFO(_class) \
if (aIID.Equals(NS_GET_IID(nsIClassInfo))) { \ if (aIID.Equals(NS_GET_IID(nsIClassInfo)) || \
aIID.Equals(NS_GET_IID(nsXPCClassInfo))) { \
extern nsISupports *NS_CLASSINFO_NAME(_class); \ extern nsISupports *NS_CLASSINFO_NAME(_class); \
if (NS_CLASSINFO_NAME(_class)) { \ if (NS_CLASSINFO_NAME(_class)) { \
foundInterface = NS_CLASSINFO_NAME(_class); \ foundInterface = NS_CLASSINFO_NAME(_class); \

Просмотреть файл

@ -43,15 +43,15 @@
#include "nsStringGlue.h" #include "nsStringGlue.h"
#define NS_IDOM_SCRIPT_OBJECT_FACTORY_IID \ #define NS_IDOM_SCRIPT_OBJECT_FACTORY_IID \
{ 0xd5a4f935, 0xe428, 0x47ec, \ { 0x8c0eb687, 0xa859, 0x4a62, \
{ 0x8f, 0x36, 0x44, 0x23, 0xfa, 0xa2, 0x21, 0x90 } } { 0x99, 0x82, 0xea, 0xbf, 0x9e, 0xf5, 0x59, 0x5f } }
class nsIScriptContext; class nsIScriptContext;
class nsIScriptGlobalObject; class nsIScriptGlobalObject;
class nsIScriptRuntime; class nsIScriptRuntime;
class nsIDOMEventListener; class nsIDOMEventListener;
typedef nsIClassInfo* (*nsDOMClassInfoExternalConstructorFnc) typedef nsXPCClassInfo* (*nsDOMClassInfoExternalConstructorFnc)
(const char* aName); (const char* aName);
class nsIDOMScriptObjectFactory : public nsISupports { class nsIDOMScriptObjectFactory : public nsISupports {

Просмотреть файл

@ -3520,13 +3520,6 @@ nsJSContext::ScriptExecuted()
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsJSContext::PreserveWrapper(nsIXPConnectWrappedNative *aWrapper)
{
nsDOMClassInfo::PreserveNodeWrapper(aWrapper);
return NS_OK;
}
//static //static
void void
nsJSContext::CC() nsJSContext::CC()

Просмотреть файл

@ -48,19 +48,12 @@
#include "nsISupports.idl" #include "nsISupports.idl"
interface nsIXPConnectWrappedNative; [uuid(13aceb15-812a-476a-9326-2adc00250b76)]
[uuid(b804504d-0025-4d6b-8ced-d94e41102a7f)]
interface nsIXPCScriptNotify : nsISupports interface nsIXPCScriptNotify : nsISupports
{ {
/** /**
* Method invoked when a script has been executed by XPConnect * Method invoked when a script has been executed by XPConnect
*/ */
void ScriptExecuted(); void ScriptExecuted();
/**
* Method invoked to preserve an nsIXPConnectWrappedNative as needed
*/
void preserveWrapper(in nsIXPConnectWrappedNative wrapper);
}; };

Просмотреть файл

@ -48,6 +48,14 @@
(NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,1)) (NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,1))
#define NS_SUCCESS_CHROME_ACCESS_ONLY \ #define NS_SUCCESS_CHROME_ACCESS_ONLY \
(NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,2)) (NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,2))
/**
* Classes that want slim wrappers should return NS_SUCCESS_ALLOW_SLIM_WRAPPERS
* from their scriptable helper's PreCreate hook. They must also force a parent
* for their wrapper (from the PreCreate hook), they must implement
* nsWrapperCache and their scriptable helper must implement nsXPCClassInfo and
* must return DONT_ASK_INSTANCE_FOR_SCRIPTABLE in the flags.
*/
#define NS_SUCCESS_ALLOW_SLIM_WRAPPERS \ #define NS_SUCCESS_ALLOW_SLIM_WRAPPERS \
(NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,3)) (NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,3))
%} %}
@ -181,3 +189,36 @@ interface nsIXPCScriptable : nsISupports
void postCreatePrototype(in JSContextPtr cx, in JSObjectPtr proto); void postCreatePrototype(in JSContextPtr cx, in JSObjectPtr proto);
}; };
%{ C++
#include "nsAutoPtr.h"
#define NS_XPCCLASSINFO_IID \
{ 0xc39aa8db, 0x619d, 0x4ee6, \
{ 0xb1, 0x72, 0x5a, 0x83, 0x5d, 0x68, 0xfb, 0xb2 } }
class NS_NO_VTABLE nsXPCClassInfo : public nsIClassInfo,
public nsIXPCScriptable
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XPCCLASSINFO_IID)
NS_IMETHOD_(nsrefcnt) AddRef() = 0;
NS_IMETHOD_(nsrefcnt) Release() = 0;
virtual void PreserveWrapper(nsISupports *aNative) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsXPCClassInfo, NS_XPCCLASSINFO_IID)
inline
nsresult
CallQueryInterface(nsISupports* aSourcePtr,
nsRefPtrGetterAddRefs<nsXPCClassInfo> aDestPtr)
{
return CallQueryInterface(aSourcePtr,
static_cast<nsXPCClassInfo**>(aDestPtr));
}
%}

Просмотреть файл

@ -618,7 +618,9 @@ ResolveNativeProperty(JSContext *cx, JSObject *wrapperObj,
// A non-string id is being resolved. Won't be found here, return // A non-string id is being resolved. Won't be found here, return
// early. // early.
return MaybePreserveWrapper(cx, wn, flags); MaybePreserveWrapper(cx, wn, flags);
return JS_TRUE;
} }
// Verify that our jsobject really is a wrapped native. // Verify that our jsobject really is a wrapped native.
@ -634,7 +636,9 @@ ResolveNativeProperty(JSContext *cx, JSObject *wrapperObj,
if (!iface) { if (!iface) {
// No interface, nothing to resolve. // No interface, nothing to resolve.
return MaybePreserveWrapper(cx, wn, flags); MaybePreserveWrapper(cx, wn, flags);
return JS_TRUE;
} }
// did we find a method/attribute by that name? // did we find a method/attribute by that name?
@ -642,7 +646,9 @@ ResolveNativeProperty(JSContext *cx, JSObject *wrapperObj,
if (!member) { if (!member) {
// No member, nothing to resolve. // No member, nothing to resolve.
return MaybePreserveWrapper(cx, wn, flags); MaybePreserveWrapper(cx, wn, flags);
return JS_TRUE;
} }
JSString *str = JSVAL_TO_STRING(id); JSString *str = JSVAL_TO_STRING(id);

Просмотреть файл

@ -276,19 +276,16 @@ GetSecurityManager()
* Used to ensure that an XPCWrappedNative stays alive when its scriptable * Used to ensure that an XPCWrappedNative stays alive when its scriptable
* helper defines an "expando" property on it. * helper defines an "expando" property on it.
*/ */
inline JSBool inline void
MaybePreserveWrapper(JSContext *cx, XPCWrappedNative *wn, uintN flags) MaybePreserveWrapper(JSContext *cx, XPCWrappedNative *wn, uintN flags)
{ {
if ((flags & JSRESOLVE_ASSIGNING) && if ((flags & JSRESOLVE_ASSIGNING)) {
(::JS_GetOptions(cx) & JSOPTION_PRIVATE_IS_NSISUPPORTS)) { nsRefPtr<nsXPCClassInfo> ci;
nsCOMPtr<nsIXPCScriptNotify> scriptNotify = CallQueryInterface(wn->Native(), getter_AddRefs(ci));
do_QueryInterface(static_cast<nsISupports*> if (ci) {
(JS_GetContextPrivate(cx))); ci->PreserveWrapper(wn->Native());
if (scriptNotify) {
return NS_SUCCEEDED(scriptNotify->PreserveWrapper(wn));
} }
} }
return JS_TRUE;
} }
inline JSBool inline JSBool

Просмотреть файл

@ -1632,15 +1632,10 @@ nsXPConnect::MoveWrappers(JSContext *aJSContext,
continue; continue;
XPCNativeScriptableCreateInfo sciProto; XPCNativeScriptableCreateInfo sciProto;
XPCNativeScriptableCreateInfo sciWrapper; XPCNativeScriptableCreateInfo sci;
const XPCNativeScriptableCreateInfo& sciWrapper =
nsresult rv = XPCWrappedNative::GatherScriptableCreateInfo(identity, info,
XPCWrappedNative::GatherScriptableCreateInfo(identity, sciProto, sci);
info.get(),
&sciProto,
&sciWrapper);
if(NS_FAILED(rv))
return NS_ERROR_FAILURE;
// If the wrapper doesn't want precreate, then we don't need to // If the wrapper doesn't want precreate, then we don't need to
// worry about reparenting it. // worry about reparenting it.
@ -1648,8 +1643,9 @@ nsXPConnect::MoveWrappers(JSContext *aJSContext,
continue; continue;
JSObject *newParent = aOldScope; JSObject *newParent = aOldScope;
rv = sciWrapper.GetCallback()->PreCreate(identity, ccx, aOldScope, nsresult rv = sciWrapper.GetCallback()->PreCreate(identity, ccx,
&newParent); aOldScope,
&newParent);
if(NS_FAILED(rv)) if(NS_FAILED(rv))
return rv; return rv;
@ -2109,7 +2105,7 @@ nsXPConnect::GetWrappedNativePrototype(JSContext * aJSContext,
return UnexpectedFailure(NS_ERROR_FAILURE); return UnexpectedFailure(NS_ERROR_FAILURE);
XPCNativeScriptableCreateInfo sciProto; XPCNativeScriptableCreateInfo sciProto;
XPCWrappedNative::GatherProtoScriptableCreateInfo(aClassInfo, &sciProto); XPCWrappedNative::GatherProtoScriptableCreateInfo(aClassInfo, sciProto);
AutoMarkingWrappedNativeProtoPtr proto(ccx); AutoMarkingWrappedNativeProtoPtr proto(ccx);
proto = XPCWrappedNativeProto::GetNewOrUsed(ccx, scope, aClassInfo, proto = XPCWrappedNativeProto::GetNewOrUsed(ccx, scope, aClassInfo,

Просмотреть файл

@ -2027,25 +2027,27 @@ private:
// it abstracts out the scriptable interface pointer and the flags. After // it abstracts out the scriptable interface pointer and the flags. After
// creation these are factored differently using XPCNativeScriptableInfo. // creation these are factored differently using XPCNativeScriptableInfo.
class XPCNativeScriptableCreateInfo class NS_STACK_CLASS XPCNativeScriptableCreateInfo
{ {
public: public:
XPCNativeScriptableCreateInfo(const XPCNativeScriptableInfo& si) XPCNativeScriptableCreateInfo(const XPCNativeScriptableInfo& si)
: mCallback(si.GetCallback()), mFlags(si.GetFlags()) {} : mCallback(si.GetCallback()), mFlags(si.GetFlags()) {}
XPCNativeScriptableCreateInfo(nsIXPCScriptable* callback = nsnull, XPCNativeScriptableCreateInfo(already_AddRefed<nsIXPCScriptable> callback,
XPCNativeScriptableFlags flags = 0) XPCNativeScriptableFlags flags)
: mCallback(callback), mFlags(flags) {} : mCallback(callback), mFlags(flags) {}
XPCNativeScriptableCreateInfo()
: mFlags(0) {}
nsIXPCScriptable* nsIXPCScriptable*
GetCallback() const {return mCallback;} GetCallback() const {return mCallback;}
const XPCNativeScriptableFlags& const XPCNativeScriptableFlags&
GetFlags() const {return mFlags;} GetFlags() const {return mFlags;}
void
SetCallback(nsIXPCScriptable* callback) {mCallback = callback;}
void void
SetCallback(already_AddRefed<nsIXPCScriptable> callback) SetCallback(already_AddRefed<nsIXPCScriptable> callback)
{mCallback = callback;} {mCallback = callback;}
@ -2609,9 +2611,9 @@ public:
char* ToString(XPCCallContext& ccx, char* ToString(XPCCallContext& ccx,
XPCWrappedNativeTearOff* to = nsnull) const; XPCWrappedNativeTearOff* to = nsnull) const;
static nsresult GatherProtoScriptableCreateInfo( static void GatherProtoScriptableCreateInfo(
nsIClassInfo* classInfo, nsIClassInfo* classInfo,
XPCNativeScriptableCreateInfo* sciProto); XPCNativeScriptableCreateInfo& sciProto);
JSBool HasExternalReference() const {return mRefCnt > 1;} JSBool HasExternalReference() const {return mRefCnt > 1;}
@ -2683,11 +2685,11 @@ private:
XPCWrappedNativeTearOff* to); XPCWrappedNativeTearOff* to);
public: public:
static nsresult GatherScriptableCreateInfo( static const XPCNativeScriptableCreateInfo& GatherScriptableCreateInfo(
nsISupports* obj, nsISupports* obj,
nsIClassInfo* classInfo, nsIClassInfo* classInfo,
XPCNativeScriptableCreateInfo* sciProto, XPCNativeScriptableCreateInfo& sciProto,
XPCNativeScriptableCreateInfo* sciWrapper); XPCNativeScriptableCreateInfo& sciWrapper);
private: private:
union union

Просмотреть файл

@ -409,7 +409,7 @@ XPCWrappedNative::GetNewOrUsed(XPCCallContext& ccx,
#endif #endif
XPCNativeScriptableCreateInfo sciProto; XPCNativeScriptableCreateInfo sciProto;
XPCNativeScriptableCreateInfo sciWrapper; XPCNativeScriptableCreateInfo sci;
// Gather scriptable create info if we are wrapping something // Gather scriptable create info if we are wrapping something
// other than an nsIClassInfo object. We need to not do this for // other than an nsIClassInfo object. We need to not do this for
@ -418,10 +418,9 @@ XPCWrappedNative::GetNewOrUsed(XPCCallContext& ccx,
// code is obviously intended for the implementation of the class // code is obviously intended for the implementation of the class
// described by the nsIClassInfo, not for the class info object // described by the nsIClassInfo, not for the class info object
// itself. // itself.
if(!isClassInfo && const XPCNativeScriptableCreateInfo& sciWrapper =
NS_FAILED(GatherScriptableCreateInfo(identity, info.get(), isClassInfo ? sci :
&sciProto, &sciWrapper))) GatherScriptableCreateInfo(identity, info, sciProto, sci);
return NS_ERROR_FAILURE;
JSObject* parent = Scope->GetGlobalJSObject(); JSObject* parent = Scope->GetGlobalJSObject();
@ -924,13 +923,30 @@ XPCWrappedNative::~XPCWrappedNative()
// This is factored out so that it can be called publicly // This is factored out so that it can be called publicly
// static // static
nsresult void
XPCWrappedNative::GatherProtoScriptableCreateInfo( XPCWrappedNative::GatherProtoScriptableCreateInfo(
nsIClassInfo* classInfo, nsIClassInfo* classInfo,
XPCNativeScriptableCreateInfo* sciProto) XPCNativeScriptableCreateInfo& sciProto)
{ {
NS_ASSERTION(classInfo, "bad param"); NS_ASSERTION(classInfo, "bad param");
NS_ASSERTION(sciProto && !sciProto->GetCallback(), "bad param"); NS_ASSERTION(!sciProto.GetCallback(), "bad param");
nsXPCClassInfo *classInfoHelper = nsnull;
CallQueryInterface(classInfo, &classInfoHelper);
if(classInfoHelper)
{
nsCOMPtr<nsIXPCScriptable> helper =
dont_AddRef(static_cast<nsIXPCScriptable*>(classInfoHelper));
JSUint32 flags;
nsresult rv = classInfoHelper->GetScriptableFlags(&flags);
if(NS_FAILED(rv))
flags = 0;
sciProto.SetCallback(helper.forget());
sciProto.SetFlags(flags);
return;
}
nsCOMPtr<nsISupports> possibleHelper; nsCOMPtr<nsISupports> possibleHelper;
nsresult rv = classInfo->GetHelperForLanguage( nsresult rv = classInfo->GetHelperForLanguage(
@ -946,34 +962,29 @@ XPCWrappedNative::GatherProtoScriptableCreateInfo(
if(NS_FAILED(rv)) if(NS_FAILED(rv))
flags = 0; flags = 0;
sciProto->SetCallback(helper.forget()); sciProto.SetCallback(helper.forget());
sciProto->SetFlags(flags); sciProto.SetFlags(flags);
} }
} }
return NS_OK;
} }
// static // static
nsresult const XPCNativeScriptableCreateInfo&
XPCWrappedNative::GatherScriptableCreateInfo( XPCWrappedNative::GatherScriptableCreateInfo(
nsISupports* obj, nsISupports* obj,
nsIClassInfo* classInfo, nsIClassInfo* classInfo,
XPCNativeScriptableCreateInfo* sciProto, XPCNativeScriptableCreateInfo& sciProto,
XPCNativeScriptableCreateInfo* sciWrapper) XPCNativeScriptableCreateInfo& sciWrapper)
{ {
NS_ASSERTION(sciProto && !sciProto->GetCallback(), "bad param"); NS_ASSERTION(!sciWrapper.GetCallback(), "bad param");
NS_ASSERTION(sciWrapper && !sciWrapper->GetCallback(), "bad param");
// Get the class scriptable helper (if present) // Get the class scriptable helper (if present)
if(classInfo) if(classInfo)
{ {
GatherProtoScriptableCreateInfo(classInfo, sciProto); GatherProtoScriptableCreateInfo(classInfo, sciProto);
sciWrapper->SetCallback(sciProto->GetCallback()); if(sciProto.GetFlags().DontAskInstanceForScriptable())
sciWrapper->SetFlags(sciProto->GetFlags()); return sciProto;
if(sciProto->GetFlags().DontAskInstanceForScriptable())
return NS_OK;
} }
// Do the same for the wrapper specific scriptable // Do the same for the wrapper specific scriptable
@ -985,65 +996,67 @@ XPCWrappedNative::GatherScriptableCreateInfo(
if(NS_FAILED(rv)) if(NS_FAILED(rv))
flags = 0; flags = 0;
sciWrapper->SetCallback(helper.forget()); sciWrapper.SetCallback(helper.forget());
sciWrapper->SetFlags(flags); sciWrapper.SetFlags(flags);
// A whole series of assertions to catch bad uses of scriptable flags on // A whole series of assertions to catch bad uses of scriptable flags on
// the siWrapper... // the siWrapper...
NS_ASSERTION(!(sciWrapper->GetFlags().WantPreCreate() && NS_ASSERTION(!(sciWrapper.GetFlags().WantPreCreate() &&
!sciProto->GetFlags().WantPreCreate()), !sciProto.GetFlags().WantPreCreate()),
"Can't set WANT_PRECREATE on an instance scriptable " "Can't set WANT_PRECREATE on an instance scriptable "
"without also setting it on the class scriptable"); "without also setting it on the class scriptable");
NS_ASSERTION(!(sciWrapper->GetFlags().DontEnumStaticProps() && NS_ASSERTION(!(sciWrapper.GetFlags().DontEnumStaticProps() &&
!sciProto->GetFlags().DontEnumStaticProps() && !sciProto.GetFlags().DontEnumStaticProps() &&
sciProto->GetCallback() && sciProto.GetCallback() &&
!sciProto->GetFlags().DontSharePrototype()), !sciProto.GetFlags().DontSharePrototype()),
"Can't set DONT_ENUM_STATIC_PROPS on an instance scriptable " "Can't set DONT_ENUM_STATIC_PROPS on an instance scriptable "
"without also setting it on the class scriptable (if present and shared)"); "without also setting it on the class scriptable (if present and shared)");
NS_ASSERTION(!(sciWrapper->GetFlags().DontEnumQueryInterface() && NS_ASSERTION(!(sciWrapper.GetFlags().DontEnumQueryInterface() &&
!sciProto->GetFlags().DontEnumQueryInterface() && !sciProto.GetFlags().DontEnumQueryInterface() &&
sciProto->GetCallback() && sciProto.GetCallback() &&
!sciProto->GetFlags().DontSharePrototype()), !sciProto.GetFlags().DontSharePrototype()),
"Can't set DONT_ENUM_QUERY_INTERFACE on an instance scriptable " "Can't set DONT_ENUM_QUERY_INTERFACE on an instance scriptable "
"without also setting it on the class scriptable (if present and shared)"); "without also setting it on the class scriptable (if present and shared)");
NS_ASSERTION(!(sciWrapper->GetFlags().DontAskInstanceForScriptable() && NS_ASSERTION(!(sciWrapper.GetFlags().DontAskInstanceForScriptable() &&
!sciProto->GetFlags().DontAskInstanceForScriptable()), !sciProto.GetFlags().DontAskInstanceForScriptable()),
"Can't set DONT_ASK_INSTANCE_FOR_SCRIPTABLE on an instance scriptable " "Can't set DONT_ASK_INSTANCE_FOR_SCRIPTABLE on an instance scriptable "
"without also setting it on the class scriptable"); "without also setting it on the class scriptable");
NS_ASSERTION(!(sciWrapper->GetFlags().ClassInfoInterfacesOnly() && NS_ASSERTION(!(sciWrapper.GetFlags().ClassInfoInterfacesOnly() &&
!sciProto->GetFlags().ClassInfoInterfacesOnly() && !sciProto.GetFlags().ClassInfoInterfacesOnly() &&
sciProto->GetCallback() && sciProto.GetCallback() &&
!sciProto->GetFlags().DontSharePrototype()), !sciProto.GetFlags().DontSharePrototype()),
"Can't set CLASSINFO_INTERFACES_ONLY on an instance scriptable " "Can't set CLASSINFO_INTERFACES_ONLY on an instance scriptable "
"without also setting it on the class scriptable (if present and shared)"); "without also setting it on the class scriptable (if present and shared)");
NS_ASSERTION(!(sciWrapper->GetFlags().AllowPropModsDuringResolve() && NS_ASSERTION(!(sciWrapper.GetFlags().AllowPropModsDuringResolve() &&
!sciProto->GetFlags().AllowPropModsDuringResolve() && !sciProto.GetFlags().AllowPropModsDuringResolve() &&
sciProto->GetCallback() && sciProto.GetCallback() &&
!sciProto->GetFlags().DontSharePrototype()), !sciProto.GetFlags().DontSharePrototype()),
"Can't set ALLOW_PROP_MODS_DURING_RESOLVE on an instance scriptable " "Can't set ALLOW_PROP_MODS_DURING_RESOLVE on an instance scriptable "
"without also setting it on the class scriptable (if present and shared)"); "without also setting it on the class scriptable (if present and shared)");
NS_ASSERTION(!(sciWrapper->GetFlags().AllowPropModsToPrototype() && NS_ASSERTION(!(sciWrapper.GetFlags().AllowPropModsToPrototype() &&
!sciProto->GetFlags().AllowPropModsToPrototype() && !sciProto.GetFlags().AllowPropModsToPrototype() &&
sciProto->GetCallback() && sciProto.GetCallback() &&
!sciProto->GetFlags().DontSharePrototype()), !sciProto.GetFlags().DontSharePrototype()),
"Can't set ALLOW_PROP_MODS_TO_PROTOTYPE on an instance scriptable " "Can't set ALLOW_PROP_MODS_TO_PROTOTYPE on an instance scriptable "
"without also setting it on the class scriptable (if present and shared)"); "without also setting it on the class scriptable (if present and shared)");
NS_ASSERTION(!(sciWrapper->GetFlags().DontSharePrototype() && NS_ASSERTION(!(sciWrapper.GetFlags().DontSharePrototype() &&
!sciProto->GetFlags().DontSharePrototype() && !sciProto.GetFlags().DontSharePrototype() &&
sciProto->GetCallback()), sciProto.GetCallback()),
"Can't set DONT_SHARE_PROTOTYPE on an instance scriptable " "Can't set DONT_SHARE_PROTOTYPE on an instance scriptable "
"without also setting it on the class scriptable (if present and shared)"); "without also setting it on the class scriptable (if present and shared)");
return sciWrapper;
} }
return NS_OK; return sciProto;
} }
void void
@ -3806,19 +3819,21 @@ ConstructSlimWrapper(XPCCallContext &ccx, nsISupports *p, nsWrapperCache *cache,
{ {
nsCOMPtr<nsISupports> identityObj = do_QueryInterface(p); nsCOMPtr<nsISupports> identityObj = do_QueryInterface(p);
nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(p); nsRefPtr<nsXPCClassInfo> classInfoHelper;
if(!classInfo) CallQueryInterface(p, getter_AddRefs(classInfoHelper));
return JS_FALSE;
// XXX Sucks a bit that we have to get the proto before we know whether we JSUint32 flagsInt;
// can create a slim wrapper. nsresult rv = classInfoHelper->GetScriptableFlags(&flagsInt);
XPCNativeScriptableCreateInfo sciProto; if(NS_FAILED(rv))
nsresult rv = XPCWrappedNative::GatherProtoScriptableCreateInfo(classInfo, flagsInt = 0;
&sciProto);
NS_ENSURE_SUCCESS(rv, JS_FALSE); XPCNativeScriptableFlags flags(flagsInt);
NS_ASSERTION(flags.DontAskInstanceForScriptable(),
"Not supported for cached wrappers!");
JSObject* parent = xpcScope->GetGlobalJSObject(); JSObject* parent = xpcScope->GetGlobalJSObject();
if(!sciProto.GetFlags().WantPreCreate()) if(!flags.WantPreCreate())
{ {
SLIM_LOG_NOT_CREATED(ccx, identityObj, SLIM_LOG_NOT_CREATED(ccx, identityObj,
"scriptable helper has no PreCreate hook"); "scriptable helper has no PreCreate hook");
@ -3827,8 +3842,7 @@ ConstructSlimWrapper(XPCCallContext &ccx, nsISupports *p, nsWrapperCache *cache,
} }
JSObject* plannedParent = parent; JSObject* plannedParent = parent;
rv = sciProto.GetCallback()->PreCreate(identityObj, ccx, parent, rv = classInfoHelper->PreCreate(identityObj, ccx, parent, &parent);
&parent);
if(rv != NS_SUCCESS_ALLOW_SLIM_WRAPPERS) if(rv != NS_SUCCESS_ALLOW_SLIM_WRAPPERS)
{ {
SLIM_LOG_NOT_CREATED(ccx, identityObj, "PreCreate hook refused"); SLIM_LOG_NOT_CREATED(ccx, identityObj, "PreCreate hook refused");
@ -3858,6 +3872,10 @@ ConstructSlimWrapper(XPCCallContext &ccx, nsISupports *p, nsWrapperCache *cache,
return JS_TRUE; return JS_TRUE;
} }
nsIClassInfo* classInfo = classInfoHelper;
XPCNativeScriptableCreateInfo sciProto(classInfoHelper.forget().get(),
flags);
AutoMarkingWrappedNativeProtoPtr xpcproto(ccx); AutoMarkingWrappedNativeProtoPtr xpcproto(ccx);
JSBool isGlobal = JS_FALSE; JSBool isGlobal = JS_FALSE;
xpcproto = XPCWrappedNativeProto::GetNewOrUsed(ccx, xpcScope, classInfo, xpcproto = XPCWrappedNativeProto::GetNewOrUsed(ccx, xpcScope, classInfo,

Просмотреть файл

@ -93,7 +93,10 @@ XPCWrappedNativeProto::Init(
JSBool isGlobal, JSBool isGlobal,
const XPCNativeScriptableCreateInfo* scriptableCreateInfo) const XPCNativeScriptableCreateInfo* scriptableCreateInfo)
{ {
if(scriptableCreateInfo && scriptableCreateInfo->GetCallback()) nsIXPCScriptable *callback = scriptableCreateInfo ?
scriptableCreateInfo->GetCallback() :
nsnull;
if(callback)
{ {
mScriptableInfo = mScriptableInfo =
XPCNativeScriptableInfo::Construct(ccx, isGlobal, scriptableCreateInfo); XPCNativeScriptableInfo::Construct(ccx, isGlobal, scriptableCreateInfo);
@ -135,19 +138,15 @@ XPCWrappedNativeProto::Init(
JSBool ok = mJSProtoObject && JS_SetPrivate(ccx, mJSProtoObject, this); JSBool ok = mJSProtoObject && JS_SetPrivate(ccx, mJSProtoObject, this);
if(ok && scriptableCreateInfo) if(ok && callback)
{ {
nsIXPCScriptable *callback = scriptableCreateInfo->GetCallback(); nsresult rv = callback->PostCreatePrototype(ccx, mJSProtoObject);
if(callback) if(NS_FAILED(rv))
{ {
nsresult rv = callback->PostCreatePrototype(ccx, mJSProtoObject); JS_SetPrivate(ccx, mJSProtoObject, nsnull);
if(NS_FAILED(rv)) mJSProtoObject = nsnull;
{ XPCThrower::Throw(rv, ccx);
JS_SetPrivate(ccx, mJSProtoObject, nsnull); return JS_FALSE;
mJSProtoObject = nsnull;
XPCThrower::Throw(rv, ccx);
return JS_FALSE;
}
} }
} }