зеркало из https://github.com/mozilla/gecko-dev.git
Bug 857439 Part 3: Make sure to delete owned interfaces if wrapping fails r=bz
This commit is contained in:
Родитель
70c70c7290
Коммит
fcdb506b78
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче