Fixes for using OOPHM while developing a FF plugin, and fixes a case where
getting a property appears to succeed but returns an undefined value.

Patch by: mmstrac
Review by: jat


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6009 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/plugins/xpcom/FFSessionHandler.cpp b/plugins/xpcom/FFSessionHandler.cpp
index 09fa9e1..2d74fbe 100755
--- a/plugins/xpcom/FFSessionHandler.cpp
+++ b/plugins/xpcom/FFSessionHandler.cpp
@@ -43,6 +43,11 @@
   if (NS_FAILED(stack->Peek(&cx))) {
     return NULL;
   }
+
+  if (cx == nsnull) {
+    Debug::log(Debug::Error) << "Null context" << Debug::flush;
+  }  
+
   return cx;
 }
 
@@ -80,7 +85,12 @@
 
 void FFSessionHandler::getToStringTearOff(JSContext* ctx) {
   jsval funcVal;
-  if (!JS_GetProperty(ctx, global, "__gwt_makeTearOff", &funcVal)) {
+
+  Debug::log(Debug::Debugging) << "Getting function \"__gwt_makeTearOff\""
+        << Debug::flush;
+
+  if (!JS_GetProperty(ctx, global, "__gwt_makeTearOff", &funcVal)
+      || funcVal == JSVAL_VOID) {
     Debug::log(Debug::Error) << "Could not get function \"__gwt_makeTearOff\""
         << Debug::flush;
     return;
@@ -202,8 +212,10 @@
 
   jsval funcVal;
   // TODO: handle non-ASCII method names
-  if (!JS_GetProperty(ctx, global, methodName.c_str(), &funcVal)) {
-    Debug::log(Debug::Error) << "Could not get function " << methodName << Debug::flush;
+  if (!JS_GetProperty(ctx, global, methodName.c_str(), &funcVal)
+      || funcVal == JSVAL_VOID) {
+    Debug::log(Debug::Error) << "Could not get function " << methodName
+        << Debug::flush;
     return true;
   }
 
diff --git a/plugins/xpcom/JSRunner.cpp b/plugins/xpcom/JSRunner.cpp
index 1a9c0ba..4b251f3 100755
--- a/plugins/xpcom/JSRunner.cpp
+++ b/plugins/xpcom/JSRunner.cpp
@@ -14,6 +14,7 @@
  * the License.
  */
 
+#include "Debug.h"
 #include "JSRunner.h"
 
 #include "nsCOMPtr.h"
@@ -46,39 +47,49 @@
     sgo = do_QueryInterface(priv);
   }
 
-  JSPrincipals *jsprin;
+  JSPrincipals *jsprin = nsnull;
+  std::string virtual_filename;
   nsresult nr;
 
   nsCOMPtr<nsIScriptObjectPrincipal> obj_prin = do_QueryInterface(sgo, &nr);
   if (NS_FAILED(nr)) {
+    Debug::log(Debug::Error) << "Error getting object principal" << Debug::flush;
     return false;
   }
 
   nsIPrincipal *principal = obj_prin->GetPrincipal();
   if (!principal) {
+    Debug::log(Debug::Error) << "Error getting principal" << Debug::flush;
     return false;
   }
 
   // Get the script scheme and host from the principal.  This is the URI that
   // Firefox treats this script as running from.
-  nsCOMPtr<nsIURI> codebase;
-  principal->GetURI(getter_AddRefs(codebase));
-  if (!codebase) { return false; }
-  nsCString scheme;
-  nsCString host;
-  if (NS_FAILED(codebase->GetScheme(scheme)) ||
-      NS_FAILED(codebase->GetHostPort(host))) {
-    return false;
-  }
 
-  // Build a virtual filename that we'll run as.  This is to workaround
-  // http://lxr.mozilla.org/seamonkey/source/dom/src/base/nsJSEnvironment.cpp#500
-  // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=387477
-  // The filename is being used as the security origin instead of the principal.
-  // TODO(zork): Remove this section if this bug is resolved.
-  std::string virtual_filename(scheme.BeginReading());
-  virtual_filename += "://";
-  virtual_filename += host.BeginReading();
+  // If the codebase is null, the script may be running from a chrome context.
+  // In that case, don't construct a virtual filename.
+
+  nsCOMPtr<nsIURI> codebase;
+  nr = principal->GetURI(getter_AddRefs(codebase));
+  if (codebase) { 
+    nsCString scheme;
+    nsCString host;
+
+    if (NS_FAILED(codebase->GetScheme(scheme)) ||
+        NS_FAILED(codebase->GetHostPort(host))) {
+      Debug::log(Debug::Error) << "Error getting codebase" << Debug::flush;
+      return false;
+    }
+
+    // Build a virtual filename that we'll run as.  This is to workaround
+    // http://lxr.mozilla.org/seamonkey/source/dom/src/base/nsJSEnvironment.cpp#500
+    // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=387477
+    // The filename is being used as the security origin instead of the principal.
+    // TODO(zork): Remove this section if this bug is resolved.
+    virtual_filename = std::string(scheme.BeginReading());
+    virtual_filename += "://";
+    virtual_filename += host.BeginReading();
+  }
 
   principal->GetJSPrincipals(ctx, &jsprin);
 
@@ -92,16 +103,21 @@
 
   uintN line_number_start = 0;
   jsval rval;
-  JSBool js_ok = 
-      JS_EvaluateScriptForPrincipals(ctx, object, jsprin, script.c_str(), script.length(),
-          virtual_filename.c_str(), line_number_start, &rval);
+  JSBool js_ok = JS_EvaluateScriptForPrincipals(ctx, object, jsprin,
+      script.c_str(), script.length(), virtual_filename.c_str(),
+      line_number_start, &rval);
 
   // Restore the context stack.
 //  JSContext *cx;
 //  stack->Pop(&cx);
 
   // Decrements ref count on jsprin (Was added in GetJSPrincipals()).
-  (void)JSPRINCIPALS_DROP(ctx, jsprin);
-  if (!js_ok) { return false; }
+  (void) JSPRINCIPALS_DROP(ctx, jsprin);
+  if (!js_ok) {
+    Debug::log(Debug::Error) << "JS execution failed in JSRunner::eval"
+        << Debug::flush;
+    return false;
+  }
+
   return true;
 }