Bug 1097987 part 3. Change XPCShellEnvironment to only use JS_ExecuteScript in global scopes. r=bholley
authorBoris Zbarsky <bzbarsky@mit.edu>
Sat, 14 Mar 2015 01:36:16 -0400
changeset 262502 9c1eafe518d06e8d7af9f532ff202243ae20f938
parent 262501 975552180fb6ffa72302970a0ac7381c10b5f097
child 262503 f642c3fe61bd619854b592bb2126d7531f0203d6
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1097987
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1097987 part 3. Change XPCShellEnvironment to only use JS_ExecuteScript in global scopes. r=bholley
ipc/testshell/XPCShellEnvironment.cpp
ipc/testshell/XPCShellEnvironment.h
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -1,8 +1,9 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=4 et sw=4 tw=80:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <stdlib.h>
 #include <errno.h>
 #ifdef HAVE_IO_H
@@ -144,16 +145,21 @@ Load(JSContext *cx,
      JS::Value *vp)
 {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
 
     JS::Rooted<JSObject*> obj(cx, JS_THIS_OBJECT(cx, vp));
     if (!obj)
         return false;
 
+    if (!JS_IsGlobalObject(obj)) {
+        JS_ReportError(cx, "Trying to load() into a non-global object");
+        return false;
+    }
+
     for (unsigned i = 0; i < args.length(); i++) {
         JS::Rooted<JSString*> str(cx, JS::ToString(cx, args[i]));
         if (!str)
             return false;
         JSAutoByteString filename(cx, str);
         if (!filename)
             return false;
         FILE *file = fopen(filename.ptr(), "r");
@@ -289,29 +295,31 @@ typedef enum JSShellErrNum
     JSShellErr_Limit
 #undef MSGDEF
 } JSShellErrNum;
 
 } /* anonymous namespace */
 
 void
 XPCShellEnvironment::ProcessFile(JSContext *cx,
-                                 JS::Handle<JSObject*> obj,
                                  const char *filename,
                                  FILE *file,
                                  bool forceTTY)
 {
     XPCShellEnvironment* env = this;
 
     JS::Rooted<JS::Value> result(cx);
     int lineno, startline;
     bool ok, hitEOF;
     char *bufp, buffer[4096];
     JSString *str;
 
+    JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
+    MOZ_ASSERT(global);
+
     if (forceTTY) {
         file = stdin;
     }
     else if (!isatty(fileno(file)))
     {
         /*
          * It's not interactive - just execute it.
          *
@@ -324,64 +332,59 @@ XPCShellEnvironment::ProcessFile(JSConte
         if (ch == '#') {
             while((ch = fgetc(file)) != EOF) {
                 if(ch == '\n' || ch == '\r')
                     break;
             }
         }
         ungetc(ch, file);
 
-        JSAutoRequest ar(cx);
-        JSAutoCompartment ac(cx, obj);
-
         JS::CompileOptions options(cx);
         options.setUTF8(true)
                .setFileAndLine(filename, 1);
         JS::Rooted<JSScript*> script(cx);
-        if (JS::Compile(cx, obj, options, file, &script))
-            (void)JS_ExecuteScript(cx, obj, script, &result);
+        if (JS::Compile(cx, global, options, file, &script))
+            (void)JS_ExecuteScript(cx, global, script, &result);
 
         return;
     }
 
     /* It's an interactive filehandle; drop into read-eval-print loop. */
     lineno = 1;
     hitEOF = false;
     do {
         bufp = buffer;
         *bufp = '\0';
 
-        JSAutoRequest ar(cx);
-        JSAutoCompartment ac(cx, obj);
-
         /*
          * Accumulate lines until we get a 'compilable unit' - one that either
          * generates an error (before running out of source) or that compiles
          * cleanly.  This should be whenever we get a complete statement that
          * coincides with the end of a line.
          */
         startline = lineno;
         do {
             if (!GetLine(bufp, file, startline == lineno ? "js> " : "")) {
                 hitEOF = true;
                 break;
             }
             bufp += strlen(bufp);
             lineno++;
-        } while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer)));
+        } while (!JS_BufferIsCompilableUnit(cx, global, buffer, strlen(buffer)));
 
         /* Clear any pending exception from previous failed compiles.  */
         JS_ClearPendingException(cx);
         JS::CompileOptions options(cx);
         options.setFileAndLine("typein", startline);
         JS::Rooted<JSScript*> script(cx);
-        if (JS_CompileScript(cx, obj, buffer, strlen(buffer), options, &script)) {
+        if (JS_CompileScript(cx, global, buffer, strlen(buffer), options,
+                             &script)) {
             JSErrorReporter older;
 
-            ok = JS_ExecuteScript(cx, obj, script, &result);
+            ok = JS_ExecuteScript(cx, global, script, &result);
             if (ok && result != JSVAL_VOID) {
                 /* Suppress error reports from JS::ToString(). */
                 older = JS_SetErrorReporter(JS_GetRuntime(cx), nullptr);
                 str = JS::ToString(cx, result);
                 JSAutoByteString bytes;
                 if (str)
                     bytes.encodeLatin1(cx, str);
                 JS_SetErrorReporter(JS_GetRuntime(cx), older);
@@ -565,17 +568,17 @@ XPCShellEnvironment::Init()
         return false;
     }
 
     mGlobalHolder = globalObj;
 
     FILE* runtimeScriptFile = fopen(kDefaultRuntimeScriptFilename, "r");
     if (runtimeScriptFile) {
         fprintf(stdout, "[loading '%s'...]\n", kDefaultRuntimeScriptFilename);
-        ProcessFile(cx, globalObj, kDefaultRuntimeScriptFilename,
+        ProcessFile(cx, kDefaultRuntimeScriptFilename,
                     runtimeScriptFile, false);
         fclose(runtimeScriptFile);
     }
 
     return true;
 }
 
 bool
--- a/ipc/testshell/XPCShellEnvironment.h
+++ b/ipc/testshell/XPCShellEnvironment.h
@@ -24,18 +24,17 @@ namespace mozilla {
 namespace ipc {
 
 class XPCShellEnvironment
 {
 public:
     static XPCShellEnvironment* CreateEnvironment();
     ~XPCShellEnvironment();
 
-    void ProcessFile(JSContext *cx, JS::Handle<JSObject*> obj,
-                     const char *filename, FILE *file, bool forceTTY);
+    void ProcessFile(JSContext *cx, const char *filename, FILE *file, bool forceTTY);
     bool EvaluateString(const nsString& aString,
                         nsString* aResult = nullptr);
 
     JSPrincipals* GetPrincipal() {
         return nsJSPrincipals::get(nsContentUtils::GetSystemPrincipal());
     }
 
     JSObject* GetGlobalObject() {