Fix for bug 499199 (Try to avoid XPCCallContexts in quickstubs for wrapper-cached things). r/sr=jst.

--HG--
extra : rebase_source : 8fc828106f3cf5e82e902cefd79e55df2b8721c3
This commit is contained in:
Peter Van der Beken 2009-08-10 12:12:59 +02:00
Родитель d201b699db
Коммит 84dc646522
15 изменённых файлов: 454 добавлений и 236 удалений

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

@ -51,7 +51,6 @@
(nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY | \
nsIXPCScriptable::USE_JSSTUB_FOR_DELPROPERTY | \
nsIXPCScriptable::USE_JSSTUB_FOR_SETPROPERTY | \
nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE | \
nsIXPCScriptable::ALLOW_PROP_MODS_TO_PROTOTYPE | \
nsIXPCScriptable::DONT_ASK_INSTANCE_FOR_SCRIPTABLE | \
nsIXPCScriptable::DONT_REFLECT_INTERFACE_NAMES)

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

@ -1222,6 +1222,7 @@ nsXPConnect::WrapNativeToJSVal(JSContext * aJSContext,
XPCCallContext ccx(NATIVE_CALLER, aJSContext);
if(!ccx.IsValid())
return UnexpectedFailure(NS_ERROR_FAILURE);
XPCLazyCallContext lccx(ccx);
nsresult rv;
if(!XPCConvert::NativeInterface2JSObject(ccx, aVal, aHolder, aCOMObj, aIID,
@ -2238,9 +2239,10 @@ nsXPConnect::VariantToJS(JSContext* ctx, JSObject* scope, nsIVariant* value, jsv
XPCCallContext ccx(NATIVE_CALLER, ctx);
if(!ccx.IsValid())
return NS_ERROR_FAILURE;
XPCLazyCallContext lccx(ccx);
nsresult rv = NS_OK;
if(!XPCVariant::VariantDataToJS(ccx, value, scope, &rv, _retval))
if(!XPCVariant::VariantDataToJS(lccx, value, scope, &rv, _retval))
{
if(NS_FAILED(rv))
return rv;

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

@ -101,16 +101,6 @@
# exposed--nsAXPCNativeCallContext does not expose
# XPCCallContext::GetPrevCallContext.)
#
# - There are a few differences in how the "this" JSObject is unwrapped.
# Ordinarily, XPConnect searches the prototype chain of the "this" JSObject
# for an XPCOM object of the desired "proto". For details, see the parts of
# XPCWrappedNative::GetWrappedNativeOfJSObject that use "proto". Some quick
# stubs (methods, not getters or setters, that have XPCCallContexts) do this,
# but most instead look for an XPCOM object that supports the desired
# *interface*. This is more lenient. The difference is observable in some
# cases where a getter/setter/method is taken from one object and applied to
# another object.
#
# - Quick stubs never suspend the JS request. So they are only suitable for
# main-thread-only interfaces.
#
@ -591,7 +581,7 @@ resultConvTemplates = {
def isVariantType(t):
return isSpecificInterfaceType(t, 'nsIVariant')
def writeResultConv(f, type, paramNum, jsvalPtr, jsvalRef):
def writeResultConv(f, type, jsvalPtr, jsvalRef):
""" Emit code to convert the C++ variable `result` to a jsval.
The emitted code contains a return statement; it returns JS_TRUE on
@ -609,15 +599,14 @@ def writeResultConv(f, type, paramNum, jsvalPtr, jsvalRef):
# else fall through; this type isn't supported yet
elif isInterfaceType(type):
if isVariantType(type):
f.write(" return xpc_qsVariantToJsval(ccx, result, %d, %s);\n"
% (paramNum, jsvalPtr))
f.write(" return xpc_qsVariantToJsval(lccx, result, %s);\n"
% jsvalPtr)
return
else:
f.write(" AutoMarkingNativeInterfacePtr resultiface(ccx, "
"%s_Interface(ccx));\n" % type.name)
f.write(" return xpc_qsXPCOMObjectToJsval(ccx, result, "
"xpc_qsGetWrapperCache(result), resultiface, %s);\n"
% jsvalPtr)
f.write(" return xpc_qsXPCOMObjectToJsval(lccx, result, "
"xpc_qsGetWrapperCache(result), &NS_GET_IID(%s), "
"&interfaces[k_%s], %s);\n"
% (type.name, type.name, jsvalPtr))
return
warn("Unable to convert result of type %s" % type.name)
@ -678,16 +667,18 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
" return JS_FALSE;\n")
# Create ccx if needed.
haveCcx = isMethod and (isInterfaceType(member.realtype)
or anyParamRequiresCcx(member))
haveCcx = isMethod and anyParamRequiresCcx(member)
if haveCcx:
f.write(" XPCCallContext ccx(JS_CALLER, cx, obj, "
"JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));\n")
else:
# In some cases we emit a ccx, but it does not count as
# "haveCcx" because it's not complete.
if isAttr and isInterfaceType(member.realtype):
f.write(" XPCCallContext ccx(JS_CALLER, cx, obj);\n")
f.write(" XPCCallContext ccx(JS_CALLER, cx, obj, "
"JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));\n")
if isInterfaceType(member.realtype):
f.write(" XPCLazyCallContext lccx(ccx);\n")
elif isInterfaceType(member.realtype):
if isMethod:
f.write(" JSObject *callee = "
"JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));\n")
elif isGetter:
f.write(" JSObject *callee = nsnull;\n")
# Get the 'self' pointer.
if customMethodCall is None or not 'thisType' in customMethodCall:
@ -697,7 +688,7 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
f.write(" xpc_qsSelfRef selfref;\n")
# Don't use FromCcx for getters or setters; the way we construct the ccx in
# a getter/setter causes it to find the wrong wrapper in some cases.
if isMethod and haveCcx:
if haveCcx:
# Undocumented, but the interpreter puts 'this' at argv[-1],
# which is vp[1]; and it's ok to overwrite it.
f.write(" if (!xpc_qsUnwrapThisFromCcx(ccx, &self, &selfref.ptr, "
@ -712,8 +703,13 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
else:
pthisval = '&vp[1]' # as above, ok to overwrite vp[1]
f.write(" if (!xpc_qsUnwrapThis(cx, obj, &self, &selfref.ptr, "
"%s))\n" % pthisval)
if not isSetter and isInterfaceType(member.realtype):
f.write(" XPCLazyCallContext lccx(JS_CALLER, cx, obj);\n")
f.write(" if (!xpc_qsUnwrapThis(cx, obj, callee, &self, "
"&selfref.ptr, %s, &lccx))\n" % pthisval)
else:
f.write(" if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, "
"&selfref.ptr, %s, nsnull))\n" % pthisval)
f.write(" return JS_FALSE;\n")
if isMethod:
@ -807,10 +803,8 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
f.write("#endif\n")
# Convert the return value.
if isMethod:
writeResultConv(f, member.realtype, len(member.params) + 1, 'vp', '*vp')
elif isGetter:
writeResultConv(f, member.realtype, None, 'vp', '*vp')
if isMethod or isGetter:
writeResultConv(f, member.realtype, 'vp', '*vp')
else:
f.write(" return JS_TRUE;\n")
@ -990,7 +984,7 @@ traceableResultConvTemplates = {
" return rval;\n",
}
def writeTraceableResultConv(f, type, paramNum):
def writeTraceableResultConv(f, type):
typeName = getBuiltinOrNativeTypeName(type)
if typeName is not None:
template = traceableResultConvTemplates.get(typeName)
@ -1002,14 +996,13 @@ def writeTraceableResultConv(f, type, paramNum):
# else fall through; this type isn't supported yet
elif isInterfaceType(type):
if isVariantType(type):
f.write(" JSBool ok = xpc_qsVariantToJsval(ccx, result, %d, "
"&vp.array[0]);\n" % paramNum)
f.write(" JSBool ok = xpc_qsVariantToJsval(lccx, result, "
"&vp.array[0]);\n")
else:
f.write(" AutoMarkingNativeInterfacePtr resultiface(ccx, "
"%s_Interface(ccx));\n" % type.name)
f.write(" JSBool ok = xpc_qsXPCOMObjectToJsval(ccx, result, "
"xpc_qsGetWrapperCache(result), resultiface, &vp.array[0]);"
"\n")
f.write(" JSBool ok = xpc_qsXPCOMObjectToJsval(lccx, result, "
"xpc_qsGetWrapperCache(result), &NS_GET_IID(%s), "
"&interfaces[k_%s], &vp.array[0]);"
"\n" % (type.name, type.name))
f.write(" if (!ok) {\n");
writeFailure(f, getTraceInfoDefaultReturn(type), 2)
f.write(" return vp.array[0];\n")
@ -1027,14 +1020,14 @@ def writeTraceableQuickStub(f, customMethodCalls, member, stubName):
'params': ["CONTEXT", "THIS"]
}
haveCcx = isInterfaceType(member.realtype) or anyParamRequiresCcx(member)
haveCcx = (member.kind == 'method') and anyParamRequiresCcx(member)
customMethodCall = customMethodCalls.get(stubName, None)
# Write the function
f.write("static %sFASTCALL\n" % getTraceType(member.type))
f.write("%s(JSContext *cx, JSObject *obj" % (stubName + "_tn"))
if haveCcx:
if haveCcx or isInterfaceType(member.realtype):
f.write(", JSObject *callee")
traceInfo["params"].append("CALLEE")
for i, param in enumerate(member.params):
@ -1047,6 +1040,8 @@ def writeTraceableQuickStub(f, customMethodCalls, member, stubName):
# Create ccx if needed.
if haveCcx:
f.write(" XPCCallContext ccx(JS_CALLER, cx, obj, callee);\n")
if isInterfaceType(member.realtype):
f.write(" XPCLazyCallContext lccx(ccx);\n")
# Get the 'self' pointer.
if customMethodCall is None or not 'thisType' in customMethodCall:
@ -1058,9 +1053,13 @@ def writeTraceableQuickStub(f, customMethodCalls, member, stubName):
if haveCcx:
f.write(" if (!xpc_qsUnwrapThisFromCcx(ccx, &self, &selfref.ptr, "
"&vp.array[0])) {\n")
elif (member.kind == 'method') and isInterfaceType(member.realtype):
f.write(" XPCLazyCallContext lccx(JS_CALLER, cx, obj);\n")
f.write(" if (!xpc_qsUnwrapThis(cx, obj, callee, &self, &selfref.ptr, "
"&vp.array[0], &lccx)) {\n")
else:
f.write(" if (!xpc_qsUnwrapThis(cx, obj, &self, &selfref.ptr, "
"&vp.array[0])) {\n")
f.write(" if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, "
"&vp.array[0], nsnull)) {\n")
writeFailure(f, getTraceInfoDefaultReturn(member.type), 2)
argNames = []
@ -1122,7 +1121,7 @@ def writeTraceableQuickStub(f, customMethodCalls, member, stubName):
f.write("#endif\n")
# Convert the return value.
writeTraceableResultConv(f, member.realtype, len(member.params) + 1)
writeTraceableResultConv(f, member.realtype)
# Epilog.
f.write("}\n\n")
@ -1228,8 +1227,7 @@ def writeResultXPCInterfacesArray(f, conf, resulttypes):
f.write("}\n\n")
i = 0
for type in resulttypes:
f.write("XPC_QS_DEFINE_XPCNATIVEINTERFACE_GETTER(%s, interfaces[%d])\n"
% (type, i))
f.write("static const PRUint32 k_%s = %d;\n" % (type, i))
i += 1
if count > 0:
f.write("\n\n")

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

@ -59,6 +59,45 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
mDestroyJSContextInDestructor(JS_FALSE),
mCallerLanguage(callerLanguage),
mCallee(nsnull)
{
Init(callerLanguage, callerLanguage == NATIVE_CALLER, obj, funobj, JS_TRUE,
name, argc, argv, rval);
}
XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
JSContext* cx,
JSBool callBeginRequest,
JSObject* obj,
JSObject* currentJSObject,
XPCWrappedNative* wrapper,
XPCWrappedNativeTearOff* tearOff)
: mState(INIT_FAILED),
mXPC(nsXPConnect::GetXPConnect()),
mThreadData(nsnull),
mXPCContext(nsnull),
mJSContext(cx),
mContextPopRequired(JS_FALSE),
mDestroyJSContextInDestructor(JS_FALSE),
mCallerLanguage(callerLanguage),
mCurrentJSObject(currentJSObject),
mWrapper(wrapper),
mTearOff(tearOff),
mCallee(nsnull)
{
Init(callerLanguage, callBeginRequest, obj, nsnull, JS_FALSE, 0, NO_ARGS,
nsnull, nsnull);
}
void
XPCCallContext::Init(XPCContext::LangType callerLanguage,
JSBool callBeginRequest,
JSObject* obj,
JSObject* funobj,
JSBool getWrappedNative,
jsval name,
uintN argc,
jsval *argv,
jsval *rval)
{
// Mark our internal string wrappers as not used. Make sure we do
// this before any early returns, as the destructor will assert
@ -110,7 +149,9 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
// Get into the request as early as we can to avoid problems with scanning
// callcontexts on other threads from within the gc callbacks.
if(mCallerLanguage == NATIVE_CALLER)
NS_ASSERTION(!callBeginRequest || mCallerLanguage == NATIVE_CALLER,
"Don't call JS_BeginRequest unless the caller is native.");
if(callBeginRequest)
JS_BeginRequest(mJSContext);
if(topJSContext != mJSContext)
@ -145,10 +186,12 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
mState = HAVE_OBJECT;
mTearOff = nsnull;
mWrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(mJSContext, obj,
funobj,
&mCurrentJSObject,
&mTearOff);
if(getWrappedNative)
mWrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(mJSContext, obj,
funobj,
&mCurrentJSObject,
&mTearOff);
if(mWrapper)
{
DEBUG_CheckWrapperThreadSafety(mWrapper);
@ -576,3 +619,19 @@ XPCCallContext::GetLanguage(PRUint16 *aResult)
*aResult = GetCallerLanguage();
return NS_OK;
}
#ifdef DEBUG
// static
void
XPCLazyCallContext::AssertContextIsTopOfStack(JSContext* cx)
{
XPCPerThreadData* tls = XPCPerThreadData::GetData(cx);
XPCJSContextStack* stack = tls->GetJSContextStack();
JSContext* topJSContext;
nsresult rv = stack->Peek(&topJSContext);
NS_ASSERTION(NS_SUCCEEDED(rv), "XPCJSContextStack::Peek failed");
NS_ASSERTION(cx == topJSContext, "wrong context on XPCJSContextStack!");
}
#endif

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

@ -238,14 +238,14 @@ INT64_TO_DOUBLE(const int64 &v)
// static
JSBool
XPCConvert::NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
XPCConvert::NativeData2JS(XPCLazyCallContext& lccx, jsval* d, const void* s,
const nsXPTType& type, const nsID* iid,
JSObject* scope, nsresult* pErr)
{
NS_PRECONDITION(s, "bad param");
NS_PRECONDITION(d, "bad param");
JSContext* cx = ccx.GetJSContext();
JSContext* cx = lccx.GetJSContext();
if(pErr)
*pErr = NS_ERROR_XPC_BAD_CONVERT_NATIVE;
@ -456,7 +456,7 @@ XPCConvert::NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
if(!variant)
return JS_FALSE;
return XPCVariant::VariantDataToJS(ccx, variant,
return XPCVariant::VariantDataToJS(lccx, variant,
scope, pErr, d);
}
// else...
@ -466,7 +466,7 @@ XPCConvert::NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
// global object will not have been collected, and
// therefore this NativeInterface2JSObject will not end up
// creating a new XPCNativeScriptableShared.
if(!NativeInterface2JSObject(ccx, d, nsnull, iface, iid,
if(!NativeInterface2JSObject(lccx, d, nsnull, iface, iid,
nsnull, nsnull, scope, PR_TRUE,
OBJ_IS_NOT_GLOBAL, pErr))
return JS_FALSE;
@ -1045,12 +1045,12 @@ CreateHolderIfNeeded(XPCCallContext& ccx, JSObject* obj, jsval* d,
/***************************************************************************/
// static
JSBool
XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
jsval* d,
nsIXPConnectJSObjectHolder** dest,
nsISupports* src,
const nsID* iid,
XPCNativeInterface* Interface,
XPCNativeInterface** Interface,
nsWrapperCache *cache,
JSObject* scope,
PRBool allowNativeWrapper,
@ -1058,6 +1058,8 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
nsresult* pErr)
{
NS_ASSERTION(scope, "bad param");
NS_ASSERTION(!Interface || iid,
"Need the iid if you pass in an XPCNativeInterface cache.");
*d = JSVAL_NULL;
if(dest)
@ -1085,10 +1087,7 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
// verify that this wrapper is for the right interface
nsCOMPtr<nsISupports> wrapper;
if(Interface)
src->QueryInterface(*Interface->GetIID(),
(void**)getter_AddRefs(wrapper));
else if(iid)
if(iid)
src->QueryInterface(*iid, (void**)getter_AddRefs(wrapper));
else
wrapper = do_QueryInterface(src);
@ -1106,13 +1105,17 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
else
#endif /* XPC_DO_DOUBLE_WRAP */
{
JSContext* cx = lccx.GetJSContext();
XPCWrappedNativeScope* xpcscope =
XPCWrappedNativeScope::FindInJSObjectScope(ccx, scope);
XPCWrappedNativeScope::FindInJSObjectScope(cx, scope);
if(!xpcscope)
return JS_FALSE;
if(!cache)
CallQueryInterface(src, &cache);
PRBool tryConstructSlimWrapper = PR_FALSE;
JSObject *flat;
if(cache)
{
@ -1121,24 +1124,11 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
{
if(!flat)
{
jsval slim;
if(ConstructSlimWrapper(ccx, src, cache, Interface,
xpcscope, &slim))
{
*d = slim;
return JS_TRUE;
}
// Even if ConstructSlimWrapper returns JS_FALSE it might
// have created a wrapper (while calling the PreCreate
// hook). In that case we need to fall through because we
// either have a slim wrapper that needs to be morphed or
// we have an XPCWrappedNative.
flat = cache->GetWrapper();
tryConstructSlimWrapper = PR_TRUE;
}
else if(!IS_WRAPPER_CLASS(STOBJ_GET_CLASS(flat)))
{
JSObject* global = JS_GetGlobalForObject(ccx, flat);
JSObject* global = JS_GetGlobalForObject(cx, flat);
if(global == xpcscope->GetGlobalJSObject())
{
*d = OBJECT_TO_JSVAL(flat);
@ -1152,12 +1142,47 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
flat = nsnull;
}
AutoMarkingNativeInterfacePtr iface(ccx, Interface);
if(!iface && iid)
if(tryConstructSlimWrapper)
{
iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
if(!iface)
XPCCallContext &ccx = lccx.GetXPCCallContext();
if(!ccx.IsValid())
return JS_FALSE;
jsval slim;
if(ConstructSlimWrapper(ccx, src, cache, xpcscope, &slim))
{
*d = slim;
return JS_TRUE;
}
// Even if ConstructSlimWrapper returns JS_FALSE it might have created a
// wrapper (while calling the PreCreate hook). In that case we need to
// fall through because we either have a slim wrapper that needs to be
// morphed or we have an XPCWrappedNative.
flat = cache->GetWrapper();
}
AutoMarkingNativeInterfacePtr iface;
if(iid)
{
XPCCallContext &ccx = lccx.GetXPCCallContext();
if(!ccx.IsValid())
return JS_FALSE;
iface.Init(ccx);
if(Interface)
iface = *Interface;
if(!iface)
{
iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
if(!iface)
return JS_FALSE;
if(Interface)
*Interface = iface;
}
}
nsresult rv;
@ -1165,6 +1190,10 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
nsRefPtr<XPCWrappedNative> strongWrapper;
if(!flat)
{
XPCCallContext &ccx = lccx.GetXPCCallContext();
if(!ccx.IsValid())
return JS_FALSE;
rv = XPCWrappedNative::GetNewOrUsed(ccx, src, xpcscope, iface,
cache, isGlobal,
getter_AddRefs(strongWrapper));
@ -1180,8 +1209,12 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
// rooted in that case).
if(dest)
strongWrapper = wrapper;
// If iface is not null we know lccx.GetXPCCallContext() returns
// a valid XPCCallContext because we checked when calling Init on
// iface.
if(iface)
wrapper->FindTearOff(ccx, iface, JS_FALSE, &rv);
wrapper->FindTearOff(lccx.GetXPCCallContext(), iface, JS_FALSE,
&rv);
else
rv = NS_OK;
}
@ -1189,6 +1222,11 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
{
NS_ASSERTION(IS_SLIM_WRAPPER(flat),
"What kind of wrapper is this?");
XPCCallContext &ccx = lccx.GetXPCCallContext();
if(!ccx.IsValid())
return JS_FALSE;
SLIM_LOG(("***** morphing from XPCConvert::NativeInterface2JSObject"
"(%p)\n",
static_cast<nsISupports*>(xpc_GetJSPrivate(flat))));
@ -1202,6 +1240,10 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx,
*pErr = rv;
if(NS_SUCCEEDED(rv) && wrapper)
{
XPCCallContext &ccx = lccx.GetXPCCallContext();
if(!ccx.IsValid())
return JS_FALSE;
uint32 flags = 0;
flat = wrapper->GetFlatJSObject();
jsval v = OBJECT_TO_JSVAL(flat);
@ -1886,7 +1928,7 @@ XPC_JSArgumentFormatter(JSContext *cx, const char *format,
// static
JSBool
XPCConvert::NativeArray2JS(XPCCallContext& ccx,
XPCConvert::NativeArray2JS(XPCLazyCallContext& lccx,
jsval* d, const void** s,
const nsXPTType& type, const nsID* iid,
JSUint32 count, JSObject* scope,
@ -1895,6 +1937,10 @@ XPCConvert::NativeArray2JS(XPCCallContext& ccx,
NS_PRECONDITION(s, "bad param");
NS_PRECONDITION(d, "bad param");
XPCCallContext& ccx = lccx.GetXPCCallContext();
if(!ccx.IsValid())
return JS_FALSE;
JSContext* cx = ccx.GetJSContext();
// XXX add support for putting chars in a string rather than an array
@ -2128,7 +2174,7 @@ failure:
// static
JSBool
XPCConvert::NativeStringWithSize2JS(XPCCallContext& ccx,
XPCConvert::NativeStringWithSize2JS(JSContext* cx,
jsval* d, const void* s,
const nsXPTType& type,
JSUint32 count,
@ -2137,8 +2183,6 @@ XPCConvert::NativeStringWithSize2JS(XPCCallContext& ccx,
NS_PRECONDITION(s, "bad param");
NS_PRECONDITION(d, "bad param");
JSContext* cx = ccx.GetJSContext();
if(pErr)
*pErr = NS_ERROR_XPC_BAD_CONVERT_NATIVE;

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

@ -120,7 +120,6 @@ static JSDHashOperator
NativeInterfaceSweeper(JSDHashTable *table, JSDHashEntryHdr *hdr,
uint32 number, void *arg)
{
CX_AND_XPCRT_Data* data = (CX_AND_XPCRT_Data*) arg;
XPCNativeInterface* iface = ((IID2NativeInterfaceMap::Entry*)hdr)->value;
if(iface->IsMarked())
{
@ -133,7 +132,7 @@ NativeInterfaceSweeper(JSDHashTable *table, JSDHashEntryHdr *hdr,
JS_GetStringBytes(JSVAL_TO_STRING(iface->GetName())));
#endif
XPCNativeInterface::DestroyInstance(data->cx, data->rt, iface);
XPCNativeInterface::DestroyInstance(iface);
return JS_DHASH_REMOVE;
}
@ -645,10 +644,8 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
self->mNativeSetMap->
Enumerate(NativeSetSweeper, nsnull);
CX_AND_XPCRT_Data data = {cx, self};
self->mIID2NativeInterfaceMap->
Enumerate(NativeInterfaceSweeper, &data);
Enumerate(NativeInterfaceSweeper, nsnull);
#ifdef DEBUG
XPCWrappedNativeScope::ASSERT_NoInterfaceSetsAreMarked();

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

@ -134,7 +134,10 @@ LogSlimWrapperWillMorph(JSContext *cx, JSObject *obj, const char *propname,
{
if(obj && IS_SLIM_WRAPPER(obj))
{
printf("***** morphing from %s", functionName);
XPCNativeScriptableInfo *si =
GetSlimWrapperProto(obj)->GetScriptableInfo();
printf("***** morphing %s from %s", si->GetJSClass()->name,
functionName);
if(propname)
printf(" for %s", propname);
printf(" (%p, %p)\n", obj,
@ -146,8 +149,15 @@ LogSlimWrapperWillMorph(JSContext *cx, JSObject *obj, const char *propname,
void
LogSlimWrapperNotCreated(JSContext *cx, nsISupports *obj, const char *reason)
{
printf("***** refusing to create slim wrapper, reason: %s (%p)\n",
reason, obj);
char* className = nsnull;
nsCOMPtr<nsIClassInfo> ci = do_QueryInterface(obj);
if(ci)
ci->GetClassDescription(&className);
printf("***** refusing to create slim wrapper%s%s, reason: %s (%p)\n",
className ? " for " : "", className ? className : "", reason, obj);
if(className)
PR_Free(className);
AutoJSRequestWithNoCallContext autoRequest(cx);
xpc_DumpJSStack(cx, JS_FALSE, JS_FALSE, JS_FALSE);
}
#endif

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

@ -1084,6 +1084,25 @@ private:
XPCCallContext(const XPCCallContext& r); // not implemented
XPCCallContext& operator= (const XPCCallContext& r); // not implemented
friend class XPCLazyCallContext;
XPCCallContext(XPCContext::LangType callerLanguage,
JSContext* cx,
JSBool callBeginRequest,
JSObject* obj,
JSObject* currentJSObject,
XPCWrappedNative* wn,
XPCWrappedNativeTearOff* tearoff);
void Init(XPCContext::LangType callerLanguage,
JSBool callBeginRequest,
JSObject* obj,
JSObject* funobj,
JSBool getWrappedNative,
jsval name,
uintN argc,
jsval *argv,
jsval *rval);
private:
// posible values for mState
enum State {
@ -1176,6 +1195,113 @@ private:
char mStringWrapperData[sizeof(StringWrapperEntry) * XPCCCX_STRING_CACHE_SIZE];
};
class XPCLazyCallContext
{
public:
XPCLazyCallContext(XPCCallContext& ccx)
: mCallBeginRequest(DONT_CALL_BEGINREQUEST),
mCcx(&ccx),
mCcxToDestroy(nsnull)
{
}
XPCLazyCallContext(XPCContext::LangType callerLanguage, JSContext* cx,
JSObject* obj = nsnull,
JSObject* currentJSObject = nsnull,
XPCWrappedNative* wrapper = nsnull,
XPCWrappedNativeTearOff* tearoff = nsnull)
: mCallBeginRequest(callerLanguage == NATIVE_CALLER ?
CALL_BEGINREQUEST : DONT_CALL_BEGINREQUEST),
mCcx(nsnull),
mCcxToDestroy(nsnull),
mCx(cx),
mCallerLanguage(callerLanguage),
mObj(obj),
mCurrentJSObject(currentJSObject),
mWrapper(wrapper),
mTearOff(tearoff)
{
NS_ASSERTION(cx, "Need a JS context!");
NS_ASSERTION(callerLanguage == NATIVE_CALLER ||
callerLanguage == JS_CALLER,
"Can't deal with unknown caller language!");
#ifdef DEBUG
AssertContextIsTopOfStack(cx);
#endif
}
~XPCLazyCallContext()
{
if(mCcxToDestroy)
mCcxToDestroy->~XPCCallContext();
else if(mCallBeginRequest == CALLED_BEGINREQUEST)
JS_EndRequest(mCx);
}
void SetWrapper(JSObject* currentJSObject,
XPCWrappedNative* wrapper,
XPCWrappedNativeTearOff* tearoff)
{
mCurrentJSObject = currentJSObject;
mWrapper = wrapper;
mTearOff = tearoff;
}
JSContext *GetJSContext()
{
if(mCcx)
return mCcx->GetJSContext();
if(mCallBeginRequest == CALL_BEGINREQUEST) {
JS_BeginRequest(mCx);
mCallBeginRequest = CALLED_BEGINREQUEST;
}
return mCx;
}
JSObject *GetCurrentJSObject() const
{
return mCurrentJSObject;
}
XPCCallContext &GetXPCCallContext()
{
if(!mCcx)
{
mCcxToDestroy = mCcx =
new (mData) XPCCallContext(mCallerLanguage, mCx,
mCallBeginRequest == CALL_BEGINREQUEST,
mObj,
mCurrentJSObject, mWrapper,
mTearOff);
if(!mCcx->IsValid())
{
NS_ERROR("This is not supposed to fail!");
}
}
return *mCcx;
}
private:
#ifdef DEBUG
static void AssertContextIsTopOfStack(JSContext* cx);
#endif
enum {
DONT_CALL_BEGINREQUEST,
CALL_BEGINREQUEST,
CALLED_BEGINREQUEST
} mCallBeginRequest;
XPCCallContext *mCcx;
XPCCallContext *mCcxToDestroy;
JSContext *mCx;
XPCContext::LangType mCallerLanguage;
JSObject *mObj;
JSObject *mCurrentJSObject;
XPCWrappedNative *mWrapper;
XPCWrappedNativeTearOff *mTearOff;
char mData[sizeof(XPCCallContext)];
};
/***************************************************************************
****************************************************************************
*
@ -1524,8 +1650,7 @@ public:
inline void TraceJS(JSTracer* trc) {}
inline void AutoTrace(JSTracer* trc) {}
static void DestroyInstance(JSContext* cx, XPCJSRuntime* rt,
XPCNativeInterface* inst);
static void DestroyInstance(XPCNativeInterface* inst);
protected:
static XPCNativeInterface* NewInstance(XPCCallContext& ccx,
@ -2078,7 +2203,6 @@ extern JSBool XPC_SWN_Equality(JSContext *cx, JSObject *obj, jsval v,
extern JSBool ConstructSlimWrapper(XPCCallContext &ccx, nsISupports *p,
nsWrapperCache *cache,
XPCNativeInterface *iface,
XPCWrappedNativeScope* xpcScope,
jsval *rval);
extern JSBool MorphSlimWrapper(JSContext *cx, JSObject *obj);
@ -2837,7 +2961,15 @@ public:
*/
static JSBool NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
const nsXPTType& type, const nsID* iid,
JSObject* scope, nsresult* pErr);
JSObject* scope, nsresult* pErr)
{
XPCLazyCallContext lccx(ccx);
return NativeData2JS(lccx, d, s, type, iid, scope, pErr);
}
static JSBool NativeData2JS(XPCLazyCallContext& lccx, jsval* d,
const void* s, const nsXPTType& type,
const nsID* iid, JSObject* scope,
nsresult* pErr);
static JSBool JSData2Native(XPCCallContext& ccx, void* d, jsval s,
const nsXPTType& type,
@ -2850,11 +2982,15 @@ public:
* @param ccx the context for the whole procedure
* @param dest [out] the resulting JSObject
* @param src the native object we're working with
* @param iid the interface of src that we want
* @param iid the interface of src that we want (may be null)
* @param Interface the interface of src that we want
* @param cache the wrapper cache for src (may be null, in which case src
* will be QI'ed to get the cache)
* @param scope the default scope to put on the new JSObject's __parent__
* chain
* @param allowNativeWrapper if true, this method may wrap the resulting
* JSObject in an XPCNativeWrapper and return that, as needed.
* @param isGlobal
* @param pErr [out] relevant error code, if any.
*/
static JSBool NativeInterface2JSObject(XPCCallContext& ccx,
@ -2862,7 +2998,24 @@ public:
nsIXPConnectJSObjectHolder** dest,
nsISupports* src,
const nsID* iid,
XPCNativeInterface* Interface,
XPCNativeInterface** Interface,
nsWrapperCache *cache,
JSObject* scope,
PRBool allowNativeWrapper,
PRBool isGlobal,
nsresult* pErr)
{
XPCLazyCallContext lccx(ccx);
return NativeInterface2JSObject(lccx, d, dest, src, iid, Interface,
cache, scope, allowNativeWrapper,
isGlobal, pErr);
}
static JSBool NativeInterface2JSObject(XPCLazyCallContext& lccx,
jsval* d,
nsIXPConnectJSObjectHolder** dest,
nsISupports* src,
const nsID* iid,
XPCNativeInterface** Interface,
nsWrapperCache *cache,
JSObject* scope,
PRBool allowNativeWrapper,
@ -2893,7 +3046,7 @@ public:
* chain
* @param pErr [out] relevant error code, if any.
*/
static JSBool NativeArray2JS(XPCCallContext& ccx,
static JSBool NativeArray2JS(XPCLazyCallContext& ccx,
jsval* d, const void** s,
const nsXPTType& type, const nsID* iid,
JSUint32 count, JSObject* scope,
@ -2905,7 +3058,7 @@ public:
JSBool useAllocator, const nsID* iid,
uintN* pErr);
static JSBool NativeStringWithSize2JS(XPCCallContext& ccx,
static JSBool NativeStringWithSize2JS(JSContext* cx,
jsval* d, const void* s,
const nsXPTType& type,
JSUint32 count,
@ -3830,9 +3983,16 @@ class AutoMarkingPtr
public:
AutoMarkingPtr(XPCCallContext& ccx)
: mNext(nsnull), mTLS(ccx.GetThreadData()) {Link();}
AutoMarkingPtr()
: mNext(nsnull), mTLS(nsnull) {}
virtual ~AutoMarkingPtr() {Unlink();}
void Init(XPCCallContext& ccx)
{NS_ASSERTION(!mTLS, "Already init'ed!");
mTLS = ccx.GetThreadData();
Link();}
void Link()
{if(!mTLS) return;
AutoMarkingPtr** list = mTLS->GetAutoRootsAdr();
@ -3865,6 +4025,8 @@ protected:
class class_ : public AutoMarkingPtr \
{ \
public: \
class_ () \
: AutoMarkingPtr(), mPtr(nsnull) {} \
class_ (XPCCallContext& ccx, type_ * ptr = nsnull) \
: AutoMarkingPtr(ccx), mPtr(ptr) {} \
virtual ~ class_ () {} \
@ -3885,7 +4047,8 @@ public: \
type_ * operator->() const {return mPtr;} \
\
class_ & operator =(type_ * p) \
{mPtr = p; return *this;} \
{NS_ASSERTION(mTLS, "Hasn't been init'ed!"); \
mPtr = p; return *this;} \
\
protected: \
type_ * mPtr; \
@ -4019,7 +4182,7 @@ public:
* @param pErr [out] relevant error code, if any.
* @param pJSVal [out] the resulting jsval.
*/
static JSBool VariantDataToJS(XPCCallContext& ccx,
static JSBool VariantDataToJS(XPCLazyCallContext& lccx,
nsIVariant* variant,
JSObject* scope, nsresult* pErr,
jsval* pJSVal);

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

@ -839,93 +839,42 @@ getNativeFromWrapper(XPCWrappedNative *wrapper,
JSBool
xpc_qsUnwrapThisImpl(JSContext *cx,
JSObject *obj,
JSObject *callee,
const nsIID &iid,
void **ppThis,
nsISupports **pThisRef,
jsval *vp)
jsval *vp,
XPCLazyCallContext *lccx)
{
// From XPCWrappedNative::GetWrappedNativeOfJSObject.
//
// Usually IS_WRAPPER_CLASS is true the first time through the while loop,
// and the QueryInterface then succeeds.
NS_ASSERTION(obj, "this == null");
JSObject *cur = obj;
while(cur)
XPCWrappedNativeTearOff *tearoff;
XPCWrappedNative *wrapper =
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj, callee, &cur,
&tearoff);
if(wrapper)
{
JSClass *clazz;
clazz = STOBJ_GET_CLASS(cur);
if(IS_SLIM_WRAPPER_CLASS(clazz))
{
nsISupports *native =
static_cast<nsISupports*>(xpc_GetJSPrivate(cur));
if(NS_SUCCEEDED(getNative(native, GetOffsetsFromSlimWrapper(cur),
cur, iid, ppThis, pThisRef, vp)))
return JS_TRUE;
*pThisRef = nsnull;
return xpc_qsThrow(cx, NS_ERROR_XPC_BAD_OP_ON_WN_PROTO);
}
XPCWrappedNative *wrapper;
nsresult rv;
if(IS_WRAPPER_CLASS(clazz))
{
wrapper = (XPCWrappedNative*) xpc_GetJSPrivate(cur);
NS_ASSERTION(wrapper, "XPCWN wrapping nothing");
}
else if(clazz == &XPC_WN_Tearoff_JSClass)
{
wrapper = (XPCWrappedNative*) xpc_GetJSPrivate(STOBJ_GET_PARENT(cur));
NS_ASSERTION(wrapper, "XPCWN wrapping nothing");
}
else
{
JSObject *unsafeObj = XPCWrapper::Unwrap(cx, cur);
if(unsafeObj)
{
cur = unsafeObj;
continue;
}
// This goto is a bug, dutifully copied from
// XPCWrappedNative::GetWrappedNativeOfJSObject.
goto next;
}
rv = getNativeFromWrapper(wrapper, iid, ppThis, pThisRef, vp);
nsresult rv = getNativeFromWrapper(wrapper, iid, ppThis, pThisRef, vp);
if(NS_SUCCEEDED(rv))
{
if(lccx)
lccx->SetWrapper(cur, wrapper, tearoff);
return JS_TRUE;
}
if(rv != NS_ERROR_NO_INTERFACE)
return xpc_qsThrow(cx, rv);
next:
cur = STOBJ_GET_PROTO(cur);
}
// If we didn't find a wrapper using the given obj, try again with obj's
// outer object, if it's got one.
JSClass *clazz = STOBJ_GET_CLASS(obj);
if((clazz->flags & JSCLASS_IS_EXTENDED) &&
((JSExtendedClass*)clazz)->outerObject)
else if(cur)
{
JSObject *outer = ((JSExtendedClass*)clazz)->outerObject(cx, obj);
// Protect against infinite recursion through XOWs.
JSObject *unsafeObj;
clazz = STOBJ_GET_CLASS(outer);
if(clazz == &sXPC_XOW_JSClass.base &&
(unsafeObj = XPCWrapper::Unwrap(cx, outer)))
nsISupports *native = static_cast<nsISupports*>(xpc_GetJSPrivate(cur));
if(NS_SUCCEEDED(getNative(native, GetOffsetsFromSlimWrapper(cur),
cur, iid, ppThis, pThisRef, vp)))
{
outer = unsafeObj;
}
if(lccx)
lccx->SetWrapper(cur, nsnull, nsnull);
if(outer && outer != obj)
return xpc_qsUnwrapThisImpl(cx, outer, iid, ppThis, pThisRef, vp);
return JS_TRUE;
}
}
*pThisRef = nsnull;
@ -1125,34 +1074,34 @@ xpc_qsStringToJsval(JSContext *cx, const nsAString &str, jsval *rval)
}
JSBool
xpc_qsXPCOMObjectToJsval(XPCCallContext &ccx, nsISupports *p,
nsWrapperCache *cache, XPCNativeInterface *iface,
jsval *rval)
xpc_qsXPCOMObjectToJsval(XPCLazyCallContext &lccx, nsISupports *p,
nsWrapperCache *cache, const nsIID *iid,
XPCNativeInterface **iface, jsval *rval)
{
// From the T_INTERFACE case in XPCConvert::NativeData2JS.
// This is one of the slowest things quick stubs do.
JSObject *scope = ccx.GetCurrentJSObject();
NS_ASSERTION(scope, "bad ccx");
JSContext *cx = lccx.GetJSContext();
if(!iface)
return xpc_qsThrow(ccx, NS_ERROR_XPC_BAD_CONVERT_NATIVE);
return xpc_qsThrow(cx, NS_ERROR_XPC_BAD_CONVERT_NATIVE);
// XXX The OBJ_IS_NOT_GLOBAL here is not really right. In
// fact, this code is depending on the fact that the
// global object will not have been collected, and
// therefore this NativeInterface2JSObject will not end up
// creating a new XPCNativeScriptableShared.
nsresult rv;
if(!XPCConvert::NativeInterface2JSObject(ccx, rval, nsnull, p, nsnull,
iface, cache, scope, PR_TRUE,
if(!XPCConvert::NativeInterface2JSObject(lccx, rval, nsnull, p,
iid, iface, cache,
lccx.GetCurrentJSObject(), PR_TRUE,
OBJ_IS_NOT_GLOBAL, &rv))
{
// I can't tell if NativeInterface2JSObject throws JS exceptions
// or not. This is a sloppy stab at the right semantics; the
// method really ought to be fixed to behave consistently.
if(!JS_IsExceptionPending(ccx))
xpc_qsThrow(ccx, NS_FAILED(rv) ? rv : NS_ERROR_UNEXPECTED);
if(!JS_IsExceptionPending(cx))
xpc_qsThrow(cx, NS_FAILED(rv) ? rv : NS_ERROR_UNEXPECTED);
return JS_FALSE;
}
@ -1167,9 +1116,8 @@ xpc_qsXPCOMObjectToJsval(XPCCallContext &ccx, nsISupports *p,
}
JSBool
xpc_qsVariantToJsval(XPCCallContext &ccx,
xpc_qsVariantToJsval(XPCLazyCallContext &lccx,
nsIVariant *p,
uintN paramNum,
jsval *rval)
{
// From the T_INTERFACE case in XPCConvert::NativeData2JS.
@ -1177,11 +1125,11 @@ xpc_qsVariantToJsval(XPCCallContext &ccx,
if(p)
{
nsresult rv;
JSBool ok = XPCVariant::VariantDataToJS(ccx, p,
ccx.GetCurrentJSObject(),
JSBool ok = XPCVariant::VariantDataToJS(lccx, p,
lccx.GetCurrentJSObject(),
&rv, rval);
if (!ok)
XPCThrower::ThrowBadParam(rv, 0, ccx);
xpc_qsThrow(lccx.GetJSContext(), rv);
return ok;
}
*rval = JSVAL_NULL;

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

@ -327,10 +327,12 @@ xpc_qsStringToJsval(JSContext *cx, const nsAString &str, jsval *rval);
JSBool
xpc_qsUnwrapThisImpl(JSContext *cx,
JSObject *obj,
JSObject *callee,
const nsIID &iid,
void **ppThis,
nsISupports **ppThisRef,
jsval *vp);
jsval *vp,
XPCLazyCallContext *lccx);
/**
* Search @a obj and its prototype chain for an XPCOM object that implements
@ -352,16 +354,20 @@ template <class T>
inline JSBool
xpc_qsUnwrapThis(JSContext *cx,
JSObject *obj,
JSObject *callee,
T **ppThis,
nsISupports **pThisRef,
jsval *pThisVal)
jsval *pThisVal,
XPCLazyCallContext *lccx)
{
return xpc_qsUnwrapThisImpl(cx,
obj,
callee,
NS_GET_TEMPLATE_IID(T),
reinterpret_cast<void **>(ppThis),
pThisRef,
pThisVal);
pThisVal,
lccx);
}
JSBool
@ -417,22 +423,19 @@ xpc_qsGetWrapperCache(void *p)
/** Convert an XPCOM pointer to jsval. Return JS_TRUE on success. */
JSBool
xpc_qsXPCOMObjectToJsval(XPCCallContext &ccx,
xpc_qsXPCOMObjectToJsval(XPCLazyCallContext &lccx,
nsISupports *p,
nsWrapperCache *cache,
XPCNativeInterface *iface,
const nsIID *iid,
XPCNativeInterface **iface,
jsval *rval);
/**
* Convert a variant to jsval. Return JS_TRUE on success.
*
* @a paramNum is used in error messages. XPConnect treats the return
* value as a parameter in this regard.
*/
JSBool
xpc_qsVariantToJsval(XPCCallContext &ccx,
xpc_qsVariantToJsval(XPCLazyCallContext &ccx,
nsIVariant *p,
uintN paramNum,
jsval *rval);
#ifdef DEBUG
@ -450,14 +453,4 @@ xpc_qsSameResult(nsISupports *result1, nsISupports *result2)
#define XPC_QS_ASSERT_CONTEXT_OK(cx) ((void) 0)
#endif
#define XPC_QS_DEFINE_XPCNATIVEINTERFACE_GETTER(_iface, _iface_cache) \
inline XPCNativeInterface* \
_iface##_Interface(XPCCallContext& ccx) \
{ \
if(!(_iface_cache)) \
(_iface_cache) = \
XPCNativeInterface::GetNewOrUsed(ccx, &NS_GET_IID(_iface)); \
return (_iface_cache); \
}
#endif /* xpcquickstubs_h___ */

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

@ -392,7 +392,7 @@ JSBool XPCVariant::InitializeData(XPCCallContext& ccx)
// static
JSBool
XPCVariant::VariantDataToJS(XPCCallContext& ccx,
XPCVariant::VariantDataToJS(XPCLazyCallContext& lccx,
nsIVariant* variant,
JSObject* scope, nsresult* pErr,
jsval* pJSVal)
@ -447,6 +447,7 @@ XPCVariant::VariantDataToJS(XPCCallContext& ccx,
xpctvar.flags = 0;
JSBool success;
JSContext* cx = lccx.GetJSContext();
switch(type)
{
case nsIDataType::VTYPE_INT8:
@ -463,7 +464,7 @@ XPCVariant::VariantDataToJS(XPCCallContext& ccx,
// Easy. Handle inline.
if(NS_FAILED(variant->GetAsDouble(&xpctvar.val.d)))
return JS_FALSE;
return JS_NewNumberValue(ccx, xpctvar.val.d, pJSVal);
return JS_NewNumberValue(cx, xpctvar.val.d, pJSVal);
}
case nsIDataType::VTYPE_BOOL:
{
@ -626,7 +627,7 @@ XPCVariant::VariantDataToJS(XPCCallContext& ccx,
}
success =
XPCConvert::NativeArray2JS(ccx, pJSVal,
XPCConvert::NativeArray2JS(lccx, pJSVal,
(const void**)&du.u.array.mArrayValue,
conversionType, pid,
du.u.array.mArrayCount,
@ -638,7 +639,7 @@ VARIANT_DONE:
}
case nsIDataType::VTYPE_EMPTY_ARRAY:
{
JSObject* array = JS_NewArrayObject(ccx, 0, nsnull);
JSObject* array = JS_NewArrayObject(cx, 0, nsnull);
if(!array)
return JS_FALSE;
*pJSVal = OBJECT_TO_JSVAL(array);
@ -660,14 +661,14 @@ VARIANT_DONE:
if(xpctvar.type.TagPart() == TD_PSTRING_SIZE_IS ||
xpctvar.type.TagPart() == TD_PWSTRING_SIZE_IS)
{
success = XPCConvert::NativeStringWithSize2JS(ccx, pJSVal,
success = XPCConvert::NativeStringWithSize2JS(cx, pJSVal,
(const void*)&xpctvar.val,
xpctvar.type,
size, pErr);
}
else
{
success = XPCConvert::NativeData2JS(ccx, pJSVal,
success = XPCConvert::NativeData2JS(lccx, pJSVal,
(const void*)&xpctvar.val,
xpctvar.type,
&iid, scope, pErr);

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

@ -1548,8 +1548,9 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
if(isArray)
{
if(!XPCConvert::NativeArray2JS(ccx, &val, (const void**)&pv->val,
XPCLazyCallContext lccx(ccx);
if(!XPCConvert::NativeArray2JS(lccx, &val,
(const void**)&pv->val,
datum_type, &param_iid,
array_count, obj, nsnull))
goto pre_call_clean_up;

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

@ -2769,7 +2769,8 @@ XPCWrappedNative::CallMethod(XPCCallContext& ccx,
if(isArray)
{
if(!XPCConvert::NativeArray2JS(ccx, &v, (const void**)&dp->val,
XPCLazyCallContext lccx(ccx);
if(!XPCConvert::NativeArray2JS(lccx, &v, (const void**)&dp->val,
datum_type, &param_iid,
array_count, ccx.GetCurrentJSObject(),
&err))
@ -3758,8 +3759,7 @@ static PRUint32 sSlimWrappers;
JSBool
ConstructSlimWrapper(XPCCallContext &ccx, nsISupports *p, nsWrapperCache *cache,
XPCNativeInterface *iface, XPCWrappedNativeScope* xpcScope,
jsval *rval)
XPCWrappedNativeScope* xpcScope, jsval *rval)
{
nsCOMPtr<nsISupports> identityObj = do_QueryInterface(p);

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

@ -280,12 +280,12 @@ XPCNativeInterface::GetNewOrUsed(XPCCallContext& ccx, const nsIID* iid)
if(!iface2)
{
NS_ERROR("failed to add our interface!");
DestroyInstance(ccx, rt, iface);
DestroyInstance(iface);
iface = nsnull;
}
else if(iface2 != iface)
{
DestroyInstance(ccx, rt, iface);
DestroyInstance(iface);
iface = iface2;
}
}
@ -327,12 +327,12 @@ XPCNativeInterface::GetNewOrUsed(XPCCallContext& ccx, nsIInterfaceInfo* info)
if(!iface2)
{
NS_ERROR("failed to add our interface!");
DestroyInstance(ccx, rt, iface);
DestroyInstance(iface);
iface = nsnull;
}
else if(iface2 != iface)
{
DestroyInstance(ccx, rt, iface);
DestroyInstance(iface);
iface = iface2;
}
}
@ -535,8 +535,7 @@ XPCNativeInterface::NewInstance(XPCCallContext& ccx,
// static
void
XPCNativeInterface::DestroyInstance(JSContext* cx, XPCJSRuntime* rt,
XPCNativeInterface* inst)
XPCNativeInterface::DestroyInstance(XPCNativeInterface* inst)
{
inst->~XPCNativeInterface();
delete [] (char*) inst;

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

@ -1131,6 +1131,10 @@ XPC_WN_Helper_NewResolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
if(!si->GetFlags().WantNewResolve())
return retval;
NS_ASSERTION(si->GetFlags().AllowPropModsToPrototype() &&
!si->GetFlags().AllowPropModsDuringResolve(),
"We don't support these flags for slim wrappers!");
rv = si->GetCallback()->NewResolve(nsnull, cx, obj, idval, flags,
&obj2FromScriptable, &retval);
if(NS_FAILED(rv))