Bug 1306327 - Use the new XRE Bootstrap API in Desktop Firefox. r=bsmedberg draft
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 16 Dec 2016 11:10:02 +0900
changeset 462689 90e52564161642a0283a92c2d791e8c797e944f5
parent 462688 3c48557b0ea9e8344a29bc5ce3c652bb24d42eb5
child 462690 62e78b11055282e0b07d8b220da09c7bfb020b13
push id41842
push userbmo:mh+mozilla@glandium.org
push dateTue, 17 Jan 2017 22:08:05 +0000
reviewersbsmedberg
bugs1306327
milestone53.0a1
Bug 1306327 - Use the new XRE Bootstrap API in Desktop Firefox. r=bsmedberg This just wraps all the XRE method calls to go through the Bootstrap API instead of relying on the XPCOM glue methods.
browser/app/nsBrowserApp.cpp
ipc/app/MozillaRuntimeMain.cpp
ipc/contentproc/plugin-container.cpp
ipc/ipdl/test/cxx/app/TestIPDL.cpp
js/xpconnect/shell/xpcshell.cpp
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -156,84 +156,51 @@ static bool IsArg(const char* arg, const
 #if defined(XP_WIN)
   if (*arg == '/')
     return !strcasecmp(++arg, s);
 #endif
 
   return false;
 }
 
-XRE_GetFileFromPathType XRE_GetFileFromPath;
-XRE_ParseAppDataType XRE_ParseAppData;
-XRE_TelemetryAccumulateType XRE_TelemetryAccumulate;
-XRE_StartupTimelineRecordType XRE_StartupTimelineRecord;
-XRE_mainType XRE_main;
-XRE_StopLateWriteChecksType XRE_StopLateWriteChecks;
-XRE_XPCShellMainType XRE_XPCShellMain;
-XRE_GetProcessTypeType XRE_GetProcessType;
-XRE_SetProcessTypeType XRE_SetProcessType;
-XRE_InitChildProcessType XRE_InitChildProcess;
-XRE_EnableSameExecutableForContentProcType XRE_EnableSameExecutableForContentProc;
-#ifdef LIBFUZZER
-XRE_LibFuzzerSetMainType XRE_LibFuzzerSetMain;
-XRE_LibFuzzerGetFuncsType XRE_LibFuzzerGetFuncs;
-#endif
-
-static const nsDynamicFunctionLoad kXULFuncs[] = {
-    { "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
-    { "XRE_ParseAppData", (NSFuncPtr*) &XRE_ParseAppData },
-    { "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
-    { "XRE_StartupTimelineRecord", (NSFuncPtr*) &XRE_StartupTimelineRecord },
-    { "XRE_main", (NSFuncPtr*) &XRE_main },
-    { "XRE_StopLateWriteChecks", (NSFuncPtr*) &XRE_StopLateWriteChecks },
-    { "XRE_XPCShellMain", (NSFuncPtr*) &XRE_XPCShellMain },
-    { "XRE_GetProcessType", (NSFuncPtr*) &XRE_GetProcessType },
-    { "XRE_SetProcessType", (NSFuncPtr*) &XRE_SetProcessType },
-    { "XRE_InitChildProcess", (NSFuncPtr*) &XRE_InitChildProcess },
-    { "XRE_EnableSameExecutableForContentProc", (NSFuncPtr*) &XRE_EnableSameExecutableForContentProc },
-#ifdef LIBFUZZER
-    { "XRE_LibFuzzerSetMain", (NSFuncPtr*) &XRE_LibFuzzerSetMain },
-    { "XRE_LibFuzzerGetFuncs", (NSFuncPtr*) &XRE_LibFuzzerGetFuncs },
-#endif
-    { nullptr, nullptr }
-};
+Bootstrap::UniquePtr gBootstrap;
 
 #ifdef LIBFUZZER
 int libfuzzer_main(int argc, char **argv);
 
 /* This wrapper is used by the libFuzzer main to call into libxul */
 
 void libFuzzerGetFuncs(const char* moduleName, LibFuzzerInitFunc* initFunc,
                        LibFuzzerTestingFunc* testingFunc) {
-  return XRE_LibFuzzerGetFuncs(moduleName, initFunc, testingFunc);
+  return gBootstrap->XRE_LibFuzzerGetFuncs(moduleName, initFunc, testingFunc);
 }
 #endif
 
 static int do_main(int argc, char* argv[], char* envp[])
 {
   nsCOMPtr<nsIFile> appini;
   nsresult rv;
 
   // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
   // Note that -app must be the *first* argument.
   const char *appDataFile = getenv("XUL_APP_FILE");
   if (appDataFile && *appDataFile) {
-    rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
+    rv = gBootstrap->XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
     if (NS_FAILED(rv)) {
       Output("Invalid path found: '%s'", appDataFile);
       return 255;
     }
   }
   else if (argc > 1 && IsArg(argv[1], "app")) {
     if (argc == 2) {
       Output("Incorrect number of arguments passed to -app");
       return 255;
     }
 
-    rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
+    rv = gBootstrap->XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
     if (NS_FAILED(rv)) {
       Output("application.ini path not recognized: '%s'", argv[2]);
       return 255;
     }
 
     char appEnv[MAXPATHLEN];
     SprintfLiteral(appEnv, "XUL_APP_FILE=%s", argv[2]);
     if (putenv(strdup(appEnv))) {
@@ -249,23 +216,23 @@ static int do_main(int argc, char* argv[
     }
 
     XREShellData shellData;
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
     shellData.sandboxBrokerServices =
       sandboxing::GetInitializedBrokerServices();
 #endif
 
-    return XRE_XPCShellMain(--argc, argv, envp, &shellData);
+    return gBootstrap->XRE_XPCShellMain(--argc, argv, envp, &shellData);
   }
 
   XREAppData appData;
 
   if (appini) {
-    rv = XRE_ParseAppData(appini, appData);
+    rv = gBootstrap->XRE_ParseAppData(appini, appData);
     if (NS_FAILED(rv)) {
       Output("Couldn't read application.ini");
       return 255;
     }
 
     appini->GetParent(getter_AddRefs(appData.directory));
   } else {
     // no -app flag so we use the compiled-in app data
@@ -298,20 +265,20 @@ static int do_main(int argc, char* argv[
     return 255;
   }
 #endif
   appData.sandboxBrokerServices = brokerServices;
 #endif
 
 #ifdef LIBFUZZER
   if (getenv("LIBFUZZER"))
-    XRE_LibFuzzerSetMain(argc, argv, libfuzzer_main);
+    gBootstrap->XRE_LibFuzzerSetMain(argc, argv, libfuzzer_main);
 #endif
 
-  return XRE_main(argc, argv, appData);
+  return gBootstrap->XRE_main(argc, argv, appData);
 }
 
 static bool
 FileExists(const char *path)
 {
 #ifdef XP_WIN
   wchar_t wideDir[MAX_PATH];
   MultiByteToWideChar(CP_UTF8, 0, path, -1, wideDir, MAX_PATH);
@@ -340,30 +307,24 @@ InitXPCOMGlue(const char *argv0)
 
   strcpy(lastSlash + 1, XPCOM_DLL);
 
   if (!FileExists(exePath)) {
     Output("Could not find the Mozilla runtime.\n");
     return NS_ERROR_FAILURE;
   }
 
-  rv = XPCOMGlueStartup(exePath);
-  if (NS_FAILED(rv)) {
+  gBootstrap = mozilla::GetBootstrap(exePath);
+  if (!gBootstrap) {
     Output("Couldn't load XPCOM.\n");
-    return rv;
-  }
-
-  rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
-  if (NS_FAILED(rv)) {
-    Output("Couldn't load XRE functions.\n");
-    return rv;
+    return NS_ERROR_FAILURE;
   }
 
   // This will set this thread as the main thread.
-  NS_LogInit();
+  gBootstrap->NS_LogInit();
 
   return NS_OK;
 }
 
 int main(int argc, char* argv[], char* envp[])
 {
   mozilla::TimeStamp start = mozilla::TimeStamp::Now();
 
@@ -392,44 +353,46 @@ int main(int argc, char* argv[], char* e
     }
 #endif
 
     nsresult rv = InitXPCOMGlue(argv[0]);
     if (NS_FAILED(rv)) {
       return 255;
     }
 
-    int result = content_process_main(argc, argv);
+    int result = content_process_main(gBootstrap.get(), argc, argv);
 
     // InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
-    NS_LogTerm();
+    gBootstrap->NS_LogTerm();
 
     return result;
   }
 #endif
 
 
   nsresult rv = InitXPCOMGlue(argv[0]);
   if (NS_FAILED(rv)) {
     return 255;
   }
 
-  XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
+  gBootstrap->XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
 
 #ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
-  XRE_EnableSameExecutableForContentProc();
+  gBootstrap->XRE_EnableSameExecutableForContentProc();
 #endif
 
   int result = do_main(argc, argv, envp);
 
-  NS_LogTerm();
+  gBootstrap->NS_LogTerm();
 
 #ifdef XP_MACOSX
   // Allow writes again. While we would like to catch writes from static
   // destructors to allow early exits to use _exit, we know that there is
   // at least one such write that we don't control (see bug 826029). For
   // now we enable writes again and early exits will have to use exit instead
   // of _exit.
-  XRE_StopLateWriteChecks();
+  gBootstrap->XRE_StopLateWriteChecks();
 #endif
 
+  gBootstrap.reset();
+
   return result;
 }
--- a/ipc/app/MozillaRuntimeMain.cpp
+++ b/ipc/app/MozillaRuntimeMain.cpp
@@ -1,19 +1,27 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 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 "../contentproc/plugin-container.cpp"
 
+#include "mozilla/Bootstrap.h"
 #include "mozilla/WindowsDllBlocklist.h"
 
+using namespace mozilla;
+
 int
 main(int argc, char *argv[])
 {
 #ifdef HAS_DLL_BLOCKLIST
   DllBlocklist_Initialize();
 #endif
 
-  return content_process_main(argc, argv);
+  Bootstrap::UniquePtr bootstrap;
+  XRE_GetBootstrap(bootstrap);
+  if (!bootstrap) {
+    return 2;
+  }
+  return content_process_main(bootstrap.get(), argc, argv);
 }
--- a/ipc/contentproc/plugin-container.cpp
+++ b/ipc/contentproc/plugin-container.cpp
@@ -2,16 +2,17 @@
  * vim: sw=4 ts=4 et :
  * 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 "nsXPCOM.h"
 #include "nsXULAppAPI.h"
 #include "nsAutoPtr.h"
+#include "mozilla/Bootstrap.h"
 
 #ifdef XP_WIN
 #include <windows.h>
 // we want a wmain entry point
 // but we don't want its DLL load protection, because we'll handle it here
 #define XRE_DONT_PROTECT_DLL_LOAD
 #include "nsWindowsWMain.cpp"
 #include "nsSetDllDirectory.h"
@@ -66,17 +67,17 @@ MakeSandboxStarter()
 #elif defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
     return mozilla::MakeUnique<MacSandboxStarter>();
 #else
     return nullptr;
 #endif
 }
 
 int
-content_process_main(int argc, char* argv[])
+content_process_main(mozilla::Bootstrap* bootstrap, int argc, char* argv[])
 {
     // Check for the absolute minimum number of args we need to move
     // forward here. We expect the last arg to be the child process type.
     if (argc < 1) {
       return 3;
     }
 
     XREChildData childData;
@@ -88,29 +89,29 @@ content_process_main(int argc, char* arg
         if (!childData.sandboxTargetServices) {
             return 1;
         }
 
         childData.ProvideLogFunction = mozilla::sandboxing::ProvideLogFunction;
     }
 #endif
 
-    XRE_SetProcessType(argv[--argc]);
+    bootstrap->XRE_SetProcessType(argv[--argc]);
 
 #ifdef XP_WIN
     // For plugins, this is done in PluginProcessChild::Init, as we need to
     // avoid it for unsupported plugins.  See PluginProcessChild::Init for
     // the details.
-    if (XRE_GetProcessType() != GeckoProcessType_Plugin) {
+    if (bootstrap->XRE_GetProcessType() != GeckoProcessType_Plugin) {
         mozilla::SanitizeEnvironmentVariables();
         SetDllDirectoryW(L"");
     }
 #endif
 #if !defined(XP_LINUX) && defined(MOZ_PLUGIN_CONTAINER)
     // On Windows and MacOS, the GMPLoader lives in plugin-container, so that its
     // code can be covered by an EME/GMP vendor's voucher.
-    if (XRE_GetProcessType() == GeckoProcessType_GMPlugin) {
+    if (bootstrap->XRE_GetProcessType() == GeckoProcessType_GMPlugin) {
         childData.gmpLoader = mozilla::gmp::CreateGMPLoader(MakeSandboxStarter());
     }
 #endif
-    nsresult rv = XRE_InitChildProcess(argc, argv, &childData);
+    nsresult rv = bootstrap->XRE_InitChildProcess(argc, argv, &childData);
     return NS_FAILED(rv);
 }
--- a/ipc/ipdl/test/cxx/app/TestIPDL.cpp
+++ b/ipc/ipdl/test/cxx/app/TestIPDL.cpp
@@ -1,20 +1,28 @@
 /* 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 "nsXULAppAPI.h"
+#define MOZ_IPDL_TESTS
+#include "mozilla/Bootstrap.h"
 
 #if defined(XP_WIN)
 #include <windows.h>
 #include "nsWindowsWMain.cpp"
 #endif
 
+using namespace mozilla;
+
 int
 main(int argc, char** argv)
 {
     // the first argument specifies which IPDL test case/suite to load
     if (argc < 2)
         return 1;
 
-    return XRE_RunIPDLTest(argc, argv);
+    Bootstrap::UniquePtr bootstrap;
+    XRE_GetBootstrap(bootstrap);
+    if (!bootstrap) {
+        return 2;
+    }
+    return bootstrap->XRE_RunIPDLTest(argc, argv);
 }
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -4,16 +4,17 @@
  * 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/. */
 
 /* XPConnect JavaScript interactive shell. */
 
 #include <stdio.h>
 
 #include "mozilla/WindowsDllBlocklist.h"
+#include "mozilla/Bootstrap.h"
 
 #include "nsXULAppAPI.h"
 #ifdef XP_MACOSX
 #include "xpcshellMacUtils.h"
 #endif
 #ifdef XP_WIN
 #include <windows.h>
 #include <shlobj.h>
@@ -54,16 +55,22 @@ main(int argc, char** argv, char** envp)
 #endif
 
     XREShellData shellData;
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
     shellData.sandboxBrokerServices =
       mozilla::sandboxing::GetInitializedBrokerServices();
 #endif
 
-    int result = XRE_XPCShellMain(argc, argv, envp, &shellData);
+    mozilla::Bootstrap::UniquePtr bootstrap;
+    XRE_GetBootstrap(bootstrap);
+    if (!bootstrap) {
+        return 2;
+    }
+
+    int result = bootstrap->XRE_XPCShellMain(argc, argv, envp, &shellData);
 
 #ifdef XP_MACOSX
     FinishAutoreleasePool();
 #endif
 
     return result;
 }