Don't leave an exception just hangin' out on the JSContext. Bug 422009, r+sr=jst, a=shaver
authorbzbarsky@mit.edu
Wed, 19 Mar 2008 17:42:47 -0700
changeset 13341 63e3861f185658a626a155891386487b8ae9c838
parent 13340 0fca09536e75404bc7009516e9236a14d37be7bf
child 13342 d86cfa9cc572daaf15473e9e3b6283d9795feeef
push idunknown
push userunknown
push dateunknown
reviewersshaver
bugs422009
milestone1.9b5pre
Don't leave an exception just hangin' out on the JSContext. Bug 422009, r+sr=jst, a=shaver
content/events/src/nsEventListenerManager.cpp
dom/public/nsIScriptContext.h
dom/src/base/nsJSEnvironment.cpp
dom/src/base/nsJSEnvironment.h
extensions/python/dom/src/nsPyContext.cpp
extensions/python/dom/src/nsPyContext.h
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -811,16 +811,17 @@ nsEventListenerManager::AddScriptEventLi
 
         rv = context->CompileEventHandler(aName, argCount, argNames,
                                           aBody,
                                           url.get(), lineNo,
                                           SCRIPTVERSION_DEFAULT, // for now?
                                           handler);
         if (rv == NS_ERROR_ILLEGAL_VALUE) {
           NS_WARNING("Probably a syntax error in the event handler!");
+          context->ReportPendingException();
           return NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA;
         }
         NS_ENSURE_SUCCESS(rv, rv);
         // And bind it.
         rv = context->BindCompiledEventHandler(aObject, scope,
                                                aName, handler);
       }
       if (NS_FAILED(rv)) return rv;
--- a/dom/public/nsIScriptContext.h
+++ b/dom/public/nsIScriptContext.h
@@ -52,19 +52,19 @@ class nsIArray;
 class nsIVariant;
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 class nsScriptObjectHolder;
 
 typedef void (*nsScriptTerminationFunc)(nsISupports* aRef);
 
 #define NS_ISCRIPTCONTEXT_IID \
-{ /* {09316a0e-8d05-4d26-9efd-8f907a7c79d2} */ \
-  0x09316a0e, 0x8d05, 0x4d26, \
- { 0x9e, 0xfd, 0x8f, 0x90, 0x7a, 0x7c, 0x79, 0xd2 } }
+{ /* {e7b9871d-3adc-4bf7-850d-7fb9554886bf} */ \
+  0xe7b9871d, 0x3adc, 0x4bf7, \
+ { 0x85, 0x0d, 0x7f, 0xb9, 0x55, 0x48, 0x86, 0xbf } }
 
 /* This MUST match JSVERSION_DEFAULT.  This version stuff if we don't
    know what language we have is a little silly... */
 #define SCRIPTVERSION_DEFAULT JSVERSION_DEFAULT
 
 /**
  * It is used by the application to initialize a runtime and run scripts.
  * A script runtime would implement this interface.
@@ -446,14 +446,17 @@ public:
    * nsScriptObjectHolder to manage the lifetimes of the held script objects.
    *
    * See also nsIScriptRuntime, which has identical methods and is useful
    * in situations when you do not have an nsIScriptContext.
    * 
    */
   virtual nsresult DropScriptObject(void *object) = 0;
   virtual nsresult HoldScriptObject(void *object) = 0;
+
+  /* Report a pending exception if there is one on the native context */
+  virtual void ReportPendingException() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContext, NS_ISCRIPTCONTEXT_IID)
 
 #endif // nsIScriptContext_h__
 
--- a/dom/src/base/nsJSEnvironment.cpp
+++ b/dom/src/base/nsJSEnvironment.cpp
@@ -3544,16 +3544,24 @@ nsJSContext::DropScriptObject(void* aScr
     NS_NOTREACHED("couldn't remove GC root");
     return NS_ERROR_FAILURE;
   }
 
   ::JS_UnlockGCThingRT(nsJSRuntime::sRuntime, aScriptObject);
   return NS_OK;
 }
 
+void
+nsJSContext::ReportPendingException()
+{
+  if (mIsInitialized && ::JS_IsExceptionPending(mContext)) {
+    ::JS_ReportPendingException(mContext);
+  }
+}
+
 /**********************************************************************
  * nsJSRuntime implementation
  *********************************************************************/
 
 // QueryInterface implementation for nsJSRuntime
 NS_INTERFACE_MAP_BEGIN(nsJSRuntime)
   NS_INTERFACE_MAP_ENTRY(nsIScriptRuntime)
 NS_INTERFACE_MAP_END
--- a/dom/src/base/nsJSEnvironment.h
+++ b/dom/src/base/nsJSEnvironment.h
@@ -161,16 +161,18 @@ public:
 
   virtual nsresult Serialize(nsIObjectOutputStream* aStream, void *aScriptObject);
   virtual nsresult Deserialize(nsIObjectInputStream* aStream,
                                nsScriptObjectHolder &aResult);
 
   virtual nsresult DropScriptObject(void *object);
   virtual nsresult HoldScriptObject(void *object);
 
+  virtual void ReportPendingException();
+
   NS_DECL_NSIXPCSCRIPTNOTIFY
 
   NS_DECL_NSITIMERCALLBACK
 
   static void LoadStart();
   static void LoadEnd();
 
   // CC does always call cycle collector and it also updates the counters
--- a/extensions/python/dom/src/nsPyContext.cpp
+++ b/extensions/python/dom/src/nsPyContext.cpp
@@ -928,8 +928,14 @@ nsPythonContext::HoldScriptObject(void *
 {
   if (object) {
     PYLEAK_STAT_INCREMENT(ScriptObject);
     CEnterLeavePython _celp;
     Py_INCREF((PyObject *)object);
   }
   return NS_OK;
 }
+
+void
+nsPythonContext::ReportPendingException()
+{
+  // Not sure there's anything to do here
+}
--- a/extensions/python/dom/src/nsPyContext.h
+++ b/extensions/python/dom/src/nsPyContext.h
@@ -208,16 +208,18 @@ public:
 
   virtual nsresult Serialize(nsIObjectOutputStream* aStream, void *aScriptObject);
   virtual nsresult Deserialize(nsIObjectInputStream* aStream,
                                nsScriptObjectHolder &aResult);
 
   virtual nsresult HoldScriptObject(void *object);
   virtual nsresult DropScriptObject(void *object);
 
+  virtual void ReportPendingException();
+
   NS_DECL_NSITIMERCALLBACK
   
   PyObject *PyObject_FromInterface(nsISupports *target,
                                    const nsIID &iid)
   {
     return ::PyObject_FromNSDOMInterface(mDelegate, target, iid);
   }
 protected: