зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
24d0bddba5
Коммит
7a3587f2d2
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче