Bug 863289 - GC: Continue the rooting of XPConnect r=bholley

This commit is contained in:
Jon Coppeard 2013-04-17 16:38:44 +01:00
Родитель 0211bf7319
Коммит 6b41db971f
10 изменённых файлов: 132 добавлений и 115 удалений

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

@ -29,6 +29,7 @@
using namespace xpc; using namespace xpc;
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
using namespace JS;
//#define STRICT_CHECK_OF_UNICODE //#define STRICT_CHECK_OF_UNICODE
#ifdef STRICT_CHECK_OF_UNICODE #ifdef STRICT_CHECK_OF_UNICODE
@ -169,7 +170,7 @@ XPCConvert::NativeData2JS(XPCLazyCallContext& lccx, jsval* d, const void* s,
nsID* iid2 = *((nsID**)s); nsID* iid2 = *((nsID**)s);
if (!iid2) if (!iid2)
break; break;
JS::RootedObject scope(cx, lccx.GetScopeForNewJSObjects()); RootedObject scope(cx, lccx.GetScopeForNewJSObjects());
JSObject* obj; JSObject* obj;
if (!(obj = xpc_NewIDObject(cx, scope, *iid2))) if (!(obj = xpc_NewIDObject(cx, scope, *iid2)))
return false; return false;
@ -369,7 +370,7 @@ bool ConvertToPrimitive(JSContext *cx, const JS::Value& v, T *retval)
// static // static
JSBool JSBool
XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s, XPCConvert::JSData2Native(JSContext* cx, void* d, HandleValue s,
const nsXPTType& type, const nsXPTType& type,
JSBool useAllocator, const nsID* iid, JSBool useAllocator, const nsID* iid,
nsresult* pErr) nsresult* pErr)
@ -754,8 +755,8 @@ XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
return false; return false;
} }
return JSObject2NativeInterface(cx, (void**)d, &s.toObject(), iid, RootedObject src(cx, &s.toObject());
nullptr, pErr); return JSObject2NativeInterface(cx, (void**)d, src, iid, nullptr, pErr);
} }
default: default:
NS_ERROR("bad type"); NS_ERROR("bad type");
@ -765,7 +766,7 @@ XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
} }
inline JSBool inline JSBool
CreateHolderIfNeeded(XPCCallContext& ccx, JSObject* obj, jsval* d, CreateHolderIfNeeded(XPCCallContext& ccx, HandleObject obj, jsval* d,
nsIXPConnectJSObjectHolder** dest) nsIXPConnectJSObjectHolder** dest)
{ {
if (dest) { if (dest) {
@ -830,7 +831,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
nsWrapperCache *cache = aHelper.GetWrapperCache(); nsWrapperCache *cache = aHelper.GetWrapperCache();
bool tryConstructSlimWrapper = false; bool tryConstructSlimWrapper = false;
JS::RootedObject flat(cx); RootedObject flat(cx);
if (cache) { if (cache) {
flat = cache->GetWrapper(); flat = cache->GetWrapper();
if (cache->IsDOMBinding()) { if (cache->IsDOMBinding()) {
@ -874,7 +875,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
if (!ccx.IsValid()) if (!ccx.IsValid())
return false; return false;
jsval slim; RootedValue slim(cx);
if (ConstructSlimWrapper(ccx, aHelper, xpcscope, &slim)) { if (ConstructSlimWrapper(ccx, aHelper, xpcscope, &slim)) {
*d = slim; *d = slim;
return true; return true;
@ -975,7 +976,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
// The call to wrap here handles both cross-compartment and same-compartment // The call to wrap here handles both cross-compartment and same-compartment
// security wrappers. // security wrappers.
JSObject *original = flat; RootedObject original(cx, flat);
if (!JS_WrapObject(ccx, flat.address())) if (!JS_WrapObject(ccx, flat.address()))
return false; return false;
@ -1006,7 +1007,7 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
// static // static
JSBool JSBool
XPCConvert::JSObject2NativeInterface(JSContext* cx, XPCConvert::JSObject2NativeInterface(JSContext* cx,
void** dest, JSObject* src, void** dest, HandleObject src,
const nsID* iid, const nsID* iid,
nsISupports* aOuter, nsISupports* aOuter,
nsresult* pErr) nsresult* pErr)
@ -1153,23 +1154,24 @@ public:
private: private:
JSContext * const mContext; JSContext * const mContext;
JS::AutoValueRooter tvr; AutoValueRooter tvr;
}; };
// static // static
nsresult nsresult
XPCConvert::JSValToXPCException(XPCCallContext& ccx, XPCConvert::JSValToXPCException(XPCCallContext& ccx,
jsval s, jsval sArg,
const char* ifaceName, const char* ifaceName,
const char* methodName, const char* methodName,
nsIException** exceptn) nsIException** exceptn)
{ {
JSContext* cx = ccx.GetJSContext(); JSContext* cx = ccx.GetJSContext();
RootedValue s(cx, sArg);
AutoExceptionRestorer aer(cx, s); AutoExceptionRestorer aer(cx, s);
if (!JSVAL_IS_PRIMITIVE(s)) { if (!JSVAL_IS_PRIMITIVE(s)) {
// we have a JSObject // we have a JSObject
JSObject* obj = JSVAL_TO_OBJECT(s); RootedObject obj(cx, JSVAL_TO_OBJECT(s));
if (!obj) { if (!obj) {
NS_ERROR("when is an object not an object?"); NS_ERROR("when is an object not an object?");
@ -1255,14 +1257,14 @@ XPCConvert::JSValToXPCException(XPCCallContext& ccx,
return ConstructException(NS_ERROR_XPC_JS_THREW_JS_OBJECT, return ConstructException(NS_ERROR_XPC_JS_THREW_JS_OBJECT,
strBytes.ptr(), ifaceName, methodName, strBytes.ptr(), ifaceName, methodName,
nullptr, exceptn, cx, &s); nullptr, exceptn, cx, s.address());
} }
} }
if (JSVAL_IS_VOID(s) || JSVAL_IS_NULL(s)) { if (JSVAL_IS_VOID(s) || JSVAL_IS_NULL(s)) {
return ConstructException(NS_ERROR_XPC_JS_THREW_NULL, return ConstructException(NS_ERROR_XPC_JS_THREW_NULL,
nullptr, ifaceName, methodName, nullptr, nullptr, ifaceName, methodName, nullptr,
exceptn, cx, &s); exceptn, cx, s.address());
} }
if (JSVAL_IS_NUMBER(s)) { if (JSVAL_IS_NUMBER(s)) {
@ -1293,7 +1295,7 @@ XPCConvert::JSValToXPCException(XPCCallContext& ccx,
if (isResult) if (isResult)
return ConstructException(rv, nullptr, ifaceName, methodName, return ConstructException(rv, nullptr, ifaceName, methodName,
nullptr, exceptn, cx, &s); nullptr, exceptn, cx, s.address());
else { else {
// XXX all this nsISupportsDouble code seems a little redundant // XXX all this nsISupportsDouble code seems a little redundant
// now that we're storing the jsval in the exception... // now that we're storing the jsval in the exception...
@ -1307,7 +1309,7 @@ XPCConvert::JSValToXPCException(XPCCallContext& ccx,
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
data->SetData(number); data->SetData(number);
rv = ConstructException(NS_ERROR_XPC_JS_THREW_NUMBER, nullptr, rv = ConstructException(NS_ERROR_XPC_JS_THREW_NUMBER, nullptr,
ifaceName, methodName, data, exceptn, cx, &s); ifaceName, methodName, data, exceptn, cx, s.address());
NS_RELEASE(data); NS_RELEASE(data);
return rv; return rv;
} }
@ -1322,7 +1324,7 @@ XPCConvert::JSValToXPCException(XPCCallContext& ccx,
if (!!strBytes) { if (!!strBytes) {
return ConstructException(NS_ERROR_XPC_JS_THREW_STRING, return ConstructException(NS_ERROR_XPC_JS_THREW_STRING,
strBytes.ptr(), ifaceName, methodName, strBytes.ptr(), ifaceName, methodName,
nullptr, exceptn, cx, &s); nullptr, exceptn, cx, s.address());
} }
} }
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -1660,7 +1662,7 @@ XPCConvert::JSArray2Native(JSContext* cx, void** d, JS::Value s,
return false; return false;
} }
JSObject* jsarray = &s.toObject(); RootedObject jsarray(cx, &s.toObject());
// If this is a typed array, then try a fast conversion with memcpy. // If this is a typed array, then try a fast conversion with memcpy.
if (JS_IsTypedArrayObject(jsarray)) { if (JS_IsTypedArrayObject(jsarray)) {
@ -1683,22 +1685,22 @@ XPCConvert::JSArray2Native(JSContext* cx, void** d, JS::Value s,
if (pErr) if (pErr)
*pErr = NS_ERROR_XPC_BAD_CONVERT_JS; *pErr = NS_ERROR_XPC_BAD_CONVERT_JS;
#define POPULATE(_mode, _t) \ #define POPULATE(_mode, _t) \
PR_BEGIN_MACRO \ PR_BEGIN_MACRO \
cleanupMode = _mode; \ cleanupMode = _mode; \
size_t max = UINT32_MAX / sizeof(_t); \ size_t max = UINT32_MAX / sizeof(_t); \
if (count > max || \ if (count > max || \
nullptr == (array = nsMemory::Alloc(count * sizeof(_t)))) { \ nullptr == (array = nsMemory::Alloc(count * sizeof(_t)))) { \
if (pErr) \ if (pErr) \
*pErr = NS_ERROR_OUT_OF_MEMORY; \ *pErr = NS_ERROR_OUT_OF_MEMORY; \
goto failure; \ goto failure; \
} \ } \
for (initedCount = 0; initedCount < count; initedCount++) { \ for (initedCount = 0; initedCount < count; initedCount++) { \
if (!JS_GetElement(cx, jsarray, initedCount, &current) || \ if (!JS_GetElement(cx, jsarray, initedCount, current.address()) || \
!JSData2Native(cx, ((_t*)array)+initedCount, current, type, \ !JSData2Native(cx, ((_t*)array)+initedCount, current, type, \
true, iid, pErr)) \ true, iid, pErr)) \
goto failure; \ goto failure; \
} \ } \
PR_END_MACRO PR_END_MACRO
// No Action, FRee memory, RElease object // No Action, FRee memory, RElease object
@ -1708,7 +1710,7 @@ XPCConvert::JSArray2Native(JSContext* cx, void** d, JS::Value s,
void *array = nullptr; void *array = nullptr;
uint32_t initedCount; uint32_t initedCount;
jsval current; RootedValue current(cx);
// XXX check IsPtr - esp. to handle array of nsID (as opposed to nsID*) // XXX check IsPtr - esp. to handle array of nsID (as opposed to nsID*)
// XXX make extra space at end of char* and wchar* and null termintate // XXX make extra space at end of char* and wchar* and null termintate

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

@ -14,6 +14,7 @@
#include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/BindingUtils.h"
using namespace mozilla; using namespace mozilla;
using namespace JS;
extern const char* xpc_qsStringTable; extern const char* xpc_qsStringTable;
@ -99,7 +100,7 @@ PointerHolderClass = {
}; };
JSBool JSBool
xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, unsigned flags, xpc_qsDefineQuickStubs(JSContext *cx, JSObject *protoArg, unsigned flags,
uint32_t ifacec, const nsIID **interfaces, uint32_t ifacec, const nsIID **interfaces,
uint32_t tableSize, const xpc_qsHashEntry *table, uint32_t tableSize, const xpc_qsHashEntry *table,
const xpc_qsPropertySpec *propspecs, const xpc_qsPropertySpec *propspecs,
@ -114,6 +115,7 @@ xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, unsigned flags,
* searching the interfaces forward. Here, definitions toward the * searching the interfaces forward. Here, definitions toward the
* front of 'interfaces' overwrite those toward the back. * front of 'interfaces' overwrite those toward the back.
*/ */
RootedObject proto(cx, protoArg);
for (uint32_t i = ifacec; i-- != 0;) { for (uint32_t i = ifacec; i-- != 0;) {
const nsID &iid = *interfaces[i]; const nsID &iid = *interfaces[i];
const xpc_qsHashEntry *entry = const xpc_qsHashEntry *entry =
@ -222,7 +224,7 @@ GetMethodInfo(JSContext *cx, jsval *vp, const char **ifaceNamep, jsid *memberIdp
static bool static bool
ThrowCallFailed(JSContext *cx, nsresult rv, ThrowCallFailed(JSContext *cx, nsresult rv,
const char *ifaceName, jsid memberId, const char *memberName) const char *ifaceName, HandleId memberId, const char *memberName)
{ {
/* Only one of memberId or memberName should be given. */ /* Only one of memberId or memberName should be given. */
MOZ_ASSERT(JSID_IS_VOID(memberId) != !memberName); MOZ_ASSERT(JSID_IS_VOID(memberId) != !memberName);
@ -273,17 +275,19 @@ ThrowCallFailed(JSContext *cx, nsresult rv,
JSBool JSBool
xpc_qsThrowGetterSetterFailed(JSContext *cx, nsresult rv, JSObject *obj, xpc_qsThrowGetterSetterFailed(JSContext *cx, nsresult rv, JSObject *obj,
jsid memberId) jsid memberIdArg)
{ {
RootedId memberId(cx, memberIdArg);
const char *ifaceName; const char *ifaceName;
GetMemberInfo(obj, memberId, &ifaceName); GetMemberInfo(obj, memberId, &ifaceName);
return ThrowCallFailed(cx, rv, ifaceName, memberId, NULL); return ThrowCallFailed(cx, rv, ifaceName, memberId, NULL);
} }
JSBool JSBool
xpc_qsThrowGetterSetterFailed(JSContext *cx, nsresult rv, JSObject *obj, xpc_qsThrowGetterSetterFailed(JSContext *cx, nsresult rv, JSObject *objArg,
const char* memberName) const char* memberName)
{ {
RootedObject obj(cx, objArg);
JSString *str = JS_InternString(cx, memberName); JSString *str = JS_InternString(cx, memberName);
if (!str) { if (!str) {
return false; return false;
@ -304,8 +308,8 @@ JSBool
xpc_qsThrowMethodFailed(JSContext *cx, nsresult rv, jsval *vp) xpc_qsThrowMethodFailed(JSContext *cx, nsresult rv, jsval *vp)
{ {
const char *ifaceName; const char *ifaceName;
jsid memberId; RootedId memberId(cx);
GetMethodInfo(cx, vp, &ifaceName, &memberId); GetMethodInfo(cx, vp, &ifaceName, memberId.address());
return ThrowCallFailed(cx, rv, ifaceName, memberId, NULL); return ThrowCallFailed(cx, rv, ifaceName, memberId, NULL);
} }
@ -321,7 +325,7 @@ xpc_qsThrowMethodFailedWithDetails(JSContext *cx, nsresult rv,
const char *ifaceName, const char *ifaceName,
const char *memberName) const char *memberName)
{ {
return ThrowCallFailed(cx, rv, ifaceName, JSID_VOID, memberName); return ThrowCallFailed(cx, rv, ifaceName, JSID_VOIDHANDLE, memberName);
} }
static void static void
@ -386,8 +390,9 @@ xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv,
void void
xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv, xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv,
JSObject *obj, const char* propName) JSObject *objArg, const char* propName)
{ {
RootedObject obj(cx, objArg);
JSString *str = JS_InternString(cx, propName); JSString *str = JS_InternString(cx, propName);
if (!str) { if (!str) {
return; return;
@ -494,7 +499,7 @@ xpc_qsAUTF8String::xpc_qsAUTF8String(JSContext *cx, jsval v, jsval *pval)
static nsresult static nsresult
getNative(nsISupports *idobj, getNative(nsISupports *idobj,
QITableEntry* entries, QITableEntry* entries,
JSObject *obj, HandleObject obj,
const nsIID &iid, const nsIID &iid,
void **ppThis, void **ppThis,
nsISupports **pThisRef, nsISupports **pThisRef,
@ -527,8 +532,9 @@ getNativeFromWrapper(JSContext *cx,
nsISupports **pThisRef, nsISupports **pThisRef,
jsval *vp) jsval *vp)
{ {
RootedObject obj(cx, wrapper->GetFlatJSObject());
return getNative(wrapper->GetIdentityObject(), wrapper->GetOffsets(), return getNative(wrapper->GetIdentityObject(), wrapper->GetOffsets(),
wrapper->GetFlatJSObject(), iid, ppThis, pThisRef, vp); obj, iid, ppThis, pThisRef, vp);
} }
@ -595,7 +601,7 @@ getWrapper(JSContext *cx,
nsresult nsresult
castNative(JSContext *cx, castNative(JSContext *cx,
XPCWrappedNative *wrapper, XPCWrappedNative *wrapper,
JSObject *cur, JSObject *curArg,
XPCWrappedNativeTearOff *tearoff, XPCWrappedNativeTearOff *tearoff,
const nsIID &iid, const nsIID &iid,
void **ppThis, void **ppThis,
@ -603,6 +609,7 @@ castNative(JSContext *cx,
jsval *vp, jsval *vp,
XPCLazyCallContext *lccx) XPCLazyCallContext *lccx)
{ {
RootedObject cur(cx, curArg);
if (wrapper) { if (wrapper) {
nsresult rv = getNativeFromWrapper(cx,wrapper, iid, ppThis, pThisRef, nsresult rv = getNativeFromWrapper(cx,wrapper, iid, ppThis, pThisRef,
vp); vp);
@ -653,9 +660,9 @@ xpc_qsUnwrapThisFromCcxImpl(XPCCallContext &ccx,
if (!native) if (!native)
return xpc_qsThrow(ccx.GetJSContext(), NS_ERROR_XPC_HAS_BEEN_SHUTDOWN); return xpc_qsThrow(ccx.GetJSContext(), NS_ERROR_XPC_HAS_BEEN_SHUTDOWN);
RootedObject obj(ccx, ccx.GetFlattenedJSObject());
nsresult rv = getNative(native, GetOffsets(native, ccx.GetProto()), nsresult rv = getNative(native, GetOffsets(native, ccx.GetProto()),
ccx.GetFlattenedJSObject(), iid, ppThis, pThisRef, obj, iid, ppThis, pThisRef, vp);
vp);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return xpc_qsThrow(ccx.GetJSContext(), rv); return xpc_qsThrow(ccx.GetJSContext(), rv);
return true; return true;
@ -670,7 +677,7 @@ xpc_qsUnwrapArgImpl(JSContext *cx,
jsval *vp) jsval *vp)
{ {
nsresult rv; nsresult rv;
JSObject *src = xpc_qsUnwrapObj(v, ppArgRef, &rv); RootedObject src(cx, xpc_qsUnwrapObj(v, ppArgRef, &rv));
if (!src) { if (!src) {
*ppArg = nullptr; *ppArg = nullptr;

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

@ -11,6 +11,8 @@
#include "jsfriendapi.h" #include "jsfriendapi.h"
using namespace JS;
NS_IMPL_CLASSINFO(XPCVariant, NULL, 0, XPCVARIANT_CID) NS_IMPL_CLASSINFO(XPCVariant, NULL, 0, XPCVARIANT_CID)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPCVariant) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPCVariant)
NS_INTERFACE_MAP_ENTRY(XPCVariant) NS_INTERFACE_MAP_ENTRY(XPCVariant)
@ -149,7 +151,7 @@ private:
static const Type StateTable[tTypeCount][tTypeCount-1]; static const Type StateTable[tTypeCount][tTypeCount-1];
public: public:
static JSBool GetTypeForArray(JSContext* cx, JSObject* array, static JSBool GetTypeForArray(JSContext* cx, HandleObject array,
uint32_t length, uint32_t length,
nsXPTType* resultType, nsID* resultID); nsXPTType* resultType, nsID* resultID);
}; };
@ -174,16 +176,17 @@ XPCArrayHomogenizer::StateTable[tTypeCount][tTypeCount-1] = {
// static // static
JSBool JSBool
XPCArrayHomogenizer::GetTypeForArray(JSContext* cx, JSObject* array, XPCArrayHomogenizer::GetTypeForArray(JSContext* cx, HandleObject array,
uint32_t length, uint32_t length,
nsXPTType* resultType, nsID* resultID) nsXPTType* resultType, nsID* resultID)
{ {
Type state = tUnk; Type state = tUnk;
Type type; Type type;
RootedValue val(cx);
RootedObject jsobj(cx);
for (uint32_t i = 0; i < length; i++) { for (uint32_t i = 0; i < length; i++) {
JS::Value val; if (!JS_GetElement(cx, array, i, val.address()))
if (!JS_GetElement(cx, array, i, &val))
return false; return false;
if (val.isInt32()) { if (val.isInt32()) {
@ -192,7 +195,7 @@ XPCArrayHomogenizer::GetTypeForArray(JSContext* cx, JSObject* array,
type = tDbl; type = tDbl;
} else if (val.isBoolean()) { } else if (val.isBoolean()) {
type = tBool; type = tBool;
} else if (val.isUndefined()) { } else if (val.isUndefined()) {
state = tVar; state = tVar;
break; break;
} else if (val.isNull()) { } else if (val.isNull()) {
@ -201,7 +204,7 @@ XPCArrayHomogenizer::GetTypeForArray(JSContext* cx, JSObject* array,
type = tStr; type = tStr;
} else { } else {
NS_ASSERTION(val.isObject(), "invalid type of jsval!"); NS_ASSERTION(val.isObject(), "invalid type of jsval!");
JSObject* jsobj = &val.toObject(); jsobj = &val.toObject();
if (JS_IsArrayObject(cx, jsobj)) if (JS_IsArrayObject(cx, jsobj))
type = tArr; type = tArr;
else if (xpc_JSObjectIsID(cx, jsobj)) else if (xpc_JSObjectIsID(cx, jsobj))
@ -267,7 +270,7 @@ JSBool XPCVariant::InitializeData(JSContext* cx)
{ {
JS_CHECK_RECURSION(cx, return false); JS_CHECK_RECURSION(cx, return false);
JS::Value val = GetJSVal(); RootedValue val(cx, GetJSVal());
if (val.isInt32()) if (val.isInt32())
return NS_SUCCEEDED(nsVariant::SetFromInt32(&mData, val.toInt32())); return NS_SUCCEEDED(nsVariant::SetFromInt32(&mData, val.toInt32()));
@ -309,7 +312,7 @@ JSBool XPCVariant::InitializeData(JSContext* cx)
// leaving only JSObject... // leaving only JSObject...
NS_ASSERTION(val.isObject(), "invalid type of jsval!"); NS_ASSERTION(val.isObject(), "invalid type of jsval!");
JSObject* jsobj = &val.toObject(); RootedObject jsobj(cx, &val.toObject());
// Let's see if it is a xpcJSID. // Let's see if it is a xpcJSID.
@ -378,16 +381,16 @@ XPCVariant::VariantDataToJS(XPCLazyCallContext& lccx,
if (NS_FAILED(variant->GetDataType(&type))) if (NS_FAILED(variant->GetDataType(&type)))
return false; return false;
jsval realVal; JSContext *cx = lccx.GetJSContext();
nsresult rv = variant->GetAsJSVal(&realVal); RootedValue realVal(cx);
nsresult rv = variant->GetAsJSVal(realVal.address());
if (NS_SUCCEEDED(rv) && if (NS_SUCCEEDED(rv) &&
(JSVAL_IS_PRIMITIVE(realVal) || (JSVAL_IS_PRIMITIVE(realVal) ||
type == nsIDataType::VTYPE_ARRAY || type == nsIDataType::VTYPE_ARRAY ||
type == nsIDataType::VTYPE_EMPTY_ARRAY || type == nsIDataType::VTYPE_EMPTY_ARRAY ||
type == nsIDataType::VTYPE_ID)) { type == nsIDataType::VTYPE_ID)) {
JSContext *cx = lccx.GetJSContext(); if (!JS_WrapValue(cx, realVal.address()))
if (!JS_WrapValue(cx, &realVal))
return false; return false;
*pJSVal = realVal; *pJSVal = realVal;
return true; return true;
@ -399,8 +402,7 @@ XPCVariant::VariantDataToJS(XPCLazyCallContext& lccx,
type == nsIDataType::VTYPE_INTERFACE_IS, type == nsIDataType::VTYPE_INTERFACE_IS,
"Weird variant"); "Weird variant");
JSContext *cx = lccx.GetJSContext(); if (!JS_WrapValue(cx, realVal.address()))
if (!JS_WrapValue(cx, &realVal))
return false; return false;
*pJSVal = realVal; *pJSVal = realVal;
return true; return true;
@ -425,7 +427,6 @@ XPCVariant::VariantDataToJS(XPCLazyCallContext& lccx,
xpctvar.flags = 0; xpctvar.flags = 0;
JSBool success; JSBool success;
JSContext* cx = lccx.GetJSContext();
NS_ABORT_IF_FALSE(js::IsObjectInContextCompartment(lccx.GetScopeForNewJSObjects(), cx), NS_ABORT_IF_FALSE(js::IsObjectInContextCompartment(lccx.GetScopeForNewJSObjects(), cx),
"bad scope for new JSObjects"); "bad scope for new JSObjects");

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

@ -406,8 +406,8 @@ nsXPCWrappedJSClass::BuildPropertyEnumerator(XPCCallContext& ccx,
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
jsval jsvalName; RootedValue jsvalName(cx);
if (!JS_IdToValue(cx, idName, &jsvalName)) if (!JS_IdToValue(cx, idName, jsvalName.address()))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
JSString* name = JS_ValueToString(cx, jsvalName); JSString* name = JS_ValueToString(cx, jsvalName);

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

@ -3616,7 +3616,7 @@ static uint32_t sSlimWrappers;
JSBool JSBool
ConstructSlimWrapper(XPCCallContext &ccx, ConstructSlimWrapper(XPCCallContext &ccx,
xpcObjectHelper &aHelper, xpcObjectHelper &aHelper,
XPCWrappedNativeScope* xpcScope, jsval *rval) XPCWrappedNativeScope* xpcScope, MutableHandleValue rval)
{ {
nsISupports *identityObj = aHelper.GetCanonical(); nsISupports *identityObj = aHelper.GetCanonical();
nsXPCClassInfo *classInfoHelper = aHelper.GetXPCClassInfo(); nsXPCClassInfo *classInfoHelper = aHelper.GetXPCClassInfo();
@ -3672,7 +3672,7 @@ ConstructSlimWrapper(XPCCallContext &ccx,
nsWrapperCache *cache = aHelper.GetWrapperCache(); nsWrapperCache *cache = aHelper.GetWrapperCache();
JSObject* wrapper = cache->GetWrapper(); JSObject* wrapper = cache->GetWrapper();
if (wrapper) { if (wrapper) {
*rval = OBJECT_TO_JSVAL(wrapper); rval.setObject(*wrapper);
return true; return true;
} }
@ -3709,7 +3709,7 @@ ConstructSlimWrapper(XPCCallContext &ccx,
SLIM_LOG(("+++++ %i created slim wrapper (%p, %p, %p)\n", ++sSlimWrappers, SLIM_LOG(("+++++ %i created slim wrapper (%p, %p, %p)\n", ++sSlimWrappers,
wrapper, p, xpcScope)); wrapper, p, xpcScope));
*rval = OBJECT_TO_JSVAL(wrapper); rval.setObject(*wrapper);
return true; return true;
} }

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

@ -2421,13 +2421,13 @@ const uint8_t HAS_ORIGIN_PRINCIPALS_FLAG = 2;
static nsresult static nsresult
WriteScriptOrFunction(nsIObjectOutputStream *stream, JSContext *cx, WriteScriptOrFunction(nsIObjectOutputStream *stream, JSContext *cx,
JSScript *script, HandleObject functionObj) JSScript *scriptArg, HandleObject functionObj)
{ {
// Exactly one of script or functionObj must be given // Exactly one of script or functionObj must be given
MOZ_ASSERT(!script != !functionObj); MOZ_ASSERT(!scriptArg != !functionObj);
if (!script) RootedScript script(cx, scriptArg ? scriptArg :
script = JS_GetFunctionScript(cx, JS_GetObjectFunction(functionObj)); JS_GetFunctionScript(cx, JS_GetObjectFunction(functionObj)));
nsIPrincipal *principal = nsIPrincipal *principal =
nsJSPrincipals::get(JS_GetScriptPrincipals(script)); nsJSPrincipals::get(JS_GetScriptPrincipals(script));

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

@ -2516,7 +2516,7 @@ class xpcObjectHelper;
extern JSBool ConstructSlimWrapper(XPCCallContext &ccx, extern JSBool ConstructSlimWrapper(XPCCallContext &ccx,
xpcObjectHelper &aHelper, xpcObjectHelper &aHelper,
XPCWrappedNativeScope* xpcScope, XPCWrappedNativeScope* xpcScope,
jsval *rval); JS::MutableHandleValue rval);
extern JSBool MorphSlimWrapper(JSContext *cx, JS::HandleObject obj); extern JSBool MorphSlimWrapper(JSContext *cx, JS::HandleObject obj);
/***********************************************/ /***********************************************/
@ -3301,7 +3301,7 @@ public:
const void* s, const nsXPTType& type, const void* s, const nsXPTType& type,
const nsID* iid, nsresult* pErr); const nsID* iid, nsresult* pErr);
static JSBool JSData2Native(JSContext* cx, void* d, jsval s, static JSBool JSData2Native(JSContext* cx, void* d, JS::HandleValue s,
const nsXPTType& type, const nsXPTType& type,
JSBool useAllocator, const nsID* iid, JSBool useAllocator, const nsID* iid,
nsresult* pErr); nsresult* pErr);
@ -3349,7 +3349,7 @@ public:
const nsID* iid, const nsID* iid,
nsresult* pErr); nsresult* pErr);
static JSBool JSObject2NativeInterface(JSContext* cx, static JSBool JSObject2NativeInterface(JSContext* cx,
void** dest, JSObject* src, void** dest, JS::HandleObject src,
const nsID* iid, const nsID* iid,
nsISupports* aOuter, nsISupports* aOuter,
nsresult* pErr); nsresult* pErr);

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

@ -166,8 +166,11 @@ IsPermitted(const char *name, JSFlatString *prop, bool set)
#undef W #undef W
static bool static bool
IsFrameId(JSContext *cx, JSObject *obj, jsid id) IsFrameId(JSContext *cx, JSObject *objArg, jsid idArg)
{ {
RootedObject obj(cx, objArg);
RootedId id(cx, idArg);
obj = JS_ObjectToInnerObject(cx, obj); obj = JS_ObjectToInnerObject(cx, obj);
MOZ_ASSERT(!js::IsWrapper(obj)); MOZ_ASSERT(!js::IsWrapper(obj));
XPCWrappedNative *wn = IS_WN_WRAPPER(obj) ? XPCWrappedNative::Get(obj) XPCWrappedNative *wn = IS_WN_WRAPPER(obj) ? XPCWrappedNative::Get(obj)
@ -279,14 +282,16 @@ EnterAndThrow(JSContext *cx, JSObject *wrapper, const char *msg)
} }
bool bool
ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper::Action act) ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapperArg, jsid idArg, Wrapper::Action act)
{ {
JSObject *wrappedObject = Wrapper::wrappedObject(wrapper); RootedObject wrapper(cx, wrapperArg);
RootedId id(cx, idArg);
RootedObject wrappedObject(cx, Wrapper::wrappedObject(wrapper));
if (act == Wrapper::CALL) if (act == Wrapper::CALL)
return true; return true;
jsid exposedPropsId = GetRTIdByIndex(cx, XPCJSRuntime::IDX_EXPOSEDPROPS); RootedId exposedPropsId(cx, GetRTIdByIndex(cx, XPCJSRuntime::IDX_EXPOSEDPROPS));
// We need to enter the wrappee's compartment to look at __exposedProps__, // We need to enter the wrappee's compartment to look at __exposedProps__,
// but we want to be in the wrapper's compartment if we call Deny(). // but we want to be in the wrapper's compartment if we call Deny().
@ -314,8 +319,8 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper:
if (id == JSID_VOID) if (id == JSID_VOID)
return true; return true;
JS::Value exposedProps; RootedValue exposedProps(cx);
if (!JS_LookupPropertyById(cx, wrappedObject, exposedPropsId, &exposedProps)) if (!JS_LookupPropertyById(cx, wrappedObject, exposedPropsId, exposedProps.address()))
return false; return false;
if (exposedProps.isNullOrUndefined()) if (exposedProps.isNullOrUndefined())
@ -398,8 +403,10 @@ ExposedPropertiesOnly::allowNativeCall(JSContext *cx, JS::IsAcceptableThis test,
} }
bool bool
ComponentsObjectPolicy::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper::Action act) ComponentsObjectPolicy::check(JSContext *cx, JSObject *wrapperArg, jsid idArg, Wrapper::Action act)
{ {
RootedObject wrapper(cx, wrapperArg);
RootedId id(cx, idArg);
JSAutoCompartment ac(cx, wrapper); JSAutoCompartment ac(cx, wrapper);
if (JSID_IS_STRING(id) && act == Wrapper::GET) { if (JSID_IS_STRING(id) && act == Wrapper::GET) {

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

@ -1,5 +1,7 @@
#include "ChromeObjectWrapper.h" #include "ChromeObjectWrapper.h"
using namespace JS;
namespace xpc { namespace xpc {
// When creating wrappers for chrome objects in content, we detect if the // When creating wrappers for chrome objects in content, we detect if the
@ -17,7 +19,7 @@ ChromeObjectWrapper ChromeObjectWrapper::singleton;
using js::assertEnteredPolicy; using js::assertEnteredPolicy;
static bool static bool
AllowedByBase(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, AllowedByBase(JSContext *cx, HandleObject wrapper, HandleId id,
js::Wrapper::Action act) js::Wrapper::Action act)
{ {
MOZ_ASSERT(js::Wrapper::wrapperHandler(wrapper) == MOZ_ASSERT(js::Wrapper::wrapperHandler(wrapper) ==
@ -31,7 +33,7 @@ static bool
PropIsFromStandardPrototype(JSContext *cx, JSPropertyDescriptor *desc) PropIsFromStandardPrototype(JSContext *cx, JSPropertyDescriptor *desc)
{ {
MOZ_ASSERT(desc->obj); MOZ_ASSERT(desc->obj);
JSObject *unwrapped = js::UncheckedUnwrap(desc->obj); RootedObject unwrapped(cx, js::UncheckedUnwrap(desc->obj));
JSAutoCompartment ac(cx, unwrapped); JSAutoCompartment ac(cx, unwrapped);
return JS_IdentifyClassPrototype(cx, unwrapped) != JSProto_Null; return JS_IdentifyClassPrototype(cx, unwrapped) != JSProto_Null;
} }
@ -41,26 +43,26 @@ PropIsFromStandardPrototype(JSContext *cx, JSPropertyDescriptor *desc)
// This lets us determine whether the property we would have found (given a // This lets us determine whether the property we would have found (given a
// transparent wrapper) would have come off a standard prototype. // transparent wrapper) would have come off a standard prototype.
static bool static bool
PropIsFromStandardPrototype(JSContext *cx, JS::Handle<JSObject*> wrapper, PropIsFromStandardPrototype(JSContext *cx, HandleObject wrapper,
JS::Handle<jsid> id) HandleId id)
{ {
MOZ_ASSERT(js::Wrapper::wrapperHandler(wrapper) == MOZ_ASSERT(js::Wrapper::wrapperHandler(wrapper) ==
&ChromeObjectWrapper::singleton); &ChromeObjectWrapper::singleton);
JSPropertyDescriptor desc; Rooted<JSPropertyDescriptor> desc(cx);
ChromeObjectWrapper *handler = &ChromeObjectWrapper::singleton; ChromeObjectWrapper *handler = &ChromeObjectWrapper::singleton;
if (!handler->ChromeObjectWrapperBase::getPropertyDescriptor(cx, wrapper, id, if (!handler->ChromeObjectWrapperBase::getPropertyDescriptor(cx, wrapper, id,
&desc, 0) || desc.address(), 0) ||
!desc.obj) !desc.object())
{ {
return false; return false;
} }
return PropIsFromStandardPrototype(cx, &desc); return PropIsFromStandardPrototype(cx, desc.address());
} }
bool bool
ChromeObjectWrapper::getPropertyDescriptor(JSContext *cx, ChromeObjectWrapper::getPropertyDescriptor(JSContext *cx,
JS::Handle<JSObject*> wrapper, HandleObject wrapper,
JS::Handle<jsid> id, HandleId id,
js::PropertyDescriptor *desc, js::PropertyDescriptor *desc,
unsigned flags) unsigned flags)
{ {
@ -80,8 +82,8 @@ ChromeObjectWrapper::getPropertyDescriptor(JSContext *cx,
desc->obj = NULL; desc->obj = NULL;
// If we found something or have no proto, we're done. // If we found something or have no proto, we're done.
JSObject *wrapperProto; RootedObject wrapperProto(cx);
if (!JS_GetPrototype(cx, wrapper, &wrapperProto)) if (!JS_GetPrototype(cx, wrapper, wrapperProto.address()))
return false; return false;
if (desc->obj || !wrapperProto) if (desc->obj || !wrapperProto)
return true; return true;
@ -92,8 +94,8 @@ ChromeObjectWrapper::getPropertyDescriptor(JSContext *cx,
} }
bool bool
ChromeObjectWrapper::has(JSContext *cx, JS::Handle<JSObject*> wrapper, ChromeObjectWrapper::has(JSContext *cx, HandleObject wrapper,
JS::Handle<jsid> id, bool *bp) HandleId id, bool *bp)
{ {
assertEnteredPolicy(cx, wrapper, id); assertEnteredPolicy(cx, wrapper, id);
// Try the lookup on the base wrapper if permitted. // Try the lookup on the base wrapper if permitted.
@ -104,25 +106,25 @@ ChromeObjectWrapper::has(JSContext *cx, JS::Handle<JSObject*> wrapper,
} }
// If we found something or have no prototype, we're done. // If we found something or have no prototype, we're done.
JSObject *wrapperProto; RootedObject wrapperProto(cx);
if (!JS_GetPrototype(cx, wrapper, &wrapperProto)) if (!JS_GetPrototype(cx, wrapper, wrapperProto.address()))
return false; return false;
if (*bp || !wrapperProto) if (*bp || !wrapperProto)
return true; return true;
// Try the prototype if that failed. // Try the prototype if that failed.
MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx));
JSPropertyDescriptor desc; Rooted<JSPropertyDescriptor> desc(cx);
if (!JS_GetPropertyDescriptorById(cx, wrapperProto, id, 0, &desc)) if (!JS_GetPropertyDescriptorById(cx, wrapperProto, id, 0, desc.address()))
return false; return false;
*bp = !!desc.obj; *bp = !!desc.object();
return true; return true;
} }
bool bool
ChromeObjectWrapper::get(JSContext *cx, JS::Handle<JSObject*> wrapper, ChromeObjectWrapper::get(JSContext *cx, HandleObject wrapper,
JS::Handle<JSObject*> receiver, JS::Handle<jsid> id, HandleObject receiver, HandleId id,
JS::MutableHandle<JS::Value> vp) MutableHandleValue vp)
{ {
assertEnteredPolicy(cx, wrapper, id); assertEnteredPolicy(cx, wrapper, id);
vp.setUndefined(); vp.setUndefined();
@ -142,8 +144,8 @@ ChromeObjectWrapper::get(JSContext *cx, JS::Handle<JSObject*> wrapper,
} }
// If we have no proto, we're done. // If we have no proto, we're done.
JSObject *wrapperProto; RootedObject wrapperProto(cx);
if (!JS_GetPrototype(cx, wrapper, &wrapperProto)) if (!JS_GetPrototype(cx, wrapper, wrapperProto.address()))
return false; return false;
if (!wrapperProto) if (!wrapperProto)
return true; return true;
@ -157,7 +159,7 @@ ChromeObjectWrapper::get(JSContext *cx, JS::Handle<JSObject*> wrapper,
// contacts API depends on Array.isArray returning true for COW-implemented // contacts API depends on Array.isArray returning true for COW-implemented
// contacts. This isn't really ideal, but make it work for now. // contacts. This isn't really ideal, but make it work for now.
bool bool
ChromeObjectWrapper::objectClassIs(JS::Handle<JSObject*> obj, js::ESClassValue classValue, ChromeObjectWrapper::objectClassIs(HandleObject obj, js::ESClassValue classValue,
JSContext *cx) JSContext *cx)
{ {
return CrossCompartmentWrapper::objectClassIs(obj, classValue, cx); return CrossCompartmentWrapper::objectClassIs(obj, classValue, cx);
@ -168,8 +170,8 @@ ChromeObjectWrapper::objectClassIs(JS::Handle<JSObject*> obj, js::ESClassValue c
// enforcement or COWs isn't cheap. But it results in the cleanest code, and this // enforcement or COWs isn't cheap. But it results in the cleanest code, and this
// whole proto remapping thing for COWs is going to be phased out anyway. // whole proto remapping thing for COWs is going to be phased out anyway.
bool bool
ChromeObjectWrapper::enter(JSContext *cx, JS::Handle<JSObject*> wrapper, ChromeObjectWrapper::enter(JSContext *cx, HandleObject wrapper,
JS::Handle<jsid> id, js::Wrapper::Action act, bool *bp) HandleId id, js::Wrapper::Action act, bool *bp)
{ {
if (AllowedByBase(cx, wrapper, id, act)) if (AllowedByBase(cx, wrapper, id, act))
return true; return true;
@ -181,9 +183,7 @@ ChromeObjectWrapper::enter(JSContext *cx, JS::Handle<JSObject*> wrapper,
// Note that PropIsFromStandardPrototype needs to invoke getPropertyDescriptor // Note that PropIsFromStandardPrototype needs to invoke getPropertyDescriptor
// before we've fully entered the policy. Waive our policy. // before we've fully entered the policy. Waive our policy.
JS::RootedObject rootedWrapper(cx, wrapper); js::AutoWaivePolicy policy(cx, wrapper, id);
JS::RootedId rootedId(cx, id);
js::AutoWaivePolicy policy(cx, rootedWrapper, rootedId);
return PropIsFromStandardPrototype(cx, wrapper, id); return PropIsFromStandardPrototype(cx, wrapper, id);
} }

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

@ -69,15 +69,15 @@ WrapperFactory::CreateXrayWaiver(JSContext *cx, HandleObject obj)
XPCWrappedNativeScope *scope = GetObjectScope(obj); XPCWrappedNativeScope *scope = GetObjectScope(obj);
// Get a waiver for the proto. // Get a waiver for the proto.
JSObject *proto; RootedObject proto(cx);
if (!js::GetObjectProto(cx, obj, &proto)) if (!js::GetObjectProto(cx, obj, proto.address()))
return nullptr; return nullptr;
if (proto && !(proto = WaiveXray(cx, proto))) if (proto && !(proto = WaiveXray(cx, proto)))
return nullptr; return nullptr;
// Create the waiver. // Create the waiver.
JSAutoCompartment ac(cx, obj); JSAutoCompartment ac(cx, obj);
if (!JS_WrapObject(cx, &proto)) if (!JS_WrapObject(cx, proto.address()))
return nullptr; return nullptr;
JSObject *waiver = Wrapper::New(cx, obj, proto, JSObject *waiver = Wrapper::New(cx, obj, proto,
JS_GetGlobalForObject(cx, obj), JS_GetGlobalForObject(cx, obj),