Bug 695843 part 9 - Use FileLocations in the component manager. r=bsmedberg
authorMike Hommey <mh+mozilla@glandium.org>
Tue, 08 Nov 2011 18:10:51 +0100
changeset 82251 502c67d69baa1c2e214781d5d92df7db9e4c0918
parent 82250 2dd63b2aa323477c6ae9ccaed57b5558c109b164
child 82252 792a9ba2aa26628e4eb540b51dfe66f6479d6e06
push idunknown
push userunknown
push dateunknown
reviewersbsmedberg
bugs695843
milestone11.0a1
Bug 695843 part 9 - Use FileLocations in the component manager. r=bsmedberg
chrome/src/nsChromeRegistry.h
chrome/src/nsChromeRegistryChrome.cpp
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/loader/mozJSComponentLoader.h
xpcom/components/ManifestParser.cpp
xpcom/components/ManifestParser.h
xpcom/components/ModuleLoader.h
xpcom/components/nsComponentManager.cpp
xpcom/components/nsComponentManager.h
xpcom/components/nsNativeComponentLoader.cpp
xpcom/components/nsNativeComponentLoader.h
xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
xpcom/reflect/xptinfo/src/xptiprivate.h
--- a/chrome/src/nsChromeRegistry.h
+++ b/chrome/src/nsChromeRegistry.h
@@ -57,16 +57,17 @@
 #include "nsTHashtable.h"
 #include "nsURIHashKey.h"
 #include "nsInterfaceHashtable.h"
 #include "nsXULAppAPI.h"
 #include "nsIResProtocolHandler.h"
 #include "nsIXPConnect.h"
 
 #include "mozilla/Omnijar.h"
+#include "mozilla/FileLocation.h"
 
 class nsIDOMWindow;
 class nsIURL;
 
 // The chrome registry is actually split between nsChromeRegistryChrome and
 // nsChromeRegistryContent. The work/data that is common to both resides in
 // the shared nsChromeRegistry implementation, with operations that only make
 // sense for one side erroring out in the other.
@@ -134,39 +135,31 @@ protected:
   static nsresult GetProviderAndPath(nsIURL* aChromeURL,
                                      nsACString& aProvider, nsACString& aPath);
 
 public:
   static already_AddRefed<nsChromeRegistry> GetSingleton();
 
   struct ManifestProcessingContext
   {
-    ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile)
+    ManifestProcessingContext(NSLocationType aType, mozilla::FileLocation &aFile)
       : mType(aType)
       , mFile(aFile)
-      , mPath(NULL)
-    { }
-
-    ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile, const char* aPath)
-      : mType(aType)
-      , mFile(aFile)
-      , mPath(aPath)
     { }
 
     ~ManifestProcessingContext()
     { }
 
     nsIURI* GetManifestURI();
     nsIXPConnect* GetXPConnect();
 
     already_AddRefed<nsIURI> ResolveURI(const char* uri);
 
     NSLocationType mType;
-    nsILocalFile* mFile;
-    const char* mPath;
+    mozilla::FileLocation mFile;
     nsCOMPtr<nsIURI> mManifestURI;
     nsCOMPtr<nsIXPConnect> mXPConnect;
   };
 
   virtual void ManifestContent(ManifestProcessingContext& cx, int lineno,
                                char *const * argv, bool platform,
                                bool contentaccessible) = 0;
   virtual void ManifestLocale(ManifestProcessingContext& cx, int lineno,
--- a/chrome/src/nsChromeRegistryChrome.cpp
+++ b/chrome/src/nsChromeRegistryChrome.cpp
@@ -783,37 +783,19 @@ nsChromeRegistryChrome::GetXULOverlays(n
   return NS_NewArrayEnumerator(aResult, *parray);
 }
 #endif // MOZ_XUL
 
 nsIURI*
 nsChromeRegistry::ManifestProcessingContext::GetManifestURI()
 {
   if (!mManifestURI) {
-    nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
-    if (!io) {
-      NS_WARNING("No IO service trying to process chrome manifests");
-      return NULL;
-    }
-
-    if (mPath) {
-      nsCOMPtr<nsIURI> fileURI;
-      io->NewFileURI(mFile, getter_AddRefs(fileURI));
-
-      nsCAutoString spec;
-      fileURI->GetSpec(spec);
-      spec.Insert(NS_LITERAL_CSTRING("jar:"), 0);
-      spec.AppendLiteral("!/");
-      spec.Append(mPath);
-
-      NS_NewURI(getter_AddRefs(mManifestURI), spec, NULL, NULL, io);
-    }
-    else {
-      io->NewFileURI(mFile, getter_AddRefs(mManifestURI));
-    }
+    nsCString uri;
+    mFile.GetURIString(uri);
+    NS_NewURI(getter_AddRefs(mManifestURI), uri);
   }
   return mManifestURI;
 }
 
 nsIXPConnect*
 nsChromeRegistry::ManifestProcessingContext::GetXPConnect()
 {
   if (!mXPConnect)
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -93,16 +93,17 @@
 #include "mozilla/scache/StartupCache.h"
 #include "mozilla/scache/StartupCacheUtils.h"
 #include "mozilla/Omnijar.h"
 
 #include "jsdbgapi.h"
 
 #include "mozilla/FunctionTimer.h"
 
+using namespace mozilla;
 using namespace mozilla::scache;
 
 static const char kJSRuntimeServiceContractID[] = "@mozilla.org/js/xpc/RuntimeService;1";
 static const char kXPConnectServiceContractID[] = "@mozilla.org/js/xpc/XPConnect;1";
 static const char kObserverServiceContractID[] = "@mozilla.org/observer-service;1";
 static const char kJSCachePrefix[] = "jsloader";
 
 /* Some platforms don't have an implementation of PR_MemMap(). */
@@ -481,83 +482,48 @@ mozJSComponentLoader::ReallyInit()
     fprintf(stderr, "mJCL: ReallyInit success!\n");
 #endif
     mInitialized = true;
 
     return NS_OK;
 }
 
 const mozilla::Module*
-mozJSComponentLoader::LoadModule(nsILocalFile* aComponentFile)
+mozJSComponentLoader::LoadModule(FileLocation &aFile)
 {
+    nsCOMPtr<nsILocalFile> file = aFile.GetBaseFile();
+
+    nsCString spec;
+    aFile.GetURIString(spec);
+
     nsCOMPtr<nsIURI> uri;
-    nsCAutoString spec;
-    NS_GetURLSpecFromActualFile(aComponentFile, spec);
-
     nsresult rv = NS_NewURI(getter_AddRefs(uri), spec);
     if (NS_FAILED(rv))
         return NULL;
 
-    return LoadModuleImpl(aComponentFile,
-                          spec,
-                          uri);
-}
-
-const mozilla::Module*
-mozJSComponentLoader::LoadModuleFromJAR(nsILocalFile *aJarFile,
-                                        const nsACString &aComponentPath)
-{
-    nsresult rv;
-
-    nsCAutoString fullSpec, fileSpec;
-    NS_GetURLSpecFromActualFile(aJarFile, fileSpec);
-    fullSpec = "jar:";
-    fullSpec += fileSpec;
-    fullSpec += "!/";
-    fullSpec += aComponentPath;
-
-    nsCOMPtr<nsIURI> uri;
-    rv = NS_NewURI(getter_AddRefs(uri), fullSpec);
-    if (NS_FAILED(rv))
-        return NULL;
-
-    return LoadModuleImpl(aJarFile,
-                          fullSpec,
-                          uri);
-}
-
-const mozilla::Module*
-mozJSComponentLoader::LoadModuleImpl(nsILocalFile* aSourceFile,
-                                     nsACString &aKey,
-                                     nsIURI* aComponentURI)
-{
-    nsresult rv;
-
 #ifdef NS_FUNCTION_TIMER
-    nsCAutoString spec__("N/A");
-    aComponentURI->GetSpec(spec__);
     NS_TIME_FUNCTION_FMT("%s (line %d) (file: %s)", MOZ_FUNCTION_NAME,
-                         __LINE__, spec__.get());
+                         __LINE__, spec.get());
 #endif
 
     if (!mInitialized) {
         rv = ReallyInit();
         if (NS_FAILED(rv))
             return NULL;
     }
 
     ModuleEntry* mod;
-    if (mModules.Get(aKey, &mod))
+    if (mModules.Get(spec, &mod))
 	return mod;
 
     nsAutoPtr<ModuleEntry> entry(new ModuleEntry);
     if (!entry)
         return NULL;
 
-    rv = GlobalForLocation(aSourceFile, aComponentURI, &entry->global,
+    rv = GlobalForLocation(file, uri, &entry->global,
                            &entry->location, nsnull);
     if (NS_FAILED(rv)) {
 #ifdef DEBUG_shaver
         fprintf(stderr, "GlobalForLocation failed!\n");
 #endif
         return NULL;
     }
 
@@ -595,17 +561,17 @@ mozJSComponentLoader::LoadModuleImpl(nsI
 #ifdef DEBUG_shaver
         fprintf(stderr, "GetJSObject of ComponentManager failed\n");
 #endif
         return NULL;
     }
 
     JSObject* file_jsobj;
     nsCOMPtr<nsIXPConnectJSObjectHolder> file_holder;
-    rv = xpc->WrapNative(cx, entry->global, aSourceFile,
+    rv = xpc->WrapNative(cx, entry->global, file,
                          NS_GET_IID(nsIFile),
                          getter_AddRefs(file_holder));
 
     if (NS_FAILED(rv)) {
         return NULL;
     }
 
     rv = file_holder->GetJSObject(&file_jsobj);
@@ -619,17 +585,17 @@ mozJSComponentLoader::LoadModuleImpl(nsI
 
     if (!JS_GetProperty(cx, entry->global, "NSGetFactory", &NSGetFactory_val) ||
         JSVAL_IS_VOID(NSGetFactory_val)) {
         return NULL;
     }
 
     if (JS_TypeOfValue(cx, NSGetFactory_val) != JSTYPE_FUNCTION) {
         nsCAutoString spec;
-        aComponentURI->GetSpec(spec);
+        uri->GetSpec(spec);
         JS_ReportError(cx, "%s has NSGetFactory property that is not a function",
                        spec.get());
         return NULL;
     }
 
     JSObject *jsGetFactoryObj;
     if (!JS_ValueToObject(cx, NSGetFactory_val, &jsGetFactoryObj) ||
         !jsGetFactoryObj) {
@@ -643,17 +609,17 @@ mozJSComponentLoader::LoadModuleImpl(nsI
         /* XXX report error properly */
 #ifdef DEBUG
         fprintf(stderr, "mJCL: couldn't get nsIModule from jsval\n");
 #endif
         return NULL;
     }
 
     // Cache this module for later
-    if (!mModules.Put(aKey, entry))
+    if (!mModules.Put(spec, entry))
         return NULL;
 
     // The hash owns the ModuleEntry now, forget about it
     return entry.forget();
 }
 
 // Some stack based classes for cleaning up on early return
 #ifdef HAVE_PR_MEMMAP
--- a/js/xpconnect/loader/mozJSComponentLoader.h
+++ b/js/xpconnect/loader/mozJSComponentLoader.h
@@ -74,30 +74,24 @@ class mozJSComponentLoader : public mozi
     NS_DECL_ISUPPORTS
     NS_DECL_XPCIJSMODULELOADER
     NS_DECL_NSIOBSERVER
 
     mozJSComponentLoader();
     virtual ~mozJSComponentLoader();
 
     // ModuleLoader
-    const mozilla::Module* LoadModule(nsILocalFile* aFile);
-    const mozilla::Module* LoadModuleFromJAR(nsILocalFile* aJARFile,
-                                             const nsACString& aPath);
+    const mozilla::Module* LoadModule(mozilla::FileLocation &aFile);
 
  protected:
     static mozJSComponentLoader* sSelf;
 
     nsresult ReallyInit();
     void UnloadModules();
 
-    const mozilla::Module* LoadModuleImpl(nsILocalFile* aSourceFile,
-                                          nsACString &aKey,
-                                          nsIURI* aComponentURI);
-
     nsresult GlobalForLocation(nsILocalFile* aComponentFile,
                                nsIURI *aComponent,
                                JSObject **aGlobal,
                                char **location,
                                jsval *exception);
 
     nsCOMPtr<nsIComponentManager> mCompMgr;
     nsCOMPtr<nsIJSRuntimeService> mRuntimeService;
--- a/xpcom/components/ManifestParser.cpp
+++ b/xpcom/components/ManifestParser.cpp
@@ -169,51 +169,46 @@ void LogMessage(const char* aMsg, ...)
   AutoPR_smprintf_free formatted(PR_vsmprintf(aMsg, args));
   va_end(args);
 
   nsCOMPtr<nsIConsoleMessage> error =
     new nsConsoleMessage(NS_ConvertUTF8toUTF16(formatted).get());
   console->LogMessage(error);
 }
 
-void LogMessageWithContext(nsILocalFile* aFile, const char* aPath,
+void LogMessageWithContext(FileLocation &aFile,
                            PRUint32 aLineNumber, const char* aMsg, ...)
 {
   va_list args;
   va_start(args, aMsg);
   AutoPR_smprintf_free formatted(PR_vsmprintf(aMsg, args));
   va_end(args);
   if (!formatted)
     return;
 
-  nsString file;
-  aFile->GetPath(file);
-  if (aPath) {
-    file.Append(':');
-    file.Append(NS_ConvertUTF8toUTF16(aPath));
-  }
+  nsCString file;
+  aFile.GetURIString(file);
 
   nsCOMPtr<nsIScriptError> error =
     do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
   if (!error) {
     // This can happen early in component registration. Fall back to a
     // generic console message.
-    LogMessage("Warning: in file '%s', line %i: %s",
-               NS_ConvertUTF16toUTF8(file).get(),
+    LogMessage("Warning: in '%s', line %i: %s", file.get(),
                aLineNumber, (char*) formatted);
     return;
   }
 
   nsCOMPtr<nsIConsoleService> console =
     do_GetService(NS_CONSOLESERVICE_CONTRACTID);
   if (!console)
     return;
 
   nsresult rv = error->Init(NS_ConvertUTF8toUTF16(formatted).get(),
-			    file.get(), NULL,
+			    NS_ConvertUTF8toUTF16(file).get(), NULL,
 			    aLineNumber, 0, nsIScriptError::warningFlag,
 			    "chrome registration");
   if (NS_FAILED(rv))
     return;
 
   console->LogMessage(error);
 }
 
@@ -418,22 +413,22 @@ namespace {
 struct CachedDirective
 {
   int lineno;
   char* argv[4];
 };
 
 } // anonymous namespace
 
-static void
-ParseManifestCommon(NSLocationType aType, nsILocalFile* aFile,
-                    nsComponentManagerImpl::ManifestProcessingContext& mgrcx,
-                    nsChromeRegistry::ManifestProcessingContext& chromecx,
-                    const char* aPath, char* buf, bool aChromeOnly)
+
+void
+ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOnly)
 {
+  nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, file, aChromeOnly);
+  nsChromeRegistry::ManifestProcessingContext chromecx(type, file);
   nsresult rv;
 
   NS_NAMED_LITERAL_STRING(kPlatform, "platform");
   NS_NAMED_LITERAL_STRING(kContentAccessible, "contentaccessible");
   NS_NAMED_LITERAL_STRING(kApplication, "application");
   NS_NAMED_LITERAL_STRING(kAppVersion, "appversion");
   NS_NAMED_LITERAL_STRING(kGeckoVersion, "platformversion");
   NS_NAMED_LITERAL_STRING(kOs, "os");
@@ -548,43 +543,43 @@ ParseManifestCommon(NSLocationType aType
 	 ++d) {
       if (!strcmp(d->directive, token)) {
 	directive = d;
 	break;
       }
     }
 
     if (!directive) {
-      LogMessageWithContext(aFile, aPath, line,
+      LogMessageWithContext(file, line,
                             "Ignoring unrecognized chrome manifest directive '%s'.",
                             token);
       continue;
     }
 
-    if (!directive->allowbootstrap && NS_BOOTSTRAPPED_LOCATION == aType) {
-      LogMessageWithContext(aFile, aPath, line,
+    if (!directive->allowbootstrap && NS_BOOTSTRAPPED_LOCATION == type) {
+      LogMessageWithContext(file, line,
                             "Bootstrapped manifest not allowed to use '%s' directive.",
                             token);
       continue;
     }
 
-    if (directive->componentonly && NS_SKIN_LOCATION == aType) {
-      LogMessageWithContext(aFile, aPath, line,
+    if (directive->componentonly && NS_SKIN_LOCATION == type) {
+      LogMessageWithContext(file, line,
                             "Skin manifest not allowed to use '%s' directive.",
                             token);
       continue;
     }
 
     NS_ASSERTION(directive->argc < 4, "Need to reset argv array length");
     char* argv[4];
     for (int i = 0; i < directive->argc; ++i)
       argv[i] = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
 
     if (!argv[directive->argc - 1]) {
-      LogMessageWithContext(aFile, aPath, line,
+      LogMessageWithContext(file, line,
                             "Not enough arguments for chrome manifest directive '%s', expected %i.",
                             token, directive->argc);
       continue;
     }
 
     bool ok = true;
     TriState stAppVersion = eUnspecified;
     TriState stGeckoVersion = eUnspecified;
@@ -609,23 +604,23 @@ ParseManifestCommon(NSLocationType aType
 
       if (directive->contentflags &&
           (CheckFlag(kPlatform, wtoken, platform) ||
            CheckFlag(kContentAccessible, wtoken, contentAccessible)))
         continue;
 
       bool xpcNativeWrappers = true; // Dummy for CheckFlag.
       if (CheckFlag(kXPCNativeWrappers, wtoken, xpcNativeWrappers)) {
-        LogMessageWithContext(aFile, aPath, line,
+        LogMessageWithContext(file, line,
                               "Warning: Ignoring obsolete chrome registration modifier '%s'.",
                               token);
         continue;
       }
 
-      LogMessageWithContext(aFile, aPath, line,
+      LogMessageWithContext(file, line,
                             "Unrecognized chrome manifest modifier '%s'.",
                             token);
       ok = false;
     }
 
     if (!ok ||
         stApp == eBad ||
         stAppVersion == eBad ||
@@ -638,17 +633,17 @@ ParseManifestCommon(NSLocationType aType
     if (directive->regfunc) {
       if (GeckoProcessType_Default != XRE_GetProcessType())
         continue;
 
       if (!nsChromeRegistry::gChromeRegistry) {
         nsCOMPtr<nsIChromeRegistry> cr =
           mozilla::services::GetChromeRegistryService();
         if (!nsChromeRegistry::gChromeRegistry) {
-          LogMessageWithContext(aFile, aPath, line,
+          LogMessageWithContext(file, line,
                                 "Chrome registry isn't available yet.");
           continue;
         }
       }
 
       (nsChromeRegistry::gChromeRegistry->*(directive->regfunc))
 	(chromecx, line, argv, platform, contentAccessible);
     }
@@ -666,27 +661,8 @@ ParseManifestCommon(NSLocationType aType
   }
 
   for (PRUint32 i = 0; i < contracts.Length(); ++i) {
     CachedDirective& d = contracts[i];
     nsComponentManagerImpl::gComponentManager->ManifestContract
       (mgrcx, d.lineno, d.argv);
   }
 }
-
-void
-ParseManifest(NSLocationType type, nsILocalFile* file,
-              char* buf, bool aChromeOnly)
-{
-  nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, file, aChromeOnly);
-  nsChromeRegistry::ManifestProcessingContext chromecx(type, file);
-  ParseManifestCommon(type, file, mgrcx, chromecx, NULL, buf, aChromeOnly);
-}
-
-void
-ParseManifest(NSLocationType type, nsIZipReader* reader, const char* jarPath,
-              char* buf, bool aChromeOnly)
-{
-  nsComponentManagerImpl::ManifestProcessingContext mgrcx(type, reader, jarPath, aChromeOnly);
-  nsChromeRegistry::ManifestProcessingContext chromecx(type, mgrcx.mFile, jarPath);
-  ParseManifestCommon(type, mgrcx.mFile, mgrcx, chromecx, jarPath,
-                      buf, aChromeOnly);
-}
--- a/xpcom/components/ManifestParser.h
+++ b/xpcom/components/ManifestParser.h
@@ -35,24 +35,21 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef ManifestParser_h
 #define ManifestParser_h
 
 #include "nsComponentManager.h"
 #include "nsChromeRegistry.h"
+#include "mozilla/FileLocation.h"
 
 class nsILocalFile;
-class nsIZipReader;
 
-void ParseManifest(NSLocationType type, nsILocalFile* file,
+void ParseManifest(NSLocationType type, mozilla::FileLocation &file,
                    char* buf, bool aChromeOnly);
 
-void ParseManifest(NSLocationType type, nsIZipReader* reader,
-                   const char* jarPath, char* buf, bool aChromeOnly);
-
 void LogMessage(const char* aMsg, ...);
 
-void LogMessageWithContext(nsILocalFile* aFile, const char* aPath,
+void LogMessageWithContext(mozilla::FileLocation &aFile,
                            PRUint32 aLineNumber, const char* aMsg, ...);
 
 #endif // ManifestParser_h
--- a/xpcom/components/ModuleLoader.h
+++ b/xpcom/components/ModuleLoader.h
@@ -36,16 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_ModuleLoader_h
 #define mozilla_ModuleLoader_h
 
 #include "nsISupports.h"
 #include "mozilla/Module.h"
+#include "mozilla/FileLocation.h"
 
 #define MOZILLA_MODULELOADER_PSEUDO_IID \
 { 0xD951A8CE, 0x6E9F, 0x464F, \
   { 0x8A, 0xC8, 0x14, 0x61, 0xC0, 0xD3, 0x63, 0xC8 } }
 
 namespace mozilla {
 
 /**
@@ -61,21 +62,15 @@ public:
   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_MODULELOADER_PSEUDO_IID)
 
   /**
    * Return the module for a specified file. The caller should cache
    * the module: the implementer should not expect for the same file
    * to be loaded multiple times. The Module object should either be
    * statically or permanently allocated; it will not be freed.
    */
-  virtual const Module* LoadModule(nsILocalFile* aFile) = 0;
-
-  /**
-   * Return the module for a file located within a JAR.
-   */
-  virtual const Module* LoadModuleFromJAR(nsILocalFile* aJARFile,
-                                          const nsACString& aPath) = 0;
+  virtual const Module* LoadModule(mozilla::FileLocation &aFile) = 0;
 };
 NS_DEFINE_STATIC_IID_ACCESSOR(ModuleLoader, MOZILLA_MODULELOADER_PSEUDO_IID)
 
 } // namespace mozilla
 
 #endif // mozilla_ModuleLoader_h
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -94,23 +94,20 @@
 #include "mozilla/Services.h"
 
 #include "nsManifestLineReader.h"
 #include "mozilla/GenericFactory.h"
 #include "nsSupportsPrimitives.h"
 #include "nsArrayEnumerator.h"
 #include "nsStringEnumerator.h"
 #include "mozilla/FileUtils.h"
-#include "nsURLHelper.h"
 
 #include NEW_H     // for placement new
 
 #include "mozilla/Omnijar.h"
-#include "nsJAR.h"
-static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
 
 #include "prlog.h"
 
 using namespace mozilla;
 
 PRLogModuleInfo* nsComponentManagerLog = nsnull;
 
 #if 0 || defined (DEBUG_timeless)
@@ -352,27 +349,27 @@ nsresult nsComponentManagerImpl::Init()
         GetLocationFromDirectoryService(NS_GRE_DIR);
     nsCOMPtr<nsILocalFile> appDir =
         GetLocationFromDirectoryService(NS_XPCOM_CURRENT_PROCESS_DIR);
 
     InitializeStaticModules();
     InitializeModuleLocations();
 
     ComponentLocation* cl = sModuleLocations->InsertElementAt(0);
+    nsCOMPtr<nsILocalFile> lf = CloneAndAppend(appDir, NS_LITERAL_CSTRING("chrome.manifest"));
     cl->type = NS_COMPONENT_LOCATION;
-    cl->location = CloneAndAppend(appDir, NS_LITERAL_CSTRING("chrome.manifest"));
-    cl->jar = false;
+    cl->location.Init(lf);
 
     bool equals = false;
     appDir->Equals(greDir, &equals);
     if (!equals) {
         cl = sModuleLocations->InsertElementAt(0);
         cl->type = NS_COMPONENT_LOCATION;
-        cl->location = CloneAndAppend(greDir, NS_LITERAL_CSTRING("chrome.manifest"));
-        cl->jar = false;
+        lf = CloneAndAppend(greDir, NS_LITERAL_CSTRING("chrome.manifest"));
+        cl->location.Init(lf);
     }
 
     PR_LOG(nsComponentManagerLog, PR_LOG_DEBUG,
            ("nsComponentManager: Initialized."));
 
     NS_TIME_FUNCTION_MARK("Next: init native module loader");
     nsresult rv = mNativeModuleLoader.Init();
     if (NS_FAILED(rv))
@@ -380,61 +377,57 @@ nsresult nsComponentManagerImpl::Init()
 
     nsCategoryManager::GetSingleton()->SuppressNotifications(true);
 
     RegisterModule(&kXPCOMModule, NULL);
 
     for (PRUint32 i = 0; i < sStaticModules->Length(); ++i)
         RegisterModule((*sStaticModules)[i], NULL);
 
-    nsCOMPtr<nsIFile> appOmnijar = mozilla::Omnijar::GetPath(mozilla::Omnijar::APP);
+    nsRefPtr<nsZipArchive> appOmnijar = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP);
     if (appOmnijar) {
         cl = sModuleLocations->InsertElementAt(1); // Insert after greDir
         cl->type = NS_COMPONENT_LOCATION;
-        cl->location = do_QueryInterface(appOmnijar);
-        cl->jar = true;
+        cl->location.Init(appOmnijar, "chrome.manifest");
     }
-    nsCOMPtr<nsIFile> greOmnijar = mozilla::Omnijar::GetPath(mozilla::Omnijar::GRE);
+    nsRefPtr<nsZipArchive> greOmnijar = mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
     if (greOmnijar) {
         cl = sModuleLocations->InsertElementAt(0);
         cl->type = NS_COMPONENT_LOCATION;
-        cl->location = do_QueryInterface(greOmnijar);
-        cl->jar = true;
+        cl->location.Init(greOmnijar, "chrome.manifest");
     }
 
     RereadChromeManifests(false);
 
     nsCategoryManager::GetSingleton()->SuppressNotifications(false);
 
     mStatus = NORMAL;
 
     return NS_OK;
 }
 
 void
 nsComponentManagerImpl::RegisterModule(const mozilla::Module* aModule,
-                                       nsILocalFile* aFile)
+                                       FileLocation* aFile)
 {
     ReentrantMonitorAutoEnter mon(mMon);
 
-    KnownModule* m = new KnownModule(aModule, aFile);
+    KnownModule* m;
     if (aFile) {
-        nsCAutoString uri;
-        nsresult rv = net_GetURLSpecFromActualFile(aFile, uri);
-        if (NS_FAILED(rv)) {
-            NS_WARNING("net_GetURLSpecFromActualFile failed");
-            return;
-        }
+        nsCString uri;
+        aFile->GetURIString(uri);
         NS_ASSERTION(!mKnownModules.Get(uri),
                      "Must not register a binary module twice.");
 
+        m = new KnownModule(aModule, *aFile);
         mKnownModules.Put(uri, m);
+    } else {
+        m = new KnownModule(aModule);
+        mKnownStaticModules.AppendElement(m);
     }
-    else
-        mKnownStaticModules.AppendElement(m);
 
     if (aModule->mCIDs) {
         const mozilla::Module::CIDEntry* entry;
         for (entry = aModule->mCIDs; entry->cid; ++entry)
             RegisterCIDEntry(entry, m);
     }
 
     if (aModule->mContractIDs) {
@@ -511,334 +504,145 @@ CutExtension(nsCString& path)
 {
     PRInt32 dotPos = path.RFindChar('.');
     if (kNotFound == dotPos)
         path.Truncate();
     else
         path.Cut(0, dotPos + 1);
 }
 
-static nsCString
-GetExtension(nsILocalFile* file)
-{
-    nsCString extension;
-    file->GetNativePath(extension);
-    CutExtension(extension);
-    return extension;
-}
-
-static already_AddRefed<nsIInputStream>
-LoadEntry(nsIZipReader* aReader, const char* aName)
-{
-    if (!aReader)
-        return NULL;
-
-    nsCOMPtr<nsIInputStream> is;
-    nsresult rv = aReader->GetInputStream(nsDependentCString(aName), getter_AddRefs(is));
-    if (NS_FAILED(rv))
-        return NULL;
-
-    return is.forget();
-}
-
 void
-nsComponentManagerImpl::RegisterJarManifest(NSLocationType aType, nsIZipReader* aReader,
-                                            const char* aPath, bool aChromeOnly)
+nsComponentManagerImpl::RegisterManifest(NSLocationType aType,
+                                         FileLocation &aFile,
+                                         bool aChromeOnly)
 {
-    nsCOMPtr<nsIInputStream> is = LoadEntry(aReader, aPath);
-    if (!is) {
-        if (NS_BOOTSTRAPPED_LOCATION != aType)
-            LogMessage("Could not find jar manifest entry '%s'.", aPath);
-        return;
-    }
-
-    PRUint32 flen;
-    is->Available(&flen);
-
-    nsAutoArrayPtr<char> whole(new char[flen + 1]);
-    if (!whole)
-        return;
-
-    for (PRUint32 totalRead = 0; totalRead < flen; ) {
-        PRUint32 avail;
-        PRUint32 read;
-
-        if (NS_FAILED(is->Available(&avail)))
-            return;
-
-        if (avail > flen)
-            return;
-
-        if (NS_FAILED(is->Read(whole + totalRead, avail, &read)))
-            return;
-
-        totalRead += read;
+    PRUint32 len;
+    FileLocation::Data data;
+    nsAutoArrayPtr<char> buf;
+    nsresult rv = aFile.GetData(data);
+    if (NS_SUCCEEDED(rv)) {
+        rv = data.GetSize(&len);
     }
-
-    whole[flen] = '\0';
-
-    ParseManifest(aType, aReader, aPath,
-                  whole, aChromeOnly);
-}
-
-void
-nsComponentManagerImpl::RegisterManifestFile(NSLocationType aType,
-                                             nsILocalFile* aFile,
-                                             bool aChromeOnly)
-{
-    nsresult rv;
-
-    mozilla::AutoFDClose fd;
-    rv = aFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd);
-    if (NS_FAILED(rv)) {
-        nsCAutoString path;
-        aFile->GetNativePath(path);
-        if (NS_BOOTSTRAPPED_LOCATION != aType)
-            LogMessage("Could not read chrome manifest file '%s'.", path.get());
-        return;
+    if (NS_SUCCEEDED(rv)) {
+        buf = new char[len + 1];
+        rv = data.Copy(buf, len);
     }
-
-    PRFileInfo64 fileInfo;
-    if (PR_SUCCESS != PR_GetOpenFileInfo64(fd, &fileInfo))
-        return;
-
-    if (fileInfo.size > PRInt64(PR_INT32_MAX))
-        return;
-
-    nsAutoArrayPtr<char> data(new char[PRInt32(fileInfo.size + 1)]);
-
-    for (PRInt32 totalRead = 0; totalRead < fileInfo.size; ) {
-        PRInt32 read = PR_Read(fd, data + totalRead, PRInt32(fileInfo.size));
-        if (read < 0)
-            return;
-        totalRead += read;
+    if (NS_SUCCEEDED(rv)) {
+        buf[len] = '\0';
+        ParseManifest(aType, aFile, buf, aChromeOnly);
+    } else if (NS_BOOTSTRAPPED_LOCATION != aType) {
+        nsCString uri;
+        aFile.GetURIString(uri);
+        LogMessage("Could not read chrome manifest '%s'.", uri.get());
     }
-
-    data[fileInfo.size] = '\0';
-    ParseManifest(aType, aFile, data, aChromeOnly);
-}
-
-#if defined(XP_WIN) || defined(XP_OS2)
-#define TRANSLATE_SLASHES
-static void
-TranslateSlashes(char* path)
-{
-    for (; *path; ++path) {
-        if ('/' == *path)
-            *path = '\\';
-    }
-}
-#endif
-
-static void
-AppendFileToManifestPath(nsCString& path,
-                         const char* file)
-{
-    PRInt32 i = path.RFindChar('/');
-    if (kNotFound == i)
-        path.Truncate(0);
-    else
-        path.Truncate(i + 1);
-
-    path.Append(file);
 }
 
 void
 nsComponentManagerImpl::ManifestManifest(ManifestProcessingContext& cx, int lineno, char *const * argv)
 {
     char* file = argv[0];
-
-    if (cx.mPath) {
-        nsCAutoString manifest(cx.mPath);
-        AppendFileToManifestPath(manifest, file);
-
-        RegisterJarManifest(cx.mType, cx.mReader, manifest.get(), cx.mChromeOnly);
-    }
-    else {
-#ifdef TRANSLATE_SLASHES
-        TranslateSlashes(file);
-#endif
-        nsCOMPtr<nsIFile> cfile;
-        cx.mFile->GetParent(getter_AddRefs(cfile));
-        nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
-
-        nsresult rv = clfile->AppendRelativeNativePath(nsDependentCString(file));
-        if (NS_FAILED(rv)) {
-            NS_WARNING("Couldn't append relative path?");
-            return;
-        }
-
-        RegisterManifestFile(cx.mType, clfile, cx.mChromeOnly);
-    }
+    FileLocation f(cx.mFile, file);
+    RegisterManifest(cx.mType, f, cx.mChromeOnly);
 }
 
 void
 nsComponentManagerImpl::ManifestBinaryComponent(ManifestProcessingContext& cx, int lineno, char *const * argv)
 {
-    if (cx.mPath) {
+    if (cx.mFile.IsZip()) {
         NS_WARNING("Cannot load binary components from a jar.");
-        LogMessageWithContext(cx.mFile, cx.mPath, lineno,
+        LogMessageWithContext(cx.mFile, lineno,
                               "Cannot load binary components from a jar.");
         return;
     }
 
-    char* file = argv[0];
-
-#ifdef TRANSLATE_SLASHES
-    TranslateSlashes(file);
-#endif
-
-    nsCOMPtr<nsIFile> cfile;
-    cx.mFile->GetParent(getter_AddRefs(cfile));
-    nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
+    FileLocation f(cx.mFile, argv[0]);
+    nsCString uri;
+    f.GetURIString(uri);
 
-    nsresult rv = clfile->AppendRelativeNativePath(nsDependentCString(file));
-    if (NS_FAILED(rv)) {
-        NS_WARNING("Couldn't append relative path?");
-        return;
-    }
-
-    nsCAutoString uri;
-    rv = net_GetURLSpecFromActualFile(clfile, uri);
-    if (NS_FAILED(rv)) {
-        NS_WARNING("net_GetURLSpecFromActualFile failed");
-        return;
-    }
     if (mKnownModules.Get(uri)) {
         NS_WARNING("Attempting to register a binary component twice.");
-        LogMessageWithContext(cx.mFile, cx.mPath, lineno,
+        LogMessageWithContext(cx.mFile, lineno,
                               "Attempting to register a binary component twice.");
         return;
     }
 
-    const mozilla::Module* m = mNativeModuleLoader.LoadModule(clfile);
+    const mozilla::Module* m = mNativeModuleLoader.LoadModule(f);
     // The native module loader should report an error here, we don't have to
     if (!m)
         return;
 
-    RegisterModule(m, clfile);
+    RegisterModule(m, &f);
 }
 
 void
 nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& cx, int lineno, char *const * argv)
 {
-    char* file = argv[0];
-
-    if (cx.mPath) {
-        nsCAutoString manifest(cx.mPath);
-        AppendFileToManifestPath(manifest, file);
-
-        nsCOMPtr<nsIInputStream> stream =
-            LoadEntry(cx.mReader, manifest.get());
-        if (!stream) {
-            NS_WARNING("Failed to load XPT file in a jar.");
-            return;
-        }
-
-        xptiInterfaceInfoManager::GetSingleton()
-            ->RegisterInputStream(stream);
+    FileLocation f(cx.mFile, argv[0]);
+    PRUint32 len;
+    FileLocation::Data data;
+    nsAutoArrayPtr<char> buf;
+    nsresult rv = f.GetData(data);
+    if (NS_SUCCEEDED(rv)) {
+        rv = data.GetSize(&len);
     }
-    else {
-#ifdef TRANSLATE_SLASHES
-        TranslateSlashes(file);
-#endif
-        nsCOMPtr<nsIFile> cfile;
-        cx.mFile->GetParent(getter_AddRefs(cfile));
-        nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
-
-        nsresult rv = clfile->AppendRelativeNativePath(nsDependentCString(file));
-        if (NS_FAILED(rv)) {
-            NS_WARNING("Couldn't append relative path?");
-            return;
-        }
-
+    if (NS_SUCCEEDED(rv)) {
+        buf = new char[len];
+        rv = data.Copy(buf, len);
+    }
+    if (NS_SUCCEEDED(rv)) {
         xptiInterfaceInfoManager::GetSingleton()
-            ->RegisterFile(clfile);
+            ->RegisterBuffer(buf, len);
+    } else {
+        nsCString uri;
+        f.GetURIString(uri);
+        LogMessage("Could not read '%s'.", uri.get());
     }
 }
 
 void
 nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& cx, int lineno, char *const * argv)
 {
     char* id = argv[0];
     char* file = argv[1];
 
     nsID cid;
     if (!cid.Parse(id)) {
-        LogMessageWithContext(cx.mFile, cx.mPath, lineno,
+        LogMessageWithContext(cx.mFile, lineno,
                               "Malformed CID: '%s'.", id);
         return;
     }
 
     ReentrantMonitorAutoEnter mon(mMon);
     nsFactoryEntry* f = mFactories.Get(cid);
     if (f) {
         char idstr[NSID_LENGTH];
         cid.ToProvidedString(idstr);
 
         nsCString existing;
         if (f->mModule)
             existing = f->mModule->Description();
         else
             existing = "<unknown module>";
 
-        LogMessageWithContext(cx.mFile, cx.mPath, lineno,
+        LogMessageWithContext(cx.mFile, lineno,
                               "Trying to re-register CID '%s' already registered by %s.",
                               idstr,
                               existing.get());
         return;
     }
 
     KnownModule* km;
-
-    if (cx.mPath) {
-        nsCAutoString manifest(cx.mPath);
-        AppendFileToManifestPath(manifest, file);
-
-        nsCAutoString hash;
-        nsresult rv = net_GetURLSpecFromActualFile(cx.mFile, hash);
-        if (NS_FAILED(rv)) {
-            NS_WARNING("net_GetURLSpecFromActualFile failed");
-            return;
-        }
-        hash.Insert("jar:", 0);
-        hash.Append("!/");
-        hash.Append(manifest);
+    FileLocation fl(cx.mFile, file);
 
-        km = mKnownModules.Get(hash);
-        if (!km) {
-            km = new KnownModule(cx.mFile, manifest);
-            mKnownModules.Put(hash, km);
-        }
-    }
-    else {
-#ifdef TRANSLATE_SLASHES
-        TranslateSlashes(file);
-#endif
-        nsCOMPtr<nsIFile> cfile;
-        cx.mFile->GetParent(getter_AddRefs(cfile));
-        nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
-
-        nsresult rv = clfile->AppendRelativeNativePath(nsDependentCString(file));
-        if (NS_FAILED(rv)) {
-            NS_WARNING("Couldn't append relative path?");
-            return;
-        }
-        nsCAutoString hash;
-        rv = net_GetURLSpecFromActualFile(clfile, hash);
-        if (NS_FAILED(rv)) {
-            NS_WARNING("net_GetURLSpecFromActualFile failed");
-            return;
-        }
-
-        km = mKnownModules.Get(hash);
-        if (!km) {
-            km = new KnownModule(clfile);
-            mKnownModules.Put(hash, km);
-        }
+    nsCString hash;
+    fl.GetURIString(hash);
+    km = mKnownModules.Get(hash);
+    if (!km) {
+        km = new KnownModule(fl);
+        mKnownModules.Put(hash, km);
     }
 
     void* place;
 
     PL_ARENA_ALLOCATE(place, &mArena, sizeof(nsCID));
     nsID* permanentCID = static_cast<nsID*>(place);
     *permanentCID = cid;
 
@@ -853,25 +657,25 @@ nsComponentManagerImpl::ManifestComponen
 void
 nsComponentManagerImpl::ManifestContract(ManifestProcessingContext& cx, int lineno, char *const * argv)
 {
     char* contract = argv[0];
     char* id = argv[1];
 
     nsID cid;
     if (!cid.Parse(id)) {
-        LogMessageWithContext(cx.mFile, cx.mPath, lineno,
+        LogMessageWithContext(cx.mFile, lineno,
                               "Malformed CID: '%s'.", id);
         return;
     }
 
     ReentrantMonitorAutoEnter mon(mMon);
     nsFactoryEntry* f = mFactories.Get(cid);
     if (!f) {
-        LogMessageWithContext(cx.mFile, cx.mPath, lineno,
+        LogMessageWithContext(cx.mFile, lineno,
                               "Could not map contract ID '%s' to CID %s because no implementation of the CID is registered.",
                               contract, id);
         return;
     }
 
     mContractIDs.Put(nsDependentCString(contract), f);
 }
 
@@ -886,61 +690,42 @@ nsComponentManagerImpl::ManifestCategory
         AddCategoryEntry(category, key, value);
 }
 
 void
 nsComponentManagerImpl::RereadChromeManifests(bool aChromeOnly)
 {
     for (PRUint32 i = 0; i < sModuleLocations->Length(); ++i) {
         ComponentLocation& l = sModuleLocations->ElementAt(i);
-        if (!l.jar) {
-            RegisterManifestFile(l.type, l.location, aChromeOnly);
-            continue;
-        }
-
-        nsresult rv;
-        nsCOMPtr<nsIZipReader> reader = do_CreateInstance(kZipReaderCID, &rv);
-        if (NS_SUCCEEDED(rv))
-            rv = reader->Open(l.location);
-        if (NS_SUCCEEDED(rv))
-            RegisterJarManifest(l.type, reader, "chrome.manifest", aChromeOnly);
+        RegisterManifest(l.type, l.location, aChromeOnly);
     }
 }
 
 bool
 nsComponentManagerImpl::KnownModule::EnsureLoader()
 {
     if (!mLoader) {
         nsCString extension;
-        if (!mPath.IsEmpty()) {
-            extension = mPath;
-            CutExtension(extension);
-        }
-        else {
-            extension = GetExtension(mFile);
-        }
-
+        mFile.GetURIString(extension);
+        CutExtension(extension);
         mLoader = nsComponentManagerImpl::gComponentManager->LoaderForExtension(extension);
     }
     return !!mLoader;
 }
 
 bool
 nsComponentManagerImpl::KnownModule::Load()
 {
     if (mFailed)
         return false;
     if (!mModule) {
         if (!EnsureLoader())
             return false;
 
-        if (!mPath.IsEmpty())
-            mModule = mLoader->LoadModuleFromJAR(mFile, mPath);
-        else
-            mModule = mLoader->LoadModule(mFile);
+        mModule = mLoader->LoadModule(mFile);
 
         if (!mModule) {
             mFailed = true;
             return false;
         }
     }
     if (!mLoaded) {
         if (mModule->loadProc) {
@@ -954,24 +739,18 @@ nsComponentManagerImpl::KnownModule::Loa
     }
     return true;
 }
 
 nsCString
 nsComponentManagerImpl::KnownModule::Description() const
 {
     nsCString s;
-    if (!mPath.IsEmpty()) {
-        mFile->GetNativePath(s);
-        s.Insert(NS_LITERAL_CSTRING("jar:"), 0);
-        s.AppendLiteral("!/");
-        s.Append(mPath);
-    }
-    else if (mFile)
-        mFile->GetNativePath(s);
+    if (mFile)
+        mFile.GetURIString(s);
     else
         s = "<static module>";
     return s;
 }
 
 nsresult nsComponentManagerImpl::Shutdown(void)
 {
     NS_TIME_FUNCTION;
@@ -2045,77 +1824,64 @@ nsComponentManagerImpl::AddBootstrappedM
 
 NS_IMETHODIMP
 nsComponentManagerImpl::RemoveBootstrappedManifestLocation(nsILocalFile* aLocation)
 {
   nsCOMPtr<nsIChromeRegistry> cr = mozilla::services::GetChromeRegistryService();
   if (!cr)
     return NS_ERROR_FAILURE;
 
-  bool isJar = false;
   nsCOMPtr<nsILocalFile> manifest;
   nsString path;
   nsresult rv = aLocation->GetPath(path);
   if (NS_FAILED(rv))
     return rv;
 
+  nsComponentManagerImpl::ComponentLocation elem;
+  elem.type = NS_BOOTSTRAPPED_LOCATION;
+
   if (Substring(path, path.Length() - 4).Equals(NS_LITERAL_STRING(".xpi"))) {
-    isJar = true;
-    manifest = aLocation;
+    elem.location.Init(aLocation, "chrome.manifest");
   } else {
-    manifest = CloneAndAppend(aLocation, NS_LITERAL_CSTRING("chrome.manifest"));
+    nsCOMPtr<nsILocalFile> lf = CloneAndAppend(aLocation, NS_LITERAL_CSTRING("chrome.manifest"));
+    elem.location.Init(lf);
   }
 
-  nsComponentManagerImpl::ComponentLocation elem = {
-    NS_BOOTSTRAPPED_LOCATION,
-    manifest,
-    isJar
-  };
-
   // Remove reference.
   nsComponentManagerImpl::sModuleLocations->RemoveElement(elem, ComponentLocationComparator());
 
   rv = cr->CheckForNewChrome();
   return rv;
 }
 
 EXPORT_XPCOM_API(nsresult)
 XRE_AddManifestLocation(NSLocationType aType, nsILocalFile* aLocation)
 {
     nsComponentManagerImpl::InitializeModuleLocations();
     nsComponentManagerImpl::ComponentLocation* c = 
         nsComponentManagerImpl::sModuleLocations->AppendElement();
     c->type = aType;
-    c->location = aLocation;
-    c->jar = false;
+    c->location.Init(aLocation);
 
     if (nsComponentManagerImpl::gComponentManager &&
         nsComponentManagerImpl::NORMAL == nsComponentManagerImpl::gComponentManager->mStatus)
-        nsComponentManagerImpl::gComponentManager->RegisterManifestFile(aType, aLocation, false);
+        nsComponentManagerImpl::gComponentManager->RegisterManifest(aType, c->location, false);
 
     return NS_OK;
 }
 
 EXPORT_XPCOM_API(nsresult)
 XRE_AddJarManifestLocation(NSLocationType aType, nsILocalFile* aLocation)
 {
     nsComponentManagerImpl::InitializeModuleLocations();
     nsComponentManagerImpl::ComponentLocation* c = 
         nsComponentManagerImpl::sModuleLocations->AppendElement();
+
     c->type = aType;
-    c->location = aLocation;
-    c->jar = true;
-
-    if (!nsComponentManagerImpl::gComponentManager ||
-        nsComponentManagerImpl::NORMAL != nsComponentManagerImpl::gComponentManager->mStatus)
-        return NS_OK;
+    c->location.Init(aLocation, "chrome.manifest");
 
-    nsresult rv;
-    nsCOMPtr<nsIZipReader> reader = do_CreateInstance(kZipReaderCID, &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = reader->Open(c->location);
-    if (NS_SUCCEEDED(rv))
-        nsComponentManagerImpl::gComponentManager->RegisterJarManifest(aType, reader, "chrome.manifest", false);
+    if (nsComponentManagerImpl::gComponentManager &&
+        nsComponentManagerImpl::NORMAL == nsComponentManagerImpl::gComponentManager->mStatus)
+        nsComponentManagerImpl::gComponentManager->RegisterManifest(aType, c->location, false);
 
     return NS_OK;
 }
 
--- a/xpcom/components/nsComponentManager.h
+++ b/xpcom/components/nsComponentManager.h
@@ -62,17 +62,16 @@
 #include "plarena.h"
 #include "nsCOMArray.h"
 #include "nsDataHashtable.h"
 #include "nsInterfaceHashtable.h"
 #include "nsClassHashtable.h"
 #include "nsTArray.h"
 
 #include "mozilla/Omnijar.h"
-#include "nsIZipReader.h"
 
 struct nsFactoryEntry;
 class nsIServiceManager;
 struct PRThread;
 
 #define NS_COMPONENTMANAGER_CID                      \
 { /* 91775d60-d5dc-11d2-92fb-00e09805570f */         \
     0x91775d60,                                      \
@@ -153,66 +152,55 @@ public:
     mozilla::ReentrantMonitor mMon;
 
     static void InitializeStaticModules();
     static void InitializeModuleLocations();
 
     struct ComponentLocation
     {
         NSLocationType type;
-        nsCOMPtr<nsILocalFile> location;
-        bool jar;
+        mozilla::FileLocation location;
     };
 
     class ComponentLocationComparator
     {
     public:
       bool Equals(const ComponentLocation& a, const ComponentLocation& b) const
       {
-        if (a.type == b.type && a.jar == b.jar) {
-          bool res;
-          nsresult rv = a.location->Equals(b.location, &res);
-          NS_ASSERTION(NS_SUCCEEDED(rv), "Error comparing locations");
-          return res;
-        }
-
-        return false;
+        return (a.type == b.type && a.location.Equals(b.location));
       }
     };
 
     static nsTArray<const mozilla::Module*>* sStaticModules;
     static nsTArray<ComponentLocation>* sModuleLocations;
 
     nsNativeModuleLoader mNativeModuleLoader;
 
     class KnownModule
     {
     public:
         /**
          * Static or binary module.
          */
-        KnownModule(const mozilla::Module* aModule, nsILocalFile* aFile)
+        KnownModule(const mozilla::Module* aModule, mozilla::FileLocation &aFile)
             : mModule(aModule)
             , mFile(aFile)
             , mLoaded(false)
             , mFailed(false)
         { }
 
-        KnownModule(nsILocalFile* aFile)
-            : mModule(NULL)
-            , mFile(aFile)
-            , mLoader(NULL)
+        KnownModule(const mozilla::Module* aModule)
+            : mModule(aModule)
             , mLoaded(false)
             , mFailed(false)
         { }
 
-        KnownModule(nsILocalFile* aFile, const nsACString& aPath)
+        KnownModule(mozilla::FileLocation &aFile)
             : mModule(NULL)
             , mFile(aFile)
-            , mPath(aPath)
             , mLoader(NULL)
             , mLoaded(false)
             , mFailed(false)
         { }
 
         ~KnownModule()
         {
             if (mLoaded && mModule->unloadProc)
@@ -230,68 +218,49 @@ public:
         /**
          * For error logging, get a description of this module, either the
          * file path, or <static module>.
          */
         nsCString Description() const;
 
     private:
         const mozilla::Module* mModule;
-        nsCOMPtr<nsILocalFile> mFile;
-        nsCString mPath;
+        mozilla::FileLocation mFile;
         nsCOMPtr<mozilla::ModuleLoader> mLoader;
         bool mLoaded;
         bool mFailed;
     };
 
     // The KnownModule is kept alive by these members, it is
     // referenced by pointer from the factory entries.
     nsTArray< nsAutoPtr<KnownModule> > mKnownStaticModules;
     // The key is the URI string of the module
     nsClassHashtable<nsCStringHashKey, KnownModule> mKnownModules;
 
     void RegisterModule(const mozilla::Module* aModule,
-                        nsILocalFile* aFile);
+                        mozilla::FileLocation* aFile);
     void RegisterCIDEntry(const mozilla::Module::CIDEntry* aEntry,
                           KnownModule* aModule);
     void RegisterContractID(const mozilla::Module::ContractIDEntry* aEntry);
 
-    void RegisterJarManifest(NSLocationType aType, nsIZipReader* aReader,
-                             const char* aPath, bool aChromeOnly);
-
-    void RegisterManifestFile(NSLocationType aType, nsILocalFile* aFile,
-                              bool aChromeOnly);
+    void RegisterManifest(NSLocationType aType, mozilla::FileLocation &aFile,
+                          bool aChromeOnly);
 
     struct ManifestProcessingContext
     {
-        ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile, bool aChromeOnly)
+        ManifestProcessingContext(NSLocationType aType, mozilla::FileLocation &aFile, bool aChromeOnly)
             : mType(aType)
             , mFile(aFile)
-            , mPath(NULL)
             , mChromeOnly(aChromeOnly)
         { }
 
-        ManifestProcessingContext(NSLocationType aType, nsIZipReader* aReader, const char* aPath, bool aChromeOnly)
-            : mType(aType)
-            , mReader(aReader)
-            , mPath(aPath)
-            , mChromeOnly(aChromeOnly)
-        {
-            nsCOMPtr<nsIFile> file;
-            aReader->GetFile(getter_AddRefs(file));
-            nsCOMPtr<nsILocalFile> localfile = do_QueryInterface(file);
-            mFile = localfile;
-        }
-
         ~ManifestProcessingContext() { }
 
         NSLocationType mType;
-        nsILocalFile* mFile;
-        nsIZipReader* mReader;
-        const char* mPath;
+        mozilla::FileLocation mFile;
         bool mChromeOnly;
     };
 
     void ManifestManifest(ManifestProcessingContext& cx, int lineno, char *const * argv);
     void ManifestBinaryComponent(ManifestProcessingContext& cx, int lineno, char *const * argv);
     void ManifestXPT(ManifestProcessingContext& cx, int lineno, char *const * argv);
     void ManifestComponent(ManifestProcessingContext& cx, int lineno, char *const * argv);
     void ManifestContract(ManifestProcessingContext& cx, int lineno, char* const * argv);
--- a/xpcom/components/nsNativeComponentLoader.cpp
+++ b/xpcom/components/nsNativeComponentLoader.cpp
@@ -78,16 +78,18 @@
 #include <lib$routines.h>
 #include <ssdef.h>
 #endif
 
 #ifdef DEBUG
 #define IMPLEMENT_BREAK_AFTER_LOAD
 #endif
 
+using namespace mozilla;
+
 static PRLogModuleInfo *nsNativeModuleLoaderLog =
     PR_NewLogModule("nsNativeModuleLoader");
 
 #define LOG(level, args) PR_LOG(nsNativeModuleLoaderLog, level, args)
 
 NS_IMPL_QUERY_INTERFACE1(nsNativeModuleLoader, 
                          mozilla::ModuleLoader)
 
@@ -105,84 +107,89 @@ nsNativeModuleLoader::Init()
 
     return mLibraries.Init() ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 class LoadModuleMainThreadRunnable : public nsRunnable
 {
 public:
     LoadModuleMainThreadRunnable(nsNativeModuleLoader* loader,
-                                 nsILocalFile* file)
+                                 FileLocation &file)
         : mLoader(loader)
         , mFile(file)
         , mResult(NULL)
     { }
 
     NS_IMETHOD Run()
     {
         mResult = mLoader->LoadModule(mFile);
         return NS_OK;
     }
 
     nsRefPtr<nsNativeModuleLoader> mLoader;
-    nsCOMPtr<nsILocalFile> mFile;
+    FileLocation mFile;
     const mozilla::Module* mResult;
 };
 
 const mozilla::Module*
-nsNativeModuleLoader::LoadModule(nsILocalFile* aFile)
+nsNativeModuleLoader::LoadModule(FileLocation &aFile)
 {
+    if (aFile.IsZip()) {
+        NS_ERROR("Binary components cannot be loaded from JARs");
+        return NULL;
+    }
+    nsCOMPtr<nsILocalFile> file = aFile.GetBaseFile();
     nsresult rv;
 
     if (!NS_IsMainThread()) {
         // If this call is off the main thread, synchronously proxy it
         // to the main thread.
         nsRefPtr<LoadModuleMainThreadRunnable> r = new LoadModuleMainThreadRunnable(this, aFile);
         NS_DispatchToMainThread(r, NS_DISPATCH_SYNC);
         return r->mResult;
     }
 
-    nsCOMPtr<nsIHashable> hashedFile(do_QueryInterface(aFile));
+    nsCOMPtr<nsIHashable> hashedFile(do_QueryInterface(file));
     if (!hashedFile) {
         NS_ERROR("nsIFile is not nsIHashable");
         return NULL;
     }
 
     nsCAutoString filePath;
-    aFile->GetNativePath(filePath);
+    file->GetNativePath(filePath);
 
     NativeLoadData data;
 
     if (mLibraries.Get(hashedFile, &data)) {
         NS_ASSERTION(data.module, "Corrupt mLibraries hash");
         LOG(PR_LOG_DEBUG,
             ("nsNativeModuleLoader::LoadModule(\"%s\") - found in cache",
              filePath.get()));
         return data.module;
     }
 
     // We haven't loaded this module before
 
-    rv = aFile->Load(&data.library);
+    rv = file->Load(&data.library);
 
     if (NS_FAILED(rv)) {
         char errorMsg[1024] = "<unknown; can't get error from NSPR>";
 
         if (PR_GetErrorTextLength() < (int) sizeof(errorMsg))
             PR_GetErrorText(errorMsg);
 
         LogMessage("Failed to load native module at path '%s': (%lx) %s",
                    filePath.get(), rv, errorMsg);
 
         return NULL;
     }
 
 #ifdef IMPLEMENT_BREAK_AFTER_LOAD
     nsCAutoString leafName;
-    aFile->GetNativeLeafName(leafName);
+    file->GetNativeLeafName(leafName);
 
     char *env = getenv("XPCOM_BREAK_ON_LOAD");
     char *blist;
     if (env && *env && (blist = strdup(env))) {
         char *nextTok = blist;
         while (char *token = NS_strtok(":", &nextTok)) {
             if (leafName.Find(token, true) != kNotFound) {
                 NS_BREAK();
@@ -209,23 +216,16 @@ nsNativeModuleLoader::LoadModule(nsILoca
         PR_UnloadLibrary(data.library);
         return NULL;
     }
         
     mLibraries.Put(hashedFile, data); // infallible
     return data.module;
 }
 
-const mozilla::Module*
-nsNativeModuleLoader::LoadModuleFromJAR(nsILocalFile* aJARFile, const nsACString &aPath)
-{
-    NS_ERROR("Binary components cannot be loaded from JARs");
-    return NULL;
-}
-
 PLDHashOperator
 nsNativeModuleLoader::ReleaserFunc(nsIHashable* aHashedFile,
                                    NativeLoadData& aLoadData, void*)
 {
     aLoadData.module = nsnull;
     return PL_DHASH_NEXT;
 }
 
--- a/xpcom/components/nsNativeComponentLoader.h
+++ b/xpcom/components/nsNativeComponentLoader.h
@@ -48,19 +48,17 @@
 class nsNativeModuleLoader : public mozilla::ModuleLoader
 {
  public:
     NS_DECL_ISUPPORTS_INHERITED
 
     nsNativeModuleLoader() {}
     ~nsNativeModuleLoader() {}
 
-    NS_OVERRIDE virtual const mozilla::Module* LoadModule(nsILocalFile* aFile);
-    NS_OVERRIDE virtual const mozilla::Module* LoadModuleFromJAR(nsILocalFile* aJARFile,
-                                                                 const nsACString& aPath);
+    NS_OVERRIDE virtual const mozilla::Module* LoadModule(mozilla::FileLocation &aFile);
 
     nsresult Init();
 
     void UnloadLibraries();
 
  private:
     struct NativeLoadData
     {
--- a/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
@@ -92,116 +92,35 @@ xptiInterfaceInfoManager::~xptiInterface
     mWorkingSet.InvalidateInterfaceInfos();
 
     gInterfaceInfoManager = nsnull;
 #ifdef DEBUG
     gCallCount = 0;
 #endif
 }
 
-XPTHeader* 
-xptiInterfaceInfoManager::ReadXPTFile(nsILocalFile* aFile)
+void
+xptiInterfaceInfoManager::RegisterBuffer(char *buf, PRUint32 length)
 {
-    mozilla::AutoFDClose fd;
-    if (NS_FAILED(aFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd)) || !fd)
-        return NULL;
-
-    PRFileInfo64 fileInfo;
-    if (PR_SUCCESS != PR_GetOpenFileInfo64(fd, &fileInfo))
-        return NULL;
-
-    if (fileInfo.size > PRInt64(PR_INT32_MAX))
-        return NULL;
-
-    nsAutoArrayPtr<char> whole(new char[PRInt32(fileInfo.size)]);
-    if (!whole)
-        return nsnull;
-
-    for (PRInt32 totalRead = 0; totalRead < fileInfo.size; ) {
-        PRInt32 read = PR_Read(fd, whole + totalRead, PRInt32(fileInfo.size));
-        if (read < 0)
-            return NULL;
-        totalRead += read;
-    }
-
-    XPTState* state = XPT_NewXDRState(XPT_DECODE, whole,
-                                      PRInt32(fileInfo.size));
+    XPTState *state = XPT_NewXDRState(XPT_DECODE, buf, length);
+    if (!state)
+        return;
 
     XPTCursor cursor;
     if (!XPT_MakeCursor(state, XPT_HEADER, 0, &cursor)) {
         XPT_DestroyXDRState(state);
-        return NULL;
+        return;
     }
-    
+
     XPTHeader *header = nsnull;
-    if (!XPT_DoHeader(gXPTIStructArena, &cursor, &header)) {
-        XPT_DestroyXDRState(state);
-        return NULL;
+    if (XPT_DoHeader(gXPTIStructArena, &cursor, &header)) {
+        RegisterXPTHeader(header);
     }
 
     XPT_DestroyXDRState(state);
-
-    return header;
-}
-
-XPTHeader*
-xptiInterfaceInfoManager::ReadXPTFileFromInputStream(nsIInputStream *stream)
-{
-    PRUint32 flen;
-    stream->Available(&flen);
-    
-    nsAutoArrayPtr<char> whole(new char[flen]);
-    if (!whole)
-        return nsnull;
-
-    for (PRUint32 totalRead = 0; totalRead < flen; ) {
-        PRUint32 avail;
-        PRUint32 read;
-
-        if (NS_FAILED(stream->Available(&avail)))
-            return NULL;
-
-        if (avail > flen)
-            return NULL;
-
-        if (NS_FAILED(stream->Read(whole+totalRead, avail, &read)))
-            return NULL;
-
-        totalRead += read;
-    }
-    
-    XPTState *state = XPT_NewXDRState(XPT_DECODE, whole, flen);
-    if (!state)
-        return NULL;
-    
-    XPTCursor cursor;
-    if (!XPT_MakeCursor(state, XPT_HEADER, 0, &cursor)) {
-        XPT_DestroyXDRState(state);
-        return NULL;
-    }
-    
-    XPTHeader *header = nsnull;
-    if (!XPT_DoHeader(gXPTIStructArena, &cursor, &header)) {
-        XPT_DestroyXDRState(state);
-        return NULL;
-    }
-
-    XPT_DestroyXDRState(state);
-
-    return header;
-}
-
-void
-xptiInterfaceInfoManager::RegisterFile(nsILocalFile* aFile)
-{
-    XPTHeader* header = ReadXPTFile(aFile);
-    if (!header)
-        return;
-
-    RegisterXPTHeader(header);
 }
 
 void
 xptiInterfaceInfoManager::RegisterXPTHeader(XPTHeader* aHeader)
 {
     if (aHeader->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION) {
         NS_ASSERTION(!aHeader->num_interfaces,"bad libxpt");
         LOG_AUTOREG(("      file is version %d.%d  Type file of version %d.0 or higher can not be read.\n", (int)header->major_version, (int)header->minor_version, (int)XPT_MAJOR_INCOMPATIBLE_VERSION));
@@ -210,24 +129,16 @@ xptiInterfaceInfoManager::RegisterXPTHea
     xptiTypelibGuts* typelib = xptiTypelibGuts::Create(aHeader);
 
     ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
     for(PRUint16 k = 0; k < aHeader->num_interfaces; k++)
         VerifyAndAddEntryIfNew(aHeader->interface_directory + k, k, typelib);
 }
 
 void
-xptiInterfaceInfoManager::RegisterInputStream(nsIInputStream* aStream)
-{
-    XPTHeader* header = ReadXPTFileFromInputStream(aStream);
-    if (header)
-        RegisterXPTHeader(header);
-}
-
-void
 xptiInterfaceInfoManager::VerifyAndAddEntryIfNew(XPTInterfaceDirectoryEntry* iface,
                                                  PRUint16 idx,
                                                  xptiTypelibGuts* typelib)
 {
     if (!iface->interface_descriptor)
         return;
 
     // The number of maximum methods is not arbitrary. It is the same value as
--- a/xpcom/reflect/xptinfo/src/xptiprivate.h
+++ b/xpcom/reflect/xptinfo/src/xptiprivate.h
@@ -439,18 +439,17 @@ class xptiInterfaceInfoManager
     typedef mozilla::ReentrantMonitor ReentrantMonitor;
     typedef mozilla::Mutex Mutex;
 
 public:
     // GetSingleton() is infallible
     static xptiInterfaceInfoManager* GetSingleton();
     static void FreeInterfaceInfoManager();
 
-    void RegisterFile(nsILocalFile* aFile);
-    void RegisterInputStream(nsIInputStream* aStream);
+    void RegisterBuffer(char *buf, PRUint32 length);
 
     xptiWorkingSet*  GetWorkingSet() {return &mWorkingSet;}
 
     static Mutex& GetResolveLock(xptiInterfaceInfoManager* self = nsnull) 
     {
         self = self ? self : GetSingleton();
         return self->mResolveLock;
     }
@@ -458,19 +457,16 @@ public:
     xptiInterfaceEntry* GetInterfaceEntryForIID(const nsIID *iid);
 
 private:
     xptiInterfaceInfoManager();
     ~xptiInterfaceInfoManager();
 
     void RegisterXPTHeader(XPTHeader* aHeader);
                           
-    XPTHeader* ReadXPTFile(nsILocalFile* aFile);
-    XPTHeader* ReadXPTFileFromInputStream(nsIInputStream *stream);
-
     // idx is the index of this interface in the XPTHeader
     void VerifyAndAddEntryIfNew(XPTInterfaceDirectoryEntry* iface,
                                 PRUint16 idx,
                                 xptiTypelibGuts* typelib);
 
 private:
     xptiWorkingSet               mWorkingSet;
     Mutex                        mResolveLock;