Bug 1321593 part A - Refactor nsXREAppData: 1) make nsXREAppData strongly own its members 2) rename it to mozilla::XREAppData 3) separate out the static compiled data into StaticXREAppData 4) Remove XRE_CreateAppData and XRE_FreeAppData, r?glandium draft
authorBenjamin Smedberg <benjamin@smedbergs.us>
Fri, 02 Dec 2016 09:07:24 -0500
changeset 447063 1dff71d4221d2504cf8611e5ffe11a92c8ba9a24
parent 446006 a3eb899eaa85d8fdaa20423978e84d4032e8fe35
child 447064 afbbcb9e1744d4b308768e7f12a74ad081515a99
push id37970
push userbsmedberg@mozilla.com
push dateFri, 02 Dec 2016 14:47:03 +0000
reviewersglandium
bugs1321593
milestone53.0a1
Bug 1321593 part A - Refactor nsXREAppData: 1) make nsXREAppData strongly own its members 2) rename it to mozilla::XREAppData 3) separate out the static compiled data into StaticXREAppData 4) Remove XRE_CreateAppData and XRE_FreeAppData, r?glandium MozReview-Commit-ID: CQv1UrSaw4D
browser/app/nsBrowserApp.cpp
build/appini_header.py
mozglue/android/APKOpen.cpp
toolkit/xre/CreateAppData.cpp
toolkit/xre/ProfileReset.cpp
toolkit/xre/nsAndroidStartup.cpp
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsAppRunner.h
toolkit/xre/nsNativeAppSupportWin.cpp
xpcom/build/XREAppData.h
xpcom/build/moz.build
xpcom/build/nsXREAppData.h
xpcom/build/nsXULAppAPI.h
xpcom/glue/AppData.cpp
xpcom/glue/AppData.h
xpcom/glue/XREAppData.cpp
xpcom/glue/moz.build
xpcom/glue/objs.mozbuild
xpcom/system/nsIXULAppInfo.idl
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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"
-#include "mozilla/AppData.h"
+#include "mozilla/XREAppData.h"
 #include "application.ini.h"
 #include "nsXPCOMGlue.h"
 #if defined(XP_WIN)
 #include <windows.h>
 #include <stdlib.h>
 #elif defined(XP_UNIX)
 #include <sys/resource.h>
 #include <unistd.h>
@@ -158,36 +158,34 @@ static bool IsArg(const char* arg, const
   if (*arg == '/')
     return !strcasecmp(++arg, s);
 #endif
 
   return false;
 }
 
 XRE_GetFileFromPathType XRE_GetFileFromPath;
-XRE_CreateAppDataType XRE_CreateAppData;
-XRE_FreeAppDataType XRE_FreeAppData;
+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_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
-    { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
+    { "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 },
@@ -257,55 +255,53 @@ static int do_main(int argc, char* argv[
     shellData.sandboxBrokerServices =
       sandboxing::GetInitializedBrokerServices();
 #endif
 
     return XRE_XPCShellMain(--argc, argv, envp, &shellData);
   }
 
   if (appini) {
-    nsXREAppData *appData;
-    rv = XRE_CreateAppData(appini, &appData);
+    XREAppData appData;
+    rv = XRE_ParseAppData(appini, appData);
     if (NS_FAILED(rv)) {
       Output("Couldn't read application.ini");
       return 255;
     }
 #if defined(HAS_DLL_BLOCKLIST)
     // The dll blocklist operates in the exe vs. xullib. Pass a flag to
     // xullib so automated tests can check the result once the browser
     // is up and running.
     appData->flags |=
       DllBlocklist_CheckStatus() ? NS_XRE_DLL_BLOCKLIST_ENABLED : 0;
 #endif
-    // xreDirectory already has a refcount from NS_NewLocalFile
-    appData->xreDirectory = xreDirectory;
-    int result = XRE_main(argc, argv, appData, mainFlags);
-    XRE_FreeAppData(appData);
-    return result;
+    appData.xreDirectory = xreDirectory;
+    appini->GetParent(getter_AddRefs(appData.directory));
+    return XRE_main(argc, argv, appData, mainFlags);
   }
 
-  ScopedAppData appData(&sAppData);
+  XREAppData appData;
+  appData = sAppData;
   nsCOMPtr<nsIFile> exeFile;
   rv = mozilla::BinaryPath::GetFile(argv[0], getter_AddRefs(exeFile));
   if (NS_FAILED(rv)) {
     Output("Couldn't find the application directory.\n");
     return 255;
   }
 
   nsCOMPtr<nsIFile> greDir;
   exeFile->GetParent(getter_AddRefs(greDir));
 #ifdef XP_MACOSX
   greDir->SetNativeLeafName(NS_LITERAL_CSTRING(kOSXResourcesFolder));
 #endif
   nsCOMPtr<nsIFile> appSubdir;
   greDir->Clone(getter_AddRefs(appSubdir));
   appSubdir->Append(NS_LITERAL_STRING(kDesktopFolder));
 
-  SetStrongPtr(appData.directory, static_cast<nsIFile*>(appSubdir.get()));
-  // xreDirectory already has a refcount from NS_NewLocalFile
+  appData.directory = appSubdir;
   appData.xreDirectory = xreDirectory;
 
 #if defined(HAS_DLL_BLOCKLIST)
   appData.flags |=
     DllBlocklist_CheckStatus() ? NS_XRE_DLL_BLOCKLIST_ENABLED : 0;
 #endif
 
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
@@ -320,17 +316,17 @@ static int do_main(int argc, char* argv[
   appData.sandboxBrokerServices = brokerServices;
 #endif
 
 #ifdef LIBFUZZER
   if (getenv("LIBFUZZER"))
     XRE_LibFuzzerSetMain(argc, argv, libfuzzer_main);
 #endif
 
-  return XRE_main(argc, argv, &appData, mainFlags);
+  return XRE_main(argc, argv, appData, mainFlags);
 }
 
 static bool
 FileExists(const char *path)
 {
 #ifdef XP_WIN
   wchar_t wideDir[MAX_PATH];
   MultiByteToWideChar(CP_UTF8, 0, path, -1, wideDir, MAX_PATH);
--- a/build/appini_header.py
+++ b/build/appini_header.py
@@ -1,14 +1,14 @@
 # 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/.
 
 '''Parses a given application.ini file and outputs the corresponding
-   XULAppData structure as a C++ header file'''
+   StaticXREAppData structure as a C++ header file'''
 
 import ConfigParser
 import sys
 
 def main(output, file):
     config = ConfigParser.RawConfigParser()
     config.read(file)
     flags = set()
@@ -29,29 +29,26 @@ def main(output, file):
     if missing:
         print >>sys.stderr, \
             "Missing values in %s: %s" % (file, ', '.join(missing))
         sys.exit(1)
 
     if not 'Crash Reporter:serverurl' in appdata:
         appdata['Crash Reporter:serverurl'] = ''
 
-    output.write('''#include "nsXREAppData.h"
-             static const nsXREAppData sAppData = {
-                 sizeof(nsXREAppData),
-                 NULL, // directory
+    output.write('''#include "mozilla/XREAppData.h"
+             static const mozilla::StaticXREAppData sAppData = {
                  "%(App:vendor)s",
                  "%(App:name)s",
                  "%(App:remotingname)s",
                  "%(App:version)s",
                  "%(App:buildid)s",
                  "%(App:id)s",
                  NULL, // copyright
                  %(flags)s,
-                 NULL, // xreDirectory
                  "%(Gecko:minversion)s",
                  "%(Gecko:maxversion)s",
                  "%(Crash Reporter:serverurl)s",
                  %(App:profile)s
              };''' % appdata)
 
 if __name__ == '__main__':
     if len(sys.argv) != 1:
--- a/mozglue/android/APKOpen.cpp
+++ b/mozglue/android/APKOpen.cpp
@@ -439,17 +439,17 @@ FreeArgv(char** argv, int argc)
 {
   for (int ix=0; ix < argc; ix++) {
     // String was allocated with strndup, so need to use free to deallocate.
     free(argv[ix]);
   }
   delete[](argv);
 }
 
-typedef void (*GeckoStart_t)(JNIEnv*, char**, int, const nsXREAppData*);
+typedef void (*GeckoStart_t)(JNIEnv*, char**, int, const StaticXREAppData&);
 typedef int GeckoProcessType;
 
 extern "C" NS_EXPORT void MOZ_JNICALL
 Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv *jenv, jclass jc, jobjectArray jargs, int crashFd, int ipcFd)
 {
   int argc = 0;
   char** argv = CreateArgvFromObjectArray(jenv, jargs, &argc);
 
@@ -458,17 +458,17 @@ Java_org_mozilla_gecko_mozglue_GeckoLoad
     xul_dlsym("GeckoStart", &GeckoStart);
 
     if (GeckoStart == nullptr) {
       FreeArgv(argv, argc);
       return;
     }
 
     ElfLoader::Singleton.ExpectShutdown(false);
-    GeckoStart(jenv, argv, argc, &sAppData);
+    GeckoStart(jenv, argv, argc, sAppData);
     ElfLoader::Singleton.ExpectShutdown(true);
   } else {
     void (*fXRE_SetAndroidChildFds)(int, int);
     xul_dlsym("XRE_SetAndroidChildFds", &fXRE_SetAndroidChildFds);
 
     void (*fXRE_SetProcessType)(char*);
     xul_dlsym("XRE_SetProcessType", &fXRE_SetProcessType);
 
--- a/toolkit/xre/CreateAppData.cpp
+++ b/toolkit/xre/CreateAppData.cpp
@@ -2,164 +2,76 @@
 /* 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"
 #include "nsINIParser.h"
 #include "nsIFile.h"
 #include "nsAutoPtr.h"
-#include "mozilla/AppData.h"
+#include "mozilla/XREAppData.h"
 
 using namespace mozilla;
 
-nsresult
-XRE_CreateAppData(nsIFile* aINIFile, nsXREAppData **aAppData)
+static void
+ReadString(nsINIParser &parser, const char* section,
+           const char* key, XREAppData::CharPtr& result)
 {
-  NS_ENSURE_ARG(aINIFile && aAppData);
-
-  nsAutoPtr<ScopedAppData> data(new ScopedAppData());
-  if (!data)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  nsresult rv = XRE_ParseAppData(aINIFile, data);
-  if (NS_FAILED(rv))
-    return rv;
-
-  if (!data->directory) {
-    nsCOMPtr<nsIFile> appDir;
-    rv = aINIFile->GetParent(getter_AddRefs(appDir));
-    if (NS_FAILED(rv))
-      return rv;
-
-    appDir.forget(&data->directory);
-  }
-
-  *aAppData = data.forget();
-  return NS_OK;
-}
-
-struct ReadString {
-  const char *section;
-  const char *key;
-  const char **buffer;
-};
-
-static void
-ReadStrings(nsINIParser &parser, const ReadString *reads)
-{
-  nsresult rv;
   nsCString str;
-
-  while (reads->section) {
-    rv = parser.GetString(reads->section, reads->key, str);
-    if (NS_SUCCEEDED(rv)) {
-      SetAllocatedString(*reads->buffer, str);
-    }
-
-    ++reads;
+  nsresult rv = parser.GetString(section, key, str);
+  if (NS_SUCCEEDED(rv)) {
+    result = str.get();
   }
 }
 
 struct ReadFlag {
   const char *section;
   const char *key;
   uint32_t flag;
 };
 
 static void
-ReadFlags(nsINIParser &parser, const ReadFlag *reads, uint32_t *buffer)
+ReadFlag(nsINIParser &parser, const char* section,
+         const char* key, uint32_t flag, uint32_t& result)
 {
-  nsresult rv;
   char buf[6]; // large enough to hold "false"
-
-  while (reads->section) {
-    rv = parser.GetString(reads->section, reads->key, buf, sizeof(buf));
-    if (NS_SUCCEEDED(rv) || rv == NS_ERROR_LOSS_OF_SIGNIFICANT_DATA) {
-      if (buf[0] == '1' || buf[0] == 't' || buf[0] == 'T') {
-        *buffer |= reads->flag;
-      }
-      if (buf[0] == '0' || buf[0] == 'f' || buf[0] == 'F') {
-        *buffer &= ~reads->flag;
-      }
+  nsresult rv = parser.GetString(section, key, buf, sizeof(buf));
+  if (NS_SUCCEEDED(rv) || rv == NS_ERROR_LOSS_OF_SIGNIFICANT_DATA) {
+    if (buf[0] == '1' || buf[0] == 't' || buf[0] == 'T') {
+      result |= flag;
     }
-
-    ++reads;
+    if (buf[0] == '0' || buf[0] == 'f' || buf[0] == 'F') {
+      result &= ~flag;
+    }
   }
 }
 
 nsresult
-XRE_ParseAppData(nsIFile* aINIFile, nsXREAppData *aAppData)
+XRE_ParseAppData(nsIFile* aINIFile, XREAppData& aAppData)
 {
-  NS_ENSURE_ARG(aINIFile && aAppData);
+  NS_ENSURE_ARG(aINIFile);
 
   nsresult rv;
 
   nsINIParser parser;
   rv = parser.Init(aINIFile);
   if (NS_FAILED(rv))
     return rv;
 
-  nsCString str;
-
-  ReadString strings[] = {
-    { "App", "Vendor",        &aAppData->vendor },
-    { "App", "Name",          &aAppData->name },
-    { "App", "RemotingName",  &aAppData->remotingName },
-    { "App", "Version",       &aAppData->version },
-    { "App", "BuildID",       &aAppData->buildID },
-    { "App", "ID",            &aAppData->ID },
-    { "App", "Copyright",     &aAppData->copyright },
-    { "App", "Profile",       &aAppData->profile },
-    { nullptr }
-  };
-  ReadStrings(parser, strings);
-
-  ReadFlag flags[] = {
-    { "XRE", "EnableProfileMigrator", NS_XRE_ENABLE_PROFILE_MIGRATOR },
-    { nullptr }
-  };
-  ReadFlags(parser, flags, &aAppData->flags);
-
-  if (aAppData->size > offsetof(nsXREAppData, xreDirectory)) {
-    ReadString strings2[] = {
-      { "Gecko", "MinVersion", &aAppData->minVersion },
-      { "Gecko", "MaxVersion", &aAppData->maxVersion },
-      { nullptr }
-    };
-    ReadStrings(parser, strings2);
-  }
-
-  if (aAppData->size > offsetof(nsXREAppData, crashReporterURL)) {
-    ReadString strings3[] = {
-      { "Crash Reporter", "ServerURL", &aAppData->crashReporterURL },
-      { nullptr }
-    };
-    ReadStrings(parser, strings3);
-    ReadFlag flags2[] = {
-      { "Crash Reporter", "Enabled", NS_XRE_ENABLE_CRASH_REPORTER },
-      { nullptr }
-    };
-    ReadFlags(parser, flags2, &aAppData->flags);
-  }
-
-  if (aAppData->size > offsetof(nsXREAppData, UAName)) {
-    ReadString strings4[] = {
-      { "App", "UAName",    &aAppData->UAName },
-      { nullptr }
-    };
-    ReadStrings(parser, strings4);
-  }
+  ReadString(parser, "App", "Vendor", aAppData.vendor);
+  ReadString(parser, "App", "Name", aAppData.name),
+  ReadString(parser, "App", "RemotingName", aAppData.remotingName);
+  ReadString(parser, "App", "Version", aAppData.version);
+  ReadString(parser, "App", "BuildID", aAppData.buildID);
+  ReadString(parser, "App", "ID", aAppData.ID);
+  ReadString(parser, "App", "Copyright", aAppData.copyright);
+  ReadString(parser, "App", "Profile", aAppData.profile);
+  ReadString(parser, "Gecko", "MinVersion", aAppData.minVersion);
+  ReadString(parser, "Gecko", "MaxVersion", aAppData.maxVersion);
+  ReadString(parser, "Crash Reporter", "ServerURL", aAppData.crashReporterURL);
+  ReadString(parser, "App", "UAName", aAppData.UAName);
+  ReadFlag(parser, "XRE", "EnableProfileMigrator",
+           NS_XRE_ENABLE_PROFILE_MIGRATOR, aAppData.flags);
+  ReadFlag(parser, "Crash Reporter", "Enabled",
+           NS_XRE_ENABLE_CRASH_REPORTER, aAppData.flags);
 
   return NS_OK;
 }
-
-void
-XRE_FreeAppData(nsXREAppData *aAppData)
-{
-  if (!aAppData) {
-    NS_ERROR("Invalid arg");
-    return;
-  }
-
-  ScopedAppData* sad = static_cast<ScopedAppData*>(aAppData);
-  delete sad;
-}
--- a/toolkit/xre/ProfileReset.cpp
+++ b/toolkit/xre/ProfileReset.cpp
@@ -10,24 +10,27 @@
 #include "nsIWindowWatcher.h"
 
 #include "ProfileReset.h"
 
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsPrintfCString.h"
+#include "nsString.h"
 #include "nsToolkitCompsCID.h"
 #include "nsXPCOMCIDInternal.h"
-#include "nsXREAppData.h"
+#include "mozilla/XREAppData.h"
 
 #include "mozilla/Services.h"
 #include "prtime.h"
 
-extern const nsXREAppData* gAppData;
+using namespace mozilla;
+
+extern const XREAppData* gAppData;
 
 static const char kProfileProperties[] =
   "chrome://mozapps/locale/profile/profileSelection.properties";
 
 /**
  * Creates a new profile with a timestamp in the name to use for profile reset.
  */
 nsresult
--- a/toolkit/xre/nsAndroidStartup.cpp
+++ b/toolkit/xre/nsAndroidStartup.cpp
@@ -16,18 +16,20 @@
 #include "nsString.h"
 #include "nsIFile.h"
 #include "nsAppRunner.h"
 #include "APKOpen.h"
 #include "nsExceptionHandler.h"
 
 #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, MOZ_APP_NAME, args)
 
+using namespace mozilla;
+
 extern "C" NS_EXPORT void
-GeckoStart(JNIEnv* env, char** argv, int argc, const nsXREAppData* appData)
+GeckoStart(JNIEnv* env, char** argv, int argc, const StaticXREAppData& aAppData)
 {
     mozilla::jni::SetGeckoThreadEnv(env);
 
 #ifdef MOZ_CRASHREPORTER
     const struct mapping_info *info = getLibraryMapping();
     while (info->name) {
       CrashReporter::AddLibraryMapping(info->name, info->base,
                                        info->len, info->offset);
@@ -35,13 +37,16 @@ GeckoStart(JNIEnv* env, char** argv, int
     }
 #endif
 
     if (!argv) {
         LOG("Failed to get arguments for GeckoStart\n");
         return;
     }
 
+    XREAppData appData;
+    appData = aAppData;
+
     int result = XRE_main(argc, argv, appData, 0);
 
     if (result)
         LOG("XRE_main returned %d", result);
 }
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -16,17 +16,17 @@
 #include "mozilla/Poison.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/ScopeExit.h"
 #include "mozilla/Services.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/Telemetry.h"
 
 #include "nsAppRunner.h"
-#include "mozilla/AppData.h"
+#include "mozilla/XREAppData.h"
 #if defined(MOZ_UPDATER) && !defined(MOZ_WIDGET_ANDROID)
 #include "nsUpdateDriver.h"
 #endif
 #include "ProfileReset.h"
 
 #ifdef MOZ_INSTRUMENT_EVENT_LOOP
 #include "EventTracer.h"
 #endif
@@ -1603,33 +1603,33 @@ DumpHelp()
 
 #ifdef MOZ_X11
   printf("X11 options\n"
          "  --display=DISPLAY  X display to use\n"
          "  --sync             Make X calls synchronous\n");
 #endif
 #ifdef XP_UNIX
   printf("  --g-fatal-warnings Make all warnings fatal\n"
-         "\n%s options\n", gAppData->name);
+         "\n%s options\n", (const char*) gAppData->name);
 #endif
 
   printf("  -h or --help       Print this message.\n"
          "  -v or --version    Print %s version.\n"
          "  -P <profile>       Start with <profile>.\n"
          "  --profile <path>   Start with profile at <path>.\n"
          "  --migration        Start with migration wizard.\n"
          "  --ProfileManager   Start with ProfileManager.\n"
          "  --no-remote        Do not accept or send remote commands; implies\n"
          "                     --new-instance.\n"
          "  --new-instance     Open new instance, not a new window in running instance.\n"
          "  --UILocale <locale> Start with <locale> resources as UI Locale.\n"
-         "  --safe-mode        Disables extensions and themes for this session.\n", gAppData->name);
+         "  --safe-mode        Disables extensions and themes for this session.\n", (const char*) gAppData->name);
 
 #if defined(XP_WIN)
-  printf("  --console          Start %s with a debugging console.\n", gAppData->name);
+  printf("  --console          Start %s with a debugging console.\n", (const char*) gAppData->name);
 #endif
 
   // this works, but only after the components have registered.  so if you drop in a new command line handler, --help
   // won't not until the second run.
   // out of the bug, because we ship a component.reg file, it works correctly.
   DumpArbitraryHelp();
 }
 
@@ -1674,20 +1674,20 @@ static int MSCRTReportHook( int aReportT
 }
 
 #endif
 
 static inline void
 DumpVersion()
 {
   if (gAppData->vendor)
-    printf("%s ", gAppData->vendor);
-  printf("%s %s", gAppData->name, gAppData->version);
+    printf("%s ", (const char*) gAppData->vendor);
+  printf("%s %s", (const char*) gAppData->name, (const char*) gAppData->version);
   if (gAppData->copyright)
-      printf(", %s", gAppData->copyright);
+      printf(", %s", (const char*) gAppData->copyright);
   printf("\n");
 }
 
 #ifdef MOZ_ENABLE_XREMOTE
 static RemoteResult
 ParseRemoteCommandLine(nsCString& program,
                        const char** profile,
                        const char** username)
@@ -2798,17 +2798,17 @@ static void MakeOrSetMinidumpPath(nsIFil
 
     nsAutoString pathStr;
     if (NS_SUCCEEDED(dumpD->GetPath(pathStr)))
       CrashReporter::SetMinidumpPath(pathStr);
   }
 }
 #endif
 
-const nsXREAppData* gAppData = nullptr;
+const XREAppData* gAppData = nullptr;
 
 #ifdef MOZ_WIDGET_GTK
 static void MOZ_gdk_display_close(GdkDisplay *display)
 {
 #if CLEANUP_MEMORY
   // XXX wallpaper for bug 417163: don't close the Display if we're using the
   // Qt theme because we crash (in Qt code) when using jemalloc.
   bool skip_display_close = false;
@@ -3015,34 +3015,34 @@ public:
 #endif
   {};
 
   ~XREMain() {
     mScopedXPCOM = nullptr;
     mAppData = nullptr;
   }
 
-  int XRE_main(int argc, char* argv[], const nsXREAppData* aAppData);
+  int XRE_main(int argc, char* argv[], const XREAppData& aAppData);
   int XRE_mainInit(bool* aExitFlag);
   int XRE_mainStartup(bool* aExitFlag);
   nsresult XRE_mainRun();
 
   nsCOMPtr<nsINativeAppSupport> mNativeApp;
   nsCOMPtr<nsIToolkitProfileService> mProfileSvc;
   nsCOMPtr<nsIFile> mProfD;
   nsCOMPtr<nsIFile> mProfLD;
   nsCOMPtr<nsIProfileLock> mProfileLock;
 #ifdef MOZ_ENABLE_XREMOTE
   nsCOMPtr<nsIRemoteService> mRemoteService;
   nsProfileLock mRemoteLock;
   nsCOMPtr<nsIFile> mRemoteLockDir;
 #endif
 
   UniquePtr<ScopedXPCOMStartup> mScopedXPCOM;
-  nsAutoPtr<mozilla::ScopedAppData> mAppData;
+  UniquePtr<XREAppData> mAppData;
 
   nsXREDirProvider mDirProvider;
   nsAutoCString mProfileName;
   nsAutoCString mDesktopStartupID;
 
   bool mStartOffline;
   bool mShuttingDown;
 #ifdef MOZ_ENABLE_XREMOTE
@@ -3154,17 +3154,17 @@ XREMain::XRE_mainInit(bool* aExitFlag)
   else if (ar == ARG_FOUND) {
     nsCOMPtr<nsIFile> overrideLF;
     rv = XRE_GetFileFromPath(override, getter_AddRefs(overrideLF));
     if (NS_FAILED(rv)) {
       Output(true, "Error: unrecognized override.ini path.\n");
       return 1;
     }
 
-    rv = XRE_ParseAppData(overrideLF, mAppData.get());
+    rv = XRE_ParseAppData(overrideLF, *mAppData);
     if (NS_FAILED(rv)) {
       Output(true, "Couldn't read override.ini");
       return 1;
     }
   }
 
   // Check sanity and correctness of app data.
 
@@ -3193,43 +3193,41 @@ XREMain::XRE_mainInit(bool* aExitFlag)
 
 #ifdef XP_MACOSX
     nsCOMPtr<nsIFile> parent;
     greDir->GetParent(getter_AddRefs(parent));
     greDir = parent.forget();
     greDir->AppendNative(NS_LITERAL_CSTRING("Resources"));
 #endif
 
-    greDir.forget(&mAppData->xreDirectory);
+    mAppData->xreDirectory = greDir;
   }
 
   if (!mAppData->directory) {
-    NS_IF_ADDREF(mAppData->directory = mAppData->xreDirectory);
+    mAppData->directory = mAppData->xreDirectory;
+  }
+
+  if (!mAppData->minVersion) {
+    Output(true, "Error: Gecko:MinVersion not specified in application.ini\n");
+    return 1;
   }
 
-  if (mAppData->size > offsetof(nsXREAppData, minVersion)) {
-    if (!mAppData->minVersion) {
-      Output(true, "Error: Gecko:MinVersion not specified in application.ini\n");
-      return 1;
-    }
-
-    if (!mAppData->maxVersion) {
-      // If no maxVersion is specified, we assume the app is only compatible
-      // with the initial preview release. Do not increment this number ever!
-      SetAllocatedString(mAppData->maxVersion, "1.*");
-    }
-
-    if (mozilla::Version(mAppData->minVersion) > gToolkitVersion ||
-        mozilla::Version(mAppData->maxVersion) < gToolkitVersion) {
-      Output(true, "Error: Platform version '%s' is not compatible with\n"
-             "minVersion >= %s\nmaxVersion <= %s\n",
-             gToolkitVersion,
-             mAppData->minVersion, mAppData->maxVersion);
-      return 1;
-    }
+  if (!mAppData->maxVersion) {
+    // If no maxVersion is specified, we assume the app is only compatible
+    // with the initial preview release. Do not increment this number ever!
+    mAppData->maxVersion = "1.*";
+  }
+
+  if (mozilla::Version(mAppData->minVersion) > gToolkitVersion ||
+      mozilla::Version(mAppData->maxVersion) < gToolkitVersion) {
+    Output(true, "Error: Platform version '%s' is not compatible with\n"
+           "minVersion >= %s\nmaxVersion <= %s\n",
+           (const char*) gToolkitVersion, (const char*) mAppData->minVersion,
+           (const char*) mAppData->maxVersion);
+    return 1;
   }
 
   rv = mDirProvider.Initialize(mAppData->directory, mAppData->xreDirectory);
   if (NS_FAILED(rv))
     return 1;
 
 #ifdef MOZ_CRASHREPORTER
   if (EnvHasValue("MOZ_CRASHREPORTER")) {
@@ -4522,17 +4520,17 @@ XRE_CreateStatsObject()
 }
 
 /*
  * XRE_main - A class based main entry point used by most platforms.
  *            Note that on OSX, aAppData->xreDirectory will point to
  *            .app/Contents/Resources.
  */
 int
-XREMain::XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
+XREMain::XRE_main(int argc, char* argv[], const XREAppData& aAppData)
 {
   ScopedLogging log;
 
   // NB: this must happen after the creation of |ScopedLogging log| since
   // ScopedLogging::ScopedLogging calls NS_LogInit, and
   // XRE_CreateStatsObject calls Telemetry::CreateStatisticsRecorder,
   // and NS_LogInit must be called before Telemetry::CreateStatisticsRecorder.
   // NS_LogInit must be called before Telemetry::CreateStatisticsRecorder
@@ -4551,26 +4549,22 @@ XREMain::XRE_main(int argc, char* argv[]
   PROFILER_LABEL("Startup", "XRE_Main",
     js::ProfileEntry::Category::OTHER);
 
   nsresult rv = NS_OK;
 
   gArgc = argc;
   gArgv = argv;
 
-  NS_ENSURE_TRUE(aAppData, 2);
-
-  mAppData = new ScopedAppData(aAppData);
-  if (!mAppData)
-    return 1;
+  mAppData = MakeUnique<XREAppData>(aAppData);
   if (!mAppData->remotingName) {
-    SetAllocatedString(mAppData->remotingName, mAppData->name);
+    mAppData->remotingName = mAppData->name;
   }
   // used throughout this file
-  gAppData = mAppData;
+  gAppData = mAppData.get();
 
   nsCOMPtr<nsIFile> binFile;
   rv = XRE_GetBinaryPath(argv[0], getter_AddRefs(binFile));
   NS_ENSURE_SUCCESS(rv, 1);
 
   rv = binFile->GetPath(gAbsoluteArgv0Path);
   NS_ENSURE_SUCCESS(rv, 1);
 
@@ -4692,17 +4686,17 @@ XREMain::XRE_main(int argc, char* argv[]
 }
 
 void
 XRE_StopLateWriteChecks(void) {
   mozilla::StopLateWriteChecks();
 }
 
 int
-XRE_main(int argc, char* argv[], const nsXREAppData* aAppData, uint32_t aFlags)
+XRE_main(int argc, char* argv[], const XREAppData& aAppData, uint32_t aFlags)
 {
   XREMain main;
 
   int result = main.XRE_main(argc, argv, aAppData);
   mozilla::RecordShutdownEndTimeStamp();
   return result;
 }
 
--- a/toolkit/xre/nsAppRunner.h
+++ b/toolkit/xre/nsAppRunner.h
@@ -37,20 +37,18 @@ class nsIToolkitProfileService;
 class nsIFile;
 class nsIProfileLock;
 class nsIProfileUnlocker;
 class nsIFactory;
 class nsString;
 
 extern nsXREDirProvider* gDirServiceProvider;
 
-// NOTE: gAppData will be null in embedded contexts. The "size" parameter
-// will be the size of the original structure passed to XRE_main, but the
-// structure will have all of the members available.
-extern const nsXREAppData* gAppData;
+// NOTE: gAppData will be null in embedded contexts.
+extern const mozilla::XREAppData* gAppData;
 extern bool gSafeMode;
 
 extern int    gArgc;
 extern char **gArgv;
 extern int    gRestartArgc;
 extern char **gRestartArgv;
 extern bool gLogConsoleErrors;
 extern nsString gAbsoluteArgv0Path;
--- a/toolkit/xre/nsNativeAppSupportWin.cpp
+++ b/toolkit/xre/nsNativeAppSupportWin.cpp
@@ -680,17 +680,17 @@ nsNativeAppSupportWin::StartDDE() {
     // Initialize DDE.
     NS_ENSURE_TRUE( DMLERR_NO_ERROR == DdeInitialize( &mInstance,
                                                       nsNativeAppSupportWin::HandleDDENotification,
                                                       APPCLASS_STANDARD,
                                                       0 ),
                     NS_ERROR_FAILURE );
 
     // Allocate DDE strings.
-    NS_ENSURE_TRUE( ( mApplication = DdeCreateStringHandleA( mInstance, (char*) gAppData->name, CP_WINANSI ) ) && InitTopicStrings(),
+    NS_ENSURE_TRUE( ( mApplication = DdeCreateStringHandleA( mInstance, (char*)(const char*) gAppData->name, CP_WINANSI ) ) && InitTopicStrings(),
                     NS_ERROR_FAILURE );
 
     // Next step is to register a DDE service.
     NS_ENSURE_TRUE( DdeNameService( mInstance, mApplication, 0, DNS_REGISTER ), NS_ERROR_FAILURE );
 
 #if MOZ_DEBUG_DDE
     printf( "DDE server started\n" );
 #endif
rename from xpcom/build/nsXREAppData.h
rename to xpcom/build/XREAppData.h
--- a/xpcom/build/nsXREAppData.h
+++ b/xpcom/build/XREAppData.h
@@ -4,147 +4,196 @@
  * 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/. */
 
 #ifndef nsXREAppData_h
 #define nsXREAppData_h
 
 #include <stdint.h>
 #include "mozilla/Attributes.h"
-
-class nsIFile;
+#include "nsCOMPtr.h"
+#include "nsCRTGlue.h"
+#include "nsIFile.h"
 
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
 namespace sandbox {
 class BrokerServices;
 }
 #endif
 
+namespace mozilla {
+
+struct StaticXREAppData;
+
 /**
  * Application-specific data needed to start the apprunner.
- *
- * @note When this structure is allocated and manipulated by XRE_CreateAppData,
- *       string fields will be allocated with moz_xmalloc, and interface pointers
- *       are strong references.
  */
-struct nsXREAppData
+class XREAppData
 {
-  /**
-   * This should be set to sizeof(nsXREAppData). This structure may be
-   * extended in future releases, and this ensures that binary compatibility
-   * is maintained.
-   */
-  uint32_t size;
+public:
+  XREAppData() { }
+  ~XREAppData() { }
+  XREAppData(const XREAppData& aOther)
+  {
+    *this = aOther;
+  }
+
+  XREAppData& operator=(const StaticXREAppData& aOther);
+  XREAppData& operator=(const XREAppData& aOther);
+  XREAppData& operator=(XREAppData&& aOther) = default;
+
+  struct NSFreePolicy
+  {
+    void operator()(const void* ptr) {
+      NS_Free(const_cast<void*>(ptr));
+    }
+  };
+
+  // Lots of code reads these fields directly like a struct, so rather
+  // than using UniquePtr directly, use an auto-converting wrapper.
+  class CharPtr
+  {
+  public:
+    explicit CharPtr() = default;
+    explicit CharPtr(const char* v)
+    {
+      *this = v;
+    }
+    CharPtr(CharPtr&&) = default;
+    ~CharPtr() = default;
+
+    CharPtr& operator=(const char* v)
+    {
+      if (v) {
+        mValue.reset(NS_strdup(v));
+      } else {
+        mValue = nullptr;
+      }
+      return *this;
+    }
+    CharPtr& operator=(const CharPtr& v)
+    {
+      *this = (const char*) v;
+      return *this;
+    }
+
+    operator const char*() const {
+      return mValue.get();
+    }
+
+  private:
+    UniquePtr<const char, NSFreePolicy> mValue;
+  };
 
   /**
    * The directory of the application to be run. May be null if the
    * xulrunner and the app are installed into the same directory.
    */
-  nsIFile* MOZ_NON_OWNING_REF directory;
+  nsCOMPtr<nsIFile> directory;
 
   /**
    * The name of the application vendor. This must be ASCII, and is normally
    * mixed-case, e.g. "Mozilla". Optional (may be null), but highly
    * recommended. Must not be the empty string.
    */
-  const char* vendor;
+  CharPtr vendor;
 
   /**
    * The name of the application. This must be ASCII, and is normally
    * mixed-case, e.g. "Firefox". Required (must not be null or an empty
    * string).
    */
-  const char* name;
+  CharPtr name;
 
   /**
    * The internal name of the application for remoting purposes. When left
    * unspecified, "name" is used instead. This must be ASCII, and is normally
    * lowercase, e.g. "firefox". Optional (may be null but not an empty string).
    */
-  const char* remotingName;
+  CharPtr remotingName;
 
   /**
    * The major version, e.g. "0.8.0+". Optional (may be null), but
    * required for advanced application features such as the extension
    * manager and update service. Must not be the empty string.
    */
-  const char* version;
+  CharPtr version;
 
   /**
    * The application's build identifier, e.g. "2004051604"
    */
-  const char* buildID;
+  CharPtr buildID;
 
   /**
    * The application's UUID. Used by the extension manager to determine
    * compatible extensions. Optional, but required for advanced application
    * features such as the extension manager and update service.
    *
    * This has traditionally been in the form
    * "{AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE}" but for new applications
    * a more readable form is encouraged: "appname@vendor.tld". Only
    * the following characters are allowed: a-z A-Z 0-9 - . @ _ { } *
    */
-  const char* ID;
+  CharPtr ID;
 
   /**
    * The copyright information to print for the -h commandline flag,
    * e.g. "Copyright (c) 2003 mozilla.org".
    */
-  const char* copyright;
+  CharPtr copyright;
 
   /**
    * Combination of NS_XRE_ prefixed flags (defined below).
    */
-  uint32_t flags;
+  uint32_t flags = 0;
 
   /**
    * The location of the XRE. XRE_main may not be able to figure this out
    * programatically.
    */
-  nsIFile* MOZ_NON_OWNING_REF xreDirectory;
+  nsCOMPtr<nsIFile> xreDirectory;
 
   /**
    * The minimum/maximum compatible XRE version.
    */
-  const char* minVersion;
-  const char* maxVersion;
+  CharPtr minVersion;
+  CharPtr maxVersion;
 
   /**
    * The server URL to send crash reports to.
    */
-  const char* crashReporterURL;
+  CharPtr crashReporterURL;
 
   /**
    * The profile directory that will be used. Optional (may be null). Must not
    * be the empty string, must be ASCII. The path is split into components
    * along the path separator characters '/' and '\'.
    *
    * The application data directory ("UAppData", see below) is normally
    * composed as follows, where $HOME is platform-specific:
    *
    *   UAppData = $HOME[/$vendor]/$name
    *
    * If present, the 'profile' string will be used instead of the combination of
    * vendor and name as follows:
    *
    *   UAppData = $HOME/$profile
    */
-  const char* profile;
+  CharPtr profile;
 
   /**
    * The application name to use in the User Agent string.
    */
-  const char* UAName;
+  CharPtr UAName;
 
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
   /**
    * Chromium sandbox BrokerServices.
    */
-  sandbox::BrokerServices* sandboxBrokerServices;
+  sandbox::BrokerServices* sandboxBrokerServices = nullptr;
 #endif
 };
 
 /**
  * Indicates whether or not the profile migrator service may be
  * invoked at startup when creating a profile.
  */
 #define NS_XRE_ENABLE_PROFILE_MIGRATOR (1 << 1)
@@ -156,9 +205,34 @@ struct nsXREAppData
  */
 #define NS_XRE_DLL_BLOCKLIST_ENABLED (1 << 2)
 
 /**
  * Indicates whether or not to use Breakpad crash reporting.
  */
 #define NS_XRE_ENABLE_CRASH_REPORTER (1 << 3)
 
-#endif // nsXREAppData_h
+/**
+ * A static version of the XRE app data is compiled into the application
+ * so that it is not necessary to read application.ini at startup.
+ *
+ * This structure is initialized into and matches nsXREAppData
+ */
+struct StaticXREAppData
+{
+  const char* vendor;
+  const char* name;
+  const char* remotingName;
+  const char* version;
+  const char* buildID;
+  const char* ID;
+  const char* copyright;
+  uint32_t flags;
+  const char* minVersion;
+  const char* maxVersion;
+  const char* crashReporterURL;
+  const char* profile;
+  const char* UAName;
+};
+
+} // namespace mozilla
+
+#endif // XREAppData_h
--- a/xpcom/build/moz.build
+++ b/xpcom/build/moz.build
@@ -3,32 +3,32 @@
 # 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/.
 
 EXPORTS += [
     'nsXPCOM.h',
     'nsXPCOMCID.h',
     'nsXPCOMCIDInternal.h',
-    'nsXREAppData.h',
     'nsXULAppAPI.h',
     'XREChildData.h',
     'xrecore.h',
     'XREShellData.h',
 ]
 
 EXPORTS.mozilla += [
     'FileLocation.h',
     'IOInterposer.h',
     'LateWriteChecks.h',
     'Omnijar.h',
     'PoisonIOInterposer.h',
     'ServiceList.h',
     'Services.h',
     'XPCOM.h',
+    'XREAppData.h',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     EXPORTS += ['nsWindowsDllInterceptor.h']
     EXPORTS.mozilla += ['perfprobe.h']
     SOURCES += [
         'perfprobe.cpp',
         'PoisonIOInterposerBase.cpp',
--- a/xpcom/build/nsXULAppAPI.h
+++ b/xpcom/build/nsXULAppAPI.h
@@ -7,17 +7,17 @@
 #ifndef _nsXULAppAPI_h__
 #define _nsXULAppAPI_h__
 
 #include "nsID.h"
 #include "xrecore.h"
 #include "nsXPCOM.h"
 #include "nsISupports.h"
 #include "mozilla/Logging.h"
-#include "nsXREAppData.h"
+#include "mozilla/XREAppData.h"
 #include "js/TypeDecls.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Vector.h"
 #include "mozilla/TimeStamp.h"
 #include "XREChildData.h"
 #include "XREShellData.h"
@@ -199,17 +199,17 @@
  * @param aFlags    Platform specific flags.
  *
  * @return         A native result code suitable for returning from main().
  *
  * @note           If the binary is linked against the standalone XPCOM glue,
  *                 XPCOMGlueStartup() should be called before this method.
  */
 XRE_API(int,
-        XRE_main, (int argc, char* argv[], const nsXREAppData* aAppData,
+        XRE_main, (int argc, char* argv[], const mozilla::XREAppData& aAppData,
                    uint32_t aFlags))
 
 /**
  * Given a path relative to the current working directory (or an absolute
  * path), return an appropriate nsIFile object.
  *
  * @note Pass UTF8 strings on Windows... native charset on other platforms.
  */
@@ -357,43 +357,25 @@ XRE_API(void,
 
 /**
  * Terminate embedding started with XRE_InitEmbedding or XRE_InitEmbedding2
  */
 XRE_API(void,
         XRE_TermEmbedding, ())
 
 /**
- * Create a new nsXREAppData structure from an application.ini file.
- *
- * @param aINIFile The application.ini file to parse.
- * @param aAppData A newly-allocated nsXREAppData structure. The caller is
- *                 responsible for freeing this structure using
- *                 XRE_FreeAppData.
- */
-XRE_API(nsresult,
-        XRE_CreateAppData, (nsIFile* aINIFile,
-                            nsXREAppData** aAppData))
-
-/**
  * Parse an INI file (application.ini or override.ini) into an existing
  * nsXREAppData structure.
  *
  * @param aINIFile The INI file to parse
  * @param aAppData The nsXREAppData structure to fill.
  */
 XRE_API(nsresult,
         XRE_ParseAppData, (nsIFile* aINIFile,
-                           nsXREAppData* aAppData))
-
-/**
- * Free a nsXREAppData structure that was allocated with XRE_CreateAppData.
- */
-XRE_API(void,
-        XRE_FreeAppData, (nsXREAppData* aAppData))
+                           mozilla::XREAppData& aAppData))
 
 enum GeckoProcessType
 {
   GeckoProcessType_Default = 0,
 
   GeckoProcessType_Plugin,
   GeckoProcessType_Content,
 
deleted file mode 100644
--- a/xpcom/glue/AppData.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- 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/. */
-
-#ifndef mozilla_AppData_h
-#define mozilla_AppData_h
-
-#include "nsXREAppData.h"
-#include "nscore.h"
-#include "nsStringGlue.h"
-#include "nsISupportsUtils.h"
-
-namespace mozilla {
-
-// Like nsXREAppData, but releases all strong refs/allocated memory
-// in the destructor.
-class ScopedAppData : public nsXREAppData
-{
-public:
-  ScopedAppData()
-  {
-    Zero();
-    this->size = sizeof(*this);
-  }
-
-  explicit ScopedAppData(const nsXREAppData* aAppData);
-
-  void Zero() { memset(this, 0, sizeof(*this)); }
-
-  ~ScopedAppData();
-};
-
-/**
- * Given |aStr| is holding a string allocated with NS_Alloc, or null:
- * replace the value in |aStr| with a new value.
- *
- * @param aNewValue Null is permitted. The string is cloned with NS_strdup.
- */
-void SetAllocatedString(const char*& aStr, const char* aNewValue);
-
-/**
- * Given "str" is holding a string allocated with NS_Alloc, or null:
- * replace the value in "str" with a new value.
- *
- * @param aNewValue If |aNewValue| is the empty string, |aStr| will be set
- *                  to null.
- */
-void SetAllocatedString(const char*& aStr, const nsACString& aNewValue);
-
-template<class T>
-void
-SetStrongPtr(T*& aPtr, T* aNewValue)
-{
-  NS_IF_RELEASE(aPtr);
-  aPtr = aNewValue;
-  NS_IF_ADDREF(aPtr);
-}
-
-} // namespace mozilla
-
-#endif
rename from xpcom/glue/AppData.cpp
rename to xpcom/glue/XREAppData.cpp
--- a/xpcom/glue/AppData.cpp
+++ b/xpcom/glue/XREAppData.cpp
@@ -1,95 +1,56 @@
 /* -*- 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 "mozilla/AppData.h"
-#include "nsXULAppAPI.h"
-#include "nsINIParser.h"
-#include "nsIFile.h"
+#include "mozilla/XREAppData.h"
 #include "nsCRTGlue.h"
-#include "nsAutoPtr.h"
 
 namespace mozilla {
 
-void
-SetAllocatedString(const char*& aStr, const char* aNewValue)
+XREAppData&
+XREAppData::operator=(const StaticXREAppData& aOther)
 {
-  NS_Free(const_cast<char*>(aStr));
-  if (aNewValue) {
-    aStr = NS_strdup(aNewValue);
-  } else {
-    aStr = nullptr;
-  }
-}
+  vendor = aOther.vendor;
+  name = aOther.name;
+  remotingName = aOther.remotingName;
+  version = aOther.version;
+  buildID = aOther.buildID;
+  ID = aOther.ID;
+  copyright = aOther.copyright;
+  flags = aOther.flags;
+  minVersion = aOther.minVersion;
+  maxVersion = aOther.maxVersion;
+  crashReporterURL = aOther.crashReporterURL;
+  profile = aOther.profile;
+  UAName = aOther.UAName;
 
-void
-SetAllocatedString(const char*& aStr, const nsACString& aNewValue)
-{
-  NS_Free(const_cast<char*>(aStr));
-  if (aNewValue.IsEmpty()) {
-    aStr = nullptr;
-  } else {
-    aStr = ToNewCString(aNewValue);
-  }
+  return *this;
 }
 
-ScopedAppData::ScopedAppData(const nsXREAppData* aAppData)
+XREAppData&
+XREAppData::operator=(const XREAppData& aOther)
 {
-  Zero();
-
-  this->size = aAppData->size;
-
-  SetAllocatedString(this->vendor, aAppData->vendor);
-  SetAllocatedString(this->name, aAppData->name);
-  SetAllocatedString(this->remotingName, aAppData->remotingName);
-  SetAllocatedString(this->version, aAppData->version);
-  SetAllocatedString(this->buildID, aAppData->buildID);
-  SetAllocatedString(this->ID, aAppData->ID);
-  SetAllocatedString(this->copyright, aAppData->copyright);
-  SetAllocatedString(this->profile, aAppData->profile);
-  SetStrongPtr(this->directory, aAppData->directory);
-  this->flags = aAppData->flags;
-
-  if (aAppData->size > offsetof(nsXREAppData, xreDirectory)) {
-    SetStrongPtr(this->xreDirectory, aAppData->xreDirectory);
-    SetAllocatedString(this->minVersion, aAppData->minVersion);
-    SetAllocatedString(this->maxVersion, aAppData->maxVersion);
-  }
-
-  if (aAppData->size > offsetof(nsXREAppData, crashReporterURL)) {
-    SetAllocatedString(this->crashReporterURL, aAppData->crashReporterURL);
-  }
-
-  if (aAppData->size > offsetof(nsXREAppData, UAName)) {
-    SetAllocatedString(this->UAName, aAppData->UAName);
-  }
-
+  directory = aOther.directory;
+  vendor = aOther.vendor;
+  name = aOther.name;
+  remotingName = aOther.remotingName;
+  version = aOther.version;
+  buildID = aOther.buildID;
+  ID = aOther.ID;
+  copyright = aOther.copyright;
+  flags = aOther.flags;
+  xreDirectory = aOther.xreDirectory;
+  minVersion = aOther.minVersion;
+  maxVersion = aOther.maxVersion;
+  crashReporterURL = aOther.crashReporterURL;
+  profile = aOther.profile;
+  UAName = aOther.UAName;
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
-  sandboxBrokerServices = aAppData->sandboxBrokerServices;
+  sandboxBrokerServices = aOther.sandboxBrokerServices;
 #endif
-}
-
-ScopedAppData::~ScopedAppData()
-{
-  SetAllocatedString(this->vendor, nullptr);
-  SetAllocatedString(this->name, nullptr);
-  SetAllocatedString(this->remotingName, nullptr);
-  SetAllocatedString(this->version, nullptr);
-  SetAllocatedString(this->buildID, nullptr);
-  SetAllocatedString(this->ID, nullptr);
-  SetAllocatedString(this->copyright, nullptr);
-  SetAllocatedString(this->profile, nullptr);
-
-  NS_IF_RELEASE(this->directory);
-
-  SetStrongPtr(this->xreDirectory, (nsIFile*)nullptr);
-  SetAllocatedString(this->minVersion, nullptr);
-  SetAllocatedString(this->maxVersion, nullptr);
-
-  SetAllocatedString(this->crashReporterURL, nullptr);
-  SetAllocatedString(this->UAName, nullptr);
+  return *this;
 }
 
 } // namespace mozilla
--- a/xpcom/glue/moz.build
+++ b/xpcom/glue/moz.build
@@ -62,17 +62,16 @@ EXPORTS += [
     'nsTWeakRef.h',
     'nsVersionComparator.h',
     'nsWeakReference.h',
     'nsXPTCUtils.h',
     'PLDHashTable.h',
 ]
 
 EXPORTS.mozilla += [
-    'AppData.h',
     'AutoRestore.h',
     'BlockingResourceBase.h',
     'CondVar.h',
     'DeadlockDetector.h',
     'EnumeratedArrayCycleCollection.h',
     'FileUtils.h',
     'GenericFactory.h',
     'IntentionalCrash.h',
--- a/xpcom/glue/objs.mozbuild
+++ b/xpcom/glue/objs.mozbuild
@@ -1,16 +1,15 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 xpcom_glue_src_lcppsrcs = [
-    'AppData.cpp',
     'FileUtils.cpp',
     'nsArrayEnumerator.cpp',
     'nsArrayUtils.cpp',
     'nsCategoryCache.cpp',
     'nsClassInfoImpl.cpp',
     'nsCOMArray.cpp',
     'nsComponentManagerUtils.cpp',
     'nsCOMPtr.cpp',
@@ -25,16 +24,17 @@ xpcom_glue_src_lcppsrcs = [
     'nsMemory.cpp',
     'nsQuickSort.cpp',
     'nsTArray.cpp',
     'nsThreadUtils.cpp',
     'nsTObserverArray.cpp',
     'nsVersionComparator.cpp',
     'nsWeakReference.cpp',
     'PLDHashTable.cpp',
+    'XREAppData.cpp',
 ]
 
 xpcom_glue_src_cppsrcs = [
     '/xpcom/glue/%s' % s for s in xpcom_glue_src_lcppsrcs
 ]
 
 xpcom_gluens_src_lcppsrcs = [
     'BlockingResourceBase.cpp',
--- a/xpcom/system/nsIXULAppInfo.idl
+++ b/xpcom/system/nsIXULAppInfo.idl
@@ -8,46 +8,46 @@
  * A scriptable interface to the nsXULAppAPI structure. See nsXULAppAPI.h for
  * a detailed description of each attribute.
  */
 
 [scriptable, uuid(ddea4f31-3c5e-4769-ac68-21ab4b3d7845)]
 interface nsIXULAppInfo : nsIPlatformInfo
 {
   /**
-   * @see nsXREAppData.vendor
-   * @returns an empty string if nsXREAppData.vendor is not set.
+   * @see XREAppData.vendor
+   * @returns an empty string if XREAppData.vendor is not set.
    */
   readonly attribute ACString vendor;
 
   /**
-   * @see nsXREAppData.name
+   * @see XREAppData.name
    */
   readonly attribute ACString name;
 
   /**
-   * @see nsXREAppData.ID
-   * @returns an empty string if nsXREAppData.ID is not set.
+   * @see XREAppData.ID
+   * @returns an empty string if XREAppData.ID is not set.
    */
   readonly attribute ACString ID;
 
   /**
    * The version of the XUL application. It is different than the
    * version of the XULRunner platform. Be careful about which one you want.
    *
-   * @see nsXREAppData.version
-   * @returns an empty string if nsXREAppData.version is not set.
+   * @see XREAppData.version
+   * @returns an empty string if XREAppData.version is not set.
    */
   readonly attribute ACString version;
 
   /**
    * The build ID/date of the application. For xulrunner applications,
    * this will be different than the build ID of the platform. Be careful
    * about which one you want.
    */
   readonly attribute ACString appBuildID;
 
   /**
-   * @see nsXREAppData.UAName
-   * @returns an empty string if nsXREAppData.UAName is not set.
+   * @see XREAppData.UAName
+   * @returns an empty string if XREAppData.UAName is not set.
    */
   readonly attribute ACString UAName;
 };