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 "nsContentList.h"
#include "nsDOMClassInfoID.h"
#include "nsIClassInfo.h"
#include "nsIXPCScriptable.h"
#include "nsIDOM3Node.h"
#include "nsDataHashtable.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) \
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); \
if (!foundInterface) { \
*aInstancePtr = nsnull; \

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

@ -1743,20 +1743,17 @@ nsDOMClassInfo::~nsDOMClassInfo()
}
}
NS_DEFINE_STATIC_IID_ACCESSOR(nsDOMClassInfo, NS_DOMCLASSINFO_IID)
NS_IMPL_ADDREF(nsDOMClassInfo)
NS_IMPL_RELEASE(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(nsIClassInfo)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCScriptable)
if (aIID.Equals(NS_GET_IID(nsDOMClassInfo))) {
*aInstancePtr = static_cast<nsIXPCScriptable*>(this);
return NS_OK;
}
else
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIClassInfo)
NS_INTERFACE_MAP_END
@ -4425,20 +4422,6 @@ nsDOMClassInfo::GetClassInfoInstance(nsDOMClassInfoData* aData)
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
void

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

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

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

@ -488,15 +488,17 @@ enum nsDOMClassInfoID {
* nsIClassInfo helper macros
*/
class nsIClassInfo;
#ifdef _IMPL_NS_LAYOUT
class nsIClassInfo;
class nsXPCClassInfo;
extern nsIClassInfo*
NS_GetDOMClassInfoInstance(nsDOMClassInfoID aID);
#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); \
if (!foundInterface) { \
*aInstancePtr = nsnull; \

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

@ -74,7 +74,8 @@
#else
#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); \
\
nsresult rv; \
@ -95,7 +96,8 @@
// nsScriptNamespaceManager. Remember to release NS_CLASSINFO_NAME(_class)
// (eg. when your module unloads).
#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); \
if (NS_CLASSINFO_NAME(_class)) { \
foundInterface = NS_CLASSINFO_NAME(_class); \

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

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

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

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

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

@ -48,19 +48,12 @@
#include "nsISupports.idl"
interface nsIXPConnectWrappedNative;
[uuid(b804504d-0025-4d6b-8ced-d94e41102a7f)]
[uuid(13aceb15-812a-476a-9326-2adc00250b76)]
interface nsIXPCScriptNotify : nsISupports
{
/**
* Method invoked when a script has been executed by XPConnect
*/
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))
#define NS_SUCCESS_CHROME_ACCESS_ONLY \
(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 \
(NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,3))
%}
@ -181,3 +189,36 @@ interface nsIXPCScriptable : nsISupports
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
// early.
return MaybePreserveWrapper(cx, wn, flags);
MaybePreserveWrapper(cx, wn, flags);
return JS_TRUE;
}
// Verify that our jsobject really is a wrapped native.
@ -634,7 +636,9 @@ ResolveNativeProperty(JSContext *cx, JSObject *wrapperObj,
if (!iface) {
// 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?
@ -642,7 +646,9 @@ ResolveNativeProperty(JSContext *cx, JSObject *wrapperObj,
if (!member) {
// No member, nothing to resolve.
return MaybePreserveWrapper(cx, wn, flags);
MaybePreserveWrapper(cx, wn, flags);
return JS_TRUE;
}
JSString *str = JSVAL_TO_STRING(id);

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

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

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

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

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

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

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

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

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

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