зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug 517196 (The JSClass of wrappers shouldn't change when morphing from slim to XPCWrappedNative). r=mrbkap.
--HG-- extra : rebase_source : 4f7978e3ed1335fc4f58478afc038fb63576581b
This commit is contained in:
Родитель
72d461b556
Коммит
f93aeceb40
|
@ -108,7 +108,6 @@ PRBool nsScriptSecurityManager::sStrictFileOriginPolicy = PR_TRUE;
|
|||
// natives, to avoid having to QI to nsIXPConnectWrappedNative all the
|
||||
// time when doing security checks.
|
||||
static JSEqualityOp sXPCWrappedNativeEqualityOps;
|
||||
static JSEqualityOp sXPCSlimWrapperEqualityOps;
|
||||
|
||||
|
||||
///////////////////////////
|
||||
|
@ -2408,8 +2407,7 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
|
|||
(jsClass->flags & JSCLASS_IS_EXTENDED) ?
|
||||
reinterpret_cast<const JSExtendedClass*>(jsClass)->equality :
|
||||
nsnull;
|
||||
if (op == sXPCWrappedNativeEqualityOps ||
|
||||
op == sXPCSlimWrapperEqualityOps) {
|
||||
if (op == sXPCWrappedNativeEqualityOps) {
|
||||
result = sXPConnect->GetPrincipal(aObj,
|
||||
#ifdef DEBUG
|
||||
aAllowShortCircuit
|
||||
|
@ -3407,8 +3405,7 @@ nsresult nsScriptSecurityManager::Init()
|
|||
JS_SetRuntimeSecurityCallbacks(sRuntime, &securityCallbacks);
|
||||
NS_ASSERTION(!oldcallbacks, "Someone else set security callbacks!");
|
||||
|
||||
sXPConnect->GetXPCWrappedNativeJSClassInfo(&sXPCWrappedNativeEqualityOps,
|
||||
&sXPCSlimWrapperEqualityOps);
|
||||
sXPConnect->GetXPCWrappedNativeJSClassInfo(&sXPCWrappedNativeEqualityOps);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -394,7 +394,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
|
|||
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
|
||||
%}
|
||||
|
||||
[uuid(c29f5d27-21b1-4b87-8282-d724d535ef7b)]
|
||||
[uuid(44d52d63-6575-4b09-a29f-e6708203fa9d)]
|
||||
interface nsIXPConnect : nsISupports
|
||||
{
|
||||
%{ C++
|
||||
|
@ -782,8 +782,7 @@ interface nsIXPConnect : nsISupports
|
|||
* a pointer to a nsIXPConnectWrappedNative or to the native in their
|
||||
* private date. See IS_WRAPPER_CLASS in xpcprivate.h for details.
|
||||
*/
|
||||
void GetXPCWrappedNativeJSClassInfo(out JSEqualityOp equality1,
|
||||
out JSEqualityOp equality2);
|
||||
void GetXPCWrappedNativeJSClassInfo(out JSEqualityOp equality);
|
||||
|
||||
/**
|
||||
* Whether or not XPConnect should report all JS exceptions when returning
|
||||
|
|
|
@ -415,8 +415,8 @@ XPC_COW_RewrapForChrome(JSContext *cx, JSObject *wrapperObj, jsval *vp)
|
|||
}
|
||||
|
||||
XPCWrappedNative *wn;
|
||||
if (IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) &&
|
||||
(wn = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj)) &&
|
||||
if (IS_WN_WRAPPER(obj) &&
|
||||
(wn = (XPCWrappedNative*)xpc_GetJSPrivate(obj)) &&
|
||||
!nsXPCWrappedJSClass::IsWrappedJS(wn->Native())) {
|
||||
// Return an explicit XPCNativeWrapper in case "chrome" code happens to be
|
||||
// XBL code cloned into an untrusted context.
|
||||
|
|
|
@ -733,7 +733,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
|||
(XPCWrappedNative*)xpc_GetJSPrivate(STOBJ_GET_PARENT(obj));
|
||||
dontTraverse = WrapperIsNotMainThreadOnly(wrapper);
|
||||
}
|
||||
else if(IS_WRAPPER_CLASS(clazz))
|
||||
else if(IS_WRAPPER_CLASS(clazz) && IS_WN_WRAPPER_OBJECT(obj))
|
||||
{
|
||||
XPCWrappedNative *wrapper = (XPCWrappedNative*)xpc_GetJSPrivate(obj);
|
||||
dontTraverse = WrapperIsNotMainThreadOnly(wrapper);
|
||||
|
@ -1345,16 +1345,13 @@ nsXPConnect::GetWrappedNativeOfJSObject(JSContext * aJSContext,
|
|||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||
|
||||
SLIM_LOG_WILL_MORPH(aJSContext, aJSObj);
|
||||
if(!IS_SLIM_WRAPPER(aJSObj) || MorphSlimWrapper(aJSContext, aJSObj))
|
||||
nsIXPConnectWrappedNative* wrapper =
|
||||
XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(aJSContext, aJSObj);
|
||||
if(wrapper)
|
||||
{
|
||||
nsIXPConnectWrappedNative* wrapper =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(aJSContext, aJSObj);
|
||||
if(wrapper)
|
||||
{
|
||||
NS_ADDREF(wrapper);
|
||||
*_retval = wrapper;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ADDREF(wrapper);
|
||||
*_retval = wrapper;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// else...
|
||||
|
@ -1990,16 +1987,14 @@ nsXPConnect::EvalInSandboxObject(const nsAString& source, JSContext *cx,
|
|||
#endif /* XPCONNECT_STANDALONE */
|
||||
}
|
||||
|
||||
/* void GetXPCWrappedNativeJSClassInfo(out JSEqualityOp equality1, JSEqualityOp *equality2); */
|
||||
/* void GetXPCWrappedNativeJSClassInfo(out JSEqualityOp equality); */
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::GetXPCWrappedNativeJSClassInfo(JSEqualityOp *equality1,
|
||||
JSEqualityOp *equality2)
|
||||
nsXPConnect::GetXPCWrappedNativeJSClassInfo(JSEqualityOp *equality)
|
||||
{
|
||||
// Expose the equality pointer used by IS_WRAPPER_CLASS(). If that macro
|
||||
// ever changes, this function needs to stay in sync.
|
||||
|
||||
*equality1 = &XPC_WN_Equality;
|
||||
*equality2 = &XPC_SWN_Equality;
|
||||
*equality = &XPC_WN_Equality;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2404,23 +2399,24 @@ nsXPConnect::GetWrapperForObject(JSContext* aJSContext,
|
|||
JSAutoRequest ar(aJSContext);
|
||||
|
||||
XPCWrappedNativeScope *objectscope;
|
||||
XPCWrappedNative *wrapper = nsnull;
|
||||
if(IS_SLIM_WRAPPER(aObject))
|
||||
JSObject* obj2;
|
||||
XPCWrappedNative *wrapper =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(aJSContext, aObject,
|
||||
nsnull, &obj2);
|
||||
if(wrapper)
|
||||
{
|
||||
objectscope = GetSlimWrapperProto(aObject)->GetScope();
|
||||
objectscope = wrapper->GetScope();
|
||||
}
|
||||
else if(obj2)
|
||||
{
|
||||
objectscope = GetSlimWrapperProto(obj2)->GetScope();
|
||||
}
|
||||
else
|
||||
{
|
||||
wrapper =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(aJSContext, aObject);
|
||||
if(!wrapper)
|
||||
{
|
||||
// Couldn't get the wrapped native (maybe a prototype?) so just return
|
||||
// the original object.
|
||||
*_retval = OBJECT_TO_JSVAL(aObject);
|
||||
return NS_OK;
|
||||
}
|
||||
objectscope = wrapper->GetScope();
|
||||
// Couldn't get the wrapped native (maybe a prototype?) so just return
|
||||
// the original object.
|
||||
*_retval = OBJECT_TO_JSVAL(aObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
XPCWrappedNativeScope *xpcscope =
|
||||
|
@ -2648,10 +2644,10 @@ nsXPConnect::SetSafeJSContext(JSContext * aSafeJSContext)
|
|||
nsIPrincipal*
|
||||
nsXPConnect::GetPrincipal(JSObject* obj, PRBool allowShortCircuit) const
|
||||
{
|
||||
NS_ASSERTION(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) || IS_SLIM_WRAPPER(obj),
|
||||
NS_ASSERTION(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)),
|
||||
"What kind of wrapper is this?");
|
||||
|
||||
if(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)))
|
||||
if(IS_WN_WRAPPER_OBJECT(obj))
|
||||
{
|
||||
XPCWrappedNative *xpcWrapper =
|
||||
(XPCWrappedNative *)xpc_GetJSPrivate(obj);
|
||||
|
|
|
@ -1126,7 +1126,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
|||
{
|
||||
tryConstructSlimWrapper = PR_TRUE;
|
||||
}
|
||||
else if(!IS_WRAPPER_CLASS(STOBJ_GET_CLASS(flat)))
|
||||
else if(IS_SLIM_WRAPPER_OBJECT(flat))
|
||||
{
|
||||
JSObject* global = JS_GetGlobalForObject(cx, flat);
|
||||
if(global == xpcscope->GetGlobalJSObject())
|
||||
|
@ -1185,6 +1185,9 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
|||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(!flat || IS_WRAPPER_CLASS(STOBJ_GET_CLASS(flat)),
|
||||
"What kind of wrapper is this?");
|
||||
|
||||
nsresult rv;
|
||||
XPCWrappedNative* wrapper;
|
||||
nsRefPtr<XPCWrappedNative> strongWrapper;
|
||||
|
@ -1200,7 +1203,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
|||
|
||||
wrapper = strongWrapper;
|
||||
}
|
||||
else if(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(flat)))
|
||||
else if(IS_WN_WRAPPER_OBJECT(flat))
|
||||
{
|
||||
wrapper = static_cast<XPCWrappedNative*>(xpc_GetJSPrivate(flat));
|
||||
|
||||
|
|
|
@ -943,22 +943,17 @@ nsJSCID::HasInstance(nsIXPConnectWrappedNative *wrapper,
|
|||
|
||||
NS_ASSERTION(obj, "when is an object not an object?");
|
||||
|
||||
nsIClassInfo* ci;
|
||||
if(IS_SLIM_WRAPPER(obj))
|
||||
{
|
||||
ci = GetSlimWrapperProto(obj)->GetClassInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
// is this really a native xpcom object with a wrapper?
|
||||
XPCWrappedNative* other_wrapper =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj);
|
||||
// is this really a native xpcom object with a wrapper?
|
||||
JSObject* obj2;
|
||||
XPCWrappedNative* other_wrapper =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj, nsnull, &obj2);
|
||||
|
||||
if(!other_wrapper)
|
||||
return NS_OK;
|
||||
if(!obj2)
|
||||
return NS_OK;
|
||||
|
||||
ci = other_wrapper->GetClassInfo();
|
||||
}
|
||||
nsIClassInfo* ci = other_wrapper ?
|
||||
other_wrapper->GetClassInfo() :
|
||||
GetSlimWrapperProto(obj2)->GetClassInfo();
|
||||
|
||||
// We consider CID equality to be the thing that matters here.
|
||||
// This is perhaps debatable.
|
||||
|
|
|
@ -265,17 +265,6 @@ extern const char XPC_XPCONNECT_CONTRACTID[];
|
|||
|
||||
#define WRAPPER_SLOTS (JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1))
|
||||
|
||||
// NOTE!!!
|
||||
//
|
||||
// If this ever changes,
|
||||
// nsScriptSecurityManager::doGetObjectPrincipal() *must* be updated
|
||||
// also!
|
||||
//
|
||||
// NOTE!!!
|
||||
#define IS_WRAPPER_CLASS(clazz) \
|
||||
(((clazz)->flags & JSCLASS_IS_EXTENDED) && \
|
||||
reinterpret_cast<JSExtendedClass*>(clazz)->equality == XPC_WN_Equality)
|
||||
|
||||
/***************************************************************************/
|
||||
// Auto locking support class...
|
||||
|
||||
|
@ -1354,6 +1343,47 @@ xpc_InitWrappedNativeJSOps();
|
|||
(clazz) == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass || \
|
||||
(clazz) == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass)
|
||||
|
||||
// NOTE!!!
|
||||
//
|
||||
// If this ever changes,
|
||||
// nsScriptSecurityManager::doGetObjectPrincipal() *must* be updated
|
||||
// also!
|
||||
//
|
||||
// NOTE!!!
|
||||
#define IS_WRAPPER_CLASS(clazz) \
|
||||
(((clazz)->flags & JSCLASS_IS_EXTENDED) && \
|
||||
reinterpret_cast<JSExtendedClass*>(clazz)->equality == XPC_WN_Equality)
|
||||
|
||||
inline JSBool
|
||||
DebugCheckWrapperClass(JSObject* obj)
|
||||
{
|
||||
NS_ASSERTION(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)),
|
||||
"Forgot to check if this is a wrapper?");
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// If IS_WRAPPER_CLASS for the JSClass of an object is true, the object can be
|
||||
// a slim wrapper, holding a native in its private slot, or a wrappednative
|
||||
// wrapper, holding the XPCWrappedNative in its private slot. A slim wrapper
|
||||
// also holds a pointer to its XPCWrappedNativeProto in a reserved slot, we can
|
||||
// check that slot for a non-void value to distinguish between the two.
|
||||
|
||||
// Only use these macros if IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) is true.
|
||||
#define IS_WN_WRAPPER_OBJECT(obj) \
|
||||
(DebugCheckWrapperClass(obj) && \
|
||||
JSVAL_IS_VOID(STOBJ_GET_SLOT(obj, JSSLOT_START(STOBJ_GET_CLASS(obj)))))
|
||||
#define IS_SLIM_WRAPPER_OBJECT(obj) \
|
||||
(DebugCheckWrapperClass(obj) && \
|
||||
!JSVAL_IS_VOID(STOBJ_GET_SLOT(obj, JSSLOT_START(STOBJ_GET_CLASS(obj)))))
|
||||
|
||||
// Use these macros if IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) might be false.
|
||||
// Avoid calling them if IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) can only be
|
||||
// true, as we'd do a redundant call to IS_WRAPPER_CLASS.
|
||||
#define IS_WN_WRAPPER(obj) \
|
||||
(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) && IS_WN_WRAPPER_OBJECT(obj))
|
||||
#define IS_SLIM_WRAPPER(obj) \
|
||||
(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) && IS_SLIM_WRAPPER_OBJECT(obj))
|
||||
|
||||
// Comes from xpcwrappednativeops.cpp
|
||||
extern void
|
||||
xpc_TraceForValidWrapper(JSTracer *trc, XPCWrappedNative* wrapper);
|
||||
|
@ -1907,14 +1937,13 @@ public:
|
|||
const XPCNativeScriptableFlags& GetFlags() const {return mFlags;}
|
||||
JSClass* GetJSClass() {return &mJSClass.base;}
|
||||
JSClass* GetSlimJSClass()
|
||||
{return &mSlimJSClass.base;}
|
||||
{if(mCanBeSlim) return GetJSClass(); return nsnull;}
|
||||
|
||||
XPCNativeScriptableShared(JSUint32 aFlags = 0, char* aName = nsnull)
|
||||
: mFlags(aFlags)
|
||||
: mFlags(aFlags),
|
||||
mCanBeSlim(JS_FALSE)
|
||||
{memset(&mJSClass, 0, sizeof(mJSClass));
|
||||
mJSClass.base.name = aName; // take ownership
|
||||
memset(&mSlimJSClass, 0, sizeof(mSlimJSClass));
|
||||
mSlimJSClass.base.name = aName; // take ownership
|
||||
MOZ_COUNT_CTOR(XPCNativeScriptableShared);}
|
||||
|
||||
~XPCNativeScriptableShared()
|
||||
|
@ -1934,7 +1963,7 @@ public:
|
|||
private:
|
||||
XPCNativeScriptableFlags mFlags;
|
||||
JSExtendedClass mJSClass;
|
||||
JSExtendedClass mSlimJSClass;
|
||||
JSBool mCanBeSlim;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -2201,13 +2230,6 @@ private:
|
|||
};
|
||||
|
||||
|
||||
extern void XPC_SWN_Finalize(JSContext *cx, JSObject *obj);
|
||||
extern JSBool XPC_SWN_Equality(JSContext *cx, JSObject *obj, jsval v,
|
||||
JSBool *bp);
|
||||
|
||||
#define IS_SLIM_WRAPPER_CLASS(clazz) ((clazz)->finalize == XPC_SWN_Finalize)
|
||||
#define IS_SLIM_WRAPPER(obj) IS_SLIM_WRAPPER_CLASS(STOBJ_GET_CLASS(obj))
|
||||
|
||||
extern JSBool ConstructSlimWrapper(XPCCallContext &ccx, nsISupports *p,
|
||||
nsWrapperCache *cache,
|
||||
XPCWrappedNativeScope* xpcScope,
|
||||
|
@ -2459,6 +2481,9 @@ public:
|
|||
XPCNativeInterface* Interface,
|
||||
XPCWrappedNative** wrapper);
|
||||
|
||||
// If pobj2 is not null and *pobj2 is not null after the call and the return
|
||||
// value is null, then *pobj2 points to an object for which
|
||||
// IS_SLIM_WRAPPER_OBJECT is true.
|
||||
static XPCWrappedNative*
|
||||
GetWrappedNativeOfJSObject(JSContext* cx, JSObject* obj,
|
||||
JSObject* funobj = nsnull,
|
||||
|
|
|
@ -504,8 +504,7 @@ GetMemberInfo(JSObject *obj,
|
|||
*ifaceName = "Unknown";
|
||||
|
||||
NS_ASSERTION(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) ||
|
||||
STOBJ_GET_CLASS(obj) == &XPC_WN_Tearoff_JSClass ||
|
||||
IS_SLIM_WRAPPER(obj),
|
||||
STOBJ_GET_CLASS(obj) == &XPC_WN_Tearoff_JSClass,
|
||||
"obj must be a wrapper");
|
||||
XPCWrappedNativeProto *proto;
|
||||
if(IS_SLIM_WRAPPER(obj))
|
||||
|
@ -900,15 +899,6 @@ xpc_qsUnwrapArgImpl(JSContext *cx,
|
|||
}
|
||||
JSObject *src = JSVAL_TO_OBJECT(v);
|
||||
|
||||
if(IS_SLIM_WRAPPER(src))
|
||||
{
|
||||
nsISupports *iface = static_cast<nsISupports*>(xpc_GetJSPrivate(src));
|
||||
if(NS_FAILED(getNative(iface, GetOffsetsFromSlimWrapper(src),
|
||||
src, iid, ppArg, ppArgRef, vp)))
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JSObject *inner = nsnull;
|
||||
if(XPCWrapper::IsSecurityWrapper(src))
|
||||
{
|
||||
|
@ -918,8 +908,10 @@ xpc_qsUnwrapArgImpl(JSContext *cx,
|
|||
}
|
||||
|
||||
// From XPCConvert::JSObject2NativeInterface
|
||||
JSObject* obj2;
|
||||
XPCWrappedNative* wrappedNative =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, inner ? inner : src);
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, inner ? inner : src,
|
||||
nsnull, &obj2);
|
||||
nsISupports *iface;
|
||||
if(wrappedNative)
|
||||
{
|
||||
|
@ -929,6 +921,14 @@ xpc_qsUnwrapArgImpl(JSContext *cx,
|
|||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
return NS_OK;
|
||||
}
|
||||
if(obj2)
|
||||
{
|
||||
iface = static_cast<nsISupports*>(xpc_GetJSPrivate(obj2));
|
||||
if(NS_FAILED(getNative(iface, GetOffsetsFromSlimWrapper(obj2),
|
||||
obj2, iid, ppArg, ppArgRef, vp)))
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
return NS_OK;
|
||||
}
|
||||
// else...
|
||||
// Slow path.
|
||||
|
||||
|
|
|
@ -465,7 +465,7 @@ XPCWrappedNative::GetNewOrUsed(XPCCallContext& ccx,
|
|||
JSObject *cached = cache->GetWrapper();
|
||||
if(cached)
|
||||
{
|
||||
if(IS_SLIM_WRAPPER(cached))
|
||||
if(IS_SLIM_WRAPPER_OBJECT(cached))
|
||||
{
|
||||
nsRefPtr<XPCWrappedNative> morphed;
|
||||
if(!XPCWrappedNative::Morph(ccx, cached, Interface, cache,
|
||||
|
@ -784,7 +784,7 @@ XPCWrappedNative::GetUsedOnly(XPCCallContext& ccx,
|
|||
if(cache)
|
||||
{
|
||||
JSObject *flat = cache->GetWrapper();
|
||||
if(flat && IS_SLIM_WRAPPER(flat) && !MorphSlimWrapper(ccx, flat))
|
||||
if(flat && IS_SLIM_WRAPPER_OBJECT(flat) && !MorphSlimWrapper(ccx, flat))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
wrapper = flat ?
|
||||
|
@ -1144,22 +1144,13 @@ XPCWrappedNative::Init(XPCCallContext& ccx,
|
|||
JSBool
|
||||
XPCWrappedNative::Init(XPCCallContext &ccx, JSObject *existingJSObject)
|
||||
{
|
||||
mScriptableInfo = GetProto()->GetScriptableInfo();
|
||||
JSClass* jsclazz = mScriptableInfo->GetJSClass();
|
||||
|
||||
// Morph the existing object.
|
||||
#ifdef DEBUG
|
||||
JSObject* protoJSObject = GetProto()->GetJSProtoObject();
|
||||
NS_ASSERTION(protoJSObject->map->ops == jsclazz->getObjectOps(ccx, jsclazz),
|
||||
"Ugh, we can't deal with that!");
|
||||
#endif
|
||||
if(!JS_SetReservedSlot(ccx, existingJSObject, 0, JSVAL_VOID))
|
||||
return JS_FALSE;
|
||||
|
||||
mScriptableInfo = GetProto()->GetScriptableInfo();
|
||||
mFlatJSObject = existingJSObject;
|
||||
|
||||
// Make sure we preserve any flags borrowing bits in classword.
|
||||
mFlatJSObject->classword ^= (jsuword)OBJ_GET_CLASS(ccx, mFlatJSObject);
|
||||
mFlatJSObject->classword |= (jsuword)jsclazz;
|
||||
|
||||
SLIM_LOG(("----- %i morphed slim wrapper (mFlatJSObject: %p, %p)\n",
|
||||
++sMorphedSlimWrappers, mFlatJSObject,
|
||||
static_cast<nsISupports*>(xpc_GetJSPrivate(mFlatJSObject))));
|
||||
|
@ -1461,7 +1452,7 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCCallContext& ccx,
|
|||
if(cache)
|
||||
{
|
||||
flat = cache->GetWrapper();
|
||||
if(flat && !IS_SLIM_WRAPPER(flat))
|
||||
if(flat && !IS_SLIM_WRAPPER_OBJECT(flat))
|
||||
wrapper = static_cast<XPCWrappedNative*>(xpc_GetJSPrivate(flat));
|
||||
|
||||
}
|
||||
|
@ -1653,10 +1644,6 @@ XPCWrappedNative::GetWrappedNativeOfJSObject(JSContext* cx,
|
|||
if(proto)
|
||||
protoClassInfo = proto->GetClassInfo();
|
||||
}
|
||||
else if(IS_SLIM_WRAPPER_CLASS(funObjParentClass))
|
||||
{
|
||||
NS_ERROR("function object has slim wrapper!");
|
||||
}
|
||||
else if(IS_WRAPPER_CLASS(funObjParentClass))
|
||||
{
|
||||
cur = funObjParent;
|
||||
|
@ -1681,32 +1668,25 @@ XPCWrappedNative::GetWrappedNativeOfJSObject(JSContext* cx,
|
|||
JSClass* clazz;
|
||||
clazz = STOBJ_GET_CLASS(cur);
|
||||
|
||||
if(IS_SLIM_WRAPPER_CLASS(clazz))
|
||||
if(IS_WRAPPER_CLASS(clazz))
|
||||
{
|
||||
return_wrapper:
|
||||
JSBool isWN = IS_WN_WRAPPER_OBJECT(cur);
|
||||
XPCWrappedNative* wrapper =
|
||||
isWN ? (XPCWrappedNative*) xpc_GetJSPrivate(cur) : nsnull;
|
||||
if(proto)
|
||||
{
|
||||
XPCWrappedNativeProto* wrapper_proto =
|
||||
GetSlimWrapperProto(cur);
|
||||
isWN ? wrapper->GetProto() : GetSlimWrapperProto(cur);
|
||||
XPCWrappedNativeScope* wrapper_scope =
|
||||
wrapper_proto ? wrapper_proto->GetScope() :
|
||||
wrapper->GetScope();
|
||||
if(proto != wrapper_proto &&
|
||||
(proto->GetScope() != wrapper_proto->GetScope() ||
|
||||
(proto->GetScope() != wrapper_scope ||
|
||||
!protoClassInfo || !wrapper_proto ||
|
||||
protoClassInfo != wrapper_proto->GetClassInfo()))
|
||||
continue;
|
||||
}
|
||||
if(pobj2)
|
||||
*pobj2 = cur;
|
||||
return nsnull;
|
||||
}
|
||||
if(IS_WRAPPER_CLASS(clazz))
|
||||
{
|
||||
return_wrapper:
|
||||
XPCWrappedNative* wrapper =
|
||||
(XPCWrappedNative*) xpc_GetJSPrivate(cur);
|
||||
if(proto && proto != wrapper->GetProto() &&
|
||||
(proto->GetScope() != wrapper->GetScope() ||
|
||||
!protoClassInfo || !wrapper->GetProto() ||
|
||||
protoClassInfo != wrapper->GetProto()->GetClassInfo()))
|
||||
continue;
|
||||
if(pobj2)
|
||||
*pobj2 = cur;
|
||||
return wrapper;
|
||||
|
@ -3827,13 +3807,14 @@ ConstructSlimWrapper(XPCCallContext &ccx, nsISupports *p, nsWrapperCache *cache,
|
|||
|
||||
XPCNativeScriptableInfo* si = xpcproto->GetScriptableInfo();
|
||||
JSClass* jsclazz = si->GetSlimJSClass();
|
||||
if(!jsclazz->addProperty)
|
||||
if(!jsclazz)
|
||||
return JS_FALSE;
|
||||
|
||||
wrapper = xpc_NewSystemInheritingJSObject(ccx, jsclazz,
|
||||
xpcproto->GetJSProtoObject(),
|
||||
parent);
|
||||
if(!JS_SetPrivate(ccx, wrapper, identityObj) ||
|
||||
if(!wrapper ||
|
||||
!JS_SetPrivate(ccx, wrapper, identityObj) ||
|
||||
!JS_SetReservedSlot(ccx, wrapper, 0, PRIVATE_TO_JSVAL(xpcproto.get())))
|
||||
return JS_FALSE;
|
||||
|
||||
|
|
|
@ -679,13 +679,30 @@ XPC_WN_Shared_Enumerate(JSContext *cx, JSObject *obj)
|
|||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef DEBUG_slimwrappers
|
||||
static PRUint32 sFinalizedSlimWrappers;
|
||||
#endif
|
||||
|
||||
static void
|
||||
XPC_WN_NoHelper_Finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
XPCWrappedNative* p = (XPCWrappedNative*) xpc_GetJSPrivate(obj);
|
||||
nsISupports* p = static_cast<nsISupports*>(xpc_GetJSPrivate(obj));
|
||||
if(!p)
|
||||
return;
|
||||
p->FlatJSObjectFinalized(cx);
|
||||
|
||||
if(IS_SLIM_WRAPPER_OBJECT(obj))
|
||||
{
|
||||
SLIM_LOG(("----- %i finalized slim wrapper (%p, %p)\n",
|
||||
++sFinalizedSlimWrappers, obj, p));
|
||||
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(p, &cache);
|
||||
cache->ClearWrapper();
|
||||
NS_RELEASE(p);
|
||||
return;
|
||||
}
|
||||
|
||||
static_cast<XPCWrappedNative*>(p)->FlatJSObjectFinalized(cx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -746,11 +763,20 @@ xpc_TraceForValidWrapper(JSTracer *trc, XPCWrappedNative* wrapper)
|
|||
static void
|
||||
XPC_WN_Shared_Trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
JSObject *obj2;
|
||||
XPCWrappedNative* wrapper =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(trc->context, obj);
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(trc->context, obj, nsnull,
|
||||
&obj2);
|
||||
|
||||
if(wrapper && wrapper->IsValid())
|
||||
xpc_TraceForValidWrapper(trc, wrapper);
|
||||
if(wrapper)
|
||||
{
|
||||
if(wrapper->IsValid())
|
||||
xpc_TraceForValidWrapper(trc, wrapper);
|
||||
}
|
||||
else if(obj2)
|
||||
{
|
||||
GetSlimWrapperProto(obj2)->TraceJS(trc);
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -807,8 +833,16 @@ XPC_WN_Equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
|||
{
|
||||
*bp = JS_FALSE;
|
||||
|
||||
JSObject *obj2;
|
||||
XPCWrappedNative *wrapper =
|
||||
XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(cx, obj);
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj, nsnull, &obj2);
|
||||
if(!wrapper && obj2)
|
||||
{
|
||||
*bp = !JSVAL_IS_PRIMITIVE(v) && (JSVAL_TO_OBJECT(v) == obj2);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);
|
||||
|
||||
XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo();
|
||||
|
@ -1096,7 +1130,20 @@ XPC_WN_Helper_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
|||
static void
|
||||
XPC_WN_Helper_Finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
XPCWrappedNative* wrapper = (XPCWrappedNative*) xpc_GetJSPrivate(obj);
|
||||
nsISupports* p = static_cast<nsISupports*>(xpc_GetJSPrivate(obj));
|
||||
if(IS_SLIM_WRAPPER(obj))
|
||||
{
|
||||
SLIM_LOG(("----- %i finalized slim wrapper (%p, %p)\n",
|
||||
++sFinalizedSlimWrappers, obj, p));
|
||||
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(p, &cache);
|
||||
cache->ClearWrapper();
|
||||
NS_RELEASE(p);
|
||||
return;
|
||||
}
|
||||
|
||||
XPCWrappedNative* wrapper = (XPCWrappedNative*)p;
|
||||
if(!wrapper)
|
||||
return;
|
||||
wrapper->GetScriptableCallback()->Finalize(wrapper, cx, obj);
|
||||
|
@ -1106,12 +1153,20 @@ XPC_WN_Helper_Finalize(JSContext *cx, JSObject *obj)
|
|||
static void
|
||||
XPC_WN_Helper_Trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
JSObject *obj2;
|
||||
XPCWrappedNative* wrapper =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(trc->context, obj);
|
||||
if(wrapper && wrapper->IsValid())
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(trc->context, obj, nsnull, &obj2);
|
||||
if(wrapper)
|
||||
{
|
||||
wrapper->GetScriptableCallback()->Trace(wrapper, trc, obj);
|
||||
xpc_TraceForValidWrapper(trc, wrapper);
|
||||
if(wrapper->IsValid())
|
||||
{
|
||||
wrapper->GetScriptableCallback()->Trace(wrapper, trc, obj);
|
||||
xpc_TraceForValidWrapper(trc, wrapper);
|
||||
}
|
||||
}
|
||||
else if(obj2)
|
||||
{
|
||||
GetSlimWrapperProto(obj2)->TraceJS(trc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1271,8 +1326,6 @@ static JSBool
|
|||
XPC_WN_JSOp_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp)
|
||||
{
|
||||
MORPH_SLIM_WRAPPER(cx, obj);
|
||||
|
||||
JSClass *clazz = STOBJ_GET_CLASS(obj);
|
||||
if(!IS_WRAPPER_CLASS(clazz) || clazz == &XPC_WN_NoHelper_JSClass.base)
|
||||
{
|
||||
|
@ -1283,6 +1336,8 @@ XPC_WN_JSOp_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
return js_ObjectOps.enumerate(cx, obj, enum_op, statep, idp);
|
||||
}
|
||||
|
||||
MORPH_SLIM_WRAPPER(cx, obj);
|
||||
|
||||
XPCCallContext ccx(JS_CALLER, cx, obj);
|
||||
XPCWrappedNative* wrapper = ccx.GetWrapper();
|
||||
THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);
|
||||
|
@ -1511,40 +1566,6 @@ JSBool xpc_InitWrappedNativeJSOps()
|
|||
|
||||
/***************************************************************************/
|
||||
|
||||
static void
|
||||
XPC_SWN_Trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
GetSlimWrapperProto(obj)->TraceJS(trc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_slimwrappers
|
||||
static PRUint32 sFinalizedSlimWrappers;
|
||||
#endif
|
||||
|
||||
void
|
||||
XPC_SWN_Finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
nsISupports* p = static_cast<nsISupports*>(xpc_GetJSPrivate(obj));
|
||||
|
||||
SLIM_LOG(("----- %i finalized slim wrapper (%p, %p)\n",
|
||||
++sFinalizedSlimWrappers, obj, p));
|
||||
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(p, &cache);
|
||||
cache->ClearWrapper();
|
||||
NS_RELEASE(p);
|
||||
}
|
||||
|
||||
JSBool
|
||||
XPC_SWN_Equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
||||
{
|
||||
*bp = !JSVAL_IS_PRIMITIVE(v) && (JSVAL_TO_OBJECT(v) == obj);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// static
|
||||
XPCNativeScriptableInfo*
|
||||
XPCNativeScriptableInfo::Construct(XPCCallContext& ccx,
|
||||
|
@ -1696,13 +1717,7 @@ XPCNativeScriptableShared::PopulateJSClass(JSBool isGlobal)
|
|||
|
||||
if(!(mFlags & (nsIXPCScriptable::WANT_OUTER_OBJECT |
|
||||
nsIXPCScriptable::WANT_INNER_OBJECT)))
|
||||
{
|
||||
memcpy(&mSlimJSClass, &mJSClass, sizeof(mJSClass));
|
||||
|
||||
mSlimJSClass.base.finalize = XPC_SWN_Finalize;
|
||||
mSlimJSClass.base.mark = JS_CLASS_TRACE(XPC_SWN_Trace);
|
||||
mSlimJSClass.equality = XPC_SWN_Equality;
|
||||
}
|
||||
mCanBeSlim = JS_TRUE;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -720,12 +720,12 @@ GetScopeOfObject(JSObject* obj)
|
|||
{
|
||||
nsISupports* supports;
|
||||
JSClass* clazz = STOBJ_GET_CLASS(obj);
|
||||
JSBool isWrapper = IS_WRAPPER_CLASS(clazz);
|
||||
|
||||
if(IS_SLIM_WRAPPER_CLASS(clazz))
|
||||
if(isWrapper && IS_SLIM_WRAPPER_OBJECT(obj))
|
||||
return GetSlimWrapperProto(obj)->GetScope();
|
||||
|
||||
if(!IS_WRAPPER_CLASS(clazz) ||
|
||||
!(supports = (nsISupports*) xpc_GetJSPrivate(obj)))
|
||||
if(!isWrapper || !(supports = (nsISupports*) xpc_GetJSPrivate(obj)))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче