Bug 698420 - Make nsScriptObjectHolder typesafe; r=bz

This commit is contained in:
Ms2ger
2011-12-18 11:05:12 +01:00
parent e1a3882c4d
commit ced4c8389a
13 changed files with 65 additions and 73 deletions

View File

@@ -579,7 +579,7 @@ nsEventListenerManager::CompileEventHandlerInternal(nsListenerStruct *aListenerS
nsIScriptContext *context = listener->GetEventContext();
nsCOMPtr<nsIScriptEventHandlerOwner> handlerOwner =
do_QueryInterface(mTarget);
nsScriptObjectHolder handler(context);
nsScriptObjectHolder<JSObject> handler(context);
if (handlerOwner) {
result = handlerOwner->GetCompiledEventHandler(aListenerStruct->mTypeAtom,
@@ -699,10 +699,10 @@ nsEventListenerManager::CompileEventHandlerInternal(nsListenerStruct *aListenerS
if (handler) {
// Bind it
nsScriptObjectHolder boundHandler(context);
nsScriptObjectHolder<JSObject> boundHandler(context);
context->BindCompiledEventHandler(mTarget, listener->GetEventScope(),
handler.getObject(), boundHandler);
listener->SetHandler(boundHandler.getObject());
handler.get(), boundHandler);
listener->SetHandler(boundHandler.get());
}
return result;

View File

@@ -307,7 +307,7 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventTarget* aTarget,
if (!boundContext)
return NS_OK;
nsScriptObjectHolder handler(boundContext);
nsScriptObjectHolder<JSObject> handler(boundContext);
nsISupports *scriptTarget;
if (winRoot) {
@@ -321,16 +321,16 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventTarget* aTarget,
// Bind it to the bound element
JSObject* scope = boundGlobal->GetGlobalJSObject();
nsScriptObjectHolder boundHandler(boundContext);
nsScriptObjectHolder<JSObject> boundHandler(boundContext);
rv = boundContext->BindCompiledEventHandler(scriptTarget, scope,
handler.getObject(), boundHandler);
handler.get(), boundHandler);
NS_ENSURE_SUCCESS(rv, rv);
// Execute it.
nsCOMPtr<nsIJSEventListener> eventListener;
rv = NS_NewJSEventListener(boundContext, scope,
scriptTarget, onEventAtom,
boundHandler.getObject(),
boundHandler.get(),
getter_AddRefs(eventListener));
NS_ENSURE_SUCCESS(rv, rv);
@@ -344,14 +344,14 @@ nsresult
nsXBLPrototypeHandler::EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
nsIScriptContext *aBoundContext,
nsIAtom *aName,
nsScriptObjectHolder &aHandler)
nsScriptObjectHolder<JSObject>& aHandler)
{
// Check to see if we've already compiled this
nsCOMPtr<nsPIDOMWindow> pWindow = do_QueryInterface(aGlobal);
if (pWindow) {
JSObject* cachedHandler = pWindow->GetCachedXBLPrototypeHandler(this);
if (cachedHandler) {
aHandler.setObject(cachedHandler);
aHandler.set(cachedHandler);
return aHandler ? NS_OK : NS_ERROR_FAILURE;
}
}

View File

@@ -194,7 +194,7 @@ protected:
nsresult DispatchXULKeyCommand(nsIDOMEvent* aEvent);
nsresult EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
nsIScriptContext *aBoundContext, nsIAtom *aName,
nsScriptObjectHolder &aHandler);
nsScriptObjectHolder<JSObject>& aHandler);
static PRInt32 KeyToMask(PRInt32 key);
static PRInt32 kAccelKey;

View File

@@ -163,9 +163,9 @@ public:
const nsAString& aBody,
const char* aURL,
PRUint32 aLineNo,
nsScriptObjectHolder &aHandler);
nsScriptObjectHolder<JSObject>& aHandler);
virtual nsresult GetCompiledEventHandler(nsIAtom *aName,
nsScriptObjectHolder &aHandler);
nsScriptObjectHolder<JSObject>& aHandler);
private:
nsRefPtr<nsXULElement> mElement;
@@ -718,7 +718,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsScriptEventHandlerOwnerTearoff)
nsresult
nsScriptEventHandlerOwnerTearoff::GetCompiledEventHandler(
nsIAtom *aName,
nsScriptObjectHolder &aHandler)
nsScriptObjectHolder<JSObject>& aHandler)
{
XUL_PROTOTYPE_ATTRIBUTE_METER(gNumCacheTests);
aHandler.drop();
@@ -727,7 +727,7 @@ nsScriptEventHandlerOwnerTearoff::GetCompiledEventHandler(
mElement->FindPrototypeAttribute(kNameSpaceID_None, aName);
if (attr) {
XUL_PROTOTYPE_ATTRIBUTE_METER(gNumCacheHits);
aHandler.setObject(attr->mEventHandler);
aHandler.set(attr->mEventHandler);
}
return NS_OK;
@@ -740,7 +740,7 @@ nsScriptEventHandlerOwnerTearoff::CompileEventHandler(
const nsAString& aBody,
const char* aURL,
PRUint32 aLineNo,
nsScriptObjectHolder &aHandler)
nsScriptObjectHolder<JSObject>& aHandler)
{
nsresult rv;
@@ -809,13 +809,13 @@ nsScriptEventHandlerOwnerTearoff::CompileEventHandler(
rv = nsContentUtils::HoldScriptObject(aContext->GetScriptTypeID(),
elem,
&NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode),
aHandler,
aHandler.get(),
elem->mHoldsScriptObject);
if (NS_FAILED(rv)) return rv;
elem->mHoldsScriptObject = true;
}
attr->mEventHandler = aHandler.getObject();
attr->mEventHandler = aHandler.get();
}
return NS_OK;
@@ -3002,7 +3002,7 @@ nsXULPrototypeScript::Deserialize(nsIObjectInputStream* aStream,
mScriptObject.mLangID);
NS_ASSERTION(context != nsnull, "Have no context for deserialization");
NS_ENSURE_TRUE(context, NS_ERROR_UNEXPECTED);
nsScriptObjectHolder newScriptObject(context);
nsScriptObjectHolder<JSScript> newScriptObject(context);
rv = context->Deserialize(aStream, newScriptObject);
if (NS_FAILED(rv)) {
NS_WARNING("Language deseralization failed");
@@ -3138,7 +3138,7 @@ nsXULPrototypeScript::Compile(const PRUnichar* aText,
// Ok, compile it to create a prototype script object!
nsScriptObjectHolder newScriptObject(context);
nsScriptObjectHolder<JSScript> newScriptObject(context);
rv = context->CompileScript(aText,
aTextLength,
// Use the enclosing document's principal

View File

@@ -336,13 +336,13 @@ public:
void UnlinkJSObjects();
void Set(nsScriptObjectHolder &aHolder)
void Set(nsScriptObjectHolder<JSScript>& aHolder)
{
NS_ASSERTION(mScriptObject.mLangID == aHolder.getScriptTypeID(),
"Wrong language, this will leak the previous object.");
mScriptObject.mLangID = aHolder.getScriptTypeID();
Set(aHolder.getScript());
Set(aHolder.get());
}
void Set(JSScript* aObject);

View File

@@ -48,17 +48,18 @@
// functions and a fully inline implementation should keep the cost down.
// [Note that a fully inline implementation is necessary for use by other
// languages, which do not link against the layout component module]
template<class T>
class NS_STACK_CLASS nsScriptObjectHolder {
public:
// A constructor that will cause a reference to |ctx| to be stored in
// the object. Only use for short-lived object holders.
nsScriptObjectHolder(nsIScriptContext *ctx, void *aObject = nsnull) :
nsScriptObjectHolder<T>(nsIScriptContext *ctx, T* aObject = nsnull) :
mObject(aObject), mContext(ctx) {
NS_ASSERTION(ctx, "Must provide a valid context");
}
// copy constructor
nsScriptObjectHolder(const nsScriptObjectHolder& other) :
nsScriptObjectHolder<T>(const nsScriptObjectHolder<T>& other) :
mObject(other.mObject),
mContext(other.mContext)
{
@@ -67,28 +68,25 @@ public:
mContext->HoldScriptObject(mObject);
}
~nsScriptObjectHolder() {
~nsScriptObjectHolder<T>() {
if (mObject)
mContext->DropScriptObject(mObject);
}
// misc operators
nsScriptObjectHolder &operator=(const nsScriptObjectHolder &other) {
nsScriptObjectHolder<T> &operator=(const nsScriptObjectHolder<T> &other) {
set(other);
return *this;
}
bool operator!() const {
return !mObject;
}
operator void *() const {
operator bool() const {
return !!mObject;
}
T* get() const {
return mObject;
}
JSScript* getScript() const {
return static_cast<JSScript*>(mObject);
}
JSObject* getObject() const {
return static_cast<JSObject*>(mObject);
}
// Drop the script object - but *not* the nsIScriptContext.
nsresult drop() {
@@ -100,13 +98,7 @@ public:
return rv;
}
nsresult setScript(JSScript* aScript) {
return set(aScript);
}
nsresult setObject(JSObject* aObject) {
return set(aObject);
}
nsresult set(void *object) {
nsresult set(T* object) {
NS_ASSERTION(getScriptTypeID() != nsIProgrammingLanguage::UNKNOWN,
"Must know the language!");
nsresult rv = drop();
@@ -121,7 +113,7 @@ public:
}
return rv;
}
nsresult set(const nsScriptObjectHolder &other) {
nsresult set(const nsScriptObjectHolder<T> &other) {
NS_ASSERTION(getScriptTypeID() == other.getScriptTypeID(),
"Must have identical languages!");
nsresult rv = drop();
@@ -134,7 +126,7 @@ public:
return mContext->GetScriptTypeID();
}
protected:
void *mObject;
T* mObject;
nsCOMPtr<nsIScriptContext> mContext;
};

View File

@@ -6884,7 +6884,7 @@ nsGlobalWindow::GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey)
void
nsGlobalWindow::CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
nsScriptObjectHolder& aHandler)
nsScriptObjectHolder<JSObject>& aHandler)
{
if (!mCachedXBLPrototypeHandlers.IsInitialized() &&
!mCachedXBLPrototypeHandlers.Init()) {
@@ -6912,7 +6912,7 @@ nsGlobalWindow::CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
}
}
mCachedXBLPrototypeHandlers.Put(aKey, aHandler.getObject());
mCachedXBLPrototypeHandlers.Put(aKey, aHandler.get());
}
NS_IMETHODIMP

View File

@@ -518,7 +518,7 @@ public:
virtual NS_HIDDEN_(void)
CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
nsScriptObjectHolder& aHandler);
nsScriptObjectHolder<JSObject>& aHandler);
virtual bool TakeFocus(bool aFocus, PRUint32 aFocusMethod);
virtual void SetReadyForFocus();

View File

@@ -53,7 +53,7 @@ class nsIArray;
class nsIVariant;
class nsIObjectInputStream;
class nsIObjectOutputStream;
class nsScriptObjectHolder;
template<class> class nsScriptObjectHolder;
class nsIScriptObjectPrincipal;
typedef void (*nsScriptTerminationFunc)(nsISupports* aRef);
@@ -74,8 +74,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContextPrincipal,
NS_ISCRIPTCONTEXTPRINCIPAL_IID)
#define NS_ISCRIPTCONTEXT_IID \
{ 0x39b3ea7c, 0xdc26, 0x4756, \
{ 0xa0, 0x3c, 0x13, 0xa0, 0x42, 0x03, 0x07, 0x6a } }
{ 0xe22f85d1, 0xae90, 0x418a, \
{ 0x83, 0xf0, 0xaf, 0x0d, 0xa3, 0x04, 0x92, 0x6a } }
/* This MUST match JSVERSION_DEFAULT. This version stuff if we don't
know what language we have is a little silly... */
@@ -151,7 +151,7 @@ public:
const char* aURL,
PRUint32 aLineNo,
PRUint32 aVersion,
nsScriptObjectHolder &aScriptObject) = 0;
nsScriptObjectHolder<JSScript>& aScriptObject) = 0;
/**
* Execute a precompiled script object.
@@ -206,7 +206,7 @@ public:
const char* aURL,
PRUint32 aLineNo,
PRUint32 aVersion,
nsScriptObjectHolder &aHandler) = 0;
nsScriptObjectHolder<JSObject>& aHandler) = 0;
/**
* Call the function object with given args and return its boolean result,
@@ -248,7 +248,7 @@ public:
virtual nsresult BindCompiledEventHandler(nsISupports* aTarget,
JSObject* aScope,
JSObject* aHandler,
nsScriptObjectHolder& aBoundHandler) = 0;
nsScriptObjectHolder<JSObject>& aBoundHandler) = 0;
/**
* Compile a function that isn't used as an event handler.
@@ -380,7 +380,7 @@ public:
/* Deserialize a script from a stream.
*/
virtual nsresult Deserialize(nsIObjectInputStream* aStream,
nsScriptObjectHolder &aResult) = 0;
nsScriptObjectHolder<JSScript>& aResult) = 0;
/**
* JS only - this function need not be implemented by languages other

View File

@@ -42,7 +42,7 @@
#include "nsIScriptContext.h"
#include "nsAString.h"
class nsScriptObjectHolder;
template<class> class nsScriptObjectHolder;
#define NS_ISCRIPTOBJECTOWNER_IID \
{ /* 8f6bca7e-ce42-11d1-b724-00600891d8c9 */ \
@@ -94,8 +94,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptObjectOwner,
class nsIAtom;
#define NS_ISCRIPTEVENTHANDLEROWNER_IID \
{ 0x1e2be5d2, 0x381a, 0x46dc, \
{ 0xae, 0x97, 0xa5, 0x5f, 0x45, 0xfd, 0x36, 0x63 } }
{ 0xc8f35f71, 0x07d1, 0x4ff3, \
{ 0xa3, 0x2f, 0x65, 0xcb, 0x35, 0x64, 0xac, 0xe0 } }
/**
* Associate a compiled event handler with its target object, which owns it
@@ -124,7 +124,7 @@ public:
const nsAString& aBody,
const char* aURL,
PRUint32 aLineNo,
nsScriptObjectHolder &aHandler) = 0;
nsScriptObjectHolder<JSObject>& aHandler) = 0;
/**
* Retrieve an already-compiled event handler that can be bound to a
@@ -134,7 +134,7 @@ public:
* @param aHandler the holder for the compiled event handler.
*/
virtual nsresult GetCompiledEventHandler(nsIAtom *aName,
nsScriptObjectHolder &aHandler) = 0;
nsScriptObjectHolder<JSObject>& aHandler) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptEventHandlerOwner,

View File

@@ -1547,7 +1547,7 @@ nsJSContext::CompileScript(const PRUnichar* aText,
const char *aURL,
PRUint32 aLineNo,
PRUint32 aVersion,
nsScriptObjectHolder &aScriptObject)
nsScriptObjectHolder<JSScript>& aScriptObject)
{
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
@@ -1587,7 +1587,7 @@ nsJSContext::CompileScript(const PRUnichar* aText,
if (script) {
NS_ASSERTION(aScriptObject.getScriptTypeID()==JAVASCRIPT,
"Expecting JS script object holder");
rv = aScriptObject.setScript(script);
rv = aScriptObject.set(script);
} else {
rv = NS_ERROR_OUT_OF_MEMORY;
}
@@ -1745,7 +1745,7 @@ nsJSContext::CompileEventHandler(nsIAtom *aName,
const nsAString& aBody,
const char *aURL, PRUint32 aLineNo,
PRUint32 aVersion,
nsScriptObjectHolder &aHandler)
nsScriptObjectHolder<JSObject>& aHandler)
{
NS_TIME_FUNCTION_MIN_FMT(1.0, "%s (line %d) (url: %s, line: %d)", MOZ_FUNCTION_NAME,
__LINE__, aURL, aLineNo);
@@ -1795,7 +1795,7 @@ nsJSContext::CompileEventHandler(nsIAtom *aName,
JSObject *handler = ::JS_GetFunctionObject(fun);
NS_ASSERTION(aHandler.getScriptTypeID()==JAVASCRIPT,
"Expecting JS script object holder");
return aHandler.setObject(handler);
return aHandler.set(handler);
}
// XXX - note that CompileFunction doesn't yet play the nsScriptObjectHolder
@@ -1985,7 +1985,7 @@ nsJSContext::CallEventHandler(nsISupports* aTarget, JSObject* aScope,
nsresult
nsJSContext::BindCompiledEventHandler(nsISupports* aTarget, JSObject* aScope,
JSObject* aHandler,
nsScriptObjectHolder& aBoundHandler)
nsScriptObjectHolder<JSObject>& aBoundHandler)
{
NS_ENSURE_ARG(aHandler);
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
@@ -2027,7 +2027,7 @@ nsJSContext::BindCompiledEventHandler(nsISupports* aTarget, JSObject* aScope,
funobj = NULL;
}
aBoundHandler.setObject(funobj);
aBoundHandler.set(funobj);
return rv;
}
@@ -2083,7 +2083,7 @@ nsJSContext::Serialize(nsIObjectOutputStream* aStream, JSScript* aScriptObject)
nsresult
nsJSContext::Deserialize(nsIObjectInputStream* aStream,
nsScriptObjectHolder &aResult)
nsScriptObjectHolder<JSScript>& aResult)
{
NS_TIME_FUNCTION_MIN(1.0);
@@ -2148,7 +2148,7 @@ nsJSContext::Deserialize(nsIObjectInputStream* aStream,
// code, which could happen for all sorts of reasons above.
NS_ENSURE_SUCCESS(rv, rv);
return aResult.setScript(result);
return aResult.set(result);
}
void

View File

@@ -95,7 +95,7 @@ public:
const char *aURL,
PRUint32 aLineNo,
PRUint32 aVersion,
nsScriptObjectHolder &aScriptObject);
nsScriptObjectHolder<JSScript>& aScriptObject);
virtual nsresult ExecuteScript(JSScript* aScriptObject,
JSObject* aScopeObject,
nsAString* aRetValue,
@@ -107,14 +107,14 @@ public:
const nsAString& aBody,
const char *aURL, PRUint32 aLineNo,
PRUint32 aVersion,
nsScriptObjectHolder &aHandler);
nsScriptObjectHolder<JSObject>& aHandler);
virtual nsresult CallEventHandler(nsISupports* aTarget, JSObject* aScope,
JSObject* aHandler,
nsIArray *argv, nsIVariant **rv);
virtual nsresult BindCompiledEventHandler(nsISupports *aTarget,
JSObject *aScope,
JSObject* aHandler,
nsScriptObjectHolder& aBoundHandler);
nsScriptObjectHolder<JSObject>& aBoundHandler);
virtual nsresult CompileFunction(JSObject* aTarget,
const nsACString& aName,
PRUint32 aArgCount,
@@ -169,7 +169,7 @@ public:
virtual nsresult Serialize(nsIObjectOutputStream* aStream, JSScript* aScriptObject);
virtual nsresult Deserialize(nsIObjectInputStream* aStream,
nsScriptObjectHolder &aResult);
nsScriptObjectHolder<JSScript>& aResult);
virtual nsresult DropScriptObject(void *object);
virtual nsresult HoldScriptObject(void *object);

View File

@@ -74,14 +74,14 @@ class nsIContent;
class nsIDocument;
class nsIScriptTimeoutHandler;
struct nsTimeout;
class nsScriptObjectHolder;
template <class> class nsScriptObjectHolder;
class nsXBLPrototypeHandler;
class nsIArray;
class nsPIWindowRoot;
#define NS_PIDOMWINDOW_IID \
{ 0x29e6cc54, 0x10da, 0x4a68, \
{ 0xb7, 0x68, 0xfe, 0xa7, 0x71, 0x17, 0x93, 0x81 } }
{ 0x1352de12, 0x7a07, 0x4610, \
{ 0x93, 0xd5, 0xb8, 0x76, 0xfe, 0x93, 0x09, 0x50 } }
class nsPIDOMWindow : public nsIDOMWindowInternal
{
@@ -488,7 +488,7 @@ public:
virtual JSObject* GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey) = 0;
virtual void CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
nsScriptObjectHolder& aHandler) = 0;
nsScriptObjectHolder<JSObject>& aHandler) = 0;
/*
* Get and set the currently focused element within the document. If