зеркало из https://github.com/mozilla/pjs.git
Backed out changeset 542fa9413bd0, fix for bug 517196 (The JSClass of wrappers shouldn't change when morphing from slim to XPCWrappedNative), to try to fix orange.
This commit is contained in:
Родитель
352b573e65
Коммит
7e4509caf0
|
@ -108,6 +108,7 @@ 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;
|
||||
|
||||
|
||||
///////////////////////////
|
||||
|
@ -2407,7 +2408,8 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
|
|||
(jsClass->flags & JSCLASS_IS_EXTENDED) ?
|
||||
reinterpret_cast<const JSExtendedClass*>(jsClass)->equality :
|
||||
nsnull;
|
||||
if (op == sXPCWrappedNativeEqualityOps) {
|
||||
if (op == sXPCWrappedNativeEqualityOps ||
|
||||
op == sXPCSlimWrapperEqualityOps) {
|
||||
result = sXPConnect->GetPrincipal(aObj,
|
||||
#ifdef DEBUG
|
||||
aAllowShortCircuit
|
||||
|
@ -3405,7 +3407,8 @@ nsresult nsScriptSecurityManager::Init()
|
|||
JS_SetRuntimeSecurityCallbacks(sRuntime, &securityCallbacks);
|
||||
NS_ASSERTION(!oldcallbacks, "Someone else set security callbacks!");
|
||||
|
||||
sXPConnect->GetXPCWrappedNativeJSClassInfo(&sXPCWrappedNativeEqualityOps);
|
||||
sXPConnect->GetXPCWrappedNativeJSClassInfo(&sXPCWrappedNativeEqualityOps,
|
||||
&sXPCSlimWrapperEqualityOps);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -394,7 +394,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
|
|||
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
|
||||
%}
|
||||
|
||||
[uuid(44d52d63-6575-4b09-a29f-e6708203fa9d)]
|
||||
[uuid(c29f5d27-21b1-4b87-8282-d724d535ef7b)]
|
||||
interface nsIXPConnect : nsISupports
|
||||
{
|
||||
%{ C++
|
||||
|
@ -782,7 +782,8 @@ 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 equality);
|
||||
void GetXPCWrappedNativeJSClassInfo(out JSEqualityOp equality1,
|
||||
out JSEqualityOp equality2);
|
||||
|
||||
/**
|
||||
* 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_WN_WRAPPER(obj) &&
|
||||
(wn = (XPCWrappedNative*)xpc_GetJSPrivate(obj)) &&
|
||||
if (IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) &&
|
||||
(wn = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, 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) && IS_WN_WRAPPER_OBJECT(obj))
|
||||
else if(IS_WRAPPER_CLASS(clazz))
|
||||
{
|
||||
XPCWrappedNative *wrapper = (XPCWrappedNative*)xpc_GetJSPrivate(obj);
|
||||
dontTraverse = WrapperIsNotMainThreadOnly(wrapper);
|
||||
|
@ -1345,13 +1345,16 @@ nsXPConnect::GetWrappedNativeOfJSObject(JSContext * aJSContext,
|
|||
return UnexpectedFailure(NS_ERROR_FAILURE);
|
||||
|
||||
SLIM_LOG_WILL_MORPH(aJSContext, aJSObj);
|
||||
nsIXPConnectWrappedNative* wrapper =
|
||||
XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(aJSContext, aJSObj);
|
||||
if(wrapper)
|
||||
if(!IS_SLIM_WRAPPER(aJSObj) || MorphSlimWrapper(aJSContext, aJSObj))
|
||||
{
|
||||
NS_ADDREF(wrapper);
|
||||
*_retval = wrapper;
|
||||
return NS_OK;
|
||||
nsIXPConnectWrappedNative* wrapper =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(aJSContext, aJSObj);
|
||||
if(wrapper)
|
||||
{
|
||||
NS_ADDREF(wrapper);
|
||||
*_retval = wrapper;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// else...
|
||||
|
@ -1987,14 +1990,16 @@ nsXPConnect::EvalInSandboxObject(const nsAString& source, JSContext *cx,
|
|||
#endif /* XPCONNECT_STANDALONE */
|
||||
}
|
||||
|
||||
/* void GetXPCWrappedNativeJSClassInfo(out JSEqualityOp equality); */
|
||||
/* void GetXPCWrappedNativeJSClassInfo(out JSEqualityOp equality1, JSEqualityOp *equality2); */
|
||||
NS_IMETHODIMP
|
||||
nsXPConnect::GetXPCWrappedNativeJSClassInfo(JSEqualityOp *equality)
|
||||
nsXPConnect::GetXPCWrappedNativeJSClassInfo(JSEqualityOp *equality1,
|
||||
JSEqualityOp *equality2)
|
||||
{
|
||||
// Expose the equality pointer used by IS_WRAPPER_CLASS(). If that macro
|
||||
// ever changes, this function needs to stay in sync.
|
||||
|
||||
*equality = &XPC_WN_Equality;
|
||||
*equality1 = &XPC_WN_Equality;
|
||||
*equality2 = &XPC_SWN_Equality;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2399,24 +2404,23 @@ nsXPConnect::GetWrapperForObject(JSContext* aJSContext,
|
|||
JSAutoRequest ar(aJSContext);
|
||||
|
||||
XPCWrappedNativeScope *objectscope;
|
||||
JSObject* obj2;
|
||||
XPCWrappedNative *wrapper =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(aJSContext, aObject,
|
||||
nsnull, &obj2);
|
||||
if(wrapper)
|
||||
XPCWrappedNative *wrapper = nsnull;
|
||||
if(IS_SLIM_WRAPPER(aObject))
|
||||
{
|
||||
objectscope = wrapper->GetScope();
|
||||
}
|
||||
else if(obj2)
|
||||
{
|
||||
objectscope = GetSlimWrapperProto(obj2)->GetScope();
|
||||
objectscope = GetSlimWrapperProto(aObject)->GetScope();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Couldn't get the wrapped native (maybe a prototype?) so just return
|
||||
// the original object.
|
||||
*_retval = OBJECT_TO_JSVAL(aObject);
|
||||
return NS_OK;
|
||||
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();
|
||||
}
|
||||
|
||||
XPCWrappedNativeScope *xpcscope =
|
||||
|
@ -2644,10 +2648,10 @@ nsXPConnect::SetSafeJSContext(JSContext * aSafeJSContext)
|
|||
nsIPrincipal*
|
||||
nsXPConnect::GetPrincipal(JSObject* obj, PRBool allowShortCircuit) const
|
||||
{
|
||||
NS_ASSERTION(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)),
|
||||
NS_ASSERTION(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) || IS_SLIM_WRAPPER(obj),
|
||||
"What kind of wrapper is this?");
|
||||
|
||||
if(IS_WN_WRAPPER_OBJECT(obj))
|
||||
if(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)))
|
||||
{
|
||||
XPCWrappedNative *xpcWrapper =
|
||||
(XPCWrappedNative *)xpc_GetJSPrivate(obj);
|
||||
|
|
|
@ -1126,7 +1126,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
|||
{
|
||||
tryConstructSlimWrapper = PR_TRUE;
|
||||
}
|
||||
else if(IS_SLIM_WRAPPER_OBJECT(flat))
|
||||
else if(!IS_WRAPPER_CLASS(STOBJ_GET_CLASS(flat)))
|
||||
{
|
||||
JSObject* global = JS_GetGlobalForObject(cx, flat);
|
||||
if(global == xpcscope->GetGlobalJSObject())
|
||||
|
@ -1185,9 +1185,6 @@ 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;
|
||||
|
@ -1203,7 +1200,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
|||
|
||||
wrapper = strongWrapper;
|
||||
}
|
||||
else if(IS_WN_WRAPPER_OBJECT(flat))
|
||||
else if(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(flat)))
|
||||
{
|
||||
wrapper = static_cast<XPCWrappedNative*>(xpc_GetJSPrivate(flat));
|
||||
|
||||
|
|
|
@ -943,17 +943,22 @@ nsJSCID::HasInstance(nsIXPConnectWrappedNative *wrapper,
|
|||
|
||||
NS_ASSERTION(obj, "when is an object not an object?");
|
||||
|
||||
// is this really a native xpcom object with a wrapper?
|
||||
JSObject* obj2;
|
||||
XPCWrappedNative* other_wrapper =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj, nsnull, &obj2);
|
||||
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);
|
||||
|
||||
if(!obj2)
|
||||
return NS_OK;
|
||||
if(!other_wrapper)
|
||||
return NS_OK;
|
||||
|
||||
nsIClassInfo* ci = other_wrapper ?
|
||||
other_wrapper->GetClassInfo() :
|
||||
GetSlimWrapperProto(obj2)->GetClassInfo();
|
||||
ci = other_wrapper->GetClassInfo();
|
||||
}
|
||||
|
||||
// We consider CID equality to be the thing that matters here.
|
||||
// This is perhaps debatable.
|
||||
|
|
|
@ -265,6 +265,17 @@ 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...
|
||||
|
||||
|
@ -1343,47 +1354,6 @@ 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);
|
||||
|
@ -1937,13 +1907,14 @@ public:
|
|||
const XPCNativeScriptableFlags& GetFlags() const {return mFlags;}
|
||||
JSClass* GetJSClass() {return &mJSClass.base;}
|
||||
JSClass* GetSlimJSClass()
|
||||
{if(mCanBeSlim) return GetJSClass(); return nsnull;}
|
||||
{return &mSlimJSClass.base;}
|
||||
|
||||
XPCNativeScriptableShared(JSUint32 aFlags = 0, char* aName = nsnull)
|
||||
: mFlags(aFlags),
|
||||
mCanBeSlim(JS_FALSE)
|
||||
: mFlags(aFlags)
|
||||
{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()
|
||||
|
@ -1963,7 +1934,7 @@ public:
|
|||
private:
|
||||
XPCNativeScriptableFlags mFlags;
|
||||
JSExtendedClass mJSClass;
|
||||
JSBool mCanBeSlim;
|
||||
JSExtendedClass mSlimJSClass;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -2230,6 +2201,13 @@ 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,
|
||||
|
@ -2481,9 +2459,6 @@ 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,7 +504,8 @@ GetMemberInfo(JSObject *obj,
|
|||
*ifaceName = "Unknown";
|
||||
|
||||
NS_ASSERTION(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) ||
|
||||
STOBJ_GET_CLASS(obj) == &XPC_WN_Tearoff_JSClass,
|
||||
STOBJ_GET_CLASS(obj) == &XPC_WN_Tearoff_JSClass ||
|
||||
IS_SLIM_WRAPPER(obj),
|
||||
"obj must be a wrapper");
|
||||
XPCWrappedNativeProto *proto;
|
||||
if(IS_SLIM_WRAPPER(obj))
|
||||
|
@ -899,6 +900,15 @@ 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))
|
||||
{
|
||||
|
@ -908,10 +918,8 @@ xpc_qsUnwrapArgImpl(JSContext *cx,
|
|||
}
|
||||
|
||||
// From XPCConvert::JSObject2NativeInterface
|
||||
JSObject* obj2;
|
||||
XPCWrappedNative* wrappedNative =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, inner ? inner : src,
|
||||
nsnull, &obj2);
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, inner ? inner : src);
|
||||
nsISupports *iface;
|
||||
if(wrappedNative)
|
||||
{
|
||||
|
@ -921,14 +929,6 @@ 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_OBJECT(cached))
|
||||
if(IS_SLIM_WRAPPER(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_OBJECT(flat) && !MorphSlimWrapper(ccx, flat))
|
||||
if(flat && IS_SLIM_WRAPPER(flat) && !MorphSlimWrapper(ccx, flat))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
wrapper = flat ?
|
||||
|
@ -1144,13 +1144,22 @@ XPCWrappedNative::Init(XPCCallContext& ccx,
|
|||
JSBool
|
||||
XPCWrappedNative::Init(XPCCallContext &ccx, JSObject *existingJSObject)
|
||||
{
|
||||
// Morph the existing object.
|
||||
if(!JS_SetReservedSlot(ccx, existingJSObject, 0, JSVAL_VOID))
|
||||
return JS_FALSE;
|
||||
|
||||
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
|
||||
|
||||
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))));
|
||||
|
@ -1452,7 +1461,7 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCCallContext& ccx,
|
|||
if(cache)
|
||||
{
|
||||
flat = cache->GetWrapper();
|
||||
if(flat && !IS_SLIM_WRAPPER_OBJECT(flat))
|
||||
if(flat && !IS_SLIM_WRAPPER(flat))
|
||||
wrapper = static_cast<XPCWrappedNative*>(xpc_GetJSPrivate(flat));
|
||||
|
||||
}
|
||||
|
@ -1644,6 +1653,10 @@ 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;
|
||||
|
@ -1668,25 +1681,32 @@ XPCWrappedNative::GetWrappedNativeOfJSObject(JSContext* cx,
|
|||
JSClass* clazz;
|
||||
clazz = STOBJ_GET_CLASS(cur);
|
||||
|
||||
if(IS_WRAPPER_CLASS(clazz))
|
||||
if(IS_SLIM_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 =
|
||||
isWN ? wrapper->GetProto() : GetSlimWrapperProto(cur);
|
||||
XPCWrappedNativeScope* wrapper_scope =
|
||||
wrapper_proto ? wrapper_proto->GetScope() :
|
||||
wrapper->GetScope();
|
||||
GetSlimWrapperProto(cur);
|
||||
if(proto != wrapper_proto &&
|
||||
(proto->GetScope() != wrapper_scope ||
|
||||
(proto->GetScope() != wrapper_proto->GetScope() ||
|
||||
!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;
|
||||
|
@ -3807,14 +3827,13 @@ ConstructSlimWrapper(XPCCallContext &ccx, nsISupports *p, nsWrapperCache *cache,
|
|||
|
||||
XPCNativeScriptableInfo* si = xpcproto->GetScriptableInfo();
|
||||
JSClass* jsclazz = si->GetSlimJSClass();
|
||||
if(!jsclazz)
|
||||
if(!jsclazz->addProperty)
|
||||
return JS_FALSE;
|
||||
|
||||
wrapper = xpc_NewSystemInheritingJSObject(ccx, jsclazz,
|
||||
xpcproto->GetJSProtoObject(),
|
||||
parent);
|
||||
if(!wrapper ||
|
||||
!JS_SetPrivate(ccx, wrapper, identityObj) ||
|
||||
if(!JS_SetPrivate(ccx, wrapper, identityObj) ||
|
||||
!JS_SetReservedSlot(ccx, wrapper, 0, PRIVATE_TO_JSVAL(xpcproto.get())))
|
||||
return JS_FALSE;
|
||||
|
||||
|
|
|
@ -679,30 +679,13 @@ 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)
|
||||
{
|
||||
nsISupports* p = static_cast<nsISupports*>(xpc_GetJSPrivate(obj));
|
||||
XPCWrappedNative* p = (XPCWrappedNative*) xpc_GetJSPrivate(obj);
|
||||
if(!p)
|
||||
return;
|
||||
|
||||
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);
|
||||
p->FlatJSObjectFinalized(cx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -763,20 +746,11 @@ 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, nsnull,
|
||||
&obj2);
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(trc->context, obj);
|
||||
|
||||
if(wrapper)
|
||||
{
|
||||
if(wrapper->IsValid())
|
||||
xpc_TraceForValidWrapper(trc, wrapper);
|
||||
}
|
||||
else if(obj2)
|
||||
{
|
||||
GetSlimWrapperProto(obj2)->TraceJS(trc);
|
||||
}
|
||||
if(wrapper && wrapper->IsValid())
|
||||
xpc_TraceForValidWrapper(trc, wrapper);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -833,16 +807,8 @@ XPC_WN_Equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
|||
{
|
||||
*bp = JS_FALSE;
|
||||
|
||||
JSObject *obj2;
|
||||
XPCWrappedNative *wrapper =
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj, nsnull, &obj2);
|
||||
if(!wrapper && obj2)
|
||||
{
|
||||
*bp = !JSVAL_IS_PRIMITIVE(v) && (JSVAL_TO_OBJECT(v) == obj2);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(cx, obj);
|
||||
THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);
|
||||
|
||||
XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo();
|
||||
|
@ -1130,20 +1096,7 @@ XPC_WN_Helper_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
|||
static void
|
||||
XPC_WN_Helper_Finalize(JSContext *cx, JSObject *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;
|
||||
XPCWrappedNative* wrapper = (XPCWrappedNative*) xpc_GetJSPrivate(obj);
|
||||
if(!wrapper)
|
||||
return;
|
||||
wrapper->GetScriptableCallback()->Finalize(wrapper, cx, obj);
|
||||
|
@ -1153,20 +1106,12 @@ 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, nsnull, &obj2);
|
||||
if(wrapper)
|
||||
XPCWrappedNative::GetWrappedNativeOfJSObject(trc->context, obj);
|
||||
if(wrapper && wrapper->IsValid())
|
||||
{
|
||||
if(wrapper->IsValid())
|
||||
{
|
||||
wrapper->GetScriptableCallback()->Trace(wrapper, trc, obj);
|
||||
xpc_TraceForValidWrapper(trc, wrapper);
|
||||
}
|
||||
}
|
||||
else if(obj2)
|
||||
{
|
||||
GetSlimWrapperProto(obj2)->TraceJS(trc);
|
||||
wrapper->GetScriptableCallback()->Trace(wrapper, trc, obj);
|
||||
xpc_TraceForValidWrapper(trc, wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1326,6 +1271,8 @@ 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)
|
||||
{
|
||||
|
@ -1336,8 +1283,6 @@ 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);
|
||||
|
@ -1566,6 +1511,40 @@ 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,
|
||||
|
@ -1717,7 +1696,13 @@ XPCNativeScriptableShared::PopulateJSClass(JSBool isGlobal)
|
|||
|
||||
if(!(mFlags & (nsIXPCScriptable::WANT_OUTER_OBJECT |
|
||||
nsIXPCScriptable::WANT_INNER_OBJECT)))
|
||||
mCanBeSlim = JS_TRUE;
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -720,12 +720,12 @@ GetScopeOfObject(JSObject* obj)
|
|||
{
|
||||
nsISupports* supports;
|
||||
JSClass* clazz = STOBJ_GET_CLASS(obj);
|
||||
JSBool isWrapper = IS_WRAPPER_CLASS(clazz);
|
||||
|
||||
if(isWrapper && IS_SLIM_WRAPPER_OBJECT(obj))
|
||||
if(IS_SLIM_WRAPPER_CLASS(clazz))
|
||||
return GetSlimWrapperProto(obj)->GetScope();
|
||||
|
||||
if(!isWrapper || !(supports = (nsISupports*) xpc_GetJSPrivate(obj)))
|
||||
if(!IS_WRAPPER_CLASS(clazz) ||
|
||||
!(supports = (nsISupports*) xpc_GetJSPrivate(obj)))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче