From fcdb506b78a9c8b101e1ccc3ac08ed0a462aef7b Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Fri, 19 Apr 2013 04:49:21 -0400 Subject: [PATCH] Bug 857439 Part 3: Make sure to delete owned interfaces if wrapping fails r=bz --- dom/bindings/BindingUtils.h | 35 +++++++++++++++++++++++++++++++++++ dom/bindings/Codegen.py | 14 ++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 724d29cb714e..c6859983f590 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -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 +inline bool +WrapNewBindingNonWrapperCachedOwnedObject(JSContext* cx, JSObject* scope, + nsAutoPtr& 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 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