Bug 877281 part 6. Replace ${jsvalPtr} with a MutableHandle ${jsvalHandle}. r=peterv

It's a little unfortunate that we need both ${jsvalHandle} and
${jsvalRef}, but the only other option is to consistently have a
MutableHandle in this code.  If the thing we have to work with is a
Rooted, that means doing JS::MutableHandle<JS::Value>(&myRooted) as
the thing to substitute for ${jsvalHandle}.  Just using "&myRooted"
doesn't work, because things like "&myRooted.set()" or
"&myRooted.address()" fail, even if parenthesized as
"(&myRooted).set()", because &myRooted is actually a Rooted*, not a
MutableHandle.

We could go the JS::MutableHandle<JS::Value>(&myRooted) route if
desired; it would primarily uglify dictionary and sequence to-js
conversions.  With the setup in this patch, ideally it looks pretty
idiomatic except for the use of .set() instead of operator= on Rooted.
This commit is contained in:
Boris Zbarsky 2013-06-07 22:45:46 -04:00
Родитель 24d0bddba5
Коммит 7a3587f2d2
14 изменённых файлов: 143 добавлений и 119 удалений

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

@ -676,7 +676,7 @@ nsContentList::NamedItem(JSContext* cx, const nsAString& name,
JS::Rooted<JSObject*> wrapper(cx, GetWrapper());
JSAutoCompartment ac(cx, wrapper);
JS::Rooted<JS::Value> v(cx);
if (!mozilla::dom::WrapObject(cx, wrapper, item, item, nullptr, v.address())) {
if (!mozilla::dom::WrapObject(cx, wrapper, item, item, nullptr, &v)) {
error.Throw(NS_ERROR_FAILURE);
return nullptr;
}

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

@ -1303,7 +1303,7 @@ WrapStyle(JSContext* cx, JSObject* objArg,
case CanvasRenderingContext2D::CMG_STYLE_GRADIENT:
{
JS::Rooted<JSObject*> obj(cx, objArg);
ok = dom::WrapObject(cx, obj, supports, v.address());
ok = dom::WrapObject(cx, obj, supports, &v);
break;
}
default:

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

@ -23,7 +23,7 @@ WebGLContext::WebGLObjectAsJSValue(JSContext *cx, const WebGLObjectType *object,
JS::Rooted<JS::Value> v(cx);
JS::Rooted<JSObject*> wrapper(cx, GetWrapper());
JSAutoCompartment ac(cx, wrapper);
if (!dom::WrapNewBindingObject(cx, wrapper, const_cast<WebGLObjectType*>(object), v.address())) {
if (!dom::WrapNewBindingObject(cx, wrapper, const_cast<WebGLObjectType*>(object), &v)) {
rv.Throw(NS_ERROR_FAILURE);
return JS::NullValue();
}

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

@ -291,8 +291,7 @@ HTMLOptionsCollection::NamedItem(JSContext* cx, const nsAString& name,
JS::Rooted<JSObject*> wrapper(cx, nsWrapperCache::GetWrapper());
JSAutoCompartment ac(cx, wrapper);
JS::Rooted<JS::Value> v(cx);
if (!mozilla::dom::WrapObject(cx, wrapper, item, item, nullptr,
v.address())) {
if (!mozilla::dom::WrapObject(cx, wrapper, item, item, nullptr, &v)) {
error.Throw(NS_ERROR_FAILURE);
return nullptr;
}

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

@ -235,7 +235,7 @@ TableRowsCollection::NamedItem(JSContext* cx, const nsAString& name,
JS::Rooted<JSObject*> wrapper(cx, nsWrapperCache::GetWrapper());
JSAutoCompartment ac(cx, wrapper);
JS::Rooted<JS::Value> v(cx);
if (!mozilla::dom::WrapObject(cx, wrapper, item, v.address())) {
if (!mozilla::dom::WrapObject(cx, wrapper, item, &v)) {
error.Throw(NS_ERROR_FAILURE);
return nullptr;
}

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

@ -3125,7 +3125,7 @@ nsGenericHTMLElement::GetItemValue(JSContext* aCx, JSObject* aScope,
if (ItemScope()) {
JS::Rooted<JS::Value> v(aCx);
if (!mozilla::dom::WrapObject(aCx, scope, this, v.address())) {
if (!mozilla::dom::WrapObject(aCx, scope, this, &v)) {
aError.Throw(NS_ERROR_FAILURE);
return JS::UndefinedValue();
}

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

@ -2556,7 +2556,7 @@ nsFormControlList::NamedItem(JSContext* cx, const nsAString& name,
JS::Rooted<JSObject*> wrapper(cx, nsWrapperCache::GetWrapper());
JSAutoCompartment ac(cx, wrapper);
JS::Rooted<JS::Value> v(cx);
if (!mozilla::dom::WrapObject(cx, wrapper, item, v.address())) {
if (!mozilla::dom::WrapObject(cx, wrapper, item, &v)) {
error.Throw(NS_ERROR_FAILURE);
return nullptr;
}

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

@ -2324,7 +2324,7 @@ nsHTMLDocument::NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
JSAutoCompartment ac(cx, wrapper);
// XXXbz Should we call the (slightly misnamed, really) WrapNativeParent
// here?
if (!dom::WrapObject(cx, wrapper, supp, cache, nullptr, val.address())) {
if (!dom::WrapObject(cx, wrapper, supp, cache, nullptr, &val)) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}

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

@ -562,7 +562,7 @@ public:
// callers should do it as needed.
bool SetTimeStamp(JSContext* cx, JSObject* obj);
bool ToDateObject(JSContext* cx, JS::Value* vp) const;
bool ToDateObject(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;
private:
double mMsecSinceEpoch;

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

@ -668,6 +668,7 @@ VariantToJsval(JSContext* aCx, JS::Handle<JSObject*> aScope,
JSBool
QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
{
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JS::Value> thisv(cx, JS_THIS(cx, vp));
if (thisv.isNull())
return false;
@ -710,7 +711,7 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
return Throw<true>(cx, rv);
}
return WrapObject(cx, origObj, ci, &NS_GET_IID(nsIClassInfo), vp);
return WrapObject(cx, origObj, ci, &NS_GET_IID(nsIClassInfo), args.rval());
}
nsCOMPtr<nsISupports> unused;
@ -1783,13 +1784,13 @@ Date::SetTimeStamp(JSContext* cx, JSObject* objArg)
}
bool
Date::ToDateObject(JSContext* cx, JS::Value* vp) const
Date::ToDateObject(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
JSObject* obj = JS_NewDateObjectMsec(cx, mMsecSinceEpoch);
if (!obj) {
return false;
}
*vp = JS::ObjectValue(*obj);
rval.set(JS::ObjectValue(*obj));
return true;
}

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

@ -521,37 +521,37 @@ SetSystemOnlyWrapper(JSObject* obj, nsWrapperCache* cache, JSObject& wrapper)
cache->SetHasSystemOnlyWrapper();
}
// If *vp is a gcthing and is not in the compartment of cx, wrap *vp
// If rval is a gcthing and is not in the compartment of cx, wrap rval
// into the compartment of cx (typically by replacing it with an Xray or
// cross-compartment wrapper around the original object).
MOZ_ALWAYS_INLINE bool
MaybeWrapValue(JSContext* cx, JS::Value* vp)
MaybeWrapValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
{
if (vp->isString()) {
JSString* str = vp->toString();
if (rval.isString()) {
JSString* str = rval.toString();
if (JS::GetGCThingZone(str) != js::GetContextZone(cx)) {
return JS_WrapValue(cx, vp);
return JS_WrapValue(cx, rval.address());
}
return true;
}
if (vp->isObject()) {
JSObject* obj = &vp->toObject();
if (rval.isObject()) {
JSObject* obj = &rval.toObject();
if (js::GetObjectCompartment(obj) != js::GetContextCompartment(cx)) {
return JS_WrapValue(cx, vp);
return JS_WrapValue(cx, rval.address());
}
// We're same-compartment, but even then we might need to wrap
// objects specially. Check for that.
if (GetSameCompartmentWrapperForDOMBinding(obj)) {
// We're a new-binding object, and "obj" now points to the right thing
*vp = JS::ObjectValue(*obj);
rval.set(JS::ObjectValue(*obj));
return true;
}
if (!IS_SLIM_WRAPPER(obj)) {
// We might need a SOW
return JS_WrapValue(cx, vp);
return JS_WrapValue(cx, rval.address());
}
// Fall through to returning true
@ -562,32 +562,33 @@ MaybeWrapValue(JSContext* cx, JS::Value* vp)
static inline void
WrapNewBindingForSameCompartment(JSContext* cx, JSObject* obj, void* value,
JS::Value* vp)
JS::MutableHandle<JS::Value> rval)
{
*vp = JS::ObjectValue(*obj);
rval.set(JS::ObjectValue(*obj));
}
static inline void
WrapNewBindingForSameCompartment(JSContext* cx, JSObject* obj,
nsWrapperCache* value, JS::Value* vp)
nsWrapperCache* value,
JS::MutableHandle<JS::Value> rval)
{
if (value->HasSystemOnlyWrapper()) {
*vp = GetSystemOnlyWrapperSlot(obj);
MOZ_ASSERT(vp->isObject());
rval.set(GetSystemOnlyWrapperSlot(obj));
MOZ_ASSERT(rval.isObject());
} else {
*vp = JS::ObjectValue(*obj);
rval.set(JS::ObjectValue(*obj));
}
}
// Create a JSObject wrapping "value", if there isn't one already, and store it
// in *vp. "value" must be a concrete class that implements a
// in rval. "value" must be a concrete class that implements a
// GetWrapperPreserveColor() which can return its existing wrapper, if any, and
// a WrapObject() which will try to create a wrapper. Typically, this is done by
// having "value" inherit from nsWrapperCache.
template <class T>
MOZ_ALWAYS_INLINE bool
WrapNewBindingObject(JSContext* cx, JS::Handle<JSObject*> scope, T* value,
JS::Value* vp)
JS::MutableHandle<JS::Value> rval)
{
MOZ_ASSERT(value);
JSObject* obj = value->GetWrapperPreserveColor();
@ -636,12 +637,12 @@ WrapNewBindingObject(JSContext* cx, JS::Handle<JSObject*> scope, T* value,
bool sameCompartment =
js::GetObjectCompartment(obj) == js::GetContextCompartment(cx);
if (sameCompartment && couldBeDOMBinding) {
WrapNewBindingForSameCompartment(cx, obj, value, vp);
WrapNewBindingForSameCompartment(cx, obj, value, rval);
return true;
}
*vp = JS::ObjectValue(*obj);
return (sameCompartment && IS_SLIM_WRAPPER(obj)) || JS_WrapValue(cx, vp);
rval.set(JS::ObjectValue(*obj));
return (sameCompartment && IS_SLIM_WRAPPER(obj)) || JS_WrapValue(cx, rval.address());
}
// Create a JSObject wrapping "value", for cases when "value" is a
@ -651,7 +652,8 @@ template <class T>
inline bool
WrapNewBindingNonWrapperCachedObject(JSContext* cx,
JS::Handle<JSObject*> scopeArg,
T* value, JS::Value* vp)
T* value,
JS::MutableHandle<JS::Value> rval)
{
MOZ_ASSERT(value);
// We try to wrap in the compartment of the underlying object of "scope"
@ -680,8 +682,8 @@ WrapNewBindingNonWrapperCachedObject(JSContext* cx,
// We can end up here in all sorts of compartments, per above. Make
// sure to JS_WrapValue!
*vp = JS::ObjectValue(*obj);
return JS_WrapValue(cx, vp);
rval.set(JS::ObjectValue(*obj));
return JS_WrapValue(cx, rval.address());
}
// Create a JSObject wrapping "value", for cases when "value" is a
@ -692,7 +694,8 @@ template <class T>
inline bool
WrapNewBindingNonWrapperCachedOwnedObject(JSContext* cx,
JS::Handle<JSObject*> scopeArg,
nsAutoPtr<T>& value, JS::Value* vp)
nsAutoPtr<T>& value,
JS::MutableHandle<JS::Value> rval)
{
// We do a runtime check on value, because otherwise we might in
// fact end up wrapping a null and invoking methods on it later.
@ -730,17 +733,18 @@ WrapNewBindingNonWrapperCachedOwnedObject(JSContext* cx,
// We can end up here in all sorts of compartments, per above. Make
// sure to JS_WrapValue!
*vp = JS::ObjectValue(*obj);
return JS_WrapValue(cx, vp);
rval.set(JS::ObjectValue(*obj));
return JS_WrapValue(cx, rval.address());
}
// Helper for smart pointers (nsAutoPtr/nsRefPtr/nsCOMPtr).
template <template <typename> class SmartPtr, typename T>
inline bool
WrapNewBindingNonWrapperCachedObject(JSContext* cx, JS::Handle<JSObject*> scope,
const SmartPtr<T>& value, JS::Value* vp)
const SmartPtr<T>& value,
JS::MutableHandle<JS::Value> rval)
{
return WrapNewBindingNonWrapperCachedObject(cx, scope, value.get(), vp);
return WrapNewBindingNonWrapperCachedObject(cx, scope, value.get(), rval);
}
// Only set allowNativeWrapper to false if you really know you need it, if in
@ -760,15 +764,15 @@ NativeInterface2JSObjectAndThrowIfFailed(JSContext* aCx,
template <class T>
MOZ_ALWAYS_INLINE bool
HandleNewBindingWrappingFailure(JSContext* cx, JS::Handle<JSObject*> scope,
T* value, JS::Value* vp)
T* value, JS::MutableHandle<JS::Value> rval)
{
if (JS_IsExceptionPending(cx)) {
return false;
}
qsObjectHelper helper(value, GetWrapperCache(value));
return NativeInterface2JSObjectAndThrowIfFailed(cx, scope, vp, helper,
nullptr, true);
return NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval.address(),
helper, nullptr, true);
}
// Helper for calling HandleNewBindingWrappingFailure with smart pointers
@ -779,9 +783,9 @@ template <class T, bool isSmartPtr=HasgetMember<T>::Value>
struct HandleNewBindingWrappingFailureHelper
{
static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
const T& value, JS::Value* vp)
const T& value, JS::MutableHandle<JS::Value> rval)
{
return HandleNewBindingWrappingFailure(cx, scope, value.get(), vp);
return HandleNewBindingWrappingFailure(cx, scope, value.get(), rval);
}
};
@ -789,18 +793,18 @@ template <class T>
struct HandleNewBindingWrappingFailureHelper<T, false>
{
static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope, T& value,
JS::Value* vp)
JS::MutableHandle<JS::Value> rval)
{
return HandleNewBindingWrappingFailure(cx, scope, &value, vp);
return HandleNewBindingWrappingFailure(cx, scope, &value, rval);
}
};
template<class T>
inline bool
HandleNewBindingWrappingFailure(JSContext* cx, JS::Handle<JSObject*> scope,
T& value, JS::Value* vp)
T& value, JS::MutableHandle<JS::Value> rval)
{
return HandleNewBindingWrappingFailureHelper<T>::Wrap(cx, scope, value, vp);
return HandleNewBindingWrappingFailureHelper<T>::Wrap(cx, scope, value, rval);
}
template<bool Fatal>
@ -945,12 +949,13 @@ VariantToJsval(JSContext* aCx, JS::Handle<JSObject*> aScope,
template<class T>
inline bool
WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
nsWrapperCache* cache, const nsIID* iid, JS::Value* vp)
nsWrapperCache* cache, const nsIID* iid,
JS::MutableHandle<JS::Value> rval)
{
if (xpc_FastGetCachedWrapper(cache, scope, vp))
if (xpc_FastGetCachedWrapper(cache, scope, rval.address()))
return true;
qsObjectHelper helper(p, cache);
return XPCOMObjectToJsval(cx, scope, helper, iid, true, vp);
return XPCOMObjectToJsval(cx, scope, helper, iid, true, rval.address());
}
// A specialization of the above for nsIVariant, because that needs to
@ -958,11 +963,12 @@ WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
template<>
inline bool
WrapObject<nsIVariant>(JSContext* cx, JS::Handle<JSObject*> scope, nsIVariant* p,
nsWrapperCache* cache, const nsIID* iid, JS::Value* vp)
nsWrapperCache* cache, const nsIID* iid,
JS::MutableHandle<JS::Value> rval)
{
MOZ_ASSERT(iid);
MOZ_ASSERT(iid->Equals(NS_GET_IID(nsIVariant)));
return VariantToJsval(cx, scope, p, vp);
return VariantToJsval(cx, scope, p, rval.address());
}
// Wrap an object "p" which is not using WebIDL bindings yet. Just like the
@ -971,9 +977,9 @@ WrapObject<nsIVariant>(JSContext* cx, JS::Handle<JSObject*> scope, nsIVariant* p
template<class T>
inline bool
WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p, const nsIID* iid,
JS::Value* vp)
JS::MutableHandle<JS::Value> rval)
{
return WrapObject(cx, scope, p, GetWrapperCache(p), iid, vp);
return WrapObject(cx, scope, p, GetWrapperCache(p), iid, rval);
}
// Just like the WrapObject above, but without requiring you to pick which
@ -981,62 +987,63 @@ WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p, const nsIID* iid,
// classinfo, for which it doesn't matter what IID is used to wrap.
template<class T>
inline bool
WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p, JS::Value* vp)
WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
JS::MutableHandle<JS::Value> rval)
{
return WrapObject(cx, scope, p, NULL, vp);
return WrapObject(cx, scope, p, NULL, rval);
}
// Helper to make it possible to wrap directly out of an nsCOMPtr
template<class T>
inline bool
WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, const nsCOMPtr<T>& p,
const nsIID* iid, JS::Value* vp)
const nsIID* iid, JS::MutableHandle<JS::Value> rval)
{
return WrapObject(cx, scope, p.get(), iid, vp);
return WrapObject(cx, scope, p.get(), iid, rval);
}
// Helper to make it possible to wrap directly out of an nsCOMPtr
template<class T>
inline bool
WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, const nsCOMPtr<T>& p,
JS::Value* vp)
JS::MutableHandle<JS::Value> rval)
{
return WrapObject(cx, scope, p, NULL, vp);
return WrapObject(cx, scope, p, NULL, rval);
}
// Helper to make it possible to wrap directly out of an nsRefPtr
template<class T>
inline bool
WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, const nsRefPtr<T>& p,
const nsIID* iid, JS::Value* vp)
const nsIID* iid, JS::MutableHandle<JS::Value> rval)
{
return WrapObject(cx, scope, p.get(), iid, vp);
return WrapObject(cx, scope, p.get(), iid, rval);
}
// Helper to make it possible to wrap directly out of an nsRefPtr
template<class T>
inline bool
WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, const nsRefPtr<T>& p,
JS::Value* vp)
JS::MutableHandle<JS::Value> rval)
{
return WrapObject(cx, scope, p, NULL, vp);
return WrapObject(cx, scope, p, NULL, rval);
}
// Specialization to make it easy to use WrapObject in codegen.
template<>
inline bool
WrapObject<JSObject>(JSContext* cx, JS::Handle<JSObject*> scope, JSObject* p,
JS::Value* vp)
JS::MutableHandle<JS::Value> rval)
{
vp->setObjectOrNull(p);
rval.set(JS::ObjectOrNullValue(p));
return true;
}
inline bool
WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, JSObject& p,
JS::Value* vp)
JS::MutableHandle<JS::Value> rval)
{
vp->setObject(p);
rval.set(JS::ObjectValue(p));
return true;
}
@ -1232,9 +1239,9 @@ template <class T, bool isSmartPtr=HasgetMember<T>::Value>
struct WrapNewBindingObjectHelper
{
static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
const T& value, JS::Value* vp)
const T& value, JS::MutableHandle<JS::Value> rval)
{
return WrapNewBindingObject(cx, scope, value.get(), vp);
return WrapNewBindingObject(cx, scope, value.get(), rval);
}
};
@ -1242,18 +1249,18 @@ template <class T>
struct WrapNewBindingObjectHelper<T, false>
{
static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope, T& value,
JS::Value* vp)
JS::MutableHandle<JS::Value> rval)
{
return WrapNewBindingObject(cx, scope, &value, vp);
return WrapNewBindingObject(cx, scope, &value, rval);
}
};
template<class T>
inline bool
WrapNewBindingObject(JSContext* cx, JS::Handle<JSObject*> scope, T& value,
JS::Value* vp)
JS::MutableHandle<JS::Value> rval)
{
return WrapNewBindingObjectHelper<T>::Wrap(cx, scope, value, vp);
return WrapNewBindingObjectHelper<T>::Wrap(cx, scope, value, rval);
}
template <class T>

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

@ -1126,7 +1126,7 @@ class CGConstructNavigatorObject(CGAbstractMethod):
return nullptr;
}
JS::Rooted<JS::Value> v(aCx);
if (!WrapNewBindingObject(aCx, aObj, result, v.address())) {
if (!WrapNewBindingObject(aCx, aObj, result, &v)) {
MOZ_ASSERT(JS_IsExceptionPending(aCx));
return nullptr;
}
@ -3799,7 +3799,16 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
the 'break' will exit).
The resulting string should be used with string.Template. It
needs the following keys when substituting: jsvalPtr/jsvalRef/obj.
needs the following keys when substituting:
jsvalHandle: something that can be passed to methods taking a
JS::MutableHandle<JS::Value>. This can be a
JS::MutableHandle<JS::Value> or a JS::Rooted<JS::Value>*.
jsvalRef: something that can have .address() called on it to get a
JS::Value* and .set() called on it to set it to a JS::Value.
This can be a JS::MutableHandle<JS::Value> or a
JS::Rooted<JS::Value>.
obj: a JS::Handle<JSObject*>.
Returns (templateString, infallibility of conversion template)
"""
@ -3818,11 +3827,11 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
if not callWrapValue:
tail = successCode
else:
tail = ("if (!MaybeWrapValue(cx, ${jsvalPtr})) {\n" +
tail = ("if (!MaybeWrapValue(cx, ${jsvalHandle})) {\n" +
("%s\n" % exceptionCodeIndented.define()) +
"}\n" +
successCode)
return ("${jsvalRef} = %s;\n" +
return ("${jsvalRef}.set(%s);\n" +
tail) % (value)
def wrapAndSetPtr(wrapCall, failureCode=None):
@ -3869,7 +3878,7 @@ if (%s.IsNull()) {
'result' : "%s[%s]" % (result, index),
'successCode': "break;",
'jsvalRef': "tmp",
'jsvalPtr': "tmp.address()",
'jsvalHandle': "&tmp",
'isCreator': isCreator,
'exceptionCode': exceptionCode,
'obj': "returnArray"
@ -3925,7 +3934,7 @@ if (!returnArray) {
wrapMethod = "WrapNewBindingNonWrapperCachedOwnedObject"
else:
wrapMethod = "WrapNewBindingNonWrapperCachedObject"
wrap = "%s(cx, ${obj}, %s, ${jsvalPtr})" % (wrapMethod, result)
wrap = "%s(cx, ${obj}, %s, ${jsvalHandle})" % (wrapMethod, result)
if not descriptor.hasXPConnectImpls:
# Can only fail to wrap as a new-binding object
# if they already threw an exception.
@ -3937,13 +3946,13 @@ if (!returnArray) {
"fallback won't work correctly" %
descriptor.interface.identifier.name)
# Try old-style wrapping for bindings which might be XPConnect impls.
failed = wrapAndSetPtr("HandleNewBindingWrappingFailure(cx, ${obj}, %s, ${jsvalPtr})" % result)
failed = wrapAndSetPtr("HandleNewBindingWrappingFailure(cx, ${obj}, %s, ${jsvalHandle})" % result)
else:
if descriptor.notflattened:
getIID = "&NS_GET_IID(%s), " % descriptor.nativeType
else:
getIID = ""
wrap = "WrapObject(cx, ${obj}, %s, %s${jsvalPtr})" % (result, getIID)
wrap = "WrapObject(cx, ${obj}, %s, %s${jsvalHandle})" % (result, getIID)
failed = None
wrappingCode += wrapAndSetPtr(wrap, failed)
@ -3951,9 +3960,9 @@ if (!returnArray) {
if type.isString():
if type.nullable():
return (wrapAndSetPtr("xpc::StringToJsval(cx, %s, ${jsvalPtr})" % result), False)
return (wrapAndSetPtr("xpc::StringToJsval(cx, %s, ${jsvalRef}.address())" % result), False)
else:
return (wrapAndSetPtr("xpc::NonVoidStringToJsval(cx, %s, ${jsvalPtr})" % result), False)
return (wrapAndSetPtr("xpc::NonVoidStringToJsval(cx, %s, ${jsvalRef}.address())" % result), False)
if type.isEnum():
if type.nullable():
@ -4022,7 +4031,7 @@ if (!returnArray) {
else:
prefix = "%s."
return (wrapAndSetPtr((prefix % result) +
"ToJSVal(cx, ${obj}, ${jsvalPtr})"), False)
"ToJSVal(cx, ${obj}, ${jsvalHandle})"), False)
if not (type.isPrimitive() or type.isDictionary() or type.isDate()):
raise TypeError("Need to learn to wrap %s" % type)
@ -4036,11 +4045,11 @@ if (!returnArray) {
"}\n" + recTemplate, recInfal)
if type.isDictionary():
return (wrapAndSetPtr("%s.ToObject(cx, ${obj}, ${jsvalPtr})" % result),
return (wrapAndSetPtr("%s.ToObject(cx, ${obj}, ${jsvalHandle})" % result),
False)
if type.isDate():
return (wrapAndSetPtr("%s.ToDateObject(cx, ${jsvalPtr})" % result),
return (wrapAndSetPtr("%s.ToDateObject(cx, ${jsvalHandle})" % result),
False)
tag = type.tag()
@ -4070,10 +4079,13 @@ def wrapForType(type, descriptorProvider, templateValues):
Reflect a C++ value of IDL type "type" into JS. TemplateValues is a dict
that should contain:
* 'jsvalRef': a C++ reference to the jsval in which to store the result of
the conversion
* 'jsvalPtr': a C++ pointer to the jsval in which to store the result of
the conversion
* 'jsvalRef': something that can have .address() called on it to get a
JS::Value* and .set() called on it to set it to a JS::Value.
This can be a JS::MutableHandle<JS::Value> or a
JS::Rooted<JS::Value>.
* 'jsvalHandle': something that can be passed to methods taking a
JS::MutableHandle<JS::Value>. This can be a
JS::MutableHandle<JS::Value> or a JS::Rooted<JS::Value>*.
* 'obj' (optional): the name of the variable that contains the JSObject to
use as a scope when wrapping, if not supplied 'obj'
will be used as the name
@ -4571,8 +4583,8 @@ if (global.Failed()) {
# values or something
self.descriptor.workers)
resultTemplateValues = { 'jsvalRef': '*args.rval().address()',
'jsvalPtr': 'args.rval().address()',
resultTemplateValues = { 'jsvalRef': 'args.rval()',
'jsvalHandle': 'args.rval()',
'isCreator': isCreator}
try:
return wrapForType(self.returnType, self.descriptor,
@ -5821,7 +5833,8 @@ ${callDestructors}
${methods}
bool ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::Value* vp) const;
bool ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj,
JS::MutableHandle<JS::Value> rval) const;
private:
friend class ${structName}Argument;
@ -5856,7 +5869,7 @@ ${destructors}
if self.type.hasNullableType:
conversionsToJS.append(" case eNull:\n"
" {\n"
" *vp = JS::NullValue();\n"
" rval.set(JS::NullValue());\n"
" return true;\n"
" }")
conversionsToJS.extend(
@ -5864,7 +5877,8 @@ ${destructors}
zip(templateVars, self.type.flatMemberTypes)))
return string.Template("""bool
${structName}::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::Value* vp) const
${structName}::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj,
JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
${doConversionsToJS}
@ -5893,8 +5907,8 @@ ${doConversionsToJS}
wrapCode = wrapForType(
type, self.descriptorProvider,
{
"jsvalRef": "*vp",
"jsvalPtr": "vp",
"jsvalRef": "rval",
"jsvalHandle": "rval",
"obj": "scopeObj",
"result": val,
"objectCanBeNonNull": True
@ -6771,7 +6785,8 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(ClassMethod):
setOrIndexedGet += "int32_t index = GetArrayIndexFromId(cx, id);\n"
readonly = toStringBool(indexedSetter is None)
fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;" % readonly
templateValues = {'jsvalRef': 'desc->value', 'jsvalPtr': '&desc->value',
templateValues = {'jsvalRef': 'JS::MutableHandle<JS::Value>::fromMarkedLocation(&desc->value)',
'jsvalHandle': 'JS::MutableHandle<JS::Value>::fromMarkedLocation(&desc->value)',
'obj': 'proxy', 'successCode': fillDescriptor}
get = ("if (IsArrayIndex(index)) {\n" +
CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define() + "\n" +
@ -6838,7 +6853,8 @@ MOZ_ASSERT_IF(desc->obj, desc->obj == ${holder});"""
if self.descriptor.supportsNamedProperties():
readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None)
fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;" % readonly
templateValues = {'jsvalRef': 'desc->value', 'jsvalPtr': '&desc->value',
templateValues = {'jsvalRef': 'JS::MutableHandle<JS::Value>::fromMarkedLocation(&desc->value)',
'jsvalHandle': 'JS::MutableHandle<JS::Value>::fromMarkedLocation(&desc->value)',
'obj': 'proxy', 'successCode': fillDescriptor}
condition = "!HasPropertyOnPrototype(cx, proxy, this, id)"
if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
@ -7169,7 +7185,7 @@ if (expando) {
}
}"""
templateValues = {'jsvalRef': '*vp.address()', 'jsvalPtr': 'vp.address()', 'obj': 'proxy'}
templateValues = {'jsvalRef': 'vp', 'jsvalHandle': 'vp', 'obj': 'proxy'}
if self.descriptor.supportsIndexedProperties():
getIndexedOrExpando = ("int32_t index = GetArrayIndexFromId(cx, id);\n" +
@ -7254,7 +7270,7 @@ class CGDOMJSProxyHandler_getElementIfPresent(ClassMethod):
def getBody(self):
successCode = ("*present = found;\n"
"return true;")
templateValues = {'jsvalRef': '*vp.address()', 'jsvalPtr': 'vp.address()',
templateValues = {'jsvalRef': 'vp', 'jsvalHandle': 'vp',
'obj': 'proxy', 'successCode': successCode}
if self.descriptor.supportsIndexedProperties():
get = (CGProxyIndexedGetter(self.descriptor, templateValues).define() + "\n"
@ -7649,10 +7665,10 @@ class CGDictionary(CGThing):
if self.dictionary.parent:
body += (
"// Per spec, we define the parent's members first\n"
"if (!%s::ToObject(cx, parentObject, vp)) {\n"
"if (!%s::ToObject(cx, parentObject, rval)) {\n"
" return false;\n"
"}\n"
"JS::Rooted<JSObject*> obj(cx, &vp->toObject());\n"
"JS::Rooted<JSObject*> obj(cx, &rval.toObject());\n"
"\n") % self.makeClassName(self.dictionary.parent)
else:
body += (
@ -7660,7 +7676,7 @@ class CGDictionary(CGThing):
"if (!obj) {\n"
" return false;\n"
"}\n"
"*vp = JS::ObjectValue(*obj);\n"
"rval.set(JS::ObjectValue(*obj));\n"
"\n")
body += "\n\n".join(self.getMemberDefinition(m).define()
@ -7670,7 +7686,7 @@ class CGDictionary(CGThing):
return ClassMethod("ToObject", "bool", [
Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'parentObject'),
Argument('JS::Value*', 'vp'),
Argument('JS::MutableHandle<JS::Value>', 'rval'),
], const=True, body=body)
def initIdsMethod(self):
@ -7875,7 +7891,7 @@ class CGDictionary(CGThing):
"}\n"
"break;" % propDef),
'jsvalRef': "temp",
'jsvalPtr': "temp.address()",
'jsvalHandle': "&temp",
'isCreator': False,
'obj': "parentObject"
})
@ -8996,7 +9012,7 @@ class CGJSImplMethod(CGNativeMember):
nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(window);
JS::Rooted<JSObject*> scopeObj(cx, globalHolder->GetGlobalJSObject());
JS::Rooted<JS::Value> wrappedVal(cx);
if (!WrapNewBindingObject(cx, scopeObj, impl, wrappedVal.address())) {
if (!WrapNewBindingObject(cx, scopeObj, impl, &wrappedVal)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
@ -9474,8 +9490,8 @@ class CallbackMember(CGNativeMember):
{
'result' : result,
'successCode' : "continue;" if arg.variadic else "break;",
'jsvalRef' : "argv[%s]" % jsvalIndex,
'jsvalPtr' : "&argv[%s]" % jsvalIndex,
'jsvalRef' : "argv.handleAt(%s)" % jsvalIndex,
'jsvalHandle' : "argv.handleAt(%s)" % jsvalIndex,
# XXXbz we don't have anything better to use for 'obj',
# really... It's OK to use CallbackPreserveColor because
# CallSetup already handled the unmark-gray bits for us.

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

@ -434,7 +434,8 @@ inDOMUtils::ColorNameToRGB(const nsAString& aColorName, JSContext* aCx,
triple.mG = NS_GET_G(color);
triple.mB = NS_GET_B(color);
if (!triple.ToObject(aCx, JS::NullPtr(), aValue)) {
if (!triple.ToObject(aCx, JS::NullPtr(),
JS::MutableHandle<JS::Value>::fromMarkedLocation(aValue))) {
return NS_ERROR_FAILURE;
}

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

@ -92,7 +92,7 @@ Dashboard::GetSockets()
}
JS::RootedValue val(cx);
if (!dict.ToObject(cx, JS::NullPtr(), val.address())) {
if (!dict.ToObject(cx, JS::NullPtr(), &val)) {
mSock.cb = nullptr;
mSock.data.Clear();
return NS_ERROR_FAILURE;
@ -198,7 +198,7 @@ Dashboard::GetHttpConnections()
}
JS::RootedValue val(cx);
if (!dict.ToObject(cx, JS::NullPtr(), val.address())) {
if (!dict.ToObject(cx, JS::NullPtr(), &val)) {
mHttp.cb = nullptr;
mHttp.data.Clear();
return NS_ERROR_FAILURE;
@ -337,7 +337,7 @@ Dashboard::GetWebSocketConnections()
}
JS::RootedValue val(cx);
if (!dict.ToObject(cx, JS::NullPtr(), val.address())) {
if (!dict.ToObject(cx, JS::NullPtr(), &val)) {
mWs.cb = nullptr;
mWs.data.Clear();
return NS_ERROR_FAILURE;
@ -425,7 +425,7 @@ Dashboard::GetDNSCacheEntries()
}
JS::RootedValue val(cx);
if (!dict.ToObject(cx, JS::NullPtr(), val.address())) {
if (!dict.ToObject(cx, JS::NullPtr(), &val)) {
mDns.cb = nullptr;
mDns.data.Clear();
return NS_ERROR_FAILURE;