Bug 857439 Part 3: Make sure to delete owned interfaces if wrapping fails r=bz

This commit is contained in:
David Zbarsky 2013-04-19 04:49:21 -04:00
Родитель 70c70c7290
Коммит fcdb506b78
2 изменённых файлов: 47 добавлений и 2 удалений

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

@ -636,6 +636,41 @@ WrapNewBindingNonWrapperCachedObject(JSContext* cx, JSObject* scope, T* value,
return JS_WrapValue(cx, vp);
}
// Create a JSObject wrapping "value", for cases when "value" is a
// non-wrapper-cached owned object using WebIDL bindings. "value" must implement a
// WrapObject() method taking a JSContext, a scope, and a boolean outparam that
// is true if the JSObject took ownership
template <class T>
inline bool
WrapNewBindingNonWrapperCachedOwnedObject(JSContext* cx, JSObject* scope,
nsAutoPtr<T>& value, JS::Value* vp)
{
// We try to wrap in the compartment of the underlying object of "scope"
JSObject* obj;
{
// scope for the JSAutoCompartment so that we restore the compartment
// before we call JS_WrapValue.
Maybe<JSAutoCompartment> ac;
if (js::IsWrapper(scope)) {
scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
if (!scope)
return false;
ac.construct(cx, scope);
}
bool tookOwnership = false;
obj = value->WrapObject(cx, scope, &tookOwnership);
if (tookOwnership) {
value.forget();
}
}
// 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);
}
// Helper for smart pointers (nsAutoPtr/nsRefPtr/nsCOMPtr).
template <template <typename> class SmartPtr, typename T>
inline bool

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

@ -1866,6 +1866,7 @@ def CreateBindingJSObject(descriptor, parent):
create += """ // Make sure the native objects inherit from NonRefcountedDOMObject so that we
// log their ctor and dtor.
MustInheritFromNonRefcountedDOMObject(aObject);
*aTookOwnership = true;
"""
return create % parent
@ -2004,6 +2005,8 @@ class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
assert descriptor.interface.hasInterfacePrototypeObject()
args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aScope'),
Argument(descriptor.nativeType + '*', 'aObject')]
if descriptor.nativeOwnership == 'owned':
args.append(Argument('bool*', 'aTookOwnership'))
CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
self.properties = properties
@ -3460,7 +3463,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
"}\n" +
successCode) % (wrapCall)
return str
if type is None or type.isVoid():
return (setValue("JSVAL_VOID"), True)
@ -3542,11 +3545,15 @@ if (!returnArray) {
failed = None
elif not descriptor.interface.isExternal() and not descriptor.skipGen:
if descriptor.wrapperCache:
assert descriptor.nativeOwnership != 'owned'
wrapMethod = "WrapNewBindingObject"
else:
if not isCreator:
raise MethodNotCreatorError(descriptor.interface.identifier.name)
wrapMethod = "WrapNewBindingNonWrapperCachedObject"
if descriptor.nativeOwnership == 'owned':
wrapMethod = "WrapNewBindingNonWrapperCachedOwnedObject"
else:
wrapMethod = "WrapNewBindingNonWrapperCachedObject"
wrap = "%s(cx, ${obj}, %s, ${jsvalPtr})" % (wrapMethod, result)
if not descriptor.hasXPConnectImpls:
# Can only fail to wrap as a new-binding object
@ -3779,6 +3786,9 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
returnType.unroll().inner.identifier.name).nativeType)
if resultAlreadyAddRefed:
result = CGTemplatedType("nsRefPtr", result)
elif descriptorProvider.getDescriptor(
returnType.unroll().inner.identifier.name).nativeOwnership == 'owned':
result = CGTemplatedType("nsAutoPtr", result)
else:
result = CGWrapper(result, post="*")
return result, False