зеркало из https://github.com/mozilla/gecko-dev.git
Bug 580128 - Give objects a way to inform XPConnect that they implement their own JS object in a way that does not involve wrapped natives. r=peterv
This commit is contained in:
Родитель
c5cde776e4
Коммит
234cbcb3a1
|
@ -78,7 +78,8 @@ public:
|
|||
void SetWrapper(JSObject* aWrapper)
|
||||
{
|
||||
NS_ASSERTION(!PreservingWrapper(), "Clearing a preserved wrapper!");
|
||||
mWrapperPtrBits = reinterpret_cast<PtrBits>(aWrapper);
|
||||
mWrapperPtrBits = reinterpret_cast<PtrBits>(aWrapper) |
|
||||
(mWrapperPtrBits & WRAPPER_IS_PROXY);
|
||||
}
|
||||
|
||||
void ClearWrapper()
|
||||
|
@ -99,12 +100,23 @@ public:
|
|||
|
||||
PRBool PreservingWrapper()
|
||||
{
|
||||
return mWrapperPtrBits & WRAPPER_BIT_PRESERVED;
|
||||
return (mWrapperPtrBits & WRAPPER_BIT_PRESERVED) != 0;
|
||||
}
|
||||
|
||||
void SetIsProxy()
|
||||
{
|
||||
mWrapperPtrBits |= WRAPPER_IS_PROXY;
|
||||
}
|
||||
|
||||
PRBool IsProxy()
|
||||
{
|
||||
return (mWrapperPtrBits & WRAPPER_IS_PROXY) != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
enum { WRAPPER_BIT_PRESERVED = 1 << 0 };
|
||||
enum { kWrapperBitMask = 0x1 };
|
||||
enum { WRAPPER_IS_PROXY = 1 << 1 };
|
||||
enum { kWrapperBitMask = (WRAPPER_BIT_PRESERVED | WRAPPER_IS_PROXY) };
|
||||
|
||||
PtrBits mWrapperPtrBits;
|
||||
};
|
||||
|
|
|
@ -1070,7 +1070,7 @@ CreateHolderIfNeeded(XPCCallContext& ccx, JSObject* obj, jsval* d,
|
|||
XPCJSObjectHolder* objHolder = XPCJSObjectHolder::newHolder(ccx, obj);
|
||||
if(!objHolder)
|
||||
return JS_FALSE;
|
||||
|
||||
|
||||
NS_ADDREF(*dest = objHolder);
|
||||
}
|
||||
|
||||
|
@ -1079,6 +1079,48 @@ CreateHolderIfNeeded(XPCCallContext& ccx, JSObject* obj, jsval* d,
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
ComputeWrapperInfo(const XPCCallContext &ccx,
|
||||
JSObject **callee,
|
||||
JSScript **script)
|
||||
{
|
||||
*callee = nsnull;
|
||||
*script = nsnull;
|
||||
|
||||
if(ccx.GetXPCContext()->CallerTypeIsJavaScript())
|
||||
{
|
||||
// Called from JS. We're going to hand the resulting
|
||||
// JSObject to said JS, so look for the script we want on
|
||||
// the stack.
|
||||
JSStackFrame* fp = JS_GetScriptedCaller(ccx, NULL);
|
||||
if(fp)
|
||||
{
|
||||
*script = fp->maybeScript();
|
||||
*callee = fp->isFunctionFrame()
|
||||
? &fp->callee()
|
||||
: &fp->scopeChain();
|
||||
}
|
||||
}
|
||||
else if(ccx.GetXPCContext()->CallerTypeIsNative())
|
||||
{
|
||||
*callee = ccx.GetCallee();
|
||||
if(*callee && JS_ObjectIsFunction(ccx, *callee))
|
||||
{
|
||||
// Called from c++, and calling out to |callee|, which is a JS
|
||||
// function object. Look for the script for this function.
|
||||
JSFunction* fun = (JSFunction*) xpc_GetJSPrivate(*callee);
|
||||
NS_ASSERTION(fun, "Must have JSFunction for a Function object");
|
||||
*script = JS_GetFunctionScript(ccx, fun);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Else we don't know whom we're calling, so don't
|
||||
// create XPCNativeWrappers.
|
||||
*callee = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
// static
|
||||
JSBool
|
||||
|
@ -1151,11 +1193,38 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
|||
|
||||
nsWrapperCache *cache = aHelper.GetWrapperCache();
|
||||
|
||||
JSObject *callee = nsnull;
|
||||
JSScript *script = nsnull;
|
||||
|
||||
PRBool tryConstructSlimWrapper = PR_FALSE;
|
||||
JSObject *flat;
|
||||
if(cache)
|
||||
{
|
||||
flat = cache->GetWrapper();
|
||||
if(cache->IsProxy())
|
||||
{
|
||||
if(flat)
|
||||
{
|
||||
XPCCallContext &ccx = lccx.GetXPCCallContext();
|
||||
if(!ccx.IsValid())
|
||||
return JS_FALSE;
|
||||
|
||||
ComputeWrapperInfo(ccx, &callee, &script);
|
||||
if(!callee)
|
||||
callee = xpcscope->GetGlobalJSObject();
|
||||
|
||||
JSAutoCrossCompartmentCall accc;
|
||||
if(!accc.enter(ccx, callee) || !JS_WrapObject(ccx, &flat))
|
||||
return JS_FALSE;
|
||||
|
||||
return CreateHolderIfNeeded(ccx, flat, d, dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
tryConstructSlimWrapper = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!dest)
|
||||
{
|
||||
if(!flat)
|
||||
|
@ -1196,6 +1265,22 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
|||
// fall through because we either have a slim wrapper that needs to be
|
||||
// morphed or we have an XPCWrappedNative.
|
||||
flat = cache->GetWrapper();
|
||||
if(cache->IsProxy())
|
||||
{
|
||||
XPCCallContext &ccx = lccx.GetXPCCallContext();
|
||||
if(!ccx.IsValid())
|
||||
return JS_FALSE;
|
||||
|
||||
ComputeWrapperInfo(ccx, &callee, &script);
|
||||
if(!callee)
|
||||
callee = xpcscope->GetGlobalJSObject();
|
||||
|
||||
JSAutoCrossCompartmentCall accc;
|
||||
if(!accc.enter(ccx, callee) || !JS_WrapObject(ccx, &flat))
|
||||
return JS_FALSE;
|
||||
|
||||
return CreateHolderIfNeeded(ccx, flat, d, dest);
|
||||
}
|
||||
}
|
||||
|
||||
AutoMarkingNativeInterfacePtr iface;
|
||||
|
@ -1221,7 +1306,8 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
|||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(!flat || IS_WRAPPER_CLASS(flat->getClass()),
|
||||
NS_ASSERTION(!flat || IS_WRAPPER_CLASS(flat->getClass()) ||
|
||||
cache->IsProxy(),
|
||||
"What kind of wrapper is this?");
|
||||
|
||||
nsresult rv;
|
||||
|
@ -1257,7 +1343,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
|||
else
|
||||
rv = NS_OK;
|
||||
}
|
||||
else
|
||||
else if(!cache->IsProxy())
|
||||
{
|
||||
NS_ASSERTION(IS_SLIM_WRAPPER(flat),
|
||||
"What kind of wrapper is this?");
|
||||
|
@ -1299,45 +1385,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
|||
|
||||
// printf("Wrapped native accessed across scope boundary\n");
|
||||
|
||||
JSScript* script = nsnull;
|
||||
JSObject* callee = nsnull;
|
||||
if(ccx.GetXPCContext()->CallerTypeIsJavaScript())
|
||||
{
|
||||
// Called from JS. We're going to hand the resulting
|
||||
// JSObject to said JS, so look for the script we want on
|
||||
// the stack.
|
||||
JSContext* cx = ccx;
|
||||
JSStackFrame* fp = JS_GetScriptedCaller(cx, NULL);
|
||||
if(fp)
|
||||
{
|
||||
script = JS_GetFrameScript(cx, fp);
|
||||
callee = JS_GetFrameCalleeObject(cx, fp);
|
||||
}
|
||||
}
|
||||
else if(ccx.GetXPCContext()->CallerTypeIsNative())
|
||||
{
|
||||
callee = ccx.GetCallee();
|
||||
if(callee && JS_ObjectIsFunction(ccx, callee))
|
||||
{
|
||||
// Called from c++, and calling out to |callee|, which
|
||||
// is a JS function object. Look for the script for
|
||||
// this function.
|
||||
JSFunction* fun =
|
||||
(JSFunction*) xpc_GetJSPrivate(callee);
|
||||
NS_ASSERTION(fun,
|
||||
"Must have JSFunction for a Function "
|
||||
"object");
|
||||
script = JS_GetFunctionScript(ccx, fun);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Else we don't know whom we're calling, so don't
|
||||
// create XPCNativeWrappers.
|
||||
callee = nsnull;
|
||||
}
|
||||
}
|
||||
// else don't create XPCNativeWrappers, since we have
|
||||
// no idea what's calling what here.
|
||||
ComputeWrapperInfo(ccx, &callee, &script);
|
||||
|
||||
flags = script ? JS_GetScriptFilenameFlags(script) : 0;
|
||||
NS_ASSERTION(flags != JSFILENAME_NULL, "null script filename");
|
||||
|
|
|
@ -3879,11 +3879,15 @@ ConstructSlimWrapper(XPCCallContext &ccx,
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
nsWrapperCache *cache = aHelper.GetWrapperCache();
|
||||
JSObject* plannedParent = parent;
|
||||
rv = classInfoHelper->PreCreate(identityObj, ccx, parent, &parent);
|
||||
if(rv != NS_SUCCESS_ALLOW_SLIM_WRAPPERS)
|
||||
{
|
||||
SLIM_LOG_NOT_CREATED(ccx, identityObj, "PreCreate hook refused");
|
||||
if(cache->IsProxy())
|
||||
NS_ASSERTION(cache->GetWrapper(), "out of memory?");
|
||||
else
|
||||
SLIM_LOG_NOT_CREATED(ccx, identityObj, "PreCreate hook refused");
|
||||
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -3902,7 +3906,6 @@ ConstructSlimWrapper(XPCCallContext &ccx,
|
|||
|
||||
// The PreCreate hook could have forced the creation of a wrapper, need
|
||||
// to check for that here and return early.
|
||||
nsWrapperCache *cache = aHelper.GetWrapperCache();
|
||||
JSObject* wrapper = cache->GetWrapper();
|
||||
if(wrapper)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче