Bug 616992 - Give nsDOMConstructors a precreate hook so that we don't accidentally create more than one wrapper object for them. r=jst@mozilla.com, gal@uci.edu, a=blocker

This commit is contained in:
Blake Kaplan 2011-01-11 12:15:52 -08:00
parent 9ab02b028a
commit 06e8f326af
4 changed files with 84 additions and 1 deletions

View File

@ -670,10 +670,12 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(DOMPrototype, nsDOMConstructorSH,
DOM_BASE_SCRIPTABLE_FLAGS |
nsIXPCScriptable::WANT_PRECREATE |
nsIXPCScriptable::WANT_HASINSTANCE |
nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE)
NS_DEFINE_CLASSINFO_DATA(DOMConstructor, nsDOMConstructorSH,
DOM_BASE_SCRIPTABLE_FLAGS |
nsIXPCScriptable::WANT_PRECREATE |
nsIXPCScriptable::WANT_HASINSTANCE |
nsIXPCScriptable::WANT_CALL |
nsIXPCScriptable::WANT_CONSTRUCT |
@ -5735,6 +5737,8 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMDOMCONSTRUCTOR
nsresult PreCreate(JSContext *cx, JSObject *globalObj, JSObject **parentObj);
nsresult Construct(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 argc, jsval *argv,
jsval *vp, PRBool *_retval);
@ -5745,7 +5749,7 @@ public:
nsresult Install(JSContext *cx, JSObject *target, jsval thisAsVal)
{
JSBool ok =
JSBool ok = JS_WrapValue(cx, &thisAsVal) &&
::JS_DefineUCProperty(cx, target,
reinterpret_cast<const jschar *>(mClassName),
nsCRT::strlen(mClassName), thisAsVal, nsnull,
@ -5875,6 +5879,20 @@ NS_INTERFACE_MAP_BEGIN(nsDOMConstructor)
} else
NS_INTERFACE_MAP_END
nsresult
nsDOMConstructor::PreCreate(JSContext *cx, JSObject *globalObj, JSObject **parentObj)
{
nsCOMPtr<nsPIDOMWindow> owner(do_QueryReferent(mWeakOwner));
if (!owner) {
// Can't do anything.
return NS_OK;
}
nsGlobalWindow *win = static_cast<nsGlobalWindow *>(owner.get());
*parentObj = win->FastGetGlobalJSObject();
return NS_OK;
}
nsresult
nsDOMConstructor::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, PRUint32 argc, jsval * argv,
@ -6155,6 +6173,12 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx,
const char *class_parent_name = nsnull;
if (!primary_iid->Equals(NS_GET_IID(nsISupports))) {
JSAutoEnterCompartment ac;
if (!ac.enter(cx, class_obj)) {
return NS_ERROR_FAILURE;
}
rv = DefineInterfaceConstants(cx, class_obj, primary_iid);
NS_ENSURE_SUCCESS(rv, rv);
@ -6280,6 +6304,11 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx,
v = OBJECT_TO_JSVAL(dot_prototype);
JSAutoEnterCompartment ac;
if (!ac.enter(cx, class_obj)) {
return NS_ERROR_UNEXPECTED;
}
// Per ECMA, the prototype property is {DontEnum, DontDelete, ReadOnly}
if (!JS_WrapValue(cx, &v) ||
!JS_DefineProperty(cx, class_obj, "prototype", v, nsnull, nsnull,
@ -10606,6 +10635,23 @@ nsEventListenerThisTranslator::TranslateThis(nsISupports *aInitialThis,
return NS_OK;
}
NS_IMETHODIMP
nsDOMConstructorSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj)
{
nsDOMConstructor *wrapped = static_cast<nsDOMConstructor *>(nativeObj);
#ifdef DEBUG
{
nsCOMPtr<nsIDOMDOMConstructor> is_constructor =
do_QueryInterface(nativeObj);
NS_ASSERTION(is_constructor, "How did we not get a constructor?");
}
#endif
return wrapped->PreCreate(cx, globalObj, parentObj);
}
NS_IMETHODIMP
nsDOMConstructorSH::Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 argc, jsval *argv, jsval *vp,

View File

@ -1702,6 +1702,8 @@ protected:
}
public:
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
JSObject *globalObj, JSObject **parentObj);
NS_IMETHOD PostCreatePrototype(JSContext * cx, JSObject * proto)
{
return NS_OK;

View File

@ -60,6 +60,7 @@ _CHROME_FILES = \
test_bug601803.xul \
test_bug610390.xul \
test_bug614757.xul \
test_bug616992.xul \
$(NULL)
# Disabled until this test gets updated to test the new proxy based

View File

@ -0,0 +1,34 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=616992
-->
<window title="Mozilla Bug 601803"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=616992"
target="_blank">Mozilla Bug 616992</a>
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
/** Test for Bug 616992 **/
const Cu = Components.utils;
var sandbox = new Cu.Sandbox(window);
sandbox.w = window;
var actual = Cu.evalInSandbox("Object.keys(w.NodeFilter)", sandbox).sort().toString();
var expected = Object.keys(NodeFilter).sort().toString();
is(actual, expected, "interface constants are visible inside sandboxes");
]]></script>
</body>
</window>