Bug 1776480 - Remove OS.File et al. r=Gijs,webidl,smaug
authorBarret Rennie <barret@brennie.ca>
Fri, 12 May 2023 18:34:28 +0000 (2023-05-12)
changeset 663653 c698636dbfea4e9d7a50338981b7a4862404ea92
parent 663652 54c0ab259e184fc9a88fa6fe00c8092f1070dafa
child 663654 973b6e904e8ce2b8b90ef0caba78fb8d45c22ad2
push id40851
push usernerli@mozilla.com
push dateSat, 13 May 2023 09:21:59 +0000 (2023-05-13)
treeherdermozilla-central@d36ba840f6ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs, webidl, smaug
bugs1776480, 1786885, 1775167, 1830097, 1830100
milestone115.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1776480 - Remove OS.File et al. r=Gijs,webidl,smaug This patch removes the vast majority of OS.File and support code. A few things remain: - The nsIOSFileConstantsService still exists, but the path related constants (OS.Constants.Path.*) are no longer added to the OS object. The plan is to replace this with a proper service e.g. Services.osConstants or similar) in bug 1786885. - There is still support for OS.File errors in ErrorSanitizer, which will be removed in bug 1775167. - The OS.File to IOUtils migration guide will be rewritten as general IOUtils documentation in bug 1830097. - dom/base/Document.cpp has a workaround for not loading osfile.jsm at startup, which may want to be reconsidered in bug 1830100. So long, and thanks for all the I/O. Differential Revision: https://phabricator.services.mozilla.com/D176543
.eslintrc-test-paths.js
.eslintrc.js
browser/base/content/test/performance/browser_startup.js
browser/base/content/test/static/browser_all_files_referenced.js
docs/code-quality/lint/linters/eslint-plugin-mozilla.rst
docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-osfile.rst
dom/system/OSFileConstants.cpp
dom/system/moz.build
dom/system/tests/chrome.ini
dom/system/tests/ioutils/test_ioutils_read_write.html
dom/system/tests/ioutils/test_ioutils_read_write_utf8.html
dom/system/tests/test_constants.xhtml
dom/system/tests/worker_constants.js
dom/webidl/NativeOSFileInternals.webidl
dom/webidl/moz.build
js/xpconnect/tests/browser/browser_import_mapped_jsm.js
modules/libpref/init/all.js
testing/runtimes/manifest-runtimes-android.json
testing/runtimes/manifest-runtimes-unix.json
testing/runtimes/manifest-runtimes-windows.json
toolkit/components/build/components.conf
toolkit/components/lz4/lz4.cpp
toolkit/components/lz4/lz4.js
toolkit/components/lz4/lz4_internal.js
toolkit/components/lz4/moz.build
toolkit/components/lz4/tests/xpcshell/data/chrome.manifest
toolkit/components/lz4/tests/xpcshell/data/compression.lz
toolkit/components/lz4/tests/xpcshell/data/worker_lz4.js
toolkit/components/lz4/tests/xpcshell/test_lz4.js
toolkit/components/lz4/tests/xpcshell/test_lz4_sync.js
toolkit/components/lz4/tests/xpcshell/xpcshell.ini
toolkit/components/moz.build
toolkit/components/osfile/NativeOSFileInternals.cpp
toolkit/components/osfile/NativeOSFileInternals.h
toolkit/components/osfile/modules/moz.build
toolkit/components/osfile/modules/osfile_async_front.jsm
toolkit/components/osfile/modules/osfile_async_worker.js
toolkit/components/osfile/modules/osfile_native.jsm
toolkit/components/osfile/modules/osfile_shared_allthreads.jsm
toolkit/components/osfile/modules/osfile_shared_front.js
toolkit/components/osfile/modules/osfile_unix_allthreads.jsm
toolkit/components/osfile/modules/osfile_unix_back.js
toolkit/components/osfile/modules/osfile_unix_front.js
toolkit/components/osfile/modules/osfile_win_allthreads.jsm
toolkit/components/osfile/modules/osfile_win_back.js
toolkit/components/osfile/modules/osfile_win_front.js
toolkit/components/osfile/modules/ospath.jsm
toolkit/components/osfile/modules/ospath_unix.jsm
toolkit/components/osfile/modules/ospath_win.jsm
toolkit/components/osfile/moz.build
toolkit/components/osfile/nsINativeOSFileInternals.idl
toolkit/components/osfile/osfile.jsm
toolkit/components/osfile/tests/mochi/chrome.ini
toolkit/components/osfile/tests/mochi/main_test_osfile_async.js
toolkit/components/osfile/tests/mochi/test_osfile_async.xhtml
toolkit/components/osfile/tests/mochi/test_osfile_back.xhtml
toolkit/components/osfile/tests/mochi/test_osfile_comms.xhtml
toolkit/components/osfile/tests/mochi/test_osfile_front.xhtml
toolkit/components/osfile/tests/mochi/worker_test_osfile_comms.js
toolkit/components/osfile/tests/mochi/worker_test_osfile_front.js
toolkit/components/osfile/tests/mochi/worker_test_osfile_unix.js
toolkit/components/osfile/tests/mochi/worker_test_osfile_win.js
toolkit/components/osfile/tests/xpcshell/.eslintrc.js
toolkit/components/osfile/tests/xpcshell/head.js
toolkit/components/osfile/tests/xpcshell/test_compression.js
toolkit/components/osfile/tests/xpcshell/test_constants.js
toolkit/components/osfile/tests/xpcshell/test_duration.js
toolkit/components/osfile/tests/xpcshell/test_exception.js
toolkit/components/osfile/tests/xpcshell/test_file_URL_conversion.js
toolkit/components/osfile/tests/xpcshell/test_logging.js
toolkit/components/osfile/tests/xpcshell/test_makeDir.js
toolkit/components/osfile/tests/xpcshell/test_open.js
toolkit/components/osfile/tests/xpcshell/test_osfile_async.js
toolkit/components/osfile/tests/xpcshell/test_osfile_async_append.js
toolkit/components/osfile/tests/xpcshell/test_osfile_async_bytes.js
toolkit/components/osfile/tests/xpcshell/test_osfile_async_copy.js
toolkit/components/osfile/tests/xpcshell/test_osfile_async_flush.js
toolkit/components/osfile/tests/xpcshell/test_osfile_async_largefiles.js
toolkit/components/osfile/tests/xpcshell/test_osfile_async_setDates.js
toolkit/components/osfile/tests/xpcshell/test_osfile_async_setPermissions.js
toolkit/components/osfile/tests/xpcshell/test_osfile_closed.js
toolkit/components/osfile/tests/xpcshell/test_osfile_error.js
toolkit/components/osfile/tests/xpcshell/test_osfile_kill.js
toolkit/components/osfile/tests/xpcshell/test_osfile_win_async_setPermissions.js
toolkit/components/osfile/tests/xpcshell/test_osfile_writeAtomic_backupTo_option.js
toolkit/components/osfile/tests/xpcshell/test_osfile_writeAtomic_unicode_filename.js
toolkit/components/osfile/tests/xpcshell/test_osfile_writeAtomic_zerobytes.js
toolkit/components/osfile/tests/xpcshell/test_path.js
toolkit/components/osfile/tests/xpcshell/test_path_constants.js
toolkit/components/osfile/tests/xpcshell/test_queue.js
toolkit/components/osfile/tests/xpcshell/test_read_write.js
toolkit/components/osfile/tests/xpcshell/test_remove.js
toolkit/components/osfile/tests/xpcshell/test_removeDir.js
toolkit/components/osfile/tests/xpcshell/test_removeEmptyDir.js
toolkit/components/osfile/tests/xpcshell/test_reset.js
toolkit/components/osfile/tests/xpcshell/test_shutdown.js
toolkit/components/osfile/tests/xpcshell/test_telemetry.js
toolkit/components/osfile/tests/xpcshell/test_unique.js
toolkit/components/osfile/tests/xpcshell/xpcshell.ini
tools/esmify/map.json
tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js
tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-osfile.js
tools/lint/eslint/eslint-plugin-mozilla/tests/reject-osfile.js
--- a/.eslintrc-test-paths.js
+++ b/.eslintrc-test-paths.js
@@ -258,17 +258,16 @@ const extraChromeTestPaths = [
   "gfx/layers/apz/test/mochitest/",
   "image/test/mochitest/",
   "layout/forms/test/",
   "layout/generic/test/",
   "layout/mathml/tests/",
   "layout/svg/tests/",
   "layout/xul/test/",
   "toolkit/components/aboutmemory/tests/",
-  "toolkit/components/osfile/tests/mochi/",
   "toolkit/components/printing/tests/",
   "toolkit/components/url-classifier/tests/mochitest/",
   "toolkit/components/viewsource/test/",
   "toolkit/components/windowcreator/test/",
   "toolkit/components/windowwatcher/test/",
   "toolkit/components/workerloader/tests/",
   "toolkit/content/tests/widgets/",
   "toolkit/profile/test/",
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -305,17 +305,16 @@ module.exports = {
         "toolkit/components/glean/tests/browser/**",
         "toolkit/components/kvstore/kvstore.sys.mjs",
         "toolkit/components/lz4/lz4.js",
         "toolkit/components/messaging-system/**",
         "toolkit/components/mozintl/mozIntl.sys.mjs",
         "toolkit/components/narrate/Narrator.jsm",
         "toolkit/components/nimbus/**",
         "toolkit/components/normandy/**",
-        "toolkit/components/osfile/**",
         "toolkit/components/passwordmgr/**",
         "toolkit/components/pdfjs/**",
         "toolkit/components/pictureinpicture/**",
         "toolkit/components/places/**",
         "toolkit/components/printing/content/print*.*",
         "toolkit/components/processtools/tests/browser/browser_test_powerMetrics.js",
         "toolkit/components/promiseworker/**/PromiseWorker.*",
         "toolkit/components/prompts/**",
@@ -609,23 +608,16 @@ module.exports = {
       extends: ["plugin:react-hooks/recommended"],
       files: [
         "browser/components/newtab/**",
         "browser/components/pocket/**",
         "devtools/**",
       ],
     },
     {
-      // Turn off the osfile rule for osfile.
-      files: ["toolkit/components/osfile/**"],
-      rules: {
-        "mozilla/reject-osfile": "off",
-      },
-    },
-    {
       // Exempt files with these paths since they have to use http for full coverage
       files: httpTestingPaths.map(path => `${path}**`),
       rules: {
         "@microsoft/sdl/no-insecure-url": "off",
       },
     },
     {
       // Exempt all components and test files that explicitly want to test http urls from 'no-insecure-url' rule.
--- a/browser/base/content/test/performance/browser_startup.js
+++ b/browser/base/content/test/performance/browser_startup.js
@@ -97,17 +97,16 @@ const startupPhases = {
   // Things that are expected to be completely out of the startup path
   // and loaded lazily when used for the first time by the user should
   // be listed here.
   "before becoming idle": {
     denylist: {
       modules: new Set([
         "resource://gre/modules/AsyncPrefs.sys.mjs",
         "resource://gre/modules/LoginManagerContextMenu.sys.mjs",
-        "resource://gre/modules/osfile.jsm",
         "resource://pdf.js/PdfStreamConverter.sys.mjs",
       ]),
     },
   },
 };
 
 if (
   Services.prefs.getBoolPref("browser.startup.blankWindow") &&
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -66,22 +66,16 @@ var gExceptionPaths = [
   // Nimbus schemas are referenced programmatically.
   "resource://nimbus/schemas/",
 
   // Activity stream schemas are referenced programmatically.
   "resource://activity-stream/schemas",
 
   // Localization file added programatically in featureCallout.jsm
   "resource://app/localization/en-US/browser/featureCallout.ftl",
-
-  // Will be removed in bug 1737308
-  "resource://gre/modules/lz4.js",
-  "resource://gre/modules/lz4_internal.js",
-  "resource://gre/modules/osfile.jsm",
-  "resource://gre/modules/osfile/",
 ];
 
 // These are not part of the omni.ja file, so we find them only when running
 // the test on a non-packaged build.
 if (AppConstants.platform == "macosx") {
   gExceptionPaths.push("resource://gre/res/cursors/");
   gExceptionPaths.push("resource://gre/res/touchbar/");
 }
--- a/docs/code-quality/lint/linters/eslint-plugin-mozilla.rst
+++ b/docs/code-quality/lint/linters/eslint-plugin-mozilla.rst
@@ -53,17 +53,16 @@ The plugin implements the following rule
    eslint-plugin-mozilla/reject-chromeutils-import-params
    eslint-plugin-mozilla/reject-eager-module-in-lazy-getter
    eslint-plugin-mozilla/reject-global-this
    eslint-plugin-mozilla/reject-globalThis-modification
    eslint-plugin-mozilla/reject-importGlobalProperties
    eslint-plugin-mozilla/reject-lazy-imports-into-globals
    eslint-plugin-mozilla/reject-mixing-eager-and-lazy
    eslint-plugin-mozilla/reject-multiple-getters-calls
-   eslint-plugin-mozilla/reject-osfile
    eslint-plugin-mozilla/reject-relative-requires
    eslint-plugin-mozilla/reject-requires-await
    eslint-plugin-mozilla/reject-scriptableunicodeconverter
    eslint-plugin-mozilla/reject-some-requires
    eslint-plugin-mozilla/reject-top-level-await
    eslint-plugin-mozilla/reject-import-system-module-from-non-system
    eslint-plugin-mozilla/use-cc-etc
    eslint-plugin-mozilla/use-chromeutils-generateqi
deleted file mode 100644
--- a/docs/code-quality/lint/linters/eslint-plugin-mozilla/reject-osfile.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-reject-osfile
-=============
-
-Rejects calls into ``OS.File`` and ``OS.Path``. This is configured as a warning.
-You should use |IOUtils|_ and |PathUtils|_ respectively for new code.  If
-modifying old code, please consider swapping it in if possible; if this is
-tricky please ensure a bug is on file.
-
-.. |IOUtils| replace:: ``IOUtils``
-.. _IOUtils: https://searchfox.org/mozilla-central/source/dom/chrome-webidl/IOUtils.webidl
-
-.. |PathUtils| replace:: ``PathUtils``
-.. _PathUtils: https://searchfox.org/mozilla-central/source/dom/chrome-webidl/PathUtils.webidl
--- a/dom/system/OSFileConstants.cpp
+++ b/dom/system/OSFileConstants.cpp
@@ -830,107 +830,22 @@ bool OSFileConstantsService::DefineOSFil
 
   // Build OS.Constants.Sys
 
   JS::Rooted<JSObject*> objSys(aCx);
   if (!(objSys = GetOrCreateObjectProperty(aCx, objConstants, "Sys"))) {
     return false;
   }
 
-  nsCOMPtr<nsIXULRuntime> runtime =
-      do_GetService(XULRUNTIME_SERVICE_CONTRACTID);
-  if (runtime) {
-    nsAutoCString os;
-    DebugOnly<nsresult> rv = runtime->GetOS(os);
-    MOZ_ASSERT(NS_SUCCEEDED(rv));
-
-    JSString* strVersion = JS_NewStringCopyZ(aCx, os.get());
-    if (!strVersion) {
-      return false;
-    }
-
-    JS::Rooted<JS::Value> valVersion(aCx, JS::StringValue(strVersion));
-    if (!JS_SetProperty(aCx, objSys, "Name", valVersion)) {
-      return false;
-    }
-  }
-
-#if defined(DEBUG)
-  JS::Rooted<JS::Value> valDebug(aCx, JS::TrueValue());
-  if (!JS_SetProperty(aCx, objSys, "DEBUG", valDebug)) {
-    return false;
-  }
-#endif
-
-#if defined(HAVE_64BIT_BUILD)
-  JS::Rooted<JS::Value> valBits(aCx, JS::Int32Value(64));
-#else
-  JS::Rooted<JS::Value> valBits(aCx, JS::Int32Value(32));
-#endif  // defined (HAVE_64BIT_BUILD)
-  if (!JS_SetProperty(aCx, objSys, "bits", valBits)) {
-    return false;
-  }
-
   if (!JS_DefineProperty(
           aCx, objSys, "umask", mUserUmask,
           JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) {
     return false;
   }
 
-  // Build OS.Constants.Path
-
-  JS::Rooted<JSObject*> objPath(aCx);
-  if (!(objPath = GetOrCreateObjectProperty(aCx, objConstants, "Path"))) {
-    return false;
-  }
-
-  // Locate libxul
-  // Note that we don't actually provide the full path, only the name of the
-  // library, which is sufficient to link to the library using js-ctypes.
-
-#if defined(XP_MACOSX)
-  // Under MacOS X, for some reason, libxul is called simply "XUL",
-  // and we need to provide the full path.
-  nsAutoString libxul;
-  libxul.Append(mPaths->libDir);
-  libxul.AppendLiteral("/XUL");
-#else
-  // On other platforms, libxul is a library "xul" with regular
-  // library prefix/suffix.
-  nsAutoString libxul;
-  libxul.AppendLiteral(MOZ_DLL_PREFIX);
-  libxul.AppendLiteral("xul");
-  libxul.AppendLiteral(MOZ_DLL_SUFFIX);
-#endif  // defined(XP_MACOSX)
-
-  if (!SetStringProperty(aCx, objPath, "libxul", libxul)) {
-    return false;
-  }
-
-  if (!SetStringProperty(aCx, objPath, "libDir", mPaths->libDir)) {
-    return false;
-  }
-
-  if (!SetStringProperty(aCx, objPath, "tmpDir", mPaths->tmpDir)) {
-    return false;
-  }
-
-  // Configure profileDir only if it is available at this stage
-  if (!mPaths->profileDir.IsVoid() &&
-      !SetStringProperty(aCx, objPath, "profileDir", mPaths->profileDir)) {
-    return false;
-  }
-
-  // Configure localProfileDir only if it is available at this stage
-  if (!mPaths->localProfileDir.IsVoid() &&
-      !SetStringProperty(aCx, objPath, "localProfileDir",
-                         mPaths->localProfileDir)) {
-    return false;
-  }
-
   return true;
 }
 
 NS_IMPL_ISUPPORTS(OSFileConstantsService, nsIOSFileConstantsService,
                   nsIObserver)
 
 /* static */
 already_AddRefed<OSFileConstantsService> OSFileConstantsService::GetOrCreate() {
--- a/dom/system/moz.build
+++ b/dom/system/moz.build
@@ -3,19 +3,16 @@
 # 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/.
 
 # This picks up *hapticfeedback* which is graveyard
 with Files("**"):
     BUG_COMPONENT = ("Core", "DOM: Core & HTML")
 
-with Files("*OSFile*"):
-    BUG_COMPONENT = ("Toolkit", "OS.File")
-
 with Files("*ocationProvider*"):
     BUG_COMPONENT = ("Core", "DOM: Geolocation")
 
 with Files("windows/*LocationProvider*"):
     BUG_COMPONENT = ("Core", "DOM: Geolocation")
 
 with Files("IOUtils*"):
     BUG_COMPONENT = ("Toolkit", "OS.File")
--- a/dom/system/tests/chrome.ini
+++ b/dom/system/tests/chrome.ini
@@ -1,9 +1,9 @@
 [DEFAULT]
+
+[test_constants.xhtml]
 support-files =
   worker_constants.js
-
-[test_constants.xhtml]
 [test_pathutils.html]
 [test_pathutils_worker.xhtml]
 support-files =
   pathutils_worker.js
--- a/dom/system/tests/ioutils/test_ioutils_read_write.html
+++ b/dom/system/tests/ioutils/test_ioutils_read_write.html
@@ -10,21 +10,16 @@
   <link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
   <script src="file_ioutils_test_fixtures.js"></script>
   <script>
     "use strict";
 
     const { Assert } = ChromeUtils.import("resource://testing-common/Assert.jsm");
     const { ObjectUtils } = ChromeUtils.import("resource://gre/modules/ObjectUtils.jsm");
 
-    // This is presently only used to test compatability between OS.File and
-    // IOUtils when it comes to writing compressed files. The import and the
-    // test `test_lz4_osfile_compat` can be removed with OS.File is removed.
-    const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
     add_task(async function test_read_failure() {
       const doesNotExist = PathUtils.join(PathUtils.tempDir, "does_not_exist.tmp");
       await Assert.rejects(
         IOUtils.read(doesNotExist),
         /Could not open the file at .*/,
         "IOUtils::read rejects when file does not exist"
       );
     });
@@ -335,41 +330,16 @@
       const readEmptyRaw = await IOUtils.read(tmpFileName, { decompress: false });
       is(readEmptyRaw.length, 12, "Expected to read back just the LZ4 header");
       const expectedHeader = Uint8Array.of(109, 111, 122, 76, 122, 52, 48, 0, 0, 0, 0, 0); // "mozLz40\0\0\0\0"
       ok(readEmptyRaw.equals(expectedHeader), "Expected to read header with content length of 0");
 
       await cleanup(tmpFileName);
     });
 
-    add_task(async function test_lz4_osfile_compat() {
-      const osfileTmpFile = PathUtils.join(PathUtils.tempDir, "test_ioutils_lz4_compat_osfile.tmp");
-      const ioutilsTmpFile = PathUtils.join(PathUtils.tempDir, "test_ioutils_lz4_compat_ioutils.tmp");
-
-      info("Test OS.File and IOUtils write the same file with LZ4 compression enabled")
-      const repeatedBytes = Uint8Array.of(...new Array(50).fill(1));
-      let expectedBytes = 23;
-      let ioutilsBytes = await IOUtils.write(ioutilsTmpFile, repeatedBytes, { compress: true });
-      let osfileBytes = await OS.File.writeAtomic(osfileTmpFile, repeatedBytes, { compression: "lz4" });
-      is(ioutilsBytes, expectedBytes, "IOUtils writes the expected number of bytes for compression");
-      is(osfileBytes, ioutilsBytes, "OS.File and IOUtils write the same number of bytes for LZ4 compression");
-
-      info("Test OS.File can read a file compressed by IOUtils");
-      const osfileReadBytes = await OS.File.read(ioutilsTmpFile, { compression: "lz4" });
-      ok(osfileReadBytes.every(byte => byte === 1), "OS.File can read a file compressed by IOUtils");
-      is(osfileReadBytes.length, 50, "OS.File reads the right number of bytes from a file compressed by IOUtils")
-
-      info("Test IOUtils can read a file compressed by OS.File");
-      const ioutilsReadBytes = await IOUtils.read(osfileTmpFile, { decompress: true });
-      ok(ioutilsReadBytes.every(byte => byte === 1), "IOUtils can read a file compressed by OS.File");
-      is(ioutilsReadBytes.length, 50, "IOUtils reads the right number of bytes from a file compressed by OS.File")
-
-      await cleanup(osfileTmpFile, ioutilsTmpFile);
-    });
-
     add_task(async function test_lz4_bad_call() {
       const tmpFileName = PathUtils.join(PathUtils.tempDir, "test_ioutils_lz4_bad_call.tmp");
 
       info("Test decompression with invalid options");
       const varyingBytes = Uint8Array.of(...new Array(50).keys());
       let bytesWritten = await IOUtils.write(tmpFileName, varyingBytes, { compress: true });
       is(bytesWritten, 64, "Expected to write 64 bytes");
       await Assert.rejects(
--- a/dom/system/tests/ioutils/test_ioutils_read_write_utf8.html
+++ b/dom/system/tests/ioutils/test_ioutils_read_write_utf8.html
@@ -10,21 +10,16 @@
   <link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
   <script src="file_ioutils_test_fixtures.js"></script>
   <script>
     "use strict";
 
     const { Assert } = ChromeUtils.import("resource://testing-common/Assert.jsm");
     const { ObjectUtils } = ChromeUtils.import("resource://gre/modules/ObjectUtils.jsm");
 
-    // This is presently only used to test compatability between OS.File and
-    // IOUtils when it comes to writing compressed files. The import and the
-    // test `test_lz4_osfile_compat` can be removed with OS.File is removed.
-    const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
     // This is an impossible sequence of bytes in an UTF-8 encoded file.
     // See section 3.5.3 of this text:
     // https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
     const invalidUTF8 = Uint8Array.of(0xfe, 0xfe, 0xff, 0xff);
 
     add_task(async function test_read_utf8_failure() {
       info("Test attempt to read non-existent file (UTF8)");
       const doesNotExist = PathUtils.join(PathUtils.tempDir, "does_not_exist.tmp");
@@ -285,39 +280,16 @@
       const readEmpty = await IOUtils.readUTF8(tmpFileName, { decompress: true });
       is(readEmpty, empty, "IOUtils can write and read back empty buffers with LZ4");
       const readEmptyRaw = await IOUtils.readUTF8(tmpFileName, { decompress: false });
       is(readEmptyRaw.length, 12, "Expected to read back just the LZ4 header");
 
       await cleanup(tmpFileName);
     });
 
-    add_task(async function test_utf8_lz4_osfile_compat() {
-      const osfileTmpFile = PathUtils.join(PathUtils.tempDir, "test_ioutils_utf8_lz4_compat_osfile.tmp");
-      const ioutilsTmpFile = PathUtils.join(PathUtils.tempDir, "test_ioutils_utf8_lz4_compat_ioutils.tmp");
-
-      info("Test OS.File and IOUtils write the same UTF-8 file with LZ4 compression enabled")
-      const emoji = "☕️ ⚧️ 😀 🖖🏿 🤠 🏳️‍🌈 🥠 🏴‍☠️ 🪐";
-      let expectedBytes = 83;
-      let ioutilsBytes = await IOUtils.writeUTF8(ioutilsTmpFile, emoji, { compress: true });
-      let osfileBytes = await OS.File.writeAtomic(osfileTmpFile, emoji, { compression: "lz4" });
-      is(ioutilsBytes, expectedBytes, "IOUtils writes the expected number of bytes for compression");
-      is(osfileBytes, ioutilsBytes, "OS.File and IOUtils write the same number of bytes for LZ4 compression");
-
-      info("Test OS.File can read an UTF-8 file compressed by IOUtils");
-      const osfileReadStr = await OS.File.read(ioutilsTmpFile, { compression: "lz4", encoding: "utf-8" });
-      is(osfileReadStr, emoji, "OS.File can read an UTF-8 file compressed by IOUtils")
-
-      info("Test IOUtils can read an UTF-8 file compressed by OS.File");
-      const ioutilsReadString = await IOUtils.readUTF8(ioutilsTmpFile, { decompress: true });
-      is(ioutilsReadString, emoji, "IOUtils can read an UTF-8 file compressed by OS.File");
-
-      await cleanup(osfileTmpFile, ioutilsTmpFile);
-    });
-
     add_task(async function test_utf8_lz4_bad_call() {
       const tmpFileName = PathUtils.join(PathUtils.tempDir, "test_ioutils_utf8_lz4_bad_call.tmp");
 
       info("readUTF8 ignores the maxBytes option if provided");
       const emoji = "☕️ ⚧️ 😀 🖖🏿 🤠 🏳️‍🌈 🥠 🏴‍☠️ 🪐";
       let bytesWritten = await IOUtils.writeUTF8(tmpFileName, emoji, { compress: true });
       is(bytesWritten, 83, "Expected to write 83 bytes");
 
--- a/dom/system/tests/test_constants.xhtml
+++ b/dom/system/tests/test_constants.xhtml
@@ -11,31 +11,16 @@
   <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
   <script type="application/javascript">
   <![CDATA[
 
 /* global OS */
 
 let worker;
 
-function test_xul() {
-  let lib;
-  isnot(null, OS.Constants.Path.libxul, "libxulpath is defined");
-  try {
-    lib = ctypes.open(OS.Constants.Path.libxul);
-    lib.declare("DumpJSStack", ctypes.default_abi, ctypes.void_t);
-  } catch (x) {
-    ok(false, "Could not open libxul " + x);
-  }
-  if (lib) {
-    lib.close();
-  }
-  ok(true, "test_xul: opened libxul successfully");
-}
-
 // Test that OS.Constants.libc is defined
 function test_libc() {
   isnot(null, OS.Constants.libc, "OS.Constants.libc is defined");
   is(0o001, OS.Constants.libc.S_IXOTH, "OS.Constants.libc.S_IXOTH is defined");
   is(0o002, OS.Constants.libc.S_IWOTH, "OS.Constants.libc.S_IWOTH is defined");
   is(0o007, OS.Constants.libc.S_IRWXO, "OS.Constants.libc.S_IRWXO is defined");
   is(0o010, OS.Constants.libc.S_IXGRP, "OS.Constants.libc.S_IXGRP is defined");
   is(0o020, OS.Constants.libc.S_IWGRP, "OS.Constants.libc.S_IWGRP is defined");
@@ -53,44 +38,35 @@ function test_Win() {
                            .getService(Ci.nsIXULRuntime);
   if(xulRuntime.OS == "Windows") {
     ok("Win" in OS.Constants, "OS.Constants.Win is defined");
     is(OS.Constants.Win.INVALID_HANDLE_VALUE, -1,
       "OS.Constants.Win.INVALID_HANDLE_VALUE is defined and correct");
   }
 }
 
-// Test that OS.Constants.Sys.DEBUG is set properly on main thread
-function test_debugBuildMainThread(isDebugBuild) {
-  is(isDebugBuild, !!OS.Constants.Sys.DEBUG, "OS.Constants.Sys.DEBUG is set properly on main thread");
-}
-
 // Test that OS.Constants.Sys.umask is set properly on main thread
 function test_umaskMainThread(umask) {
   is(umask, OS.Constants.Sys.umask,
      "OS.Constants.Sys.umask is set properly on main thread: " +
      ("0000"+umask.toString(8)).slice(-4));
 }
 
 var ctypes;
 function test() {
   ok(true, "test_constants.xhtml: Starting test");
 
   // Test 1: Load libxul from main thread
   Cc["@mozilla.org/net/osfileconstantsservice;1"].
     getService(Ci.nsIOSFileConstantsService).
     init();
   ({ctypes} = ChromeUtils.import("resource://gre/modules/ctypes.jsm"));
-  test_xul();
   test_libc();
   test_Win();
 
-  let isDebugBuild = Cc["@mozilla.org/xpcom/debug;1"]
-                            .getService(Ci.nsIDebug2).isDebugBuild;
-  test_debugBuildMainThread(isDebugBuild);
 
   let umask = Cc["@mozilla.org/system-info;1"].
     getService(Ci.nsIPropertyBag2).
     getProperty("umask");
   test_umaskMainThread(umask);
 
   // Test 2: Load libxul from chrome thread
   worker = new ChromeWorker("worker_constants.js");
@@ -118,17 +94,16 @@ function test() {
       SimpleTest.ok(false, "test_constants.xhtml: wrong message " + JSON.stringify(msg.data));
       return;
     }
   };
 
   // pass expected values that are unavailable off-main-thread
   // to the worker
   worker.postMessage({
-    isDebugBuild: isDebugBuild,
     umask: umask
   });
   ok(true, "test_constants.xhtml: Test in progress");
 };
 ]]>
   </script>
 
   <body xmlns="http://www.w3.org/1999/xhtml">
--- a/dom/system/tests/worker_constants.js
+++ b/dom/system/tests/worker_constants.js
@@ -10,23 +10,19 @@ function log(text) {
 function send(message) {
   self.postMessage(message);
 }
 
 self.onmessage = function(msg) {
   self.onmessage = function(msgInner) {
     log("ignored message " + JSON.stringify(msgInner.data));
   };
-  let { isDebugBuild, umask } = msg.data;
+  let { umask } = msg.data;
   try {
-    test_name();
-    test_xul();
-    test_debugBuildWorkerThread(isDebugBuild);
     test_umaskWorkerThread(umask);
-    test_bits();
   } catch (x) {
     log("Catching error: " + x);
     log("Stack: " + x.stack);
     log("Source: " + x.toSource());
     ok(false, x.toString() + "\n" + x.stack);
   }
   finish();
 };
@@ -40,56 +36,17 @@ function ok(condition, description) {
 }
 function is(a, b, description) {
   send({ kind: "is", a, b, description });
 }
 function isnot(a, b, description) {
   send({ kind: "isnot", a, b, description });
 }
 
-// Test that OS.Constants.Sys.Name is defined
-function test_name() {
-  isnot(null, OS.Constants.Sys.Name, "OS.Constants.Sys.Name is defined");
-}
-
-// Test that OS.Constants.Sys.DEBUG is set properly in ChromeWorker thread
-function test_debugBuildWorkerThread(isDebugBuild) {
-  is(
-    isDebugBuild,
-    !!OS.Constants.Sys.DEBUG,
-    "OS.Constants.Sys.DEBUG is set properly on worker thread"
-  );
-}
-
 // Test that OS.Constants.Sys.umask is set properly in ChromeWorker thread
 function test_umaskWorkerThread(umask) {
   is(
     umask,
     OS.Constants.Sys.umask,
     "OS.Constants.Sys.umask is set properly on worker thread: " +
       ("0000" + umask.toString(8)).slice(-4)
   );
 }
-
-// Test that OS.Constants.Path.libxul lets us open libxul
-function test_xul() {
-  let lib;
-  isnot(null, OS.Constants.Path.libxul, "libxul is defined");
-  try {
-    lib = ctypes.open(OS.Constants.Path.libxul);
-    lib.declare("DumpJSStack", ctypes.default_abi, ctypes.void_t);
-  } catch (x) {
-    ok(false, "test_xul: Could not open libxul: " + x);
-  }
-  if (lib) {
-    lib.close();
-  }
-  ok(true, "test_xul: opened libxul successfully");
-}
-
-// Check if the value of OS.Constants.Sys.bits is 32 or 64
-function test_bits() {
-  is(
-    OS.Constants.Sys.bits,
-    ctypes.int.ptr.size * 8,
-    "OS.Constants.Sys.bits is either 32 or 64"
-  );
-}
deleted file mode 100644
--- a/dom/webidl/NativeOSFileInternals.webidl
+++ /dev/null
@@ -1,60 +0,0 @@
-/* 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 obtaone at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Options for nsINativeOSFileInternals::Read
- */
-[GenerateInit]
-dictionary NativeOSFileReadOptions
-{
-  /**
-   * If specified, convert the raw bytes to a String
-   * with the specified encoding. Otherwise, return
-   * the raw bytes as a TypedArray.
-   */
-  DOMString? encoding;
-
-  /**
-   * If specified, limit the number of bytes to read.
-   */
-  unsigned long long? bytes;
-};
-
-/**
- * Options for nsINativeOSFileInternals::WriteAtomic
- */
-[GenerateInit]
-dictionary NativeOSFileWriteAtomicOptions
-{
-  /**
-   * If specified, specify the number of bytes to write.
-   * NOTE: This takes (and should take) a uint64 here but the actual
-   * value is limited to int32. This needs to be fixed, see Bug 1063635.
-   */
-  unsigned long long? bytes;
-
-  /**
-   * If specified, write all data to a temporary file in the
-   * |tmpPath|. Else, write to the given path directly.
-   */
-  DOMString? tmpPath = null;
-
-  /**
-   * If specified and true, a failure will occur if the file
-   * already exists in the given path.
-   */
-  boolean noOverwrite = false;
-
-  /**
-   * If specified and true, this will sync any buffered data
-   * for the file to disk. This might be slower, but safer.
-   */
-  boolean flush = false;
-
-  /**
-   * If specified, this will backup the destination file as
-   * specified.
-   */
-  DOMString? backupTo = null;
-};
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -224,19 +224,16 @@ with Files("MIDI*"):
     BUG_COMPONENT = ("Core", "DOM: Device Interfaces")
 
 with Files("Mouse*"):
     BUG_COMPONENT = ("Core", "DOM: UI Events & Focus Handling")
 
 with Files("MutationEvent.webidl"):
     BUG_COMPONENT = ("Core", "DOM: Events")
 
-with Files("NativeOSFileInternals.webidl"):
-    BUG_COMPONENT = ("Toolkit", "OS.File")
-
 with Files("NavigationPreloadManager.webidl"):
     BUG_COMPONENT = ("Core", "DOM: Service Workers")
 
 with Files("Net*"):
     BUG_COMPONENT = ("Core", "Networking")
 
 with Files("OfflineAudio*"):
     BUG_COMPONENT = ("Core", "Web Audio")
@@ -741,17 +738,16 @@ WEBIDL_FILES = [
     "MimeType.webidl",
     "MimeTypeArray.webidl",
     "MouseEvent.webidl",
     "MouseScrollEvent.webidl",
     "MozFrameLoaderOwner.webidl",
     "MutationEvent.webidl",
     "MutationObserver.webidl",
     "NamedNodeMap.webidl",
-    "NativeOSFileInternals.webidl",
     "NavigationPreloadManager.webidl",
     "Navigator.webidl",
     "NetErrorInfo.webidl",
     "NetworkInformation.webidl",
     "NetworkOptions.webidl",
     "NodeFilter.webidl",
     "NodeIterator.webidl",
     "NodeList.webidl",
--- a/js/xpconnect/tests/browser/browser_import_mapped_jsm.js
+++ b/js/xpconnect/tests/browser/browser_import_mapped_jsm.js
@@ -23,17 +23,16 @@ const JSMs = [
   "resource://gre/modules/FileUtils.jsm",
   "resource://gre/modules/LightweightThemeManager.jsm",
   "resource://gre/modules/NetUtil.jsm",
   "resource://gre/modules/PlacesUtils.jsm",
   "resource://gre/modules/PluralForm.jsm",
   "resource://gre/modules/PrivateBrowsingUtils.jsm",
   "resource://gre/modules/Timer.jsm",
   "resource://gre/modules/XPCOMUtils.jsm",
-  "resource://gre/modules/osfile.jsm",
   "resource://gre/modules/addons/XPIDatabase.jsm",
   "resource://gre/modules/addons/XPIProvider.jsm",
   "resource://gre/modules/addons/XPIInstall.jsm",
   "resource:///modules/BrowserWindowTracker.jsm",
 ];
 
 if (AppConstants.platform === "win") {
   JSMs.push("resource:///modules/WindowsJumpLists.jsm");
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -619,19 +619,16 @@ pref("findbar.matchdiacritics", 0);
 pref("findbar.modalHighlight", false);
 
 // use Mac OS X Appearance panel text smoothing setting when rendering text, disabled by default
 pref("gfx.use_text_smoothing_setting", false);
 
 // Number of characters to consider emphasizing for rich autocomplete results
 pref("toolkit.autocomplete.richBoundaryCutoff", 200);
 
-// Variable controlling logging for osfile.
-pref("toolkit.osfile.log", false);
-
 pref("toolkit.scrollbox.smoothScroll", true);
 pref("toolkit.scrollbox.scrollIncrement", 20);
 pref("toolkit.scrollbox.clickToScroll.scrollDelay", 150);
 
 // Controls logging for Sqlite.sys.mjs.
 pref("toolkit.sqlitejsm.loglevel", "Error");
 
 pref("toolkit.tabbox.switchByScrolling", false);
--- a/testing/runtimes/manifest-runtimes-android.json
+++ b/testing/runtimes/manifest-runtimes-android.json
@@ -1559,17 +1559,16 @@
     "toolkit/components/autocomplete/tests/unit/xpcshell.ini": 12.66,
     "toolkit/components/captivedetect/test/unit/xpcshell.ini": 6.15,
     "toolkit/components/cascade_bloom_filter/test/xpcshell/xpcshell.ini": 0.54,
     "toolkit/components/contextualidentity/tests/unit/xpcshell.ini": 1.87,
     "toolkit/components/extensions/test/xpcshell/xpcshell-remote.ini": 0.85,
     "toolkit/components/extensions/test/xpcshell/xpcshell.ini": 19.12,
     "toolkit/components/featuregates/test/unit/xpcshell.ini": 1.71,
     "toolkit/components/mozintl/test/xpcshell.ini": 1.82,
-    "toolkit/components/osfile/tests/xpcshell/xpcshell.ini": 27.1,
     "toolkit/components/telemetry/tests/unit/xpcshell.ini": 42.36,
     "toolkit/components/timermanager/tests/unit/xpcshell.ini": 9.07,
     "toolkit/components/utils/test/unit/xpcshell.ini": 2.22,
     "toolkit/components/windowcreator/tests/unit/xpcshell.ini": 1.15,
     "toolkit/content/tests/unit/xpcshell.ini": 0.53,
     "toolkit/modules/tests/xpcshell/xpcshell.ini": 28.47,
     "toolkit/mozapps/downloads/tests/unit/xpcshell.ini": 2.41,
     "uriloader/exthandler/tests/unit/xpcshell.ini": 5.05,
--- a/testing/runtimes/manifest-runtimes-unix.json
+++ b/testing/runtimes/manifest-runtimes-unix.json
@@ -381,17 +381,16 @@
     "layout/xul/test/chrome.ini": 13.96,
     "security/manager/ssl/tests/mochitest/stricttransportsecurity/chrome.ini": 4.78,
     "services/fxaccounts/tests/mochitest/chrome.ini": 1.3,
     "testing/mochitest/chrome/chrome.ini": 2.22,
     "toolkit/components/aboutmemory/tests/chrome.ini": 23.09,
     "toolkit/components/certviewer/tests/chrome/chrome.ini": 2.78,
     "toolkit/components/ctypes/tests/chrome/chrome.ini": 1.4,
     "toolkit/components/extensions/test/mochitest/chrome.ini": 11.29,
-    "toolkit/components/osfile/tests/mochi/chrome.ini": 9.12,
     "toolkit/components/places/tests/chrome/chrome.ini": 1.87,
     "toolkit/components/prompts/test/chrome.ini": 106.31,
     "toolkit/components/resistfingerprinting/tests/chrome.ini": 3.99,
     "toolkit/components/url-classifier/tests/mochitest/chrome.ini": 35.15,
     "toolkit/components/viewsource/test/chrome.ini": 1.14,
     "toolkit/components/windowcreator/test/chrome.ini": 1.54,
     "toolkit/components/windowwatcher/test/chrome.ini": 1.32,
     "toolkit/components/workerloader/tests/chrome.ini": 1.19,
--- a/testing/runtimes/manifest-runtimes-windows.json
+++ b/testing/runtimes/manifest-runtimes-windows.json
@@ -383,17 +383,16 @@
     "layout/xul/test/chrome.ini": 12.69,
     "security/manager/ssl/tests/mochitest/stricttransportsecurity/chrome.ini": 3.14,
     "services/fxaccounts/tests/mochitest/chrome.ini": 1.37,
     "testing/mochitest/chrome/chrome.ini": 2.22,
     "toolkit/components/aboutmemory/tests/chrome.ini": 24.16,
     "toolkit/components/certviewer/tests/chrome/chrome.ini": 2.35,
     "toolkit/components/ctypes/tests/chrome/chrome.ini": 1.38,
     "toolkit/components/extensions/test/mochitest/chrome.ini": 8.63,
-    "toolkit/components/osfile/tests/mochi/chrome.ini": 7.73,
     "toolkit/components/places/tests/chrome/chrome.ini": 1.89,
     "toolkit/components/prompts/test/chrome.ini": 41.2,
     "toolkit/components/resistfingerprinting/tests/chrome.ini": 3.59,
     "toolkit/components/url-classifier/tests/mochitest/chrome.ini": 22.42,
     "toolkit/components/viewsource/test/chrome.ini": 1.14,
     "toolkit/components/windowcreator/test/chrome.ini": 1.51,
     "toolkit/components/windowwatcher/test/chrome.ini": 1.56,
     "toolkit/components/workerloader/tests/chrome.ini": 1.21,
--- a/toolkit/components/build/components.conf
+++ b/toolkit/components/build/components.conf
@@ -70,22 +70,16 @@ Classes = [
         'cid': '{91fa9e67-1427-4ee9-8ee0-1a6ed578bee1}',
         'contract_ids': ['@mozilla.org/reputationservice/login-reputation-service;1'],
         'singleton': True,
         'type': 'mozilla::LoginReputationService',
         'headers': ['/toolkit/components/reputationservice/LoginReputation.h'],
         'constructor': 'mozilla::LoginReputationService::GetSingleton',
     },
     {
-        'cid': '{63a69303-8a64-45a9-848c-d4e2792794e6}',
-        'contract_ids': ['@mozilla.org/toolkit/osfile/native-internals;1'],
-        'type': 'mozilla::NativeOSFileInternalsService',
-        'headers': ['mozilla/NativeOSFileInternals.h'],
-    },
-    {
         'name': 'Alerts',
         'cid': '{a0ccaaf8-09da-44d8-b250-9ac3e93c8117}',
         'contract_ids': ['@mozilla.org/alerts-service;1'],
         'type': 'nsAlertsService',
         'headers': ['/toolkit/components/alerts/nsAlertsService.h'],
         'overridable': True,
     },
     {
deleted file mode 100644
--- a/toolkit/components/lz4/lz4.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/* 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/Compression.h"
-
-/**
- * LZ4 is a very fast byte-wise compression algorithm.
- *
- * Compared to Google's Snappy it is faster to compress and decompress and
- * generally produces output of about the same size.
- *
- * Compared to zlib it compresses at about 10x the speed, decompresses at about
- * 4x the speed and produces output of about 1.5x the size.
- *
- */
-
-using namespace mozilla::Compression;
-
-/**
- * Compresses 'inputSize' bytes from 'source' into 'dest'.
- * Destination buffer must be already allocated,
- * and must be sized to handle worst cases situations (input data not
- * compressible) Worst case size evaluation is provided by function
- * LZ4_compressBound()
- *
- * @param inputSize is the input size. Max supported value is ~1.9GB
- * @param return the number of bytes written in buffer dest
- */
-extern "C" MOZ_EXPORT size_t workerlz4_compress(const char* source,
-                                                size_t inputSize, char* dest) {
-  return LZ4::compress(source, inputSize, dest);
-}
-
-/**
- * If the source stream is malformed, the function will stop decoding
- * and return a negative result, indicating the byte position of the
- * faulty instruction
- *
- * This function never writes outside of provided buffers, and never
- * modifies input buffer.
- *
- * note : destination buffer must be already allocated.
- *        its size must be a minimum of 'outputSize' bytes.
- * @param outputSize is the output size, therefore the original size
- * @return true/false
- */
-extern "C" MOZ_EXPORT int workerlz4_decompress(const char* source,
-                                               size_t inputSize, char* dest,
-                                               size_t maxOutputSize,
-                                               size_t* bytesOutput) {
-  return LZ4::decompress(source, inputSize, dest, maxOutputSize, bytesOutput);
-}
-
-/*
-  Provides the maximum size that LZ4 may output in a "worst case"
-  scenario (input data not compressible) primarily useful for memory
-  allocation of output buffer.
-  note : this function is limited by "int" range (2^31-1)
-
-  @param inputSize is the input size. Max supported value is ~1.9GB
-  @return maximum output size in a "worst case" scenario
-*/
-extern "C" MOZ_EXPORT size_t workerlz4_maxCompressedSize(size_t inputSize) {
-  return LZ4::maxCompressedSize(inputSize);
-}
deleted file mode 100644
--- a/toolkit/components/lz4/lz4.js
+++ /dev/null
@@ -1,188 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-var SharedAll;
-if (typeof Components != "undefined") {
-  SharedAll = ChromeUtils.import(
-    "resource://gre/modules/osfile/osfile_shared_allthreads.jsm"
-  );
-  var { Primitives } = ChromeUtils.import(
-    "resource://gre/modules/lz4_internal.js"
-  );
-  var { ctypes } = ChromeUtils.importESModule(
-    "resource://gre/modules/ctypes.sys.mjs"
-  );
-
-  this.EXPORTED_SYMBOLS = ["Lz4"];
-  this.exports = {};
-} else if (typeof module != "undefined" && typeof require != "undefined") {
-  /* eslint-env commonjs */
-  SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
-  Primitives = require("resource://gre/modules/lz4_internal.js");
-  ctypes = self.ctypes;
-} else {
-  throw new Error(
-    "Please load this module with Component.utils.import or with require()"
-  );
-}
-
-const MAGIC_NUMBER = new Uint8Array([109, 111, 122, 76, 122, 52, 48, 0]); // "mozLz40\0"
-
-const BYTES_IN_SIZE_HEADER = ctypes.uint32_t.size;
-
-const HEADER_SIZE = MAGIC_NUMBER.byteLength + BYTES_IN_SIZE_HEADER;
-
-/**
- * An error during (de)compression
- *
- * @param {string} operation The name of the operation ("compress", "decompress")
- * @param {string} reason A reason to be used when matching errors. Must start
- * with "because", e.g. "becauseInvalidContent".
- * @param {string} message A human-readable message.
- */
-function LZError(operation, reason, message) {
-  SharedAll.OSError.call(this);
-  this.operation = operation;
-  this[reason] = true;
-  this.message = message;
-}
-LZError.prototype = Object.create(SharedAll.OSError);
-LZError.prototype.toString = function toString() {
-  return this.message;
-};
-exports.Error = LZError;
-
-/**
- * Compress a block to a form suitable for writing to disk.
- *
- * Compatibility note: For the moment, we are basing our code on lz4
- * 1.3, which does not specify a *file* format. Therefore, we define
- * our own format. Once lz4 defines a complete file format, we will
- * migrate both |compressFileContent| and |decompressFileContent| to this file
- * format. For backwards-compatibility, |decompressFileContent| will however
- * keep the ability to decompress files provided with older versions of
- * |compressFileContent|.
- *
- * Compressed files have the following layout:
- *
- * | MAGIC_NUMBER (8 bytes) | content size (uint32_t, little endian) | content, as obtained from lz4_compress |
- *
- * @param {TypedArray|void*} buffer The buffer to write to the disk.
- * @param {object=} options An object that may contain the following fields:
- *  - {number} bytes The number of bytes to read from |buffer|. If |buffer|
- *    is an |ArrayBuffer|, |bytes| defaults to |buffer.byteLength|. If
- *    |buffer| is a |void*|, |bytes| MUST be provided.
- * @return {Uint8Array} An array of bytes suitable for being written to the
- * disk.
- */
-function compressFileContent(array, options = {}) {
-  // Prepare the output array
-  let inputBytes;
-  if (SharedAll.isTypedArray(array) && !(options && "bytes" in options)) {
-    inputBytes = array.byteLength;
-  } else if (options && options.bytes) {
-    inputBytes = options.bytes;
-  } else {
-    throw new TypeError("compressFileContent requires a size");
-  }
-  let maxCompressedSize = Primitives.maxCompressedSize(inputBytes);
-  let outputArray = new Uint8Array(HEADER_SIZE + maxCompressedSize);
-
-  // Compress to output array
-  let payload = new Uint8Array(
-    outputArray.buffer,
-    outputArray.byteOffset + HEADER_SIZE
-  );
-  let compressedSize = Primitives.compress(array, inputBytes, payload);
-
-  // Add headers
-  outputArray.set(MAGIC_NUMBER);
-  let view = new DataView(outputArray.buffer);
-  view.setUint32(MAGIC_NUMBER.byteLength, inputBytes, true);
-
-  return new Uint8Array(outputArray.buffer, 0, HEADER_SIZE + compressedSize);
-}
-exports.compressFileContent = compressFileContent;
-
-function decompressFileContent(array, options = {}) {
-  let bytes = SharedAll.normalizeBufferArgs(array, options.bytes || null);
-  if (bytes < HEADER_SIZE) {
-    throw new LZError(
-      "decompress",
-      "becauseLZNoHeader",
-      `Buffer is too short (no header) - Data: ${options.path || array}`
-    );
-  }
-
-  // Read headers
-  let expectMagicNumber = new DataView(
-    array.buffer,
-    0,
-    MAGIC_NUMBER.byteLength
-  );
-  for (let i = 0; i < MAGIC_NUMBER.byteLength; ++i) {
-    if (expectMagicNumber.getUint8(i) != MAGIC_NUMBER[i]) {
-      throw new LZError(
-        "decompress",
-        "becauseLZWrongMagicNumber",
-        `Invalid header (no magic number) - Data: ${options.path || array}`
-      );
-    }
-  }
-
-  let sizeBuf = new DataView(
-    array.buffer,
-    MAGIC_NUMBER.byteLength,
-    BYTES_IN_SIZE_HEADER
-  );
-  let expectDecompressedSize =
-    sizeBuf.getUint8(0) +
-    (sizeBuf.getUint8(1) << 8) +
-    (sizeBuf.getUint8(2) << 16) +
-    (sizeBuf.getUint8(3) << 24);
-  if (expectDecompressedSize == 0) {
-    // The underlying algorithm cannot handle a size of 0
-    return new Uint8Array(0);
-  }
-
-  // Prepare the input buffer
-  let inputData = new DataView(array.buffer, HEADER_SIZE);
-
-  // Prepare the output buffer
-  let outputBuffer = new Uint8Array(expectDecompressedSize);
-  let decompressedBytes = new SharedAll.Type.size_t.implementation(0);
-
-  // Decompress
-  let success = Primitives.decompress(
-    inputData,
-    bytes - HEADER_SIZE,
-    outputBuffer,
-    outputBuffer.byteLength,
-    decompressedBytes.address()
-  );
-  if (!success) {
-    throw new LZError(
-      "decompress",
-      "becauseLZInvalidContent",
-      `Invalid content: Decompression stopped at ${
-        decompressedBytes.value
-      } - Data: ${options.path || array}`
-    );
-  }
-  return new Uint8Array(
-    outputBuffer.buffer,
-    outputBuffer.byteOffset,
-    decompressedBytes.value
-  );
-}
-exports.decompressFileContent = decompressFileContent;
-
-if (typeof Components != "undefined") {
-  this.Lz4 = {
-    compressFileContent,
-    decompressFileContent,
-  };
-}
deleted file mode 100644
--- a/toolkit/components/lz4/lz4_internal.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/* 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/. */
-
-/* eslint-env commonjs */
-
-"use strict";
-
-var Primitives = {};
-
-var SharedAll;
-if (typeof Components != "undefined") {
-  SharedAll = ChromeUtils.import(
-    "resource://gre/modules/osfile/osfile_shared_allthreads.jsm"
-  );
-
-  this.EXPORTED_SYMBOLS = ["Primitives"];
-  this.Primitives = Primitives;
-  this.exports = {};
-} else if (typeof module != "undefined" && typeof require != "undefined") {
-  SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
-} else {
-  throw new Error(
-    "Please load this module with Component.utils.import or with require()"
-  );
-}
-
-var libxul = new SharedAll.Library("libxul", SharedAll.Constants.Path.libxul);
-var Type = SharedAll.Type;
-
-libxul.declareLazyFFI(
-  Primitives,
-  "compress",
-  "workerlz4_compress",
-  null,
-  /* return*/ Type.size_t,
-  /* const source*/ Type.void_t.in_ptr,
-  /* inputSize*/ Type.size_t,
-  /* dest*/ Type.void_t.out_ptr
-);
-
-libxul.declareLazyFFI(
-  Primitives,
-  "decompress",
-  "workerlz4_decompress",
-  null,
-  /* return*/ Type.int,
-  /* const source*/ Type.void_t.in_ptr,
-  /* inputSize*/ Type.size_t,
-  /* dest*/ Type.void_t.out_ptr,
-  /* maxOutputSize*/ Type.size_t,
-  /* actualOutputSize*/ Type.size_t.out_ptr
-);
-
-libxul.declareLazyFFI(
-  Primitives,
-  "maxCompressedSize",
-  "workerlz4_maxCompressedSize",
-  null,
-  /* return*/ Type.size_t,
-  /* inputSize*/ Type.size_t
-);
-
-if (typeof module != "undefined") {
-  module.exports = {
-    get compress() {
-      return Primitives.compress;
-    },
-    get decompress() {
-      return Primitives.decompress;
-    },
-    get maxCompressedSize() {
-      return Primitives.maxCompressedSize;
-    },
-  };
-}
deleted file mode 100644
--- a/toolkit/components/lz4/moz.build
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- 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/.
-
-with Files("**"):
-    BUG_COMPONENT = ("Toolkit", "OS.File")
-
-XPCSHELL_TESTS_MANIFESTS += ["tests/xpcshell/xpcshell.ini"]
-
-EXTRA_JS_MODULES += [
-    "lz4.js",
-    "lz4_internal.js",
-]
-
-SOURCES += [
-    "lz4.cpp",
-]
-
-FINAL_LIBRARY = "xul"
deleted file mode 100644
--- a/toolkit/components/lz4/tests/xpcshell/data/chrome.manifest
+++ /dev/null
@@ -1,1 +0,0 @@
-content test_lz4 ./
deleted file mode 100644
index a354edc03673f2d3fc3b9f07f9f39d1bd59bf656..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
--- a/toolkit/components/lz4/tests/xpcshell/data/worker_lz4.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/* eslint-env mozilla/chrome-worker */
-
-/* import-globals-from /toolkit/components/workerloader/require.js */
-importScripts("resource://gre/modules/workers/require.js");
-/* import-globals-from /toolkit/components/osfile/osfile.jsm */
-importScripts("resource://gre/modules/osfile.jsm");
-
-function info(x) {
-  // self.postMessage({kind: "do_print", args: [x]});
-  dump("TEST-INFO: " + x + "\n");
-}
-
-const Assert = {
-  ok(x) {
-    self.postMessage({ kind: "assert_ok", args: [!!x] });
-    if (x) {
-      dump("TEST-PASS: " + x + "\n");
-    } else {
-      throw new Error("Assert.ok failed");
-    }
-  },
-
-  equal(a, b) {
-    let result = a == b;
-    self.postMessage({ kind: "assert_ok", args: [result] });
-    if (!result) {
-      throw new Error("Assert.equal failed " + a + " != " + b);
-    }
-  },
-};
-
-function do_test_complete() {
-  self.postMessage({ kind: "do_test_complete", args: [] });
-}
-
-self.onmessage = function() {
-  try {
-    run_test();
-  } catch (ex) {
-    let { message, moduleStack, moduleName, lineNumber } = ex;
-    let error = new Error(message, moduleName, lineNumber);
-    error.stack = moduleStack;
-    dump("Uncaught error: " + error + "\n");
-    dump("Full stack: " + moduleStack + "\n");
-    throw error;
-  }
-};
-
-var Lz4;
-var Internals;
-function test_import() {
-  Lz4 = require("resource://gre/modules/lz4.js");
-  Internals = require("resource://gre/modules/lz4_internal.js");
-}
-
-function test_bound() {
-  for (let k of ["compress", "decompress", "maxCompressedSize"]) {
-    try {
-      info("Checking the existence of " + k + "\n");
-      Assert.ok(!!Internals[k]);
-      info(k + " exists");
-    } catch (ex) {
-      // Ignore errors
-      info(k + " doesn't exist!");
-    }
-  }
-}
-
-function test_reference_file() {
-  info("Decompress reference file");
-  let path = OS.Path.join("data", "compression.lz");
-  let data = OS.File.read(path);
-  let decompressed = Lz4.decompressFileContent(data);
-  let text = new TextDecoder().decode(decompressed);
-  Assert.equal(text, "Hello, lz4");
-}
-
-function compare_arrays(a, b) {
-  return Array.prototype.join.call(a) == Array.prototype.join.call(b);
-}
-
-function run_rawcompression(name, array) {
-  info("Raw compression test " + name);
-  let length = array.byteLength;
-  let compressedArray = new Uint8Array(Internals.maxCompressedSize(length));
-  let compressedBytes = Internals.compress(array, length, compressedArray);
-  compressedArray = new Uint8Array(compressedArray.buffer, 0, compressedBytes);
-  info("Raw compressed: " + length + " into " + compressedBytes);
-
-  let decompressedArray = new Uint8Array(length);
-  let decompressedBytes = new ctypes.size_t();
-  let success = Internals.decompress(
-    compressedArray,
-    compressedBytes,
-    decompressedArray,
-    length,
-    decompressedBytes.address()
-  );
-  info("Raw decompression success? " + success);
-  info("Raw decompression size: " + decompressedBytes.value);
-  Assert.ok(compare_arrays(array, decompressedArray));
-}
-
-function run_filecompression(name, array) {
-  info("File compression test " + name);
-  let compressed = Lz4.compressFileContent(array);
-  info(
-    "Compressed " + array.byteLength + " bytes into " + compressed.byteLength
-  );
-
-  let decompressed = Lz4.decompressFileContent(compressed);
-  info(
-    "Decompressed " +
-      compressed.byteLength +
-      " bytes into " +
-      decompressed.byteLength
-  );
-  Assert.ok(compare_arrays(array, decompressed));
-}
-
-function run_faileddecompression(name, array) {
-  info("invalid decompression test " + name);
-
-  // Ensure that raw decompression doesn't segfault
-  let length = 1 << 14;
-  let decompressedArray = new Uint8Array(length);
-  let decompressedBytes = new ctypes.size_t();
-  Internals.decompress(
-    array,
-    array.byteLength,
-    decompressedArray,
-    length,
-    decompressedBytes.address()
-  );
-
-  // File decompression should fail with an acceptable exception
-  let exn = null;
-  try {
-    Lz4.decompressFileContent(array);
-  } catch (ex) {
-    exn = ex;
-  }
-  Assert.ok(exn);
-  if (array.byteLength < 10) {
-    Assert.ok(exn.becauseLZNoHeader);
-  } else {
-    Assert.ok(exn.becauseLZWrongMagicNumber);
-  }
-}
-
-function run_test() {
-  test_import();
-  test_bound();
-  test_reference_file();
-  for (let length of [0, 1, 1024]) {
-    let array = new Uint8Array(length);
-    for (let i = 0; i < length; ++i) {
-      array[i] = i % 256;
-    }
-    let name = length + " bytes";
-    run_rawcompression(name, array);
-    run_filecompression(name, array);
-    run_faileddecompression(name, array);
-  }
-  do_test_complete();
-}
deleted file mode 100644
--- a/toolkit/components/lz4/tests/xpcshell/test_lz4.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var WORKER_SOURCE_URI = "chrome://test_lz4/content/worker_lz4.js";
-do_load_manifest("data/chrome.manifest");
-
-add_task(function() {
-  let worker = new ChromeWorker(WORKER_SOURCE_URI);
-  return new Promise((resolve, reject) => {
-    worker.onmessage = function(event) {
-      let data = event.data;
-      switch (data.kind) {
-        case "assert_ok":
-          try {
-            Assert.ok(data.args[0]);
-          } catch (ex) {
-            // Ignore errors
-          }
-          return;
-        case "do_test_complete":
-          resolve();
-          worker.terminate();
-          break;
-        case "do_print":
-          info(data.args[0]);
-      }
-    };
-    worker.onerror = function(event) {
-      let error = new Error(event.message, event.filename, event.lineno);
-      worker.terminate();
-      reject(error);
-    };
-    worker.postMessage("START");
-  });
-});
deleted file mode 100644
--- a/toolkit/components/lz4/tests/xpcshell/test_lz4_sync.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const { Lz4 } = ChromeUtils.import("resource://gre/modules/lz4.js");
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-function compare_arrays(a, b) {
-  return Array.prototype.join.call(a) == Array.prototype.join.call(b);
-}
-
-add_task(async function() {
-  let path = OS.Path.join("data", "compression.lz");
-  let data = await OS.File.read(path);
-  let decompressed = Lz4.decompressFileContent(data);
-  let text = new TextDecoder().decode(decompressed);
-  Assert.equal(text, "Hello, lz4");
-});
-
-add_task(async function() {
-  for (let length of [0, 1, 1024]) {
-    let array = new Uint8Array(length);
-    for (let i = 0; i < length; ++i) {
-      array[i] = i % 256;
-    }
-
-    let compressed = Lz4.compressFileContent(array);
-    info(
-      "Compressed " + array.byteLength + " bytes into " + compressed.byteLength
-    );
-
-    let decompressed = Lz4.decompressFileContent(compressed);
-    info(
-      "Decompressed " +
-        compressed.byteLength +
-        " bytes into " +
-        decompressed.byteLength
-    );
-
-    Assert.ok(compare_arrays(array, decompressed));
-  }
-});
deleted file mode 100644
--- a/toolkit/components/lz4/tests/xpcshell/xpcshell.ini
+++ /dev/null
@@ -1,10 +0,0 @@
-[DEFAULT]
-head =
-skip-if = toolkit == 'android'
-support-files =
-  data/worker_lz4.js
-  data/chrome.manifest
-  data/compression.lz
-
-[test_lz4.js]
-[test_lz4_sync.js]
--- a/toolkit/components/moz.build
+++ b/toolkit/components/moz.build
@@ -41,21 +41,19 @@ DIRS += [
     "formautofill",
     "finalizationwitness",
     "find",
     "forgetaboutsite",
     "glean",
     "httpsonlyerror",
     "jsoncpp/src/lib_json",
     "kvstore",
-    "lz4",
     "mediasniffer",
     "mozintl",
     "mozprotocol",
-    "osfile",
     "parentalcontrols",
     "passwordmgr",
     "pdfjs",
     "perfmonitoring",
     "pictureinpicture",
     "places",
     "processtools",
     "processsingleton",
deleted file mode 100644
--- a/toolkit/components/osfile/NativeOSFileInternals.cpp
+++ /dev/null
@@ -1,1263 +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/. */
-
-/**
- * Native implementation of some OS.File operations.
- */
-
-#include "NativeOSFileInternals.h"
-
-#include "nsString.h"
-#include "nsNetCID.h"
-#include "nsThreadUtils.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsServiceManagerUtils.h"
-#include "nsProxyRelease.h"
-
-#include "mozilla/dom/NativeOSFileInternalsBinding.h"
-
-#include "mozilla/Encoding.h"
-#include "nsIEventTarget.h"
-
-#include "mozilla/DebugOnly.h"
-#include "mozilla/Scoped.h"
-#include "mozilla/HoldDropJSObjects.h"
-#include "mozilla/TimeStamp.h"
-#include "mozilla/UniquePtr.h"
-
-#include "prio.h"
-#include "prerror.h"
-#include "private/pprio.h"
-
-#include "jsapi.h"
-#include "jsfriendapi.h"
-#include "js/ArrayBuffer.h"  // JS::GetArrayBufferByteLength,IsArrayBufferObject,NewArrayBufferWithContents,StealArrayBufferContents
-#include "js/experimental/TypedData.h"  // JS_NewUint8ArrayWithBuffer
-#include "js/Utility.h"
-#include "xpcpublic.h"
-
-#include <algorithm>
-#if defined(XP_UNIX)
-#  include <errno.h>
-#endif  // defined (XP_UNIX)
-
-#if defined(XP_WIN)
-#  include <windows.h>
-#endif  // defined (XP_WIN)
-
-namespace mozilla {
-
-MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc, PRFileDesc,
-                                          PR_Close)
-
-namespace {
-
-// Utilities for safely manipulating ArrayBuffer contents even in the
-// absence of a JSContext.
-
-/**
- * The C buffer underlying to an ArrayBuffer. Throughout the code, we manipulate
- * this instead of a void* buffer, as this lets us transfer data across threads
- * and into JavaScript without copy.
- */
-struct ArrayBufferContents {
-  /**
-   * The data of the ArrayBuffer. This is the pointer manipulated to
-   * read/write the contents of the buffer.
-   */
-  uint8_t* data;
-  /**
-   * The number of bytes in the ArrayBuffer.
-   */
-  size_t nbytes;
-};
-
-/**
- * RAII for ArrayBufferContents.
- */
-struct ScopedArrayBufferContentsTraits {
-  typedef ArrayBufferContents type;
-  const static type empty() {
-    type result = {0, 0};
-    return result;
-  }
-  static void release(type ptr) {
-    js_free(ptr.data);
-    ptr.data = nullptr;
-    ptr.nbytes = 0;
-  }
-};
-
-struct MOZ_NON_TEMPORARY_CLASS ScopedArrayBufferContents
-    : public Scoped<ScopedArrayBufferContentsTraits> {
-  explicit ScopedArrayBufferContents()
-      : Scoped<ScopedArrayBufferContentsTraits>() {}
-
-  ScopedArrayBufferContents& operator=(ArrayBufferContents ptr) {
-    Scoped<ScopedArrayBufferContentsTraits>::operator=(ptr);
-    return *this;
-  }
-
-  /**
-   * Request memory for this ArrayBufferContent. This memory may later
-   * be used to create an ArrayBuffer object (possibly on another
-   * thread) without copy.
-   *
-   * @return true In case of success, false otherwise.
-   */
-  bool Allocate(uint32_t length) {
-    dispose();
-    ArrayBufferContents& value = rwget();
-    void* ptr = js_calloc(1, length);
-    if (ptr) {
-      value.data = (uint8_t*)ptr;
-      value.nbytes = length;
-      return true;
-    }
-    return false;
-  }
-
- private:
-  explicit ScopedArrayBufferContents(ScopedArrayBufferContents& source) =
-      delete;
-  ScopedArrayBufferContents& operator=(ScopedArrayBufferContents& source) =
-      delete;
-};
-
-///////// Cross-platform issues
-
-// Platform specific constants. As OS.File always uses OS-level
-// errors, we need to map a few high-level errors to OS-level
-// constants.
-#if defined(XP_UNIX)
-#  define OS_ERROR_FILE_EXISTS EEXIST
-#  define OS_ERROR_NOMEM ENOMEM
-#  define OS_ERROR_INVAL EINVAL
-#  define OS_ERROR_TOO_LARGE EFBIG
-#  define OS_ERROR_RACE EIO
-#elif defined(XP_WIN)
-#  define OS_ERROR_FILE_EXISTS ERROR_ALREADY_EXISTS
-#  define OS_ERROR_NOMEM ERROR_NOT_ENOUGH_MEMORY
-#  define OS_ERROR_INVAL ERROR_BAD_ARGUMENTS
-#  define OS_ERROR_TOO_LARGE ERROR_FILE_TOO_LARGE
-#  define OS_ERROR_RACE ERROR_SHARING_VIOLATION
-#else
-#  error "We do not have platform-specific constants for this platform"
-#endif
-
-///////// Results of OS.File operations
-
-/**
- * Base class for results passed to the callbacks.
- *
- * This base class implements caching of JS values returned to the client.
- * We make use of this caching in derived classes e.g. to avoid accidents
- * when we transfer data allocated on another thread into JS. Note that
- * this caching can lead to cycles (e.g. if a client adds a back-reference
- * in the JS value), so we implement all Cycle Collector primitives in
- * AbstractResult.
- */
-class AbstractResult : public nsINativeOSFileResult {
- public:
-  NS_DECL_NSINATIVEOSFILERESULT
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AbstractResult)
-
-  /**
-   * Construct the result object. Must be called on the main thread
-   * as the AbstractResult is cycle-collected.
-   *
-   * @param aStartDate The instant at which the operation was
-   * requested.  Used to collect Telemetry statistics.
-   */
-  explicit AbstractResult(TimeStamp aStartDate) : mStartDate(aStartDate) {
-    MOZ_ASSERT(NS_IsMainThread());
-    mozilla::HoldJSObjects(this);
-  }
-
-  /**
-   * Setup the AbstractResult once data is available.
-   *
-   * @param aDispatchDate The instant at which the IO thread received
-   * the operation request. Used to collect Telemetry statistics.
-   * @param aExecutionDuration The duration of the operation on the
-   * IO thread.
-   */
-  void Init(TimeStamp aDispatchDate, TimeDuration aExecutionDuration) {
-    MOZ_ASSERT(!NS_IsMainThread());
-
-    mDispatchDuration = (aDispatchDate - mStartDate);
-    mExecutionDuration = aExecutionDuration;
-  }
-
-  /**
-   * Drop any data that could lead to a cycle.
-   */
-  void DropJSData() { mCachedResult = JS::UndefinedValue(); }
-
- protected:
-  virtual ~AbstractResult() {
-    MOZ_ASSERT(NS_IsMainThread());
-    mozilla::DropJSObjects(this);
-  }
-
-  virtual nsresult GetCacheableResult(JSContext* cx,
-                                      JS::MutableHandle<JS::Value> aResult) = 0;
-
- private:
-  TimeStamp mStartDate;
-  TimeDuration mDispatchDuration;
-  TimeDuration mExecutionDuration;
-  JS::Heap<JS::Value> mCachedResult;
-};
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(AbstractResult)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(AbstractResult)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(AbstractResult)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AbstractResult)
-  NS_INTERFACE_MAP_ENTRY(nsINativeOSFileResult)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(AbstractResult)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCachedResult)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AbstractResult)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AbstractResult)
-  tmp->DropJSData();
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMETHODIMP
-AbstractResult::GetDispatchDurationMS(double* aDispatchDuration) {
-  *aDispatchDuration = mDispatchDuration.ToMilliseconds();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-AbstractResult::GetExecutionDurationMS(double* aExecutionDuration) {
-  *aExecutionDuration = mExecutionDuration.ToMilliseconds();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-AbstractResult::GetResult(JSContext* cx, JS::MutableHandle<JS::Value> aResult) {
-  if (mCachedResult.isUndefined()) {
-    nsresult rv = GetCacheableResult(cx, aResult);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    mCachedResult = aResult;
-    return NS_OK;
-  }
-  aResult.set(mCachedResult);
-  return NS_OK;
-}
-
-/**
- * Return a result as a string.
- *
- * In this implementation, attribute |result| is a string. Strings are
- * passed to JS without copy.
- */
-class StringResult final : public AbstractResult {
- public:
-  explicit StringResult(TimeStamp aStartDate) : AbstractResult(aStartDate) {}
-
-  /**
-   * Initialize the object once the contents of the result as available.
-   *
-   * @param aContents The string to pass to JavaScript. Ownership of the
-   * string and its contents is passed to StringResult. The string must
-   * be valid UTF-16.
-   */
-  void Init(TimeStamp aDispatchDate, TimeDuration aExecutionDuration,
-            nsString& aContents) {
-    AbstractResult::Init(aDispatchDate, aExecutionDuration);
-    mContents = aContents;
-  }
-
- protected:
-  nsresult GetCacheableResult(JSContext* cx,
-                              JS::MutableHandle<JS::Value> aResult) override;
-
- private:
-  nsString mContents;
-};
-
-nsresult StringResult::GetCacheableResult(
-    JSContext* cx, JS::MutableHandle<JS::Value> aResult) {
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mContents.get());
-
-  // Convert mContents to a js string without copy. Note that this
-  // may have the side-effect of stealing the contents of the string
-  // from XPCOM and into JS.
-  if (!xpc::StringToJsval(cx, mContents, aResult)) {
-    return NS_ERROR_FAILURE;
-  }
-  return NS_OK;
-}
-
-/**
- * Return a result as a Uint8Array.
- *
- * In this implementation, attribute |result| is a Uint8Array. The array
- * is passed to JS without memory copy.
- */
-class TypedArrayResult final : public AbstractResult {
- public:
-  explicit TypedArrayResult(TimeStamp aStartDate)
-      : AbstractResult(aStartDate) {}
-
-  /**
-   * @param aContents The contents to pass to JS. Calling this method.
-   * transmits ownership of the ArrayBufferContents to the TypedArrayResult.
-   * Do not reuse this value anywhere else.
-   */
-  void Init(TimeStamp aDispatchDate, TimeDuration aExecutionDuration,
-            ArrayBufferContents aContents) {
-    AbstractResult::Init(aDispatchDate, aExecutionDuration);
-    mContents = aContents;
-  }
-
- protected:
-  nsresult GetCacheableResult(JSContext* cx,
-                              JS::MutableHandle<JS::Value> aResult) override;
-
- private:
-  ScopedArrayBufferContents mContents;
-};
-
-nsresult TypedArrayResult::GetCacheableResult(
-    JSContext* cx, JS::MutableHandle<JS::Value> aResult) {
-  MOZ_ASSERT(NS_IsMainThread());
-  // We cannot simply construct a typed array using contents.data as
-  // this would allow us to have several otherwise unrelated
-  // ArrayBuffers with the same underlying C buffer. As this would be
-  // very unsafe, we need to cache the result once we have it.
-
-  const ArrayBufferContents& contents = mContents.get();
-  MOZ_ASSERT(contents.data);
-
-  // This takes ownership of the buffer and notes the memory allocation.
-  JS::Rooted<JSObject*> arrayBuffer(
-      cx, JS::NewArrayBufferWithContents(cx, contents.nbytes, contents.data));
-  if (!arrayBuffer) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  JS::Rooted<JSObject*> result(
-      cx, JS_NewUint8ArrayWithBuffer(cx, arrayBuffer, 0, contents.nbytes));
-  if (!result) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-  mContents.forget();
-
-  aResult.setObject(*result);
-  return NS_OK;
-}
-
-/**
- * Return a result as an int32_t.
- *
- * In this implementation, attribute |result| is an int32_t.
- */
-class Int32Result final : public AbstractResult {
- public:
-  explicit Int32Result(TimeStamp aStartDate)
-      : AbstractResult(aStartDate), mContents(0) {}
-
-  /**
-   * Initialize the object once the contents of the result are available.
-   *
-   * @param aContents The contents to pass to JS. This is an int32_t.
-   */
-  void Init(TimeStamp aDispatchDate, TimeDuration aExecutionDuration,
-            int32_t aContents) {
-    AbstractResult::Init(aDispatchDate, aExecutionDuration);
-    mContents = aContents;
-  }
-
- protected:
-  nsresult GetCacheableResult(JSContext* cx,
-                              JS::MutableHandle<JS::Value> aResult) override;
-
- private:
-  int32_t mContents;
-};
-
-nsresult Int32Result::GetCacheableResult(JSContext* cx,
-                                         JS::MutableHandle<JS::Value> aResult) {
-  MOZ_ASSERT(NS_IsMainThread());
-  aResult.set(JS::NumberValue(mContents));
-  return NS_OK;
-}
-
-//////// Callback events
-
-/**
- * An event used to notify asynchronously of an error.
- */
-class OSFileErrorEvent final : public Runnable {
- public:
-  /**
-   * @param aOnSuccess The success callback.
-   * @param aOnError The error callback.
-   * @param aDiscardedResult The discarded result.
-   * @param aOperation The name of the operation, used for error reporting.
-   * @param aOSError The OS error of the operation, as returned by errno/
-   * GetLastError().
-   *
-   * Note that we pass both the success callback and the error
-   * callback, as well as the discarded result to ensure that they are
-   * all released on the main thread, rather than on the IO thread
-   * (which would hopefully segfault). Also, we pass the callbacks as
-   * alread_AddRefed to ensure that we do not manipulate main-thread
-   * only refcounters off the main thread.
-   */
-  OSFileErrorEvent(
-      nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback>& aOnSuccess,
-      nsMainThreadPtrHandle<nsINativeOSFileErrorCallback>& aOnError,
-      already_AddRefed<AbstractResult>& aDiscardedResult,
-      const nsACString& aOperation, int32_t aOSError)
-      : Runnable("OSFileErrorEvent"),
-        mOnSuccess(aOnSuccess),
-        mOnError(aOnError),
-        mDiscardedResult(aDiscardedResult),
-        mOSError(aOSError),
-        mOperation(aOperation) {
-    MOZ_ASSERT(!NS_IsMainThread());
-  }
-
-  NS_IMETHOD Run() override {
-    MOZ_ASSERT(NS_IsMainThread());
-    (void)mOnError->Complete(mOperation, mOSError);
-
-    // Ensure that the callbacks are released on the main thread.
-    mOnSuccess = nullptr;
-    mOnError = nullptr;
-    mDiscardedResult = nullptr;
-
-    return NS_OK;
-  }
-
- private:
-  // The callbacks. Maintained as nsMainThreadPtrHandle as they are generally
-  // xpconnect values, which cannot be manipulated with nsCOMPtr off
-  // the main thread. We store both the success callback and the
-  // error callback to ensure that they are safely released on the
-  // main thread.
-  nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback> mOnSuccess;
-  nsMainThreadPtrHandle<nsINativeOSFileErrorCallback> mOnError;
-  RefPtr<AbstractResult> mDiscardedResult;
-  int32_t mOSError;
-  nsCString mOperation;
-};
-
-/**
- * An event used to notify of a success.
- */
-class SuccessEvent final : public Runnable {
- public:
-  /**
-   * @param aOnSuccess The success callback.
-   * @param aOnError The error callback.
-   *
-   * Note that we pass both the success callback and the error
-   * callback to ensure that they are both released on the main
-   * thread, rather than on the IO thread (which would hopefully
-   * segfault). Also, we pass them as alread_AddRefed to ensure that
-   * we do not manipulate xpconnect refcounters off the main thread
-   * (which is illegal).
-   */
-  SuccessEvent(
-      nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback>& aOnSuccess,
-      nsMainThreadPtrHandle<nsINativeOSFileErrorCallback>& aOnError,
-      already_AddRefed<nsINativeOSFileResult>& aResult)
-      : Runnable("SuccessEvent"),
-        mOnSuccess(aOnSuccess),
-        mOnError(aOnError),
-        mResult(aResult) {
-    MOZ_ASSERT(!NS_IsMainThread());
-  }
-
-  NS_IMETHOD Run() override {
-    MOZ_ASSERT(NS_IsMainThread());
-    (void)mOnSuccess->Complete(mResult);
-
-    // Ensure that the callbacks are released on the main thread.
-    mOnSuccess = nullptr;
-    mOnError = nullptr;
-    mResult = nullptr;
-
-    return NS_OK;
-  }
-
- private:
-  // The callbacks. Maintained as nsMainThreadPtrHandle as they are generally
-  // xpconnect values, which cannot be manipulated with nsCOMPtr off
-  // the main thread. We store both the success callback and the
-  // error callback to ensure that they are safely released on the
-  // main thread.
-  nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback> mOnSuccess;
-  nsMainThreadPtrHandle<nsINativeOSFileErrorCallback> mOnError;
-  RefPtr<nsINativeOSFileResult> mResult;
-};
-
-//////// Action events
-
-/**
- * Base class shared by actions.
- */
-class AbstractDoEvent : public Runnable {
- public:
-  AbstractDoEvent(
-      nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback>& aOnSuccess,
-      nsMainThreadPtrHandle<nsINativeOSFileErrorCallback>& aOnError)
-      : Runnable("AbstractDoEvent"),
-        mOnSuccess(aOnSuccess),
-        mOnError(aOnError)
-#if defined(DEBUG)
-        ,
-        mResolved(false)
-#endif  // defined(DEBUG)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  /**
-   * Fail, asynchronously.
-   */
-  void Fail(const nsACString& aOperation,
-            already_AddRefed<AbstractResult>&& aDiscardedResult,
-            int32_t aOSError = 0) {
-    Resolve();
-
-    RefPtr<OSFileErrorEvent> event = new OSFileErrorEvent(
-        mOnSuccess, mOnError, aDiscardedResult, aOperation, aOSError);
-    nsresult rv = NS_DispatchToMainThread(event);
-    if (NS_FAILED(rv)) {
-      // Last ditch attempt to release on the main thread - some of
-      // the members of event are not thread-safe, so letting the
-      // pointer go out of scope would cause a crash.
-      NS_ReleaseOnMainThread("AbstractDoEvent::OSFileErrorEvent",
-                             event.forget());
-    }
-  }
-
-  /**
-   * Succeed, asynchronously.
-   */
-  void Succeed(already_AddRefed<nsINativeOSFileResult>&& aResult) {
-    Resolve();
-    RefPtr<SuccessEvent> event =
-        new SuccessEvent(mOnSuccess, mOnError, aResult);
-    nsresult rv = NS_DispatchToMainThread(event);
-    if (NS_FAILED(rv)) {
-      // Last ditch attempt to release on the main thread - some of
-      // the members of event are not thread-safe, so letting the
-      // pointer go out of scope would cause a crash.
-      NS_ReleaseOnMainThread("AbstractDoEvent::SuccessEvent", event.forget());
-    }
-  }
-
- private:
-  /**
-   * Mark the event as complete, for debugging purposes.
-   */
-  void Resolve() {
-#if defined(DEBUG)
-    MOZ_ASSERT(!mResolved);
-    mResolved = true;
-#endif  // defined(DEBUG)
-  }
-
- private:
-  nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback> mOnSuccess;
-  nsMainThreadPtrHandle<nsINativeOSFileErrorCallback> mOnError;
-#if defined(DEBUG)
-  // |true| once the action is complete
-  bool mResolved;
-#endif  // defined(DEBUG)
-};
-
-/**
- * An abstract event implementing reading from a file.
- *
- * Concrete subclasses are responsible for handling the
- * data obtained from the file and possibly post-processing it.
- */
-class AbstractReadEvent : public AbstractDoEvent {
- public:
-  /**
-   * @param aPath The path of the file.
-   */
-  AbstractReadEvent(
-      const nsAString& aPath, const uint64_t aBytes,
-      nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback>& aOnSuccess,
-      nsMainThreadPtrHandle<nsINativeOSFileErrorCallback>& aOnError)
-      : AbstractDoEvent(aOnSuccess, aOnError), mPath(aPath), mBytes(aBytes) {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  NS_IMETHOD Run() override {
-    MOZ_ASSERT(!NS_IsMainThread());
-    TimeStamp dispatchDate = TimeStamp::Now();
-
-    nsresult rv = BeforeRead();
-    if (NS_FAILED(rv)) {
-      // Error reporting is handled by BeforeRead();
-      return NS_OK;
-    }
-
-    ScopedArrayBufferContents buffer;
-    rv = Read(buffer);
-    if (NS_FAILED(rv)) {
-      // Error reporting is handled by Read();
-      return NS_OK;
-    }
-
-    AfterRead(dispatchDate, buffer);
-    return NS_OK;
-  }
-
- private:
-  /**
-   * Read synchronously.
-   *
-   * Must be called off the main thread.
-   *
-   * @param aBuffer The destination buffer.
-   */
-  nsresult Read(ScopedArrayBufferContents& aBuffer) {
-    MOZ_ASSERT(!NS_IsMainThread());
-
-    ScopedPRFileDesc file;
-#if defined(XP_WIN)
-    // On Windows, we can't use PR_OpenFile because it doesn't
-    // handle UTF-16 encoding, which is pretty bad. In addition,
-    // PR_OpenFile opens files without sharing, which is not the
-    // general semantics of OS.File.
-    HANDLE handle =
-        ::CreateFileW(mPath.get(), GENERIC_READ,
-                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-                      /*Security attributes*/ nullptr, OPEN_EXISTING,
-                      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
-                      /*Template file*/ nullptr);
-
-    if (handle == INVALID_HANDLE_VALUE) {
-      Fail("open"_ns, nullptr, ::GetLastError());
-      return NS_ERROR_FAILURE;
-    }
-
-    file = PR_ImportFile((PROsfd)handle);
-    if (!file) {
-      // |file| is closed by PR_ImportFile
-      Fail("ImportFile"_ns, nullptr, PR_GetOSError());
-      return NS_ERROR_FAILURE;
-    }
-
-#else
-    // On other platforms, PR_OpenFile will do.
-    NS_ConvertUTF16toUTF8 path(mPath);
-    file = PR_OpenFile(path.get(), PR_RDONLY, 0);
-    if (!file) {
-      Fail("open"_ns, nullptr, PR_GetOSError());
-      return NS_ERROR_FAILURE;
-    }
-
-#endif  // defined(XP_XIN)
-
-    PRFileInfo64 stat;
-    if (PR_GetOpenFileInfo64(file, &stat) != PR_SUCCESS) {
-      Fail("stat"_ns, nullptr, PR_GetOSError());
-      return NS_ERROR_FAILURE;
-    }
-
-    uint64_t bytes = std::min((uint64_t)stat.size, mBytes);
-    if (bytes > UINT32_MAX) {
-      Fail("Arithmetics"_ns, nullptr, OS_ERROR_INVAL);
-      return NS_ERROR_FAILURE;
-    }
-
-    if (!aBuffer.Allocate(bytes)) {
-      Fail("allocate"_ns, nullptr, OS_ERROR_NOMEM);
-      return NS_ERROR_FAILURE;
-    }
-
-    uint64_t total_read = 0;
-    int32_t just_read = 0;
-    char* dest_chars = reinterpret_cast<char*>(aBuffer.rwget().data);
-    do {
-      just_read = PR_Read(file, dest_chars + total_read,
-                          std::min(uint64_t(PR_INT32_MAX), bytes - total_read));
-      if (just_read == -1) {
-        Fail("read"_ns, nullptr, PR_GetOSError());
-        return NS_ERROR_FAILURE;
-      }
-      total_read += just_read;
-    } while (just_read != 0 && total_read < bytes);
-    if (total_read != bytes) {
-      // We seem to have a race condition here.
-      Fail("read"_ns, nullptr, OS_ERROR_RACE);
-      return NS_ERROR_FAILURE;
-    }
-
-    return NS_OK;
-  }
-
- protected:
-  /**
-   * Any steps that need to be taken before reading.
-   *
-   * In case of error, this method should call Fail() and return
-   * a failure code.
-   */
-  virtual nsresult BeforeRead() { return NS_OK; }
-
-  /**
-   * Proceed after reading.
-   */
-  virtual void AfterRead(TimeStamp aDispatchDate,
-                         ScopedArrayBufferContents& aBuffer) = 0;
-
- protected:
-  const nsString mPath;
-  const uint64_t mBytes;
-};
-
-/**
- * An implementation of a Read event that provides the data
- * as a TypedArray.
- */
-class DoReadToTypedArrayEvent final : public AbstractReadEvent {
- public:
-  DoReadToTypedArrayEvent(
-      const nsAString& aPath, const uint32_t aBytes,
-      nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback>& aOnSuccess,
-      nsMainThreadPtrHandle<nsINativeOSFileErrorCallback>& aOnError)
-      : AbstractReadEvent(aPath, aBytes, aOnSuccess, aOnError),
-        mResult(new TypedArrayResult(TimeStamp::Now())) {}
-
-  ~DoReadToTypedArrayEvent() override {
-    // If AbstractReadEvent::Run() has bailed out, we may need to cleanup
-    // mResult, which is main-thread only data
-    if (!mResult) {
-      return;
-    }
-    NS_ReleaseOnMainThread("DoReadToTypedArrayEvent::mResult",
-                           mResult.forget());
-  }
-
- protected:
-  void AfterRead(TimeStamp aDispatchDate,
-                 ScopedArrayBufferContents& aBuffer) override {
-    MOZ_ASSERT(!NS_IsMainThread());
-    mResult->Init(aDispatchDate, TimeStamp::Now() - aDispatchDate,
-                  aBuffer.forget());
-    Succeed(mResult.forget());
-  }
-
- private:
-  RefPtr<TypedArrayResult> mResult;
-};
-
-/**
- * An implementation of a Read event that provides the data
- * as a JavaScript string.
- */
-class DoReadToStringEvent final : public AbstractReadEvent {
- public:
-  DoReadToStringEvent(
-      const nsAString& aPath, const nsACString& aEncoding,
-      const uint32_t aBytes,
-      nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback>& aOnSuccess,
-      nsMainThreadPtrHandle<nsINativeOSFileErrorCallback>& aOnError)
-      : AbstractReadEvent(aPath, aBytes, aOnSuccess, aOnError),
-        mEncoding(aEncoding),
-        mResult(new StringResult(TimeStamp::Now())) {}
-
-  ~DoReadToStringEvent() override {
-    // If AbstraactReadEvent::Run() has bailed out, we may need to cleanup
-    // mResult, which is main-thread only data
-    if (!mResult) {
-      return;
-    }
-    NS_ReleaseOnMainThread("DoReadToStringEvent::mResult", mResult.forget());
-  }
-
- protected:
-  nsresult BeforeRead() override {
-    // Obtain the decoder. We do this before reading to avoid doing
-    // any unnecessary I/O in case the name of the encoding is incorrect.
-    MOZ_ASSERT(!NS_IsMainThread());
-    const Encoding* encoding = Encoding::ForLabel(mEncoding);
-    if (!encoding) {
-      Fail("Decode"_ns, mResult.forget(), OS_ERROR_INVAL);
-      return NS_ERROR_FAILURE;
-    }
-    mDecoder = encoding->NewDecoderWithBOMRemoval();
-    if (!mDecoder) {
-      Fail("DecoderForEncoding"_ns, mResult.forget(), OS_ERROR_INVAL);
-      return NS_ERROR_FAILURE;
-    }
-
-    return NS_OK;
-  }
-
-  void AfterRead(TimeStamp aDispatchDate,
-                 ScopedArrayBufferContents& aBuffer) override {
-    MOZ_ASSERT(!NS_IsMainThread());
-
-    auto src = Span(aBuffer.get().data, aBuffer.get().nbytes);
-
-    CheckedInt<size_t> needed = mDecoder->MaxUTF16BufferLength(src.Length());
-    if (!needed.isValid() ||
-        needed.value() > std::numeric_limits<nsAString::size_type>::max()) {
-      Fail("arithmetics"_ns, mResult.forget(), OS_ERROR_TOO_LARGE);
-      return;
-    }
-
-    nsString resultString;
-    auto resultSpan = resultString.GetMutableData(needed.value(), fallible);
-    if (!resultSpan) {
-      Fail("allocation"_ns, mResult.forget(), OS_ERROR_TOO_LARGE);
-      return;
-    }
-
-    // Yoric said on IRC that this method is normally called for the entire
-    // file, but that's not guaranteed. Retaining the bug that EOF in conversion
-    // isn't handled anywhere.
-    uint32_t result;
-    size_t read;
-    size_t written;
-    std::tie(result, read, written, std::ignore) =
-        mDecoder->DecodeToUTF16(src, *resultSpan, false);
-    MOZ_ASSERT(result == kInputEmpty);
-    MOZ_ASSERT(read == src.Length());
-    MOZ_ASSERT(written <= needed.value());
-    bool ok = resultString.SetLength(written, fallible);
-    if (!ok) {
-      Fail("allocation"_ns, mResult.forget(), OS_ERROR_TOO_LARGE);
-      return;
-    }
-
-    mResult->Init(aDispatchDate, TimeStamp::Now() - aDispatchDate,
-                  resultString);
-    Succeed(mResult.forget());
-  }
-
- private:
-  nsCString mEncoding;
-  mozilla::UniquePtr<mozilla::Decoder> mDecoder;
-  RefPtr<StringResult> mResult;
-};
-
-/**
- * An event implenting writing atomically to a file.
- */
-class DoWriteAtomicEvent : public AbstractDoEvent {
- public:
-  /**
-   * @param aPath The path of the file.
-   */
-  DoWriteAtomicEvent(
-      const nsAString& aPath, UniquePtr<char[], JS::FreePolicy> aBuffer,
-      const uint64_t aBytes, const nsAString& aTmpPath,
-      const nsAString& aBackupTo, const bool aFlush, const bool aNoOverwrite,
-      nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback>& aOnSuccess,
-      nsMainThreadPtrHandle<nsINativeOSFileErrorCallback>& aOnError)
-      : AbstractDoEvent(aOnSuccess, aOnError),
-        mPath(aPath),
-        mBuffer(std::move(aBuffer)),
-        mBytes(aBytes),
-        mTmpPath(aTmpPath),
-        mBackupTo(aBackupTo),
-        mFlush(aFlush),
-        mNoOverwrite(aNoOverwrite),
-        mResult(new Int32Result(TimeStamp::Now())) {
-    MOZ_ASSERT(NS_IsMainThread());
-  }
-
-  ~DoWriteAtomicEvent() override {
-    // If Run() has bailed out, we may need to cleanup
-    // mResult, which is main-thread only data
-    if (!mResult) {
-      return;
-    }
-    NS_ReleaseOnMainThread("DoWriteAtomicEvent::mResult", mResult.forget());
-  }
-
-  NS_IMETHODIMP Run() override {
-    MOZ_ASSERT(!NS_IsMainThread());
-    TimeStamp dispatchDate = TimeStamp::Now();
-    int32_t bytesWritten;
-
-    nsresult rv = WriteAtomic(&bytesWritten);
-    if (NS_FAILED(rv)) {
-      return NS_OK;
-    }
-
-    AfterWriteAtomic(dispatchDate, bytesWritten);
-    return NS_OK;
-  }
-
- private:
-  /**
-   * Write atomically to a file.
-   * Must be called off the main thread.
-   * @param aBytesWritten will contain the total bytes written.
-   * This does not support compression in this implementation.
-   */
-  nsresult WriteAtomic(int32_t* aBytesWritten) {
-    MOZ_ASSERT(!NS_IsMainThread());
-
-    // Note: In Windows, many NSPR File I/O functions which act on pathnames
-    // do not handle UTF-16 encoding. Thus, we use the following functions
-    // to overcome this.
-    // PR_Access : GetFileAttributesW
-    // PR_Delete : DeleteFileW
-    // PR_OpenFile : CreateFileW followed by PR_ImportFile
-    // PR_Rename : MoveFileW
-
-    ScopedPRFileDesc file;
-    NS_ConvertUTF16toUTF8 path(mPath);
-    NS_ConvertUTF16toUTF8 tmpPath(mTmpPath);
-    NS_ConvertUTF16toUTF8 backupTo(mBackupTo);
-    bool fileExists = false;
-
-    if (!mTmpPath.IsVoid() || !mBackupTo.IsVoid() || mNoOverwrite) {
-      // fileExists needs to be computed in the case of tmpPath, since
-      // the rename behaves differently depending on whether the
-      // file already exists. It's also computed for backupTo since the
-      // backup can be skipped if the file does not exist in the first place.
-#if defined(XP_WIN)
-      fileExists = ::GetFileAttributesW(mPath.get()) != INVALID_FILE_ATTRIBUTES;
-#else
-      fileExists = PR_Access(path.get(), PR_ACCESS_EXISTS) == PR_SUCCESS;
-#endif  // defined(XP_WIN)
-    }
-
-    // Check noOverwrite.
-    if (mNoOverwrite && fileExists) {
-      Fail("noOverwrite"_ns, nullptr, OS_ERROR_FILE_EXISTS);
-      return NS_ERROR_FAILURE;
-    }
-
-    // Backup the original file if it exists.
-    if (!mBackupTo.IsVoid() && fileExists) {
-#if defined(XP_WIN)
-      if (::GetFileAttributesW(mBackupTo.get()) != INVALID_FILE_ATTRIBUTES) {
-        // The file specified by mBackupTo exists, so we need to delete it
-        // first.
-        if (::DeleteFileW(mBackupTo.get()) == false) {
-          Fail("delete"_ns, nullptr, ::GetLastError());
-          return NS_ERROR_FAILURE;
-        }
-      }
-
-      if (::MoveFileW(mPath.get(), mBackupTo.get()) == false) {
-        Fail("rename"_ns, nullptr, ::GetLastError());
-        return NS_ERROR_FAILURE;
-      }
-#else
-      if (PR_Access(backupTo.get(), PR_ACCESS_EXISTS) == PR_SUCCESS) {
-        // The file specified by mBackupTo exists, so we need to delete it
-        // first.
-        if (PR_Delete(backupTo.get()) == PR_FAILURE) {
-          Fail("delete"_ns, nullptr, PR_GetOSError());
-          return NS_ERROR_FAILURE;
-        }
-      }
-
-      if (PR_Rename(path.get(), backupTo.get()) == PR_FAILURE) {
-        Fail("rename"_ns, nullptr, PR_GetOSError());
-        return NS_ERROR_FAILURE;
-      }
-#endif  // defined(XP_WIN)
-    }
-
-#if defined(XP_WIN)
-    // In addition to not handling UTF-16 encoding in file paths,
-    // PR_OpenFile opens files without sharing, which is not the
-    // general semantics of OS.File.
-    HANDLE handle;
-    // if we're dealing with a tmpFile, we need to write there.
-    if (!mTmpPath.IsVoid()) {
-      handle = ::CreateFileW(
-          mTmpPath.get(), GENERIC_WRITE,
-          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-          /*Security attributes*/ nullptr,
-          // CREATE_ALWAYS is used since since we need to create the temporary
-          // file, which we don't care about overwriting.
-          CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
-          /*Template file*/ nullptr);
-    } else {
-      handle = ::CreateFileW(
-          mPath.get(), GENERIC_WRITE,
-          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-          /*Security attributes*/ nullptr,
-          // CREATE_ALWAYS is used since since have already checked the
-          // noOverwrite condition, and thus can overwrite safely.
-          CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
-          /*Template file*/ nullptr);
-    }
-
-    if (handle == INVALID_HANDLE_VALUE) {
-      Fail("open"_ns, nullptr, ::GetLastError());
-      return NS_ERROR_FAILURE;
-    }
-
-    file = PR_ImportFile((PROsfd)handle);
-    if (!file) {
-      // |file| is closed by PR_ImportFile
-      Fail("ImportFile"_ns, nullptr, PR_GetOSError());
-      return NS_ERROR_FAILURE;
-    }
-
-#else
-    // if we're dealing with a tmpFile, we need to write there.
-    if (!mTmpPath.IsVoid()) {
-      file =
-          PR_OpenFile(tmpPath.get(), PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
-                      PR_IRUSR | PR_IWUSR);
-    } else {
-      file = PR_OpenFile(path.get(), PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
-                         PR_IRUSR | PR_IWUSR);
-    }
-
-    if (!file) {
-      Fail("open"_ns, nullptr, PR_GetOSError());
-      return NS_ERROR_FAILURE;
-    }
-#endif  // defined(XP_WIN)
-
-    int32_t bytesWrittenSuccess =
-        PR_Write(file, (void*)(mBuffer.get()), mBytes);
-
-    if (bytesWrittenSuccess == -1) {
-      Fail("write"_ns, nullptr, PR_GetOSError());
-      return NS_ERROR_FAILURE;
-    }
-
-    // Apply any tmpPath renames.
-    if (!mTmpPath.IsVoid()) {
-      if (mBackupTo.IsVoid() && fileExists) {
-        // We need to delete the old file first, if it exists and we haven't
-        // already renamed it as a part of backing it up.
-#if defined(XP_WIN)
-        if (::DeleteFileW(mPath.get()) == false) {
-          Fail("delete"_ns, nullptr, ::GetLastError());
-          return NS_ERROR_FAILURE;
-        }
-#else
-        if (PR_Delete(path.get()) == PR_FAILURE) {
-          Fail("delete"_ns, nullptr, PR_GetOSError());
-          return NS_ERROR_FAILURE;
-        }
-#endif  // defined(XP_WIN)
-      }
-
-#if defined(XP_WIN)
-      if (::MoveFileW(mTmpPath.get(), mPath.get()) == false) {
-        Fail("rename"_ns, nullptr, ::GetLastError());
-        return NS_ERROR_FAILURE;
-      }
-#else
-      if (PR_Rename(tmpPath.get(), path.get()) == PR_FAILURE) {
-        Fail("rename"_ns, nullptr, PR_GetOSError());
-        return NS_ERROR_FAILURE;
-      }
-#endif  // defined(XP_WIN)
-    }
-
-    if (mFlush) {
-      if (PR_Sync(file) == PR_FAILURE) {
-        Fail("sync"_ns, nullptr, PR_GetOSError());
-        return NS_ERROR_FAILURE;
-      }
-    }
-
-    *aBytesWritten = bytesWrittenSuccess;
-    return NS_OK;
-  }
-
- protected:
-  nsresult AfterWriteAtomic(TimeStamp aDispatchDate, int32_t aBytesWritten) {
-    MOZ_ASSERT(!NS_IsMainThread());
-    mResult->Init(aDispatchDate, TimeStamp::Now() - aDispatchDate,
-                  aBytesWritten);
-    Succeed(mResult.forget());
-    return NS_OK;
-  }
-
-  const nsString mPath;
-  const UniquePtr<char[], JS::FreePolicy> mBuffer;
-  const int32_t mBytes;
-  const nsString mTmpPath;
-  const nsString mBackupTo;
-  const bool mFlush;
-  const bool mNoOverwrite;
-
- private:
-  RefPtr<Int32Result> mResult;
-};
-
-}  // namespace
-
-// The OS.File service
-
-NS_IMPL_ISUPPORTS(NativeOSFileInternalsService,
-                  nsINativeOSFileInternalsService);
-
-NS_IMETHODIMP
-NativeOSFileInternalsService::Read(const nsAString& aPath,
-                                   JS::Handle<JS::Value> aOptions,
-                                   nsINativeOSFileSuccessCallback* aOnSuccess,
-                                   nsINativeOSFileErrorCallback* aOnError,
-                                   JSContext* cx) {
-  // Extract options
-  nsCString encoding;
-  uint64_t bytes = UINT64_MAX;
-
-  if (aOptions.isObject()) {
-    dom::NativeOSFileReadOptions dict;
-    if (!dict.Init(cx, aOptions)) {
-      return NS_ERROR_INVALID_ARG;
-    }
-
-    if (dict.mEncoding.WasPassed()) {
-      CopyUTF16toUTF8(dict.mEncoding.Value(), encoding);
-    }
-
-    if (dict.mBytes.WasPassed() && !dict.mBytes.Value().IsNull()) {
-      bytes = dict.mBytes.Value().Value();
-    }
-  }
-
-  // Prepare the off main thread event and dispatch it
-  nsCOMPtr<nsINativeOSFileSuccessCallback> onSuccess(aOnSuccess);
-  nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback> onSuccessHandle(
-      new nsMainThreadPtrHolder<nsINativeOSFileSuccessCallback>(
-          "nsINativeOSFileSuccessCallback", onSuccess));
-  nsCOMPtr<nsINativeOSFileErrorCallback> onError(aOnError);
-  nsMainThreadPtrHandle<nsINativeOSFileErrorCallback> onErrorHandle(
-      new nsMainThreadPtrHolder<nsINativeOSFileErrorCallback>(
-          "nsINativeOSFileErrorCallback", onError));
-
-  RefPtr<AbstractDoEvent> event;
-  if (encoding.IsEmpty()) {
-    event = new DoReadToTypedArrayEvent(aPath, bytes, onSuccessHandle,
-                                        onErrorHandle);
-  } else {
-    event = new DoReadToStringEvent(aPath, encoding, bytes, onSuccessHandle,
-                                    onErrorHandle);
-  }
-
-  nsresult rv;
-  nsCOMPtr<nsIEventTarget> target =
-      do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
-
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  return target->Dispatch(event, NS_DISPATCH_NORMAL);
-}
-
-// Note: This method steals the contents of `aBuffer`.
-NS_IMETHODIMP
-NativeOSFileInternalsService::WriteAtomic(
-    const nsAString& aPath, JS::Handle<JS::Value> aBuffer,
-    JS::Handle<JS::Value> aOptions, nsINativeOSFileSuccessCallback* aOnSuccess,
-    nsINativeOSFileErrorCallback* aOnError, JSContext* cx) {
-  MOZ_ASSERT(NS_IsMainThread());
-  // Extract typed-array/string into buffer. We also need to store the length
-  // of the buffer as that may be required if not provided in `aOptions`.
-  UniquePtr<char[], JS::FreePolicy> buffer;
-  int32_t bytes;
-
-  // The incoming buffer must be an Object.
-  if (!aBuffer.isObject()) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  JS::Rooted<JSObject*> bufferObject(cx, nullptr);
-  if (!JS_ValueToObject(cx, aBuffer, &bufferObject)) {
-    return NS_ERROR_FAILURE;
-  }
-  if (!JS::IsArrayBufferObject(bufferObject.get())) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  {
-    // Throw for large ArrayBuffers to prevent truncation.
-    size_t len = JS::GetArrayBufferByteLength(bufferObject.get());
-    if (len > INT32_MAX) {
-      return NS_ERROR_INVALID_ARG;
-    }
-    bytes = len;
-  }
-  buffer.reset(
-      static_cast<char*>(JS::StealArrayBufferContents(cx, bufferObject)));
-
-  if (!buffer) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // Extract options.
-  dom::NativeOSFileWriteAtomicOptions dict;
-
-  if (aOptions.isObject()) {
-    if (!dict.Init(cx, aOptions)) {
-      return NS_ERROR_INVALID_ARG;
-    }
-  } else {
-    // If an options object is not provided, initializing with a `null`
-    // value, which will give a set of defaults defined in the WebIDL binding.
-    if (!dict.Init(cx, JS::NullHandleValue)) {
-      return NS_ERROR_FAILURE;
-    }
-  }
-
-  if (dict.mBytes.WasPassed() && !dict.mBytes.Value().IsNull()) {
-    // We need to check size and cast because NSPR and WebIDL have different
-    // types.
-    if (dict.mBytes.Value().Value() > PR_INT32_MAX) {
-      return NS_ERROR_INVALID_ARG;
-    }
-    bytes = (int32_t)(dict.mBytes.Value().Value());
-  }
-
-  // Prepare the off main thread event and dispatch it
-  nsCOMPtr<nsINativeOSFileSuccessCallback> onSuccess(aOnSuccess);
-  nsMainThreadPtrHandle<nsINativeOSFileSuccessCallback> onSuccessHandle(
-      new nsMainThreadPtrHolder<nsINativeOSFileSuccessCallback>(
-          "nsINativeOSFileSuccessCallback", onSuccess));
-  nsCOMPtr<nsINativeOSFileErrorCallback> onError(aOnError);
-  nsMainThreadPtrHandle<nsINativeOSFileErrorCallback> onErrorHandle(
-      new nsMainThreadPtrHolder<nsINativeOSFileErrorCallback>(
-          "nsINativeOSFileErrorCallback", onError));
-
-  RefPtr<AbstractDoEvent> event = new DoWriteAtomicEvent(
-      aPath, std::move(buffer), bytes, dict.mTmpPath, dict.mBackupTo,
-      dict.mFlush, dict.mNoOverwrite, onSuccessHandle, onErrorHandle);
-  nsresult rv;
-  nsCOMPtr<nsIEventTarget> target =
-      do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
-
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  return target->Dispatch(event, NS_DISPATCH_NORMAL);
-}
-
-}  // namespace mozilla
deleted file mode 100644
--- a/toolkit/components/osfile/NativeOSFileInternals.h
+++ /dev/null
@@ -1,29 +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_nativeosfileinternalservice_h__
-#define mozilla_nativeosfileinternalservice_h__
-
-#include "nsINativeOSFileInternals.h"
-
-#include "nsISupports.h"
-
-namespace mozilla {
-
-class NativeOSFileInternalsService final
-    : public nsINativeOSFileInternalsService {
- public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSINATIVEOSFILEINTERNALSSERVICE
- private:
-  ~NativeOSFileInternalsService() = default;
-  // Avoid accidental use of built-in operator=
-  void operator=(const NativeOSFileInternalsService& other) = delete;
-};
-
-}  // namespace mozilla
-
-#endif  // mozilla_finalizationwitnessservice_h__
deleted file mode 100644
--- a/toolkit/components/osfile/modules/moz.build
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- 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/.
-
-EXTRA_JS_MODULES.osfile += [
-    "osfile_async_front.jsm",
-    "osfile_async_worker.js",
-    "osfile_native.jsm",
-    "osfile_shared_allthreads.jsm",
-    "osfile_shared_front.js",
-    "ospath.jsm",
-    "ospath_unix.jsm",
-    "ospath_win.jsm",
-]
-
-if CONFIG["OS_TARGET"] == "WINNT":
-    EXTRA_JS_MODULES.osfile += [
-        "osfile_win_allthreads.jsm",
-        "osfile_win_back.js",
-        "osfile_win_front.js",
-    ]
-else:
-    EXTRA_JS_MODULES.osfile += [
-        "osfile_unix_allthreads.jsm",
-        "osfile_unix_back.js",
-        "osfile_unix_front.js",
-    ]
deleted file mode 100644
--- a/toolkit/components/osfile/modules/osfile_async_front.jsm
+++ /dev/null
@@ -1,1570 +0,0 @@
-/* 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/. */
-
-/**
- * Asynchronous front-end for OS.File.
- *
- * This front-end is meant to be imported from the main thread. In turn,
- * it spawns one worker (perhaps more in the future) and delegates all
- * disk I/O to this worker.
- *
- * Documentation note: most of the functions and methods in this module
- * return promises. For clarity, we denote as follows a promise that may resolve
- * with type |A| and some value |value| or reject with type |B| and some
- * reason |reason|
- * @resolves {A} value
- * @rejects {B} reason
- */
-
-"use strict";
-
-// Scheduler is exported for test-only usage.
-var EXPORTED_SYMBOLS = ["OS", "Scheduler"];
-
-var SharedAll = ChromeUtils.import(
-  "resource://gre/modules/osfile/osfile_shared_allthreads.jsm"
-);
-const { clearInterval, setInterval } = ChromeUtils.importESModule(
-  "resource://gre/modules/Timer.sys.mjs"
-);
-
-// Boilerplate, to simplify the transition to require()
-var LOG = SharedAll.LOG.bind(SharedAll, "Controller");
-var isTypedArray = SharedAll.isTypedArray;
-
-// The constructor for file errors.
-var SysAll;
-if (SharedAll.Constants.Win) {
-  SysAll = ChromeUtils.import(
-    "resource://gre/modules/osfile/osfile_win_allthreads.jsm"
-  );
-} else if (SharedAll.Constants.libc) {
-  SysAll = ChromeUtils.import(
-    "resource://gre/modules/osfile/osfile_unix_allthreads.jsm"
-  );
-} else {
-  throw new Error("I am neither under Windows nor under a Posix system");
-}
-var OSError = SysAll.Error;
-var Type = SysAll.Type;
-
-var Path = ChromeUtils.import("resource://gre/modules/osfile/ospath.jsm");
-
-const lazy = {};
-
-// The library of promises.
-ChromeUtils.defineESModuleGetters(lazy, {
-  PromiseUtils: "resource://gre/modules/PromiseUtils.sys.mjs",
-});
-
-// The implementation of communications
-const { BasePromiseWorker } = ChromeUtils.import(
-  "resource://gre/modules/PromiseWorker.jsm"
-);
-const { AsyncShutdown } = ChromeUtils.importESModule(
-  "resource://gre/modules/AsyncShutdown.sys.mjs"
-);
-var Native = ChromeUtils.import(
-  "resource://gre/modules/osfile/osfile_native.jsm"
-);
-
-// It's possible for osfile.jsm to get imported before the profile is
-// set up. In this case, some path constants aren't yet available.
-// Here, we make them lazy loaders.
-
-function lazyPathGetter(constProp, dirKey) {
-  return function() {
-    let path;
-    try {
-      path = Services.dirsvc.get(dirKey, Ci.nsIFile).path;
-      delete SharedAll.Constants.Path[constProp];
-      SharedAll.Constants.Path[constProp] = path;
-    } catch (ex) {
-      // Ignore errors if the value still isn't available. Hopefully
-      // the next access will return it.
-    }
-
-    return path;
-  };
-}
-
-for (let [constProp, dirKey] of [
-  ["localProfileDir", "ProfLD"],
-  ["profileDir", "ProfD"],
-  ["userApplicationDataDir", "UAppData"],
-  ["winAppDataDir", "AppData"],
-  ["winLocalAppDataDir", "LocalAppData"],
-  ["winStartMenuProgsDir", "Progs"],
-  ["tmpDir", "TmpD"],
-  ["homeDir", "Home"],
-  ["macUserLibDir", "ULibDir"],
-]) {
-  if (constProp in SharedAll.Constants.Path) {
-    continue;
-  }
-
-  LOG(
-    "Installing lazy getter for OS.Constants.Path." +
-      constProp +
-      " because it isn't defined and profile may not be loaded."
-  );
-  Object.defineProperty(SharedAll.Constants.Path, constProp, {
-    get: lazyPathGetter(constProp, dirKey),
-  });
-}
-
-/**
- * Return a shallow clone of the enumerable properties of an object.
- */
-var clone = SharedAll.clone;
-
-/**
- * Extract a shortened version of an object, fit for logging.
- *
- * This function returns a copy of the original object in which all
- * long strings, Arrays, TypedArrays, ArrayBuffers are removed and
- * replaced with placeholders. Use this function to sanitize objects
- * if you wish to log them or to keep them in memory.
- *
- * @param {*} obj The obj to shorten.
- * @return {*} array A shorter object, fit for logging.
- */
-function summarizeObject(obj) {
-  if (!obj) {
-    return null;
-  }
-  if (typeof obj == "string") {
-    if (obj.length > 1024) {
-      return { "Long string": obj.length };
-    }
-    return obj;
-  }
-  if (typeof obj == "object") {
-    if (Array.isArray(obj)) {
-      if (obj.length > 32) {
-        return { "Long array": obj.length };
-      }
-      return obj.map(summarizeObject);
-    }
-    if ("byteLength" in obj) {
-      // Assume TypedArray or ArrayBuffer
-      return { "Binary Data": obj.byteLength };
-    }
-    let result = {};
-    for (let k of Object.keys(obj)) {
-      result[k] = summarizeObject(obj[k]);
-    }
-    return result;
-  }
-  return obj;
-}
-
-var Scheduler = {
-  /**
-   * |true| once we have sent at least one message to the worker.
-   * This field is unaffected by resetting the worker.
-   */
-  launched: false,
-
-  /**
-   * |true| once shutdown has begun i.e. we should reject any
-   * message, including resets.
-   */
-  shutdown: false,
-
-  /**
-   * A promise resolved once all currently pending operations are complete.
-   *
-   * This promise is never rejected and the result is always undefined.
-   */
-  queue: Promise.resolve(),
-
-  /**
-   * A promise resolved once all currently pending `kill` operations
-   * are complete.
-   *
-   * This promise is never rejected and the result is always undefined.
-   */
-  _killQueue: Promise.resolve(),
-
-  /**
-   * Miscellaneous debugging information
-   */
-  Debugging: {
-    /**
-     * The latest message sent and still waiting for a reply.
-     */
-    latestSent: undefined,
-
-    /**
-     * The latest reply received, or null if we are waiting for a reply.
-     */
-    latestReceived: undefined,
-
-    /**
-     * Number of messages sent to the worker. This includes the
-     * initial SET_DEBUG, if applicable.
-     */
-    messagesSent: 0,
-
-    /**
-     * Total number of messages ever queued, including the messages
-     * sent.
-     */
-    messagesQueued: 0,
-
-    /**
-     * Number of messages received from the worker.
-     */
-    messagesReceived: 0,
-  },
-
-  /**
-   * A timer used to automatically shut down the worker after some time.
-   */
-  resetTimer: null,
-
-  /**
-   * A flag indicating whether we had some activities when waiting the
-   * timer and if it's not we can shut down the worker.
-   */
-  hasRecentActivity: false,
-
-  /**
-   * The worker to which to send requests.
-   *
-   * If the worker has never been created or has been reset, this is a
-   * fresh worker, initialized with osfile_async_worker.js.
-   *
-   * @type {PromiseWorker}
-   */
-  get worker() {
-    if (!this._worker) {
-      // Either the worker has never been created or it has been
-      // reset.  In either case, it is time to instantiate the worker.
-      this._worker = new BasePromiseWorker(
-        "resource://gre/modules/osfile/osfile_async_worker.js"
-      );
-      this._worker.log = LOG;
-      this._worker.ExceptionHandlers["OS.File.Error"] = OSError.fromMsg;
-
-      let delay = Services.prefs.getIntPref("osfile.reset_worker_delay", 0);
-      if (delay) {
-        this.resetTimer = setInterval(() => {
-          if (this.hasRecentActivity) {
-            this.hasRecentActivity = false;
-            return;
-          }
-          clearInterval(this.resetTimer);
-          Scheduler.kill({ reset: true, shutdown: false });
-        }, delay);
-      }
-    }
-    return this._worker;
-  },
-
-  _worker: null,
-
-  /**
-   * Restart the OS.File worker killer timer.
-   */
-  restartTimer(arg) {
-    this.hasRecentActivity = true;
-  },
-
-  /**
-   * Shutdown OS.File.
-   *
-   * @param {*} options
-   * - {boolean} shutdown If |true|, reject any further request. Otherwise,
-   *   further requests will resurrect the worker.
-   * - {boolean} reset If |true|, instruct the worker to shutdown if this
-   *   would not cause leaks. Otherwise, assume that the worker will be shutdown
-   *   through some other mean.
-   */
-  kill({ shutdown, reset }) {
-    // Grab the kill queue to make sure that we
-    // cannot be interrupted by another call to `kill`.
-    let killQueue = this._killQueue;
-
-    // Deactivate the queue, to ensure that no message is sent
-    // to an obsolete worker (we reactivate it in the `finally`).
-    // This needs to be done right now so that we maintain relative
-    // ordering with calls to post(), etc.
-    let deferred = lazy.PromiseUtils.defer();
-    let savedQueue = this.queue;
-    this.queue = deferred.promise;
-
-    return (this._killQueue = (async () => {
-      await killQueue;
-      // From this point, and until the end of the Task, we are the
-      // only call to `kill`, regardless of any `yield`.
-
-      await savedQueue;
-
-      try {
-        // Enter critical section: no yield in this block
-        // (we want to make sure that we remain the only
-        // request in the queue).
-
-        if (!this.launched || this.shutdown || !this._worker) {
-          // Nothing to kill
-          this.shutdown = this.shutdown || shutdown;
-          this._worker = null;
-          return null;
-        }
-
-        // Exit critical section
-
-        let message = ["Meta_shutdown", [reset]];
-
-        Scheduler.latestReceived = [];
-        let stack = new Error().stack;
-        Scheduler.latestSent = [Date.now(), stack, ...message];
-
-        // Wait for result
-        let resources;
-        try {
-          resources = await this._worker.post(...message);
-
-          Scheduler.latestReceived = [Date.now(), message];
-        } catch (ex) {
-          LOG("Could not dispatch Meta_reset", ex);
-          // It's most likely a programmer error, but we'll assume that
-          // the worker has been shutdown, as it's less risky than the
-          // opposite stance.
-          resources = {
-            openedFiles: [],
-            openedDirectoryIterators: [],
-            killed: true,
-          };
-
-          Scheduler.latestReceived = [Date.now(), message, ex];
-        }
-
-        let { openedFiles, openedDirectoryIterators, killed } = resources;
-        if (
-          !reset &&
-          ((openedFiles && openedFiles.length) ||
-            (openedDirectoryIterators && openedDirectoryIterators.length))
-        ) {
-          // The worker still holds resources. Report them.
-
-          let msg = "";
-          if (openedFiles.length) {
-            msg +=
-              "The following files are still open:\n" + openedFiles.join("\n");
-          }
-          if (openedDirectoryIterators.length) {
-            msg +=
-              "The following directory iterators are still open:\n" +
-              openedDirectoryIterators.join("\n");
-          }
-
-          LOG("WARNING: File descriptors leaks detected.\n" + msg);
-        }
-
-        // Make sure that we do not leave an invalid |worker| around.
-        if (killed || shutdown) {
-          this._worker = null;
-        }
-
-        this.shutdown = shutdown;
-
-        return resources;
-      } finally {
-        // Resume accepting messages. If we have set |shutdown| to |true|,
-        // any pending/future request will be rejected. Otherwise, any
-        // pending/future request will spawn a new worker if necessary.
-        deferred.resolve();
-      }
-    })());
-  },
-
-  /**
-   * Push a task at the end of the queue.
-   *
-   * @param {function} code A function returning a Promise.
-   * This function will be executed once all the previously
-   * pushed tasks have completed.
-   * @return {Promise} A promise with the same behavior as
-   * the promise returned by |code|.
-   */
-  push(code) {
-    let promise = this.queue.then(code);
-    // By definition, |this.queue| can never reject.
-    this.queue = promise.catch(() => undefined);
-    // Fork |promise| to ensure that uncaught errors are reported
-    return promise.then();
-  },
-
-  /**
-   * Post a message to the worker thread.
-   *
-   * @param {string} method The name of the method to call.
-   * @param {...} args The arguments to pass to the method. These arguments
-   * must be clonable.
-   * The last argument by convention may be an object `options`, with some of
-   * the following fields:
-   *   - {number|null} outSerializationDuration A parameter to be filled with
-   *     duration of the `this.worker.post` method.
-   * @return {Promise} A promise conveying the result/error caused by
-   * calling |method| with arguments |args|.
-   */
-  post: function post(method, args = undefined, closure = undefined) {
-    if (this.shutdown) {
-      LOG(
-        "OS.File is not available anymore. The following request has been rejected.",
-        method,
-        args
-      );
-      return Promise.reject(
-        new Error("OS.File has been shut down. Rejecting post to " + method)
-      );
-    }
-    let firstLaunch = !this.launched;
-    this.launched = true;
-
-    if (firstLaunch && SharedAll.Config.DEBUG) {
-      // If we have delayed sending SET_DEBUG, do it now.
-      this.worker.post("SET_DEBUG", [true]);
-      Scheduler.Debugging.messagesSent++;
-    }
-
-    Scheduler.Debugging.messagesQueued++;
-    return this.push(async () => {
-      if (this.shutdown) {
-        LOG(
-          "OS.File is not available anymore. The following request has been rejected.",
-          method,
-          args
-        );
-        throw new Error(
-          "OS.File has been shut down. Rejecting request to " + method
-        );
-      }
-
-      // Update debugging information. As |args| may be quite
-      // expensive, we only keep a shortened version of it.
-      Scheduler.Debugging.latestReceived = null;
-      Scheduler.Debugging.latestSent = [
-        Date.now(),
-        method,
-        summarizeObject(args),
-      ];
-
-      // Don't kill the worker just yet
-      Scheduler.restartTimer();
-
-      // The last object inside the args may be an options object.
-      let options = null;
-      if (
-        args &&
-        args.length >= 1 &&
-        typeof args[args.length - 1] === "object"
-      ) {
-        options = args[args.length - 1];
-      }
-
-      let reply;
-      try {
-        try {
-          Scheduler.Debugging.messagesSent++;
-          Scheduler.Debugging.latestSent = Scheduler.Debugging.latestSent.slice(
-            0,
-            2
-          );
-          let serializationStartTimeMs = Date.now();
-          reply = await this.worker.post(method, args, closure);
-          let serializationEndTimeMs = Date.now();
-          Scheduler.Debugging.latestReceived = [
-            Date.now(),
-            summarizeObject(reply),
-          ];
-
-          // There were no options for recording the serialization duration.
-          if (options && "outSerializationDuration" in options) {
-            // The difference might be negative for very fast operations, since Date.now() may not be monotonic.
-            let serializationDurationMs = Math.max(
-              0,
-              serializationEndTimeMs - serializationStartTimeMs
-            );
-
-            if (typeof options.outSerializationDuration === "number") {
-              options.outSerializationDuration += serializationDurationMs;
-            } else {
-              options.outSerializationDuration = serializationDurationMs;
-            }
-          }
-          return reply;
-        } finally {
-          Scheduler.Debugging.messagesReceived++;
-        }
-      } catch (error) {
-        Scheduler.Debugging.latestReceived = [
-          Date.now(),
-          error.message,
-          error.fileName,
-          error.lineNumber,
-        ];
-        throw error;
-      } finally {
-        if (firstLaunch) {
-          Scheduler._updateTelemetry();
-        }
-        Scheduler.restartTimer();
-      }
-    });
-  },
-
-  /**
-   * Post Telemetry statistics.
-   *
-   * This is only useful on first launch.
-   */
-  _updateTelemetry() {
-    let worker = this.worker;
-    let workerTimeStamps = worker.workerTimeStamps;
-    if (!workerTimeStamps) {
-      // If the first call to OS.File results in an uncaught errors,
-      // the timestamps are absent. As this case is a developer error,
-      // let's not waste time attempting to extract telemetry from it.
-      return;
-    }
-    let HISTOGRAM_LAUNCH = Services.telemetry.getHistogramById(
-      "OSFILE_WORKER_LAUNCH_MS"
-    );
-    HISTOGRAM_LAUNCH.add(
-      worker.workerTimeStamps.entered - worker.launchTimeStamp
-    );
-
-    let HISTOGRAM_READY = Services.telemetry.getHistogramById(
-      "OSFILE_WORKER_READY_MS"
-    );
-    HISTOGRAM_READY.add(
-      worker.workerTimeStamps.loaded - worker.launchTimeStamp
-    );
-  },
-};
-
-const PREF_OSFILE_LOG = "toolkit.osfile.log";
-const PREF_OSFILE_LOG_REDIRECT = "toolkit.osfile.log.redirect";
-
-/**
- * Safely read a PREF_OSFILE_LOG preference.
- * Returns a value read or, in case of an error, oldPref or false.
- *
- * @param bool oldPref
- *        An optional value that the DEBUG flag was set to previously.
- */
-function readDebugPref(prefName, oldPref = false) {
-  // If neither pref nor oldPref were set, default it to false.
-  return Services.prefs.getBoolPref(prefName, oldPref);
-}
-
-/**
- * Listen to PREF_OSFILE_LOG changes and update gShouldLog flag
- * appropriately.
- */
-Services.prefs.addObserver(PREF_OSFILE_LOG, function prefObserver(
-  aSubject,
-  aTopic,
-  aData
-) {
-  SharedAll.Config.DEBUG = readDebugPref(
-    PREF_OSFILE_LOG,
-    SharedAll.Config.DEBUG
-  );
-  if (Scheduler.launched) {
-    // Don't start the worker just to set this preference.
-    Scheduler.post("SET_DEBUG", [SharedAll.Config.DEBUG]);
-  }
-});
-SharedAll.Config.DEBUG = readDebugPref(PREF_OSFILE_LOG, false);
-
-Services.prefs.addObserver(PREF_OSFILE_LOG_REDIRECT, function prefObserver(
-  aSubject,
-  aTopic,
-  aData
-) {
-  SharedAll.Config.TEST = readDebugPref(
-    PREF_OSFILE_LOG_REDIRECT,
-    OS.Shared.TEST
-  );
-});
-SharedAll.Config.TEST = readDebugPref(PREF_OSFILE_LOG_REDIRECT, false);
-
-/**
- * If |true|, use the native implementaiton of OS.File methods
- * whenever possible. Otherwise, force the use of the JS version.
- */
-var nativeWheneverAvailable = true;
-const PREF_OSFILE_NATIVE = "toolkit.osfile.native";
-Services.prefs.addObserver(PREF_OSFILE_NATIVE, function prefObserver(
-  aSubject,
-  aTopic,
-  aData
-) {
-  nativeWheneverAvailable = readDebugPref(
-    PREF_OSFILE_NATIVE,
-    nativeWheneverAvailable
-  );
-});
-
-// Update worker's DEBUG flag if it's true.
-// Don't start the worker just for this, though.
-if (SharedAll.Config.DEBUG && Scheduler.launched) {
-  Scheduler.post("SET_DEBUG", [true]);
-}
-
-// Preference used to configure test shutdown observer.
-const PREF_OSFILE_TEST_SHUTDOWN_OBSERVER =
-  "toolkit.osfile.test.shutdown.observer";
-
-AsyncShutdown.xpcomWillShutdown.addBlocker(
-  "OS.File: flush pending requests, warn about unclosed files, shut down service.",
-  async function() {
-    // Give clients a last chance to enqueue requests.
-    await Barriers.shutdown.wait({ crashAfterMS: null });
-
-    // Wait until all requests are complete and kill the worker.
-    await Scheduler.kill({ reset: false, shutdown: true });
-  },
-  () => {
-    let details = Barriers.getDetails();
-    details.clients = Barriers.shutdown.state;
-    return details;
-  }
-);
-
-// Attaching an observer for PREF_OSFILE_TEST_SHUTDOWN_OBSERVER to enable or
-// disable the test shutdown event observer.
-// Note: By default the PREF_OSFILE_TEST_SHUTDOWN_OBSERVER is unset.
-// Note: This is meant to be used for testing purposes only.
-Services.prefs.addObserver(
-  PREF_OSFILE_TEST_SHUTDOWN_OBSERVER,
-  function prefObserver() {
-    // The temporary phase topic used to trigger the unclosed
-    // phase warning.
-    let TOPIC = Services.prefs.getCharPref(
-      PREF_OSFILE_TEST_SHUTDOWN_OBSERVER,
-      ""
-    );
-    if (TOPIC) {
-      // Generate a phase, add a blocker.
-      // Note that this can work only if AsyncShutdown itself has been
-      // configured for testing by the testsuite.
-      let phase = AsyncShutdown._getPhase(TOPIC);
-      phase.addBlocker(
-        "(for testing purposes) OS.File: warn about unclosed files",
-        () => Scheduler.kill({ shutdown: false, reset: false })
-      );
-    }
-  }
-);
-
-/**
- * Representation of a file, with asynchronous methods.
- *
- * @param {*} fdmsg The _message_ representing the platform-specific file
- * handle.
- *
- * @constructor
- */
-var File = function File(fdmsg) {
-  // FIXME: At the moment, |File| does not close on finalize
-  // (see bug 777715)
-  this._fdmsg = fdmsg;
-  this._closeResult = null;
-  this._closed = null;
-};
-
-File.prototype = {
-  /**
-   * Close a file asynchronously.
-   *
-   * This method is idempotent.
-   *
-   * @return {promise}
-   * @resolves {null}
-   * @rejects {OS.File.Error}
-   */
-  close: function close() {
-    if (this._fdmsg != null) {
-      let msg = this._fdmsg;
-      this._fdmsg = null;
-      return (this._closeResult = Scheduler.post(
-        "File_prototype_close",
-        [msg],
-        this
-      ));
-    }
-    return this._closeResult;
-  },
-
-  /**
-   * Fetch information about the file.
-   *
-   * @return {promise}
-   * @resolves {OS.File.Info} The latest information about the file.
-   * @rejects {OS.File.Error}
-   */
-  stat: function stat() {
-    return Scheduler.post("File_prototype_stat", [this._fdmsg], this).then(
-      File.Info.fromMsg
-    );
-  },
-
-  /**
-   * Write bytes from a buffer to this file.
-   *
-   * Note that, by default, this function may perform several I/O
-   * operations to ensure that the buffer is fully written.
-   *
-   * @param {Typed array | C pointer} buffer The buffer in which the
-   * the bytes are stored. The buffer must be large enough to
-   * accomodate |bytes| bytes. Using the buffer before the operation
-   * is complete is a BAD IDEA.
-   * @param {*=} options Optionally, an object that may contain the
-   * following fields:
-   * - {number} bytes The number of |bytes| to write from the buffer. If
-   * unspecified, this is |buffer.byteLength|. Note that |bytes| is required
-   * if |buffer| is a C pointer.
-   *
-   * @return {number} The number of bytes actually written.
-   */
-  write: function write(buffer, options = {}) {
-    // If |buffer| is a typed array and there is no |bytes| options,
-    // we need to extract the |byteLength| now, as it will be lost
-    // by communication.
-    // Options might be a nullish value, so better check for that before using
-    // the |in| operator.
-    if (isTypedArray(buffer) && !(options && "bytes" in options)) {
-      // Preserve reference to option |outExecutionDuration|, |outSerializationDuration|, if it is passed.
-      options = clone(options, [
-        "outExecutionDuration",
-        "outSerializationDuration",
-      ]);
-      options.bytes = buffer.byteLength;
-    }
-    return Scheduler.post(
-      "File_prototype_write",
-      [this._fdmsg, Type.void_t.in_ptr.toMsg(buffer), options],
-      buffer /* Ensure that |buffer| is not gc-ed*/
-    );
-  },
-
-  /**
-   * Read bytes from this file to a new buffer.
-   *
-   * @param {number=} bytes If unspecified, read all the remaining bytes from
-   * this file. If specified, read |bytes| bytes, or less if the file does not
-   * contain that many bytes.
-   * @param {JSON} options
-   * @return {promise}
-   * @resolves {Uint8Array} An array containing the bytes read.
-   */
-  read: function read(nbytes, options = {}) {
-    let promise = Scheduler.post("File_prototype_read", [
-      this._fdmsg,
-      nbytes,
-      options,
-    ]);
-    return promise.then(function onSuccess(data) {
-      return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
-    });
-  },
-
-  /**
-   * Return the current position in the file, as bytes.
-   *
-   * @return {promise}
-   * @resolves {number} The current position in the file,
-   * as a number of bytes since the start of the file.
-   */
-  getPosition: function getPosition() {
-    return Scheduler.post("File_prototype_getPosition", [this._fdmsg]);
-  },
-
-  /**
-   * Set the current position in the file, as bytes.
-   *
-   * @param {number} pos A number of bytes.
-   * @param {number} whence The reference position in the file,
-   * which may be either POS_START (from the start of the file),
-   * POS_END (from the end of the file) or POS_CUR (from the
-   * current position in the file).
-   *
-   * @return {promise}
-   */
-  setPosition: function setPosition(pos, whence) {
-    return Scheduler.post("File_prototype_setPosition", [
-      this._fdmsg,
-      pos,
-      whence,
-    ]);
-  },
-
-  /**
-   * Flushes the file's buffers and causes all buffered data
-   * to be written.
-   * Disk flushes are very expensive and therefore should be used carefully,
-   * sparingly and only in scenarios where it is vital that data survives
-   * system crashes. Even though the function will be executed off the
-   * main-thread, it might still affect the overall performance of any running
-   * application.
-   *
-   * @return {promise}
-   */
-  flush: function flush() {
-    return Scheduler.post("File_prototype_flush", [this._fdmsg]);
-  },
-
-  /**
-   * Set the file's access permissions.  This does nothing on Windows.
-   *
-   * This operation is likely to fail if applied to a file that was
-   * not created by the currently running program (more precisely,
-   * if it was created by a program running under a different OS-level
-   * user account).  It may also fail, or silently do nothing, if the
-   * filesystem containing the file does not support access permissions.
-   *
-   * @param {*=} options Object specifying the requested permissions:
-   *
-   * - {number} unixMode The POSIX file mode to set on the file.  If omitted,
-   *  the POSIX file mode is reset to the default used by |OS.file.open|.  If
-   *  specified, the permissions will respect the process umask as if they
-   *  had been specified as arguments of |OS.File.open|, unless the
-   *  |unixHonorUmask| parameter tells otherwise.
-   * - {bool} unixHonorUmask If omitted or true, any |unixMode| value is
-   *  modified by the process umask, as |OS.File.open| would have done.  If
-   *  false, the exact value of |unixMode| will be applied.
-   */
-  setPermissions: function setPermissions(options = {}) {
-    return Scheduler.post("File_prototype_setPermissions", [
-      this._fdmsg,
-      options,
-    ]);
-  },
-};
-
-if (SharedAll.Constants.Sys.Name != "Android") {
-  /**
-   * Set the last access and modification date of the file.
-   * The time stamp resolution is 1 second at best, but might be worse
-   * depending on the platform.
-   *
-   * WARNING: This method is not implemented on Android/B2G. On Android/B2G,
-   * you should use File.setDates instead.
-   *
-   * @return {promise}
-   * @rejects {TypeError}
-   * @rejects {OS.File.Error}
-   */
-  File.prototype.setDates = function(accessDate, modificationDate) {
-    return Scheduler.post(
-      "File_prototype_setDates",
-      [this._fdmsg, accessDate, modificationDate],
-      this
-    );
-  };
-}
-
-/**
- * Open a file asynchronously.
- *
- * @return {promise}
- * @resolves {OS.File}
- * @rejects {OS.Error}
- */
-File.open = function open(path, mode, options) {
-  return Scheduler.post(
-    "open",
-    [Type.path.toMsg(path), mode, options],
-    path
-  ).then(function onSuccess(msg) {
-    return new File(msg);
-  });
-};
-
-/**
- * Creates and opens a file with a unique name. By default, generate a random HEX number and use it to create a unique new file name.
- *
- * @param {string} path The path to the file.
- * @param {*=} options Additional options for file opening. This
- * implementation interprets the following fields:
- *
- * - {number} humanReadable If |true|, create a new filename appending a decimal number. ie: filename-1.ext, filename-2.ext.
- *  If |false| use HEX numbers ie: filename-A65BC0.ext
- * - {number} maxReadableNumber Used to limit the amount of tries after a failed
- *  file creation. Default is 20.
- *
- * @return {Object} contains A file object{file} and the path{path}.
- * @throws {OS.File.Error} If the file could not be opened.
- */
-File.openUnique = function openUnique(path, options) {
-  return Scheduler.post(
-    "openUnique",
-    [Type.path.toMsg(path), options],
-    path
-  ).then(function onSuccess(msg) {
-    return {
-      path: msg.path,
-      file: new File(msg.file),
-    };
-  });
-};
-
-/**
- * Get the information on the file.
- *
- * @return {promise}
- * @resolves {OS.File.Info}
- * @rejects {OS.Error}
- */
-File.stat = function stat(path, options) {
-  return Scheduler.post("stat", [Type.path.toMsg(path), options], path).then(
-    File.Info.fromMsg
-  );
-};
-
-/**
- * Set the last access and modification date of the file.
- * The time stamp resolution is 1 second at best, but might be worse
- * depending on the platform.
- *
- * @return {promise}
- * @rejects {TypeError}
- * @rejects {OS.File.Error}
- */
-File.setDates = function setDates(path, accessDate, modificationDate) {
-  return Scheduler.post(
-    "setDates",
-    [Type.path.toMsg(path), accessDate, modificationDate],
-    this
-  );
-};
-
-/**
- * Set the file's access permissions.  This does nothing on Windows.
- *
- * This operation is likely to fail if applied to a file that was
- * not created by the currently running program (more precisely,
- * if it was created by a program running under a different OS-level
- * user account).  It may also fail, or silently do nothing, if the
- * filesystem containing the file does not support access permissions.
- *
- * @param {string} path The path to the file.
- * @param {*=} options Object specifying the requested permissions:
- *
- * - {number} unixMode The POSIX file mode to set on the file.  If omitted,
- *  the POSIX file mode is reset to the default used by |OS.file.open|.  If
- *  specified, the permissions will respect the process umask as if they
- *  had been specified as arguments of |OS.File.open|, unless the
- *  |unixHonorUmask| parameter tells otherwise.
- * - {bool} unixHonorUmask If omitted or true, any |unixMode| value is
- *  modified by the process umask, as |OS.File.open| would have done.  If
- *  false, the exact value of |unixMode| will be applied.
- */
-File.setPermissions = function setPermissions(path, options = {}) {
-  return Scheduler.post("setPermissions", [Type.path.toMsg(path), options]);
-};
-
-/**
- * Fetch the current directory
- *
- * @return {promise}
- * @resolves {string} The current directory, as a path usable with OS.Path
- * @rejects {OS.Error}
- */
-File.getCurrentDirectory = function getCurrentDirectory() {
-  return Scheduler.post("getCurrentDirectory").then(Type.path.fromMsg);
-};
-
-/**
- * Copy a file to a destination.
- *
- * @param {string} sourcePath The platform-specific path at which
- * the file may currently be found.
- * @param {string} destPath The platform-specific path at which the
- * file should be copied.
- * @param {*=} options An object which may contain the following fields:
- *
- * @option {bool} noOverwrite - If true, this function will fail if
- * a file already exists at |destPath|. Otherwise, if this file exists,
- * it will be erased silently.
- *
- * @rejects {OS.File.Error} In case of any error.
- *
- * General note: The behavior of this function is defined only when
- * it is called on a single file. If it is called on a directory, the
- * behavior is undefined and may not be the same across all platforms.
- *
- * General note: The behavior of this function with respect to metadata
- * is unspecified. Metadata may or may not be copied with the file. The
- * behavior may not be the same across all platforms.
- */
-File.copy = function copy(sourcePath, destPath, options) {
-  return Scheduler.post(
-    "copy",
-    [Type.path.toMsg(sourcePath), Type.path.toMsg(destPath), options],
-    [sourcePath, destPath]
-  );
-};
-
-/**
- * Move a file to a destination.
- *
- * @param {string} sourcePath The platform-specific path at which
- * the file may currently be found.
- * @param {string} destPath The platform-specific path at which the
- * file should be moved.
- * @param {*=} options An object which may contain the following fields:
- *
- * @option {bool} noOverwrite - If set, this function will fail if
- * a file already exists at |destPath|. Otherwise, if this file exists,
- * it will be erased silently.
- *
- * @returns {Promise}
- * @rejects {OS.File.Error} In case of any error.
- *
- * General note: The behavior of this function is defined only when
- * it is called on a single file. If it is called on a directory, the
- * behavior is undefined and may not be the same across all platforms.
- *
- * General note: The behavior of this function with respect to metadata
- * is unspecified. Metadata may or may not be moved with the file. The
- * behavior may not be the same across all platforms.
- */
-File.move = function move(sourcePath, destPath, options) {
-  return Scheduler.post(
-    "move",
-    [Type.path.toMsg(sourcePath), Type.path.toMsg(destPath), options],
-    [sourcePath, destPath]
-  );
-};
-
-/**
- * Create a symbolic link to a source.
- *
- * @param {string} sourcePath The platform-specific path to which
- * the symbolic link should point.
- * @param {string} destPath The platform-specific path at which the
- * symbolic link should be created.
- *
- * @returns {Promise}
- * @rejects {OS.File.Error} In case of any error.
- */
-if (!SharedAll.Constants.Win) {
-  File.unixSymLink = function unixSymLink(sourcePath, destPath) {
-    return Scheduler.post(
-      "unixSymLink",
-      [Type.path.toMsg(sourcePath), Type.path.toMsg(destPath)],
-      [sourcePath, destPath]
-    );
-  };
-}
-
-/**
- * Remove an empty directory.
- *
- * @param {string} path The name of the directory to remove.
- * @param {*=} options Additional options.
- *   - {bool} ignoreAbsent If |true|, do not fail if the
- *     directory does not exist yet.
- */
-File.removeEmptyDir = function removeEmptyDir(path, options) {
-  return Scheduler.post(
-    "removeEmptyDir",
-    [Type.path.toMsg(path), options],
-    path
-  );
-};
-
-/**
- * Remove an existing file.
- *
- * @param {string} path The name of the file.
- * @param {*=} options Additional options.
- *   - {bool} ignoreAbsent If |false|, throw an error if the file does
- *     not exist. |true| by default.
- *
- * @throws {OS.File.Error} In case of I/O error.
- */
-File.remove = function remove(path, options) {
-  return Scheduler.post("remove", [Type.path.toMsg(path), options], path);
-};
-
-/**
- * Create a directory and, optionally, its parent directories.
- *
- * @param {string} path The name of the directory.
- * @param {*=} options Additional options.
- *
- * - {string} from If specified, the call to |makeDir| creates all the
- * ancestors of |path| that are descendants of |from|. Note that |path|
- * must be a descendant of |from|, and that |from| and its existing
- * subdirectories present in |path|  must be user-writeable.
- * Example:
- *   makeDir(Path.join(profileDir, "foo", "bar"), { from: profileDir });
- *  creates directories profileDir/foo, profileDir/foo/bar
- * - {bool} ignoreExisting If |false|, throw an error if the directory
- * already exists. |true| by default. Ignored if |from| is specified.
- * - {number} unixMode Under Unix, if specified, a file creation mode,
- * as per libc function |mkdir|. If unspecified, dirs are
- * created with a default mode of 0700 (dir is private to
- * the user, the user can read, write and execute). Ignored under Windows
- * or if the file system does not support file creation modes.
- * - {C pointer} winSecurity Under Windows, if specified, security
- * attributes as per winapi function |CreateDirectory|. If
- * unspecified, use the default security descriptor, inherited from
- * the parent directory. Ignored under Unix or if the file system
- * does not support security descriptors.
- */
-File.makeDir = function makeDir(path, options) {
-  return Scheduler.post("makeDir", [Type.path.toMsg(path), options], path);
-};
-
-/**
- * Return the contents of a file
- *
- * @param {string} path The path to the file.
- * @param {number=} bytes Optionally, an upper bound to the number of bytes
- * to read. DEPRECATED - please use options.bytes instead.
- * @param {JSON} options Additional options.
- * - {boolean} sequential A flag that triggers a population of the page cache
- * with data from a file so that subsequent reads from that file would not
- * block on disk I/O. If |true| or unspecified, inform the system that the
- * contents of the file will be read in order. Otherwise, make no such
- * assumption. |true| by default.
- * - {number} bytes An upper bound to the number of bytes to read.
- * - {string} compression If "lz4" and if the file is compressed using the lz4
- * compression algorithm, decompress the file contents on the fly.
- *
- * @resolves {Uint8Array} A buffer holding the bytes
- * read from the file.
- */
-File.read = function read(path, bytes, options = {}) {
-  if (typeof bytes == "object") {
-    // Passing |bytes| as an argument is deprecated.
-    // We should now be passing it as a field of |options|.
-    options = bytes || {};
-  } else {
-    options = clone(options, [
-      "outExecutionDuration",
-      "outSerializationDuration",
-    ]);
-    if (typeof bytes != "undefined") {
-      options.bytes = bytes;
-    }
-  }
-
-  if (options.compression || !nativeWheneverAvailable) {
-    // We need to use the JS implementation.
-    let promise = Scheduler.post(
-      "read",
-      [Type.path.toMsg(path), bytes, options],
-      path
-    );
-    return promise.then(function onSuccess(data) {
-      if (typeof data == "string") {
-        return data;
-      }
-      return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
-    });
-  }
-
-  // Otherwise, use the native implementation.
-  return Scheduler.push(() => Native.read(path, options));
-};
-
-/**
- * Find outs if a file exists.
- *
- * @param {string} path The path to the file.
- *
- * @return {bool} true if the file exists, false otherwise.
- */
-File.exists = function exists(path) {
-  return Scheduler.post("exists", [Type.path.toMsg(path)], path);
-};
-
-/**
- * Write a file, atomically.
- *
- * By opposition to a regular |write|, this operation ensures that,
- * until the contents are fully written, the destination file is
- * not modified.
- *
- * Limitation: In a few extreme cases (hardware failure during the
- * write, user unplugging disk during the write, etc.), data may be
- * corrupted. If your data is user-critical (e.g. preferences,
- * application data, etc.), you may wish to consider adding options
- * |tmpPath| and/or |flush| to reduce the likelihood of corruption, as
- * detailed below. Note that no combination of options can be
- * guaranteed to totally eliminate the risk of corruption.
- *
- * @param {string} path The path of the file to modify.
- * @param {Typed Array | C pointer} buffer A buffer containing the bytes to write.
- * @param {*=} options Optionally, an object determining the behavior
- * of this function. This object may contain the following fields:
- * - {number} bytes The number of bytes to write. If unspecified,
- * |buffer.byteLength|. Required if |buffer| is a C pointer.
- * - {string} tmpPath If |null| or unspecified, write all data directly
- * to |path|. If specified, write all data to a temporary file called
- * |tmpPath| and, once this write is complete, rename the file to
- * replace |path|. Performing this additional operation is a little
- * slower but also a little safer.
- * - {bool} noOverwrite - If set, this function will fail if a file already
- * exists at |path|.
- * - {bool} flush - If |false| or unspecified, return immediately once the
- * write is complete. If |true|, before writing, force the operating system
- * to write its internal disk buffers to the disk. This is considerably slower
- * (not just for the application but for the whole system) but also safer:
- * if the system shuts down improperly (typically due to a kernel freeze
- * or a power failure) or if the device is disconnected before the buffer
- * is flushed, the file has more chances of not being corrupted.
- * - {string} backupTo - If specified, backup the destination file as |backupTo|.
- * Note that this function renames the destination file before overwriting it.
- * If the process or the operating system freezes or crashes
- * during the short window between these operations,
- * the destination file will have been moved to its backup.
- *
- * @return {promise}
- * @resolves {number} The number of bytes actually written.
- */
-File.writeAtomic = function writeAtomic(path, buffer, options = {}) {
-  const useNativeImplementation =
-    nativeWheneverAvailable &&
-    !options.compression &&
-    !(isTypedArray(buffer) && "byteOffset" in buffer && buffer.byteOffset > 0);
-  // Copy |options| to avoid modifying the original object but preserve the
-  // reference to |outExecutionDuration|, |outSerializationDuration| option if it is passed.
-  options = clone(options, [
-    "outExecutionDuration",
-    "outSerializationDuration",
-  ]);
-  // As options.tmpPath is a path, we need to encode it as |Type.path| message, but only
-  // if we are not using the native implementation.
-  if ("tmpPath" in options && !useNativeImplementation) {
-    options.tmpPath = Type.path.toMsg(options.tmpPath);
-  }
-  if (isTypedArray(buffer) && !("bytes" in options)) {
-    options.bytes = buffer.byteLength;
-  }
-  let refObj = {};
-  let promise;
-  TelemetryStopwatch.start("OSFILE_WRITEATOMIC_JANK_MS", refObj);
-  if (useNativeImplementation) {
-    promise = Scheduler.push(() => Native.writeAtomic(path, buffer, options));
-  } else {
-    promise = Scheduler.post(
-      "writeAtomic",
-      [Type.path.toMsg(path), Type.void_t.in_ptr.toMsg(buffer), options],
-      [options, buffer, path]
-    );
-  }
-  TelemetryStopwatch.finish("OSFILE_WRITEATOMIC_JANK_MS", refObj);
-  return promise;
-};
-
-File.removeDir = function(path, options = {}) {
-  return Scheduler.post("removeDir", [Type.path.toMsg(path), options], path);
-};
-
-/**
- * Information on a file, as returned by OS.File.stat or
- * OS.File.prototype.stat
- *
- * @constructor
- */
-File.Info = function Info(value) {
-  // Note that we can't just do this[k] = value[k] because our
-  // prototype defines getters for all of these fields.
-  for (let k in value) {
-    Object.defineProperty(this, k, { value: value[k] });
-  }
-};
-File.Info.prototype = SysAll.AbstractInfo.prototype;
-
-File.Info.fromMsg = function fromMsg(value) {
-  return new File.Info(value);
-};
-
-/**
- * Get worker's current DEBUG flag.
- * Note: This is used for testing purposes.
- */
-File.GET_DEBUG = function GET_DEBUG() {
-  return Scheduler.post("GET_DEBUG");
-};
-
-/**
- * Iterate asynchronously through a directory
- *
- * @constructor
- */
-var DirectoryIterator = function DirectoryIterator(path, options) {
-  /**
-   * Open the iterator on the worker thread
-   *
-   * @type {Promise}
-   * @resolves {*} A message accepted by the methods of DirectoryIterator
-   * in the worker thread
-   */
-  this._itmsg = Scheduler.post(
-    "new_DirectoryIterator",
-    [Type.path.toMsg(path), options],
-    path
-  );
-  this._isClosed = false;
-};
-DirectoryIterator.prototype = {
-  [Symbol.asyncIterator]() {
-    return this;
-  },
-
-  _itmsg: null,
-
-  /**
-   * Determine whether the directory exists.
-   *
-   * @resolves {boolean}
-   */
-  async exists() {
-    if (this._isClosed) {
-      return Promise.resolve(false);
-    }
-    let iterator = await this._itmsg;
-    return Scheduler.post("DirectoryIterator_prototype_exists", [iterator]);
-  },
-  /**
-   * Get the next entry in the directory.
-   *
-   * @return {Promise}
-   * @resolves By definition of the async iterator protocol, either
-   * `{value: {File.Entry}, done: false}` if there is an unvisited entry
-   * in the directory, or `{value: undefined, done: true}`, otherwise.
-   */
-  async next() {
-    if (this._isClosed) {
-      return { value: undefined, done: true };
-    }
-    return this._next(await this._itmsg);
-  },
-  /**
-   * Get several entries at once.
-   *
-   * @param {number=} length If specified, the number of entries
-   * to return. If unspecified, return all remaining entries.
-   * @return {Promise}
-   * @resolves {Array} An array containing the |length| next entries.
-   */
-  async nextBatch(size) {
-    if (this._isClosed) {
-      return [];
-    }
-    let iterator = await this._itmsg;
-    let array = await Scheduler.post("DirectoryIterator_prototype_nextBatch", [
-      iterator,
-      size,
-    ]);
-    return array.map(DirectoryIterator.Entry.fromMsg);
-  },
-  /**
-   * Apply a function to all elements of the directory sequentially.
-   *
-   * @param {Function} cb This function will be applied to all entries
-   * of the directory. It receives as arguments
-   *  - the OS.File.Entry corresponding to the entry;
-   *  - the index of the entry in the enumeration;
-   *  - the iterator itself - return |iterator.close()| to stop the loop.
-   *
-   * If the callback returns a promise, iteration waits until the
-   * promise is resolved before proceeding.
-   *
-   * @return {Promise} A promise resolved once the loop has reached
-   * its end.
-   */
-  async forEach(cb, options) {
-    if (this._isClosed) {
-      return undefined;
-    }
-    let position = 0;
-    let iterator = await this._itmsg;
-    while (true) {
-      if (this._isClosed) {
-        return undefined;
-      }
-      let { value, done } = await this._next(iterator);
-      if (done) {
-        return undefined;
-      }
-      await cb(value, position++, this);
-    }
-  },
-  /**
-   * Auxiliary method: fetch the next item
-   *
-   * @resolves `{value: undefined, done: true}` If all entries have already
-   * been visited or the iterator has been closed.
-   */
-  async _next(iterator) {
-    if (this._isClosed) {
-      return { value: undefined, done: true };
-    }
-    let {
-      value,
-      done,
-    } = await Scheduler.post("DirectoryIterator_prototype_next", [iterator]);
-    if (done) {
-      this.close();
-      return { value: undefined, done: true };
-    }
-    return { value: DirectoryIterator.Entry.fromMsg(value), done: false };
-  },
-  /**
-   * Close the iterator
-   */
-  async close() {
-    if (this._isClosed) {
-      return undefined;
-    }
-    this._isClosed = true;
-    let iterator = this._itmsg;
-    this._itmsg = null;
-    return Scheduler.post("DirectoryIterator_prototype_close", [iterator]);
-  },
-};
-
-DirectoryIterator.Entry = function Entry(value) {
-  return value;
-};
-DirectoryIterator.Entry.prototype = Object.create(
-  SysAll.AbstractEntry.prototype
-);
-
-DirectoryIterator.Entry.fromMsg = function fromMsg(value) {
-  return new DirectoryIterator.Entry(value);
-};
-
-File.resetWorker = function() {
-  return (async function() {
-    let resources = await Scheduler.kill({ shutdown: false, reset: true });
-    if (resources && !resources.killed) {
-      throw new Error(
-        "Could not reset worker, this would leak file descriptors: " +
-          JSON.stringify(resources)
-      );
-    }
-  })();
-};
-
-// Constants
-File.POS_START = SysAll.POS_START;
-File.POS_CURRENT = SysAll.POS_CURRENT;
-File.POS_END = SysAll.POS_END;
-
-// Exports
-File.Error = OSError;
-File.DirectoryIterator = DirectoryIterator;
-
-var OS = {};
-OS.File = File;
-OS.Constants = SharedAll.Constants;
-OS.Shared = {
-  LOG: SharedAll.LOG,
-  Type: SysAll.Type,
-  get DEBUG() {
-    return SharedAll.Config.DEBUG;
-  },
-  set DEBUG(x) {
-    SharedAll.Config.DEBUG = x;
-  },
-};
-Object.freeze(OS.Shared);
-OS.Path = Path;
-
-// Returns a resolved promise when all the queued operation have been completed.
-Object.defineProperty(OS.File, "queue", {
-  get() {
-    return Scheduler.queue;
-  },
-});
-
-// `true` if this is a content process, `false` otherwise.
-// It would be nicer to go through `Services.appinfo`, but some tests need to be
-// able to replace that field with a custom implementation before it is first
-// called.
-const isContent =
-  // eslint-disable-next-line mozilla/use-services
-  Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).processType ==
-  Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT;
-
-/**
- * Shutdown barriers, to let clients register to be informed during shutdown.
- */
-var Barriers = {
-  shutdown: new AsyncShutdown.Barrier(
-    "OS.File: Waiting for clients before full shutdown"
-  ),
-  /**
-   * Return the shutdown state of OS.File
-   */
-  getDetails() {
-    let result = {
-      launched: Scheduler.launched,
-      shutdown: Scheduler.shutdown,
-      worker: !!Scheduler._worker,
-      pendingReset: !!Scheduler.resetTimer,
-      latestSent: Scheduler.Debugging.latestSent,
-      latestReceived: Scheduler.Debugging.latestReceived,
-      messagesSent: Scheduler.Debugging.messagesSent,
-      messagesReceived: Scheduler.Debugging.messagesReceived,
-      messagesQueued: Scheduler.Debugging.messagesQueued,
-      DEBUG: SharedAll.Config.DEBUG,
-    };
-    // Convert dates to strings for better readability
-    for (let key of ["latestSent", "latestReceived"]) {
-      if (result[key] && typeof result[key][0] == "number") {
-        result[key][0] = Date(result[key][0]);
-      }
-    }
-    return result;
-  },
-};
-
-function setupShutdown(phaseName) {
-  Barriers[phaseName] = new AsyncShutdown.Barrier(
-    `OS.File: Waiting for clients before ${phaseName}`
-  );
-  File[phaseName] = Barriers[phaseName].client;
-
-  // Auto-flush OS.File during `phaseName`. This ensures that any I/O
-  // that has been queued *before* `phaseName` is properly completed.
-  // To ensure that I/O queued *during* `phaseName` change is completed,
-  // clients should register using AsyncShutdown.addBlocker.
-  AsyncShutdown[phaseName].addBlocker(
-    `OS.File: flush I/O queued before ${phaseName}`,
-    async function() {
-      // Give clients a last chance to enqueue requests.
-      await Barriers[phaseName].wait({ crashAfterMS: null });
-
-      // Wait until all currently enqueued requests are completed.
-      await Scheduler.queue;
-    },
-    () => {
-      let details = Barriers.getDetails();
-      details.clients = Barriers[phaseName].state;
-      return details;
-    }
-  );
-}
-
-// profile-before-change only exists in the parent, and OS.File should
-// not be used in the child process anyways.
-if (!isContent) {
-  setupShutdown("profileBeforeChange");
-}
-File.shutdown = Barriers.shutdown.client;
deleted file mode 100644
--- a/toolkit/components/osfile/modules/osfile_async_worker.js
+++ /dev/null
@@ -1,450 +0,0 @@
-/* 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/. */
-
-/* eslint-env worker */
-
-if (this.Components) {
-  throw new Error("This worker can only be loaded from a worker thread");
-}
-
-// Worker thread for osfile asynchronous front-end
-
-(function(exports) {
-  "use strict";
-
-  // Timestamps, for use in Telemetry.
-  // The object is set to |null| once it has been sent
-  // to the main thread.
-  let timeStamps = {
-    entered: Date.now(),
-    loaded: null,
-  };
-
-  // NOTE: osfile.jsm imports require.js
-  /* import-globals-from /toolkit/components/workerloader/require.js */
-  /* import-globals-from /toolkit/components/osfile/osfile.jsm */
-  importScripts("resource://gre/modules/osfile.jsm");
-
-  let PromiseWorker = require("resource://gre/modules/workers/PromiseWorker.js");
-  let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
-  let LOG = SharedAll.LOG.bind(SharedAll, "Agent");
-
-  let worker = new PromiseWorker.AbstractWorker();
-  worker.dispatch = function(method, args = []) {
-    let startTime = performance.now();
-    try {
-      return Agent[method](...args);
-    } finally {
-      let text = method;
-      if (args.length && args[0] instanceof Object && args[0].string) {
-        // Including the path in the marker text here means it will be part of
-        // profiles. It's fine to include personally identifiable information
-        // in profiles, because when a profile is captured only the user will
-        // see it, and before uploading it a sanitization step will be offered.
-        // The 'OS.File' name will help the profiler know that these markers
-        // should be sanitized.
-        text += " — " + args[0].string;
-      }
-      ChromeUtils.addProfilerMarker("OS.File", startTime, text);
-    }
-  };
-  worker.log = LOG;
-  worker.postMessage = function(message, ...transfers) {
-    if (timeStamps) {
-      message.timeStamps = timeStamps;
-      timeStamps = null;
-    }
-    self.postMessage(message, ...transfers);
-  };
-  worker.close = function() {
-    self.close();
-  };
-  let Meta = PromiseWorker.Meta;
-
-  self.addEventListener("message", msg => worker.handleMessage(msg));
-  self.addEventListener("unhandledrejection", function(error) {
-    throw error.reason;
-  });
-
-  /**
-   * A data structure used to track opened resources
-   */
-  let ResourceTracker = function ResourceTracker() {
-    // A number used to generate ids
-    this._idgen = 0;
-    // A map from id to resource
-    this._map = new Map();
-  };
-  ResourceTracker.prototype = {
-    /**
-     * Get a resource from its unique identifier.
-     */
-    get(id) {
-      let result = this._map.get(id);
-      if (result == null) {
-        return result;
-      }
-      return result.resource;
-    },
-    /**
-     * Remove a resource from its unique identifier.
-     */
-    remove(id) {
-      if (!this._map.has(id)) {
-        throw new Error("Cannot find resource id " + id);
-      }
-      this._map.delete(id);
-    },
-    /**
-     * Add a resource, return a new unique identifier
-     *
-     * @param {*} resource A resource.
-     * @param {*=} info Optional information. For debugging purposes.
-     *
-     * @return {*} A unique identifier. For the moment, this is a number,
-     * but this might not remain the case forever.
-     */
-    add(resource, info) {
-      let id = this._idgen++;
-      this._map.set(id, { resource, info });
-      return id;
-    },
-    /**
-     * Return a list of all open resources i.e. the ones still present in
-     * ResourceTracker's _map.
-     */
-    listOpenedResources: function listOpenedResources() {
-      return Array.from(this._map, ([id, resource]) => resource.info.path);
-    },
-  };
-
-  /**
-   * A map of unique identifiers to opened files.
-   */
-  let OpenedFiles = new ResourceTracker();
-
-  /**
-   * Execute a function in the context of a given file.
-   *
-   * @param {*} id A unique identifier, as used by |OpenFiles|.
-   * @param {Function} f A function to call.
-   * @param {boolean} ignoreAbsent If |true|, the error is ignored. Otherwise, the error causes an exception.
-   * @return The return value of |f()|
-   *
-   * This function attempts to get the file matching |id|. If
-   * the file exists, it executes |f| within the |this| set
-   * to the corresponding file. Otherwise, it throws an error.
-   */
-  let withFile = function withFile(id, f, ignoreAbsent) {
-    let file = OpenedFiles.get(id);
-    if (file == null) {
-      if (!ignoreAbsent) {
-        throw OS.File.Error.closed("accessing file");
-      }
-      return undefined;
-    }
-    return f.call(file);
-  };
-
-  let OpenedDirectoryIterators = new ResourceTracker();
-  let withDir = function withDir(fd, f, ignoreAbsent) {
-    let file = OpenedDirectoryIterators.get(fd);
-    if (file == null) {
-      if (!ignoreAbsent) {
-        throw OS.File.Error.closed("accessing directory");
-      }
-      return undefined;
-    }
-    if (!(file instanceof File.DirectoryIterator)) {
-      throw new Error(
-        "file is not a directory iterator " +
-          Object.getPrototypeOf(file).toSource()
-      );
-    }
-    return f.call(file);
-  };
-
-  let Type = exports.OS.Shared.Type;
-
-  let File = exports.OS.File;
-
-  /**
-   * The agent.
-   *
-   * It is in charge of performing method-specific deserialization
-   * of messages, calling the function/method of OS.File and serializing
-   * back the results.
-   */
-  let Agent = {
-    // Update worker's OS.Shared.DEBUG flag message from controller.
-    SET_DEBUG(aDEBUG) {
-      SharedAll.Config.DEBUG = aDEBUG;
-    },
-    // Return worker's current OS.Shared.DEBUG value to controller.
-    // Note: This is used for testing purposes.
-    GET_DEBUG() {
-      return SharedAll.Config.DEBUG;
-    },
-    /**
-     * Execute shutdown sequence, returning data on leaked file descriptors.
-     *
-     * @param {bool} If |true|, kill the worker if this would not cause
-     * leaks.
-     */
-    Meta_shutdown(kill) {
-      let result = {
-        openedFiles: OpenedFiles.listOpenedResources(),
-        openedDirectoryIterators: OpenedDirectoryIterators.listOpenedResources(),
-        killed: false, // Placeholder
-      };
-
-      // Is it safe to kill the worker?
-      let safe =
-        !result.openedFiles.length && !result.openedDirectoryIterators.length;
-      result.killed = safe && kill;
-
-      return new Meta(result, { shutdown: result.killed });
-    },
-    // Functions of OS.File
-    stat: function stat(path, options) {
-      return exports.OS.File.Info.toMsg(
-        exports.OS.File.stat(Type.path.fromMsg(path), options)
-      );
-    },
-    setPermissions: function setPermissions(path, options = {}) {
-      return exports.OS.File.setPermissions(Type.path.fromMsg(path), options);
-    },
-    setDates: function setDates(path, accessDate, modificationDate) {
-      return exports.OS.File.setDates(
-        Type.path.fromMsg(path),
-        accessDate,
-        modificationDate
-      );
-    },
-    getCurrentDirectory: function getCurrentDirectory() {
-      return exports.OS.Shared.Type.path.toMsg(File.getCurrentDirectory());
-    },
-    copy: function copy(sourcePath, destPath, options) {
-      return File.copy(
-        Type.path.fromMsg(sourcePath),
-        Type.path.fromMsg(destPath),
-        options
-      );
-    },
-    move: function move(sourcePath, destPath, options) {
-      return File.move(
-        Type.path.fromMsg(sourcePath),
-        Type.path.fromMsg(destPath),
-        options
-      );
-    },
-    makeDir: function makeDir(path, options) {
-      return File.makeDir(Type.path.fromMsg(path), options);
-    },
-    removeEmptyDir: function removeEmptyDir(path, options) {
-      return File.removeEmptyDir(Type.path.fromMsg(path), options);
-    },
-    remove: function remove(path, options) {
-      return File.remove(Type.path.fromMsg(path), options);
-    },
-    open: function open(path, mode, options) {
-      let filePath = Type.path.fromMsg(path);
-      let file = File.open(filePath, mode, options);
-      return OpenedFiles.add(file, {
-        // Adding path information to keep track of opened files
-        // to report leaks when debugging.
-        path: filePath,
-      });
-    },
-    openUnique: function openUnique(path, options) {
-      let filePath = Type.path.fromMsg(path);
-      let openedFile = OS.Shared.AbstractFile.openUnique(filePath, options);
-      let resourceId = OpenedFiles.add(openedFile.file, {
-        // Adding path information to keep track of opened files
-        // to report leaks when debugging.
-        path: openedFile.path,
-      });
-
-      return {
-        path: openedFile.path,
-        file: resourceId,
-      };
-    },
-    read: function read(path, bytes, options) {
-      let data = File.read(Type.path.fromMsg(path), bytes, options);
-      if (typeof data == "string") {
-        return data;
-      }
-      return new Meta(
-        {
-          buffer: data.buffer,
-          byteOffset: data.byteOffset,
-          byteLength: data.byteLength,
-        },
-        {
-          transfers: [data.buffer],
-        }
-      );
-    },
-    exists: function exists(path) {
-      return File.exists(Type.path.fromMsg(path));
-    },
-    writeAtomic: function writeAtomic(path, buffer, options) {
-      if (options.tmpPath) {
-        options.tmpPath = Type.path.fromMsg(options.tmpPath);
-      }
-      return File.writeAtomic(
-        Type.path.fromMsg(path),
-        Type.voidptr_t.fromMsg(buffer),
-        options
-      );
-    },
-    removeDir(path, options) {
-      return File.removeDir(Type.path.fromMsg(path), options);
-    },
-    new_DirectoryIterator: function new_DirectoryIterator(path, options) {
-      let directoryPath = Type.path.fromMsg(path);
-      let iterator = new File.DirectoryIterator(directoryPath, options);
-      return OpenedDirectoryIterators.add(iterator, {
-        // Adding path information to keep track of opened directory
-        // iterators to report leaks when debugging.
-        path: directoryPath,
-      });
-    },
-    // Methods of OS.File
-    File_prototype_close: function close(fd) {
-      return withFile(fd, function do_close() {
-        try {
-          return this.close();
-        } finally {
-          OpenedFiles.remove(fd);
-        }
-      });
-    },
-    File_prototype_stat: function stat(fd) {
-      return withFile(fd, function do_stat() {
-        return exports.OS.File.Info.toMsg(this.stat());
-      });
-    },
-    File_prototype_setPermissions: function setPermissions(fd, options = {}) {
-      return withFile(fd, function do_setPermissions() {
-        return this.setPermissions(options);
-      });
-    },
-    File_prototype_setDates: function setDates(
-      fd,
-      accessTime,
-      modificationTime
-    ) {
-      return withFile(fd, function do_setDates() {
-        return this.setDates(accessTime, modificationTime);
-      });
-    },
-    File_prototype_read: function read(fd, nbytes, options) {
-      return withFile(fd, function do_read() {
-        let data = this.read(nbytes, options);
-        return new Meta(
-          {
-            buffer: data.buffer,
-            byteOffset: data.byteOffset,
-            byteLength: data.byteLength,
-          },
-          {
-            transfers: [data.buffer],
-          }
-        );
-      });
-    },
-    File_prototype_readTo: function readTo(fd, buffer, options) {
-      return withFile(fd, function do_readTo() {
-        return this.readTo(
-          exports.OS.Shared.Type.voidptr_t.fromMsg(buffer),
-          options
-        );
-      });
-    },
-    File_prototype_write: function write(fd, buffer, options) {
-      return withFile(fd, function do_write() {
-        return this.write(
-          exports.OS.Shared.Type.voidptr_t.fromMsg(buffer),
-          options
-        );
-      });
-    },
-    File_prototype_setPosition: function setPosition(fd, pos, whence) {
-      return withFile(fd, function do_setPosition() {
-        return this.setPosition(pos, whence);
-      });
-    },
-    File_prototype_getPosition: function getPosition(fd) {
-      return withFile(fd, function do_getPosition() {
-        return this.getPosition();
-      });
-    },
-    File_prototype_flush: function flush(fd) {
-      return withFile(fd, function do_flush() {
-        return this.flush();
-      });
-    },
-    // Methods of OS.File.DirectoryIterator
-    DirectoryIterator_prototype_next: function next(dir) {
-      return withDir(
-        dir,
-        function do_next() {
-          let { value, done } = this.next();
-          if (done) {
-            OpenedDirectoryIterators.remove(dir);
-            return { value: undefined, done: true };
-          }
-          return {
-            value: File.DirectoryIterator.Entry.toMsg(value),
-            done: false,
-          };
-        },
-        false
-      );
-    },
-    DirectoryIterator_prototype_nextBatch: function nextBatch(dir, size) {
-      return withDir(
-        dir,
-        function do_nextBatch() {
-          let result;
-          try {
-            result = this.nextBatch(size);
-          } catch (x) {
-            OpenedDirectoryIterators.remove(dir);
-            throw x;
-          }
-          return result.map(File.DirectoryIterator.Entry.toMsg);
-        },
-        false
-      );
-    },
-    DirectoryIterator_prototype_close: function close(dir) {
-      return withDir(
-        dir,
-        function do_close() {
-          this.close();
-          OpenedDirectoryIterators.remove(dir);
-        },
-        true
-      ); // ignore error to support double-closing |DirectoryIterator|
-    },
-    DirectoryIterator_prototype_exists: function exists(dir) {
-      return withDir(dir, function do_exists() {
-        return this.exists();
-      });
-    },
-  };
-  if (!SharedAll.Constants.Win) {
-    Agent.unixSymLink = function unixSymLink(sourcePath, destPath) {
-      return File.unixSymLink(
-        Type.path.fromMsg(sourcePath),
-        Type.path.fromMsg(destPath)
-      );
-    };
-  }
-
-  timeStamps.loaded = Date.now();
-})(this);
deleted file mode 100644
--- a/toolkit/components/osfile/modules/osfile_native.jsm
+++ /dev/null
@@ -1,126 +0,0 @@
-/* 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/. */
-
-/**
- * Native (xpcom) implementation of key OS.File functions
- */
-
-"use strict";
-
-var EXPORTED_SYMBOLS = ["read", "writeAtomic"];
-
-var { Constants } = ChromeUtils.import(
-  "resource://gre/modules/osfile/osfile_shared_allthreads.jsm"
-);
-
-var SysAll;
-if (Constants.Win) {
-  SysAll = ChromeUtils.import(
-    "resource://gre/modules/osfile/osfile_win_allthreads.jsm"
-  );
-} else if (Constants.libc) {
-  SysAll = ChromeUtils.import(
-    "resource://gre/modules/osfile/osfile_unix_allthreads.jsm"
-  );
-} else {
-  throw new Error("I am neither under Windows nor under a Posix system");
-}
-var { XPCOMUtils } = ChromeUtils.importESModule(
-  "resource://gre/modules/XPCOMUtils.sys.mjs"
-);
-
-const lazy = {};
-
-/**
- * The native service holding the implementation of the functions.
- */
-XPCOMUtils.defineLazyServiceGetter(
-  lazy,
-  "Internals",
-  "@mozilla.org/toolkit/osfile/native-internals;1",
-  "nsINativeOSFileInternalsService"
-);
-
-/**
- * Native implementation of OS.File.read
- *
- * This implementation does not handle option |compression|.
- */
-var read = function(path, options = {}) {
-  // Sanity check on types of options
-  if ("encoding" in options && typeof options.encoding != "string") {
-    return Promise.reject(new TypeError("Invalid type for option encoding"));
-  }
-  if ("compression" in options && typeof options.compression != "string") {
-    return Promise.reject(new TypeError("Invalid type for option compression"));
-  }
-  if ("bytes" in options && typeof options.bytes != "number") {
-    return Promise.reject(new TypeError("Invalid type for option bytes"));
-  }
-
-  return new Promise((resolve, reject) => {
-    lazy.Internals.read(
-      path,
-      options,
-      function onSuccess(success) {
-        success.QueryInterface(Ci.nsINativeOSFileResult);
-        if ("outExecutionDuration" in options) {
-          options.outExecutionDuration =
-            success.executionDurationMS + (options.outExecutionDuration || 0);
-        }
-        resolve(success.result);
-      },
-      function onError(operation, oserror) {
-        reject(new SysAll.Error(operation, oserror, path));
-      }
-    );
-  });
-};
-
-/**
- * Native implementation of OS.File.writeAtomic.
- * This should not be called when |buffer| is a view with some non-zero byte offset.
- * Does not handle option |compression|.
- */
-var writeAtomic = function(path, buffer, options = {}) {
-  // Sanity check on types of options - we check only the encoding, since
-  // the others are checked inside Internals.writeAtomic.
-  if ("encoding" in options && typeof options.encoding !== "string") {
-    return Promise.reject(new TypeError("Invalid type for option encoding"));
-  }
-
-  if (typeof buffer == "string") {
-    // Normalize buffer to a C buffer by encoding it
-    buffer = new TextEncoder().encode(buffer);
-  }
-
-  if (ArrayBuffer.isView(buffer)) {
-    // We need to throw an error if it's a buffer with some byte offset.
-    if ("byteOffset" in buffer && buffer.byteOffset > 0) {
-      return Promise.reject(
-        new Error("Invalid non-zero value of Typed Array byte offset")
-      );
-    }
-    buffer = buffer.buffer;
-  }
-
-  return new Promise((resolve, reject) => {
-    lazy.Internals.writeAtomic(
-      path,
-      buffer,
-      options,
-      function onSuccess(success) {
-        success.QueryInterface(Ci.nsINativeOSFileResult);
-        if ("outExecutionDuration" in options) {
-          options.outExecutionDuration =
-            success.executionDurationMS + (options.outExecutionDuration || 0);
-        }
-        resolve(success.result);
-      },
-      function onError(operation, oserror) {
-        reject(new SysAll.Error(operation, oserror, path));
-      }
-    );
-  });
-};
deleted file mode 100644
--- a/toolkit/components/osfile/modules/osfile_shared_allthreads.jsm
+++ /dev/null
@@ -1,1371 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-/**
- * OS.File utilities used by all threads.
- *
- * This module defines:
- * - logging;
- * - the base constants;
- * - base types and primitives for declaring new types;
- * - primitives for importing C functions;
- * - primitives for dealing with integers, pointers, typed arrays;
- * - the base class OSError;
- * - a few additional utilities.
- */
-
-/* eslint-env worker */
-
-// Boilerplate used to be able to import this module both from the main
-// thread and from worker threads.
-
-/**
- * A constructor for messages that require transfers instead of copies.
- *
- * See BasePromiseWorker.Meta.
- *
- * @constructor
- */
-var Meta;
-if (typeof Components != "undefined") {
-  // Global definition of |exports|, to keep everybody happy.
-  // In non-main thread, |exports| is provided by the module
-  // loader.
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.exports = {};
-  Meta = ChromeUtils.import("resource://gre/modules/PromiseWorker.jsm")
-    .BasePromiseWorker.Meta;
-} else {
-  /* import-globals-from /toolkit/components/workerloader/require.js */
-  importScripts("resource://gre/modules/workers/require.js");
-  Meta = require("resource://gre/modules/workers/PromiseWorker.js").Meta;
-}
-
-var EXPORTED_SYMBOLS = [
-  "LOG",
-  "clone",
-  "Config",
-  "Constants",
-  "Type",
-  "HollowStructure",
-  "OSError",
-  "Library",
-  "declareFFI",
-  "declareLazy",
-  "declareLazyFFI",
-  "normalizeBufferArgs",
-  "projectValue",
-  "isArrayBuffer",
-  "isTypedArray",
-  "defineLazyGetter",
-  "OS", // Warning: this exported symbol will disappear
-];
-
-// //////////////////// Configuration of OS.File
-
-var Config = {
-  /**
-   * If |true|, calls to |LOG| are shown. Otherwise, they are hidden.
-   *
-   * This configuration option is controlled by preference "toolkit.osfile.log".
-   */
-  DEBUG: false,
-
-  /**
-   * TEST
-   */
-  TEST: false,
-};
-exports.Config = Config;
-
-// //////////////////// OS Constants
-
-if (typeof Components != "undefined") {
-  // On the main thread, OS.Constants is defined by a xpcom
-  // component. On other threads, it is available automatically
-  /* global OS */
-  var { ctypes } = ChromeUtils.importESModule(
-    "resource://gre/modules/ctypes.sys.mjs"
-  );
-  Cc["@mozilla.org/net/osfileconstantsservice;1"]
-    .getService(Ci.nsIOSFileConstantsService)
-    .init();
-} else {
-  ctypes = self.ctypes;
-}
-
-exports.Constants = OS.Constants;
-
-// /////////////////// Utilities
-
-// Define a lazy getter for a property
-var defineLazyGetter = function defineLazyGetter(object, name, getter) {
-  Object.defineProperty(object, name, {
-    configurable: true,
-    get: function lazy() {
-      delete this[name];
-      let value = getter.call(this);
-      Object.defineProperty(object, name, {
-        value,
-      });
-      return value;
-    },
-  });
-};
-exports.defineLazyGetter = defineLazyGetter;
-
-// /////////////////// Logging
-
-/**
- * The default implementation of the logger.
- *
- * The choice of logger can be overridden with Config.TEST.
- */
-var gLogger;
-// eslint-disable-next-line no-undef
-if (typeof window != "undefined" && window.console && console.log) {
-  gLogger = console.log.bind(console, "OS");
-} else {
-  gLogger = function(...args) {
-    dump("OS " + args.join(" ") + "\n");
-  };
-}
-
-/**
- * Attempt to stringify an argument into something useful for
- * debugging purposes, by using |.toString()| or |JSON.stringify|
- * if available.
- *
- * @param {*} arg An argument to be stringified if possible.
- * @return {string} A stringified version of |arg|.
- */
-var stringifyArg = function stringifyArg(arg) {
-  if (typeof arg === "string") {
-    return arg;
-  }
-  if (arg && typeof arg === "object") {
-    let argToString = "" + arg;
-
-    /**
-     * The only way to detect whether this object has a non-default
-     * implementation of |toString| is to check whether it returns
-     * '[object Object]'. Unfortunately, we cannot simply compare |arg.toString|
-     * and |Object.prototype.toString| as |arg| typically comes from another
-     * compartment.
-     */
-    if (argToString === "[object Object]") {
-      return JSON.stringify(arg, function(key, value) {
-        if (isTypedArray(value)) {
-          return (
-            "[" +
-            value.constructor.name +
-            " " +
-            value.byteOffset +
-            " " +
-            value.byteLength +
-            "]"
-          );
-        }
-        if (isArrayBuffer(arg)) {
-          return "[" + value.constructor.name + " " + value.byteLength + "]";
-        }
-        return value;
-      });
-    }
-    return argToString;
-  }
-  return arg;
-};
-
-var LOG = function(...args) {
-  if (!Config.DEBUG) {
-    // If logging is deactivated, don't log
-    return;
-  }
-
-  let logFunc = gLogger;
-  if (Config.TEST && typeof Components != "undefined") {
-    // If _TESTING_LOGGING is set, and if we are on the main thread,
-    // redirect logs to Services.console, for testing purposes
-    logFunc = function logFunc(...args) {
-      let message = ["TEST", "OS"].concat(args).join(" ");
-      Services.console.logStringMessage(message + "\n");
-    };
-  }
-  logFunc.apply(null, args.map(stringifyArg));
-};
-
-exports.LOG = LOG;
-
-/**
- * Return a shallow clone of the enumerable properties of an object.
- *
- * Utility used whenever normalizing options requires making (shallow)
- * changes to an option object. The copy ensures that we do not modify
- * a client-provided object by accident.
- *
- * Note: to reference and not copy specific fields, provide an optional
- * |refs| argument containing their names.
- *
- * @param {JSON} object Options to be cloned.
- * @param {Array} refs An optional array of field names to be passed by
- * reference instead of copying.
- */
-var clone = function(object, refs = []) {
-  let result = {};
-  // Make a reference between result[key] and object[key].
-  let refer = function refer(result, key, object) {
-    Object.defineProperty(result, key, {
-      enumerable: true,
-      get() {
-        return object[key];
-      },
-      set(value) {
-        object[key] = value;
-      },
-    });
-  };
-  for (let k in object) {
-    if (!refs.includes(k)) {
-      result[k] = object[k];
-    } else {
-      refer(result, k, object);
-    }
-  }
-  return result;
-};
-
-exports.clone = clone;
-
-// /////////////////// Abstractions above js-ctypes
-
-/**
- * Abstraction above js-ctypes types.
- *
- * Use values of this type to register FFI functions. In addition to the
- * usual features of js-ctypes, values of this type perform the necessary
- * transformations to ensure that C errors are handled nicely, to connect
- * resources with their finalizer, etc.
- *
- * @param {string} name The name of the type. Must be unique.
- * @param {CType} implementation The js-ctypes implementation of the type.
- *
- * @constructor
- */
-function Type(name, implementation) {
-  if (!(typeof name == "string")) {
-    throw new TypeError("Type expects as first argument a name, got: " + name);
-  }
-  if (!(implementation instanceof ctypes.CType)) {
-    throw new TypeError(
-      "Type expects as second argument a ctypes.CType" +
-        ", got: " +
-        implementation
-    );
-  }
-  Object.defineProperty(this, "name", { value: name });
-  Object.defineProperty(this, "implementation", { value: implementation });
-}
-Type.prototype = {
-  /**
-   * Serialize a value of |this| |Type| into a format that can
-   * be transmitted as a message (not necessarily a string).
-   *
-   * In the default implementation, the method returns the
-   * value unchanged.
-   */
-  toMsg: function default_toMsg(value) {
-    return value;
-  },
-  /**
-   * Deserialize a message to a value of |this| |Type|.
-   *
-   * In the default implementation, the method returns the
-   * message unchanged.
-   */
-  fromMsg: function default_fromMsg(msg) {
-    return msg;
-  },
-  /**
-   * Import a value from C.
-   *
-   * In this default implementation, return the value
-   * unchanged.
-   */
-  importFromC: function default_importFromC(value) {
-    return value;
-  },
-
-  /**
-   * A pointer/array used to pass data to the foreign function.
-   */
-  get in_ptr() {
-    delete this.in_ptr;
-    let ptr_t = new PtrType(
-      "[in] " + this.name + "*",
-      this.implementation.ptr,
-      this
-    );
-    Object.defineProperty(this, "in_ptr", {
-      get() {
-        return ptr_t;
-      },
-    });
-    return ptr_t;
-  },
-
-  /**
-   * A pointer/array used to receive data from the foreign function.
-   */
-  get out_ptr() {
-    delete this.out_ptr;
-    let ptr_t = new PtrType(
-      "[out] " + this.name + "*",
-      this.implementation.ptr,
-      this
-    );
-    Object.defineProperty(this, "out_ptr", {
-      get() {
-        return ptr_t;
-      },
-    });
-    return ptr_t;
-  },
-
-  /**
-   * A pointer/array used to both pass data to the foreign function
-   * and receive data from the foreign function.
-   *
-   * Whenever possible, prefer using |in_ptr| or |out_ptr|, which
-   * are generally faster.
-   */
-  get inout_ptr() {
-    delete this.inout_ptr;
-    let ptr_t = new PtrType(
-      "[inout] " + this.name + "*",
-      this.implementation.ptr,
-      this
-    );
-    Object.defineProperty(this, "inout_ptr", {
-      get() {
-        return ptr_t;
-      },
-    });
-    return ptr_t;
-  },
-
-  /**
-   * Attach a finalizer to a type.
-   */
-  releaseWith: function releaseWith(finalizer) {
-    let parent = this;
-    let type = this.withName("[auto " + this.name + ", " + finalizer + "] ");
-    type.importFromC = function importFromC(value, operation) {
-      return ctypes.CDataFinalizer(
-        parent.importFromC(value, operation),
-        finalizer
-      );
-    };
-    return type;
-  },
-
-  /**
-   * Lazy variant of releaseWith.
-   * Attach a finalizer lazily to a type.
-   *
-   * @param {function} getFinalizer The function that
-   * returns finalizer lazily.
-   */
-  releaseWithLazy: function releaseWithLazy(getFinalizer) {
-    let parent = this;
-    let type = this.withName("[auto " + this.name + ", (lazy)] ");
-    type.importFromC = function importFromC(value, operation) {
-      return ctypes.CDataFinalizer(
-        parent.importFromC(value, operation),
-        getFinalizer()
-      );
-    };
-    return type;
-  },
-
-  /**
-   * Return an alias to a type with a different name.
-   */
-  withName: function withName(name) {
-    return Object.create(this, { name: { value: name } });
-  },
-
-  /**
-   * Cast a C value to |this| type.
-   *
-   * Throw an error if the value cannot be casted.
-   */
-  cast: function cast(value) {
-    return ctypes.cast(value, this.implementation);
-  },
-
-  /**
-   * Return the number of bytes in a value of |this| type.
-   *
-   * This may not be defined, e.g. for |void_t|, array types
-   * without length, etc.
-   */
-  get size() {
-    return this.implementation.size;
-  },
-};
-
-/**
- * Utility function used to determine whether an object is a typed array
- */
-var isTypedArray = function isTypedArray(obj) {
-  return obj != null && typeof obj == "object" && "byteOffset" in obj;
-};
-exports.isTypedArray = isTypedArray;
-
-/**
- * Utility function used to determine whether an object is an ArrayBuffer.
- */
-var isArrayBuffer = function(obj) {
-  return (
-    obj != null &&
-    typeof obj == "object" &&
-    obj.constructor.name == "ArrayBuffer"
-  );
-};
-exports.isArrayBuffer = isArrayBuffer;
-
-/**
- * A |Type| of pointers.
- *
- * @param {string} name The name of this type.
- * @param {CType} implementation The type of this pointer.
- * @param {Type} targetType The target type.
- */
-function PtrType(name, implementation, targetType) {
-  Type.call(this, name, implementation);
-  if (targetType == null || !(targetType instanceof Type)) {
-    throw new TypeError("targetType must be an instance of Type");
-  }
-  /**
-   * The type of values targeted by this pointer type.
-   */
-  Object.defineProperty(this, "targetType", {
-    value: targetType,
-  });
-}
-PtrType.prototype = Object.create(Type.prototype);
-
-/**
- * Convert a value to a pointer.
- *
- * Protocol:
- * - |null| returns |null|
- * - a string returns |{string: value}|
- * - a typed array returns |{ptr: address_of_buffer}|
- * - a C array returns |{ptr: address_of_buffer}|
- * everything else raises an error
- */
-PtrType.prototype.toMsg = function ptr_toMsg(value) {
-  if (value == null) {
-    return null;
-  }
-  if (typeof value == "string") {
-    return { string: value };
-  }
-  if (isTypedArray(value)) {
-    // Automatically transfer typed arrays
-    return new Meta({ data: value }, { transfers: [value.buffer] });
-  }
-  if (isArrayBuffer(value)) {
-    // Automatically transfer array buffers
-    return new Meta({ data: value }, { transfers: [value] });
-  }
-  let normalized;
-  if ("addressOfElement" in value) {
-    // C array
-    normalized = value.addressOfElement(0);
-  } else if ("isNull" in value) {
-    // C pointer
-    normalized = value;
-  } else {
-    throw new TypeError("Value " + value + " cannot be converted to a pointer");
-  }
-  let cast = Type.uintptr_t.cast(normalized);
-  return { ptr: cast.value.toString() };
-};
-
-/**
- * Convert a message back to a pointer.
- */
-PtrType.prototype.fromMsg = function ptr_fromMsg(msg) {
-  if (msg == null) {
-    return null;
-  }
-  if ("string" in msg) {
-    return msg.string;
-  }
-  if ("data" in msg) {
-    return msg.data;
-  }
-  if ("ptr" in msg) {
-    let address = ctypes.uintptr_t(msg.ptr);
-    return this.cast(address);
-  }
-  throw new TypeError(
-    "Message " + msg.toSource() + " does not represent a pointer"
-  );
-};
-
-exports.Type = Type;
-
-/*
- * Some values are large integers on 64 bit platforms. Unfortunately,
- * in practice, 64 bit integers cannot be manipulated in JS. We
- * therefore project them to regular numbers whenever possible.
- */
-
-var projectLargeInt = function projectLargeInt(x) {
-  let str = x.toString();
-  let rv = parseInt(str, 10);
-  if (rv.toString() !== str) {
-    throw new TypeError("Number " + str + " cannot be projected to a double");
-  }
-  return rv;
-};
-var projectLargeUInt = function projectLargeUInt(x) {
-  return projectLargeInt(x);
-};
-var projectValue = function projectValue(x) {
-  if (!(x instanceof ctypes.CData)) {
-    return x;
-  }
-  if (!("value" in x)) {
-    // Sanity check
-    throw new TypeError("Number " + x.toSource() + " has no field |value|");
-  }
-  return x.value;
-};
-
-function projector(type, signed) {
-  LOG(
-    "Determining best projection for",
-    type,
-    "(size: ",
-    type.size,
-    ")",
-    signed ? "signed" : "unsigned"
-  );
-  if (type instanceof Type) {
-    type = type.implementation;
-  }
-  if (!type.size) {
-    throw new TypeError("Argument is not a proper C type");
-  }
-  // Determine if type is projected to Int64/Uint64
-  if (
-    type.size == 8 || // Usual case
-    // The following cases have special treatment in js-ctypes
-    // Regardless of their size, the value getter returns
-    // a Int64/Uint64
-    type == ctypes.size_t || // Special cases
-    type == ctypes.ssize_t ||
-    type == ctypes.intptr_t ||
-    type == ctypes.uintptr_t ||
-    type == ctypes.off_t
-  ) {
-    if (signed) {
-      LOG("Projected as a large signed integer");
-      return projectLargeInt;
-    }
-    LOG("Projected as a large unsigned integer");
-    return projectLargeUInt;
-  }
-  LOG("Projected as a regular number");
-  return projectValue;
-}
-exports.projectValue = projectValue;
-
-/**
- * Get the appropriate type for an unsigned int of the given size.
- *
- * This function is useful to define types such as |mode_t| whose
- * actual width depends on the OS/platform.
- *
- * @param {number} size The number of bytes requested.
- */
-Type.uintn_t = function uintn_t(size) {
-  switch (size) {
-    case 1:
-      return Type.uint8_t;
-    case 2:
-      return Type.uint16_t;
-    case 4:
-      return Type.uint32_t;
-    case 8:
-      return Type.uint64_t;
-    default:
-      throw new Error(
-        "Cannot represent unsigned integers of " + size + " bytes"
-      );
-  }
-};
-
-/**
- * Get the appropriate type for an signed int of the given size.
- *
- * This function is useful to define types such as |mode_t| whose
- * actual width depends on the OS/platform.
- *
- * @param {number} size The number of bytes requested.
- */
-Type.intn_t = function intn_t(size) {
-  switch (size) {
-    case 1:
-      return Type.int8_t;
-    case 2:
-      return Type.int16_t;
-    case 4:
-      return Type.int32_t;
-    case 8:
-      return Type.int64_t;
-    default:
-      throw new Error("Cannot represent integers of " + size + " bytes");
-  }
-};
-
-/**
- * Actual implementation of common C types.
- */
-
-/**
- * The void value.
- */
-Type.void_t = new Type("void", ctypes.void_t);
-
-/**
- * Shortcut for |void*|.
- */
-Type.voidptr_t = new PtrType("void*", ctypes.voidptr_t, Type.void_t);
-
-// void* is a special case as we can cast any pointer to/from it
-// so we have to shortcut |in_ptr|/|out_ptr|/|inout_ptr| and
-// ensure that js-ctypes' casting mechanism is invoked directly
-["in_ptr", "out_ptr", "inout_ptr"].forEach(function(key) {
-  Object.defineProperty(Type.void_t, key, {
-    value: Type.voidptr_t,
-  });
-});
-
-/**
- * A Type of integers.
- *
- * @param {string} name The name of this type.
- * @param {CType} implementation The underlying js-ctypes implementation.
- * @param {bool} signed |true| if this is a type of signed integers,
- * |false| otherwise.
- *
- * @constructor
- */
-function IntType(name, implementation, signed) {
-  Type.call(this, name, implementation);
-  this.importFromC = projector(implementation, signed);
-  this.project = this.importFromC;
-}
-IntType.prototype = Object.create(Type.prototype);
-IntType.prototype.toMsg = function toMsg(value) {
-  if (typeof value == "number") {
-    return value;
-  }
-  return this.project(value);
-};
-
-/**
- * A C char (one byte)
- */
-Type.char = new Type("char", ctypes.char);
-
-/**
- * A C wide char (two bytes)
- */
-Type.char16_t = new Type("char16_t", ctypes.char16_t);
-
-/**
- * Base string types.
- */
-Type.cstring = Type.char.in_ptr.withName("[in] C string");
-Type.wstring = Type.char16_t.in_ptr.withName("[in] wide string");
-Type.out_cstring = Type.char.out_ptr.withName("[out] C string");
-Type.out_wstring = Type.char16_t.out_ptr.withName("[out] wide string");
-
-/**
- * A C integer (8-bits).
- */
-Type.int8_t = new IntType("int8_t", ctypes.int8_t, true);
-
-Type.uint8_t = new IntType("uint8_t", ctypes.uint8_t, false);
-
-/**
- * A C integer (16-bits).
- *
- * Also known as WORD under Windows.
- */
-Type.int16_t = new IntType("int16_t", ctypes.int16_t, true);
-
-Type.uint16_t = new IntType("uint16_t", ctypes.uint16_t, false);
-
-/**
- * A C integer (32-bits).
- *
- * Also known as DWORD under Windows.
- */
-Type.int32_t = new IntType("int32_t", ctypes.int32_t, true);
-
-Type.uint32_t = new IntType("uint32_t", ctypes.uint32_t, false);
-
-/**
- * A C integer (64-bits).
- */
-Type.int64_t = new IntType("int64_t", ctypes.int64_t, true);
-
-Type.uint64_t = new IntType("uint64_t", ctypes.uint64_t, false);
-
-/**
- * A C integer
- *
- * Size depends on the platform.
- */
-Type.int = Type.intn_t(ctypes.int.size).withName("int");
-
-Type.unsigned_int = Type.intn_t(ctypes.unsigned_int.size).withName(
-  "unsigned int"
-);
-
-/**
- * A C long integer.
- *
- * Size depends on the platform.
- */
-Type.long = Type.intn_t(ctypes.long.size).withName("long");
-
-Type.unsigned_long = Type.intn_t(ctypes.unsigned_long.size).withName(
-  "unsigned long"
-);
-
-/**
- * An unsigned integer with the same size as a pointer.
- *
- * Used to cast a pointer to an integer, whenever necessary.
- */
-Type.uintptr_t = Type.uintn_t(ctypes.uintptr_t.size).withName("uintptr_t");
-
-/**
- * A boolean.
- * Implemented as a C integer.
- */
-Type.bool = Type.int.withName("bool");
-Type.bool.importFromC = function projectBool(x) {
-  return !!x.value;
-};
-
-/**
- * A user identifier.
- *
- * Implemented as a C integer.
- */
-Type.uid_t = Type.int.withName("uid_t");
-
-/**
- * A group identifier.
- *
- * Implemented as a C integer.
- */
-Type.gid_t = Type.int.withName("gid_t");
-
-/**
- * An offset (positive or negative).
- *
- * Implemented as a C integer.
- */
-Type.off_t = new IntType("off_t", ctypes.off_t, true);
-
-/**
- * A size (positive).
- *
- * Implemented as a C size_t.
- */
-Type.size_t = new IntType("size_t", ctypes.size_t, false);
-
-/**
- * An offset (positive or negative).
- * Implemented as a C integer.
- */
-Type.ssize_t = new IntType("ssize_t", ctypes.ssize_t, true);
-
-/**
- * Encoding/decoding strings
- */
-Type.uencoder = new Type("uencoder", ctypes.StructType("uencoder"));
-Type.udecoder = new Type("udecoder", ctypes.StructType("udecoder"));
-
-/**
- * Utility class, used to build a |struct| type
- * from a set of field names, types and offsets.
- *
- * @param {string} name The name of the |struct| type.
- * @param {number} size The total size of the |struct| type in bytes.
- */
-function HollowStructure(name, size) {
-  if (!name) {
-    throw new TypeError("HollowStructure expects a name");
-  }
-  if (!size || size < 0) {
-    throw new TypeError("HollowStructure expects a (positive) size");
-  }
-
-  // A mapping from offsets in the struct to name/type pairs
-  // (or nothing if no field starts at that offset).
-  this.offset_to_field_info = [];
-
-  // The name of the struct
-  this.name = name;
-
-  // The size of the struct, in bytes
-  this.size = size;
-
-  // The number of paddings inserted so far.
-  // Used to give distinct names to padding fields.
-  this._paddings = 0;
-}
-HollowStructure.prototype = {
-  /**
-   * Add a field at a given offset.
-   *
-   * @param {number} offset The offset at which to insert the field.
-   * @param {string} name The name of the field.
-   * @param {CType|Type} type The type of the field.
-   */
-  add_field_at: function add_field_at(offset, name, type) {
-    if (offset == null) {
-      throw new TypeError("add_field_at requires a non-null offset");
-    }
-    if (!name) {
-      throw new TypeError("add_field_at requires a non-null name");
-    }
-    if (!type) {
-      throw new TypeError("add_field_at requires a non-null type");
-    }
-    if (type instanceof Type) {
-      type = type.implementation;
-    }
-    if (this.offset_to_field_info[offset]) {
-      throw new Error(
-        "HollowStructure " +
-          this.name +
-          " already has a field at offset " +
-          offset
-      );
-    }
-    if (offset + type.size > this.size) {
-      throw new Error(
-        "HollowStructure " +
-          this.name +
-          " cannot place a value of type " +
-          type +
-          " at offset " +
-          offset +
-          " without exceeding its size of " +
-          this.size
-      );
-    }
-    let field = { name, type };
-    this.offset_to_field_info[offset] = field;
-  },
-
-  /**
-   * Create a pseudo-field that will only serve as padding.
-   *
-   * @param {number} size The number of bytes in the field.
-   * @return {Object} An association field-name => field-type,
-   * as expected by |ctypes.StructType|.
-   */
-  _makePaddingField: function makePaddingField(size) {
-    let field = {};
-    field["padding_" + this._paddings] = ctypes.ArrayType(ctypes.uint8_t, size);
-    this._paddings++;
-    return field;
-  },
-
-  /**
-   * Convert this |HollowStructure| into a |Type|.
-   */
-  getType: function getType() {
-    // Contents of the structure, in the format expected
-    // by ctypes.StructType.
-    let struct = [];
-
-    let i = 0;
-    while (i < this.size) {
-      let currentField = this.offset_to_field_info[i];
-      if (!currentField) {
-        // No field was specified at this offset, we need to
-        // introduce some padding.
-
-        // Firstly, determine how many bytes of padding
-        let padding_length = 1;
-        while (
-          i + padding_length < this.size &&
-          !this.offset_to_field_info[i + padding_length]
-        ) {
-          ++padding_length;
-        }
-
-        // Then add the padding
-        struct.push(this._makePaddingField(padding_length));
-
-        // And proceed
-        i += padding_length;
-      } else {
-        // We have a field at this offset.
-
-        // Firstly, ensure that we do not have two overlapping fields
-        for (let j = 1; j < currentField.type.size; ++j) {
-          let candidateField = this.offset_to_field_info[i + j];
-          if (candidateField) {
-            throw new Error(
-              "Fields " +
-                currentField.name +
-                " and " +
-                candidateField.name +
-                " overlap at position " +
-                (i + j)
-            );
-          }
-        }
-
-        // Then add the field
-        let field = {};
-        field[currentField.name] = currentField.type;
-        struct.push(field);
-
-        // And proceed
-        i += currentField.type.size;
-      }
-    }
-    let result = new Type(this.name, ctypes.StructType(this.name, struct));
-    if (result.implementation.size != this.size) {
-      throw new Error(
-        "Wrong size for type " +
-          this.name +
-          ": expected " +
-          this.size +
-          ", found " +
-          result.implementation.size +
-          " (" +
-          result.implementation.toSource() +
-          ")"
-      );
-    }
-    return result;
-  },
-};
-exports.HollowStructure = HollowStructure;
-
-/**
- * Representation of a native library.
- *
- * The native library is opened lazily, during the first call to its
- * field |library| or whenever accessing one of the methods imported
- * with declareLazyFFI.
- *
- * @param {string} name A human-readable name for the library. Used
- * for debugging and error reporting.
- * @param {string...} candidates A list of system libraries that may
- * represent this library. Used e.g. to try different library names
- * on distinct operating systems ("libxul", "XUL", etc.).
- *
- * @constructor
- */
-function Library(name, ...candidates) {
-  this.name = name;
-  this._candidates = candidates;
-}
-Library.prototype = Object.freeze({
-  /**
-   * The native library as a js-ctypes object.
-   *
-   * @throws {Error} If none of the candidate libraries could be opened.
-   */
-  get library() {
-    let library;
-    delete this.library;
-    for (let candidate of this._candidates) {
-      try {
-        library = ctypes.open(candidate);
-        break;
-      } catch (ex) {
-        LOG("Could not open library", candidate, ex);
-      }
-    }
-    this._candidates = null;
-    if (library) {
-      Object.defineProperty(this, "library", {
-        value: library,
-      });
-      Object.freeze(this);
-      return library;
-    }
-    let error = new Error("Could not open library " + this.name);
-    Object.defineProperty(this, "library", {
-      get() {
-        throw error;
-      },
-    });
-    Object.freeze(this);
-    throw error;
-  },
-
-  /**
-   * Declare a function, lazily.
-   *
-   * @param {object} The object containing the function as a field.
-   * @param {string} The name of the field containing the function.
-   * @param {string} symbol The name of the function, as defined in the
-   * library.
-   * @param {ctypes.abi} abi The abi to use, or |null| for default.
-   * @param {Type} returnType The type of values returned by the function.
-   * @param {...Type} argTypes The type of arguments to the function.
-   */
-  declareLazyFFI(object, field, ...args) {
-    let lib = this;
-    Object.defineProperty(object, field, {
-      get() {
-        delete this[field];
-        let ffi = declareFFI(lib.library, ...args);
-        if (ffi) {
-          return (this[field] = ffi);
-        }
-        return undefined;
-      },
-      configurable: true,
-      enumerable: true,
-    });
-  },
-
-  /**
-   * Define a js-ctypes function lazily using ctypes method declare.
-   *
-   * @param {object} The object containing the function as a field.
-   * @param {string} The name of the field containing the function.
-   * @param {string} symbol The name of the function, as defined in the
-   * library.
-   * @param {ctypes.abi} abi The abi to use, or |null| for default.
-   * @param {ctypes.CType} returnType The type of values returned by the function.
-   * @param {...ctypes.CType} argTypes The type of arguments to the function.
-   */
-  declareLazy(object, field, ...args) {
-    let lib = this;
-    Object.defineProperty(object, field, {
-      get() {
-        delete this[field];
-        let ffi = lib.library.declare(...args);
-        if (ffi) {
-          return (this[field] = ffi);
-        }
-        return undefined;
-      },
-      configurable: true,
-      enumerable: true,
-    });
-  },
-
-  /**
-   * Define a js-ctypes function lazily using ctypes method declare,
-   * with a fallback library to use if this library can't be opened
-   * or the function cannot be declared.
-   *
-   * @param {fallbacklibrary} The fallback Library object.
-   * @param {object} The object containing the function as a field.
-   * @param {string} The name of the field containing the function.
-   * @param {string} symbol The name of the function, as defined in the
-   * library.
-   * @param {ctypes.abi} abi The abi to use, or |null| for default.
-   * @param {ctypes.CType} returnType The type of values returned by the function.
-   * @param {...ctypes.CType} argTypes The type of arguments to the function.
-   */
-  declareLazyWithFallback(fallbacklibrary, object, field, ...args) {
-    let lib = this;
-    Object.defineProperty(object, field, {
-      get() {
-        delete this[field];
-        try {
-          let ffi = lib.library.declare(...args);
-          if (ffi) {
-            return (this[field] = ffi);
-          }
-        } catch (ex) {
-          // Use the fallback library and get the symbol from there.
-          fallbacklibrary.declareLazy(object, field, ...args);
-          return object[field];
-        }
-        return undefined;
-      },
-      configurable: true,
-      enumerable: true,
-    });
-  },
-
-  toString() {
-    return "[Library " + this.name + "]";
-  },
-});
-exports.Library = Library;
-
-/**
- * Declare a function through js-ctypes
- *
- * @param {ctypes.library} lib The ctypes library holding the function.
- * @param {string} symbol The name of the function, as defined in the
- * library.
- * @param {ctypes.abi} abi The abi to use, or |null| for default.
- * @param {Type} returnType The type of values returned by the function.
- * @param {...Type} argTypes The type of arguments to the function.
- *
- * @return null if the function could not be defined (generally because
- * it does not exist), or a JavaScript wrapper performing the call to C
- * and any type conversion required.
- */
-var declareFFI = function declareFFI(
-  lib,
-  symbol,
-  abi,
-  returnType /* , argTypes ...*/
-) {
-  LOG("Attempting to declare FFI ", symbol);
-  // We guard agressively, to avoid any late surprise
-  if (typeof symbol != "string") {
-    throw new TypeError("declareFFI expects as first argument a string");
-  }
-  abi = abi || ctypes.default_abi;
-  if (Object.prototype.toString.call(abi) != "[object CABI]") {
-    // Note: This is the only known manner of checking whether an object
-    // is an abi.
-    throw new TypeError("declareFFI expects as second argument an abi or null");
-  }
-  if (!returnType.importFromC) {
-    throw new TypeError(
-      "declareFFI expects as third argument an instance of Type"
-    );
-  }
-  let signature = [symbol, abi];
-  for (let i = 3; i < arguments.length; ++i) {
-    let current = arguments[i];
-    if (!current) {
-      throw new TypeError(
-        "Missing type for argument " + (i - 3) + " of symbol " + symbol
-      );
-    }
-    // Ellipsis for variadic arguments.
-    if (current == "...") {
-      if (i != arguments.length - 1) {
-        throw new TypeError("Variadic ellipsis must be the last argument");
-      }
-      signature.push(current);
-      continue;
-    }
-    if (!current.implementation) {
-      throw new TypeError(
-        "Missing implementation for argument " +
-          (i - 3) +
-          " of symbol " +
-          symbol +
-          " ( " +
-          current.name +
-          " )"
-      );
-    }
-    signature.push(current.implementation);
-  }
-  try {
-    let fun = lib.declare.apply(lib, signature);
-    let result = function ffi(...args) {
-      for (let i = 0; i < args.length; i++) {
-        if (typeof args[i] == "undefined") {
-          throw new TypeError(
-            "Argument " + i + " of " + symbol + " is undefined"
-          );
-        }
-      }
-      let result = fun.apply(fun, args);
-      return returnType.importFromC(result, symbol);
-    };
-    LOG("Function", symbol, "declared");
-    return result;
-  } catch (x) {
-    // Note: Not being able to declare a function is normal.
-    // Some functions are OS (or OS version)-specific.
-    LOG("Could not declare function ", symbol, x);
-    return null;
-  }
-};
-exports.declareFFI = declareFFI;
-
-/**
- * Define a lazy getter to a js-ctypes function using declareFFI.
- *
- * @param {object} The object containing the function as a field.
- * @param {string} The name of the field containing the function.
- * @param {ctypes.library} lib The ctypes library holding the function.
- * @param {string} symbol The name of the function, as defined in the
- * library.
- * @param {ctypes.abi} abi The abi to use, or |null| for default.
- * @param {Type} returnType The type of values returned by the function.
- * @param {...Type} argTypes The type of arguments to the function.
- */
-function declareLazyFFI(object, field, ...declareFFIArgs) {
-  Object.defineProperty(object, field, {
-    get() {
-      delete this[field];
-      let ffi = declareFFI(...declareFFIArgs);
-      if (ffi) {
-        return (this[field] = ffi);
-      }
-      return undefined;
-    },
-    configurable: true,
-    enumerable: true,
-  });
-}
-exports.declareLazyFFI = declareLazyFFI;
-
-/**
- * Define a lazy getter to a js-ctypes function using ctypes method declare.
- *
- * @param {object} The object containing the function as a field.
- * @param {string} The name of the field containing the function.
- * @param {ctypes.library} lib The ctypes library holding the function.
- * @param {string} symbol The name of the function, as defined in the
- * library.
- * @param {ctypes.abi} abi The abi to use, or |null| for default.
- * @param {ctypes.CType} returnType The type of values returned by the function.
- * @param {...ctypes.CType} argTypes The type of arguments to the function.
- */
-function declareLazy(object, field, lib, ...declareArgs) {
-  Object.defineProperty(object, field, {
-    get() {
-      delete this[field];
-      try {
-        let ffi = lib.declare(...declareArgs);
-        return (this[field] = ffi);
-      } catch (ex) {
-        // The symbol doesn't exist
-        return undefined;
-      }
-    },
-    configurable: true,
-  });
-}
-exports.declareLazy = declareLazy;
-
-/**
- * Utility function used to sanity check buffer and length arguments.  The
- * buffer must be a Typed Array.
- *
- * @param {Typed array} candidate The buffer.
- * @param {number} bytes The number of bytes that |candidate| should contain.
- *
- * @return number The bytes argument clamped to the length of the buffer.
- */
-function normalizeBufferArgs(candidate, bytes) {
-  if (!candidate) {
-    throw new TypeError("Expecting a Typed Array");
-  }
-  if (!isTypedArray(candidate)) {
-    throw new TypeError("Expecting a Typed Array");
-  }
-  if (bytes == null) {
-    bytes = candidate.byteLength;
-  } else if (candidate.byteLength < bytes) {
-    throw new TypeError(
-      "Buffer is too short. I need at least " +
-        bytes +
-        " bytes but I have only " +
-        candidate.byteLength +
-        "bytes"
-    );
-  }
-  return bytes;
-}
-exports.normalizeBufferArgs = normalizeBufferArgs;
-
-// /////////////////// OS interactions
-
-/**
- * An OS error.
- *
- * This class is provided mostly for type-matching. If you need more
- * details about an error, you should use the platform-specific error
- * codes provided by subclasses of |OS.Shared.Error|.
- *
- * @param {string} operation The operation that failed.
- * @param {string=} path The path of the file on which the operation failed,
- * or nothing if there was no file involved in the failure.
- *
- * @constructor
- */
-function OSError(operation, path = "") {
-  Error.call(this);
-  this.operation = operation;
-  this.path = path;
-}
-OSError.prototype = Object.create(Error.prototype);
-exports.OSError = OSError;
-
-// /////////////////// Temporary boilerplate
-// Boilerplate, to simplify the transition to require()
-// Do not rely upon this symbol, it will disappear with
-// bug 883050.
-exports.OS = {
-  Constants: exports.Constants,
-  Shared: {
-    LOG,
-    clone,
-    Type,
-    HollowStructure,
-    Error: OSError,
-    declareFFI,
-    projectValue,
-    isTypedArray,
-    defineLazyGetter,
-  },
-};
-
-Object.defineProperty(exports.OS.Shared, "DEBUG", {
-  get() {
-    return Config.DEBUG;
-  },
-  set(x) {
-    Config.DEBUG = x;
-  },
-});
-Object.defineProperty(exports.OS.Shared, "TEST", {
-  get() {
-    return Config.TEST;
-  },
-  set(x) {
-    Config.TEST = x;
-  },
-});
-
-// /////////////////// Permanent boilerplate
-if (typeof Components != "undefined") {
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.EXPORTED_SYMBOLS = EXPORTED_SYMBOLS;
-  for (let symbol of EXPORTED_SYMBOLS) {
-    // eslint-disable-next-line mozilla/reject-global-this
-    this[symbol] = exports[symbol];
-  }
-}
deleted file mode 100644
--- a/toolkit/components/osfile/modules/osfile_shared_front.js
+++ /dev/null
@@ -1,607 +0,0 @@
-/* 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/. */
-
-/**
- * Code shared by OS.File front-ends.
- *
- * This code is meant to be included by another library. It is also meant to
- * be executed only on a worker thread.
- */
-
-/* eslint-env node */
-/* global OS */
-
-if (typeof Components != "undefined") {
-  throw new Error("osfile_shared_front.js cannot be used from the main thread");
-}
-(function(exports) {
-  var SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
-  var Path = require("resource://gre/modules/osfile/ospath.jsm");
-  var Lz4 = require("resource://gre/modules/lz4.js");
-  SharedAll.LOG.bind(SharedAll, "Shared front-end");
-  var clone = SharedAll.clone;
-
-  /**
-   * Code shared by implementations of File.
-   *
-   * @param {*} fd An OS-specific file handle.
-   * @param {string} path File path of the file handle, used for error-reporting.
-   * @constructor
-   */
-  var AbstractFile = function AbstractFile(fd, path) {
-    this._fd = fd;
-    if (!path) {
-      throw new TypeError("path is expected");
-    }
-    this._path = path;
-  };
-
-  AbstractFile.prototype = {
-    /**
-     * Return the file handle.
-     *
-     * @throw OS.File.Error if the file has been closed.
-     */
-    get fd() {
-      if (this._fd) {
-        return this._fd;
-      }
-      throw OS.File.Error.closed("accessing file", this._path);
-    },
-    /**
-     * Read bytes from this file to a new buffer.
-     *
-     * @param {number=} maybeBytes (deprecated, please use options.bytes)
-     * @param {JSON} options
-     * @return {Uint8Array} An array containing the bytes read.
-     */
-    read: function read(maybeBytes, options = {}) {
-      if (typeof maybeBytes === "object") {
-        // Caller has skipped `maybeBytes` and provided an options object.
-        options = clone(maybeBytes);
-        maybeBytes = null;
-      } else {
-        options = options || {};
-      }
-      let bytes = options.bytes || undefined;
-      if (bytes === undefined) {
-        bytes = maybeBytes == null ? this.stat().size : maybeBytes;
-      }
-      let buffer = new Uint8Array(bytes);
-      let pos = 0;
-      while (pos < bytes) {
-        let length = bytes - pos;
-        let view = new DataView(buffer.buffer, pos, length);
-        let chunkSize = this._read(view, length, options);
-        if (chunkSize == 0) {
-          break;
-        }
-        pos += chunkSize;
-      }
-      if (pos == bytes) {
-        return buffer;
-      }
-      return buffer.subarray(0, pos);
-    },
-
-    /**
-     * Write bytes from a buffer to this file.
-     *
-     * Note that, by default, this function may perform several I/O
-     * operations to ensure that the buffer is fully written.
-     *
-     * @param {Typed array} buffer The buffer in which the the bytes are
-     * stored. The buffer must be large enough to accomodate |bytes| bytes.
-     * @param {*=} options Optionally, an object that may contain the
-     * following fields:
-     * - {number} bytes The number of |bytes| to write from the buffer. If
-     * unspecified, this is |buffer.byteLength|.
-     *
-     * @return {number} The number of bytes actually written.
-     */
-    write: function write(buffer, options = {}) {
-      let bytes = SharedAll.normalizeBufferArgs(
-        buffer,
-        "bytes" in options ? options.bytes : undefined
-      );
-      let pos = 0;
-      while (pos < bytes) {
-        let length = bytes - pos;
-        let view = new DataView(buffer.buffer, buffer.byteOffset + pos, length);
-        let chunkSize = this._write(view, length, options);
-        pos += chunkSize;
-      }
-      return pos;
-    },
-  };
-
-  /**
-   * Creates and opens a file with a unique name. By default, generate a random HEX number and use it to create a unique new file name.
-   *
-   * @param {string} path The path to the file.
-   * @param {*=} options Additional options for file opening. This
-   * implementation interprets the following fields:
-   *
-   * - {number} humanReadable If |true|, create a new filename appending a decimal number. ie: filename-1.ext, filename-2.ext.
-   *  If |false| use HEX numbers ie: filename-A65BC0.ext
-   * - {number} maxReadableNumber Used to limit the amount of tries after a failed
-   *  file creation. Default is 20.
-   *
-   * @return {Object} contains A file object{file} and the path{path}.
-   * @throws {OS.File.Error} If the file could not be opened.
-   */
-  AbstractFile.openUnique = function openUnique(path, options = {}) {
-    let mode = {
-      create: true,
-    };
-
-    let dirName = Path.dirname(path);
-    let leafName = Path.basename(path);
-    let lastDotCharacter = leafName.lastIndexOf(".");
-    let fileName = leafName.substring(
-      0,
-      lastDotCharacter != -1 ? lastDotCharacter : leafName.length
-    );
-    let suffix =
-      lastDotCharacter != -1 ? leafName.substring(lastDotCharacter) : "";
-    let uniquePath = "";
-    let maxAttempts = options.maxAttempts || 99;
-    let humanReadable = !!options.humanReadable;
-    const HEX_RADIX = 16;
-    // We produce HEX numbers between 0 and 2^24 - 1.
-    const MAX_HEX_NUMBER = 16777215;
-
-    try {
-      return {
-        path,
-        file: OS.File.open(path, mode),
-      };
-    } catch (ex) {
-      if (ex instanceof OS.File.Error && ex.becauseExists) {
-        for (let i = 0; i < maxAttempts; ++i) {
-          try {
-            if (humanReadable) {
-              uniquePath = Path.join(
-                dirName,
-                fileName + "-" + (i + 1) + suffix
-              );
-            } else {
-              let hexNumber = Math.floor(
-                Math.random() * MAX_HEX_NUMBER
-              ).toString(HEX_RADIX);
-              uniquePath = Path.join(
-                dirName,
-                fileName + "-" + hexNumber + suffix
-              );
-            }
-            return {
-              path: uniquePath,
-              file: OS.File.open(uniquePath, mode),
-            };
-          } catch (ex) {
-            if (ex instanceof OS.File.Error && ex.becauseExists) {
-              // keep trying ...
-            } else {
-              throw ex;
-            }
-          }
-        }
-        throw OS.File.Error.exists("could not find an unused file name.", path);
-      }
-      throw ex;
-    }
-  };
-
-  /**
-   * Code shared by iterators.
-   */
-  AbstractFile.AbstractIterator = function AbstractIterator() {};
-  AbstractFile.AbstractIterator.prototype = {
-    /**
-     * Allow iterating with |for-of|
-     */
-    [Symbol.iterator]() {
-      return this;
-    },
-    /**
-     * Apply a function to all elements of the directory sequentially.
-     *
-     * @param {Function} cb This function will be applied to all entries
-     * of the directory. It receives as arguments
-     *  - the OS.File.Entry corresponding to the entry;
-     *  - the index of the entry in the enumeration;
-     *  - the iterator itself - calling |close| on the iterator stops
-     *   the loop.
-     */
-    forEach: function forEach(cb) {
-      let index = 0;
-      for (let entry of this) {
-        cb(entry, index++, this);
-      }
-    },
-    /**
-     * Return several entries at once.
-     *
-     * Entries are returned in the same order as a walk with |forEach| or
-     * |for(...)|.
-     *
-     * @param {number=} length If specified, the number of entries
-     * to return. If unspecified, return all remaining entries.
-     * @return {Array} An array containing the next |length| entries, or
-     * less if the iteration contains less than |length| entries left.
-     */
-    nextBatch: function nextBatch(length) {
-      let array = [];
-      let i = 0;
-      for (let entry of this) {
-        array.push(entry);
-        if (++i >= length) {
-          return array;
-        }
-      }
-      return array;
-    },
-  };
-
-  /**
-   * Utility function shared by implementations of |OS.File.open|:
-   * extract read/write/trunc/create/existing flags from a |mode|
-   * object.
-   *
-   * @param {*=} mode An object that may contain fields |read|,
-   * |write|, |truncate|, |create|, |existing|. These fields
-   * are interpreted only if true-ish.
-   * @return {{read:bool, write:bool, trunc:bool, create:bool,
-   * existing:bool}} an object recapitulating the options set
-   * by |mode|.
-   * @throws {TypeError} If |mode| contains other fields, or
-   * if it contains both |create| and |truncate|, or |create|
-   * and |existing|.
-   */
-  AbstractFile.normalizeOpenMode = function normalizeOpenMode(mode) {
-    let result = {
-      read: false,
-      write: false,
-      trunc: false,
-      create: false,
-      existing: false,
-      append: true,
-    };
-    for (let key in mode) {
-      let val = !!mode[key]; // bool cast.
-      switch (key) {
-        case "read":
-          result.read = val;
-          break;
-        case "write":
-          result.write = val;
-          break;
-        case "truncate": // fallthrough
-        case "trunc":
-          result.trunc = val;
-          result.write |= val;
-          break;
-        case "create":
-          result.create = val;
-          result.write |= val;
-          break;
-        case "existing": // fallthrough
-        case "exist":
-          result.existing = val;
-          break;
-        case "append":
-          result.append = val;
-          break;
-        default:
-          throw new TypeError("Mode " + key + " not understood");
-      }
-    }
-    // Reject opposite modes
-    if (result.existing && result.create) {
-      throw new TypeError("Cannot specify both existing:true and create:true");
-    }
-    if (result.trunc && result.create) {
-      throw new TypeError("Cannot specify both trunc:true and create:true");
-    }
-    // Handle read/write
-    if (!result.write) {
-      result.read = true;
-    }
-    return result;
-  };
-
-  /**
-   * Return the contents of a file.
-   *
-   * @param {string} path The path to the file.
-   * @param {number=} bytes Optionally, an upper bound to the number of bytes
-   * to read. DEPRECATED - please use options.bytes instead.
-   * @param {object=} options Optionally, an object with some of the following
-   * fields:
-   * - {number} bytes An upper bound to the number of bytes to read.
-   * - {string} compression If "lz4" and if the file is compressed using the lz4
-   *   compression algorithm, decompress the file contents on the fly.
-   *
-   * @return {Uint8Array} A buffer holding the bytes
-   * and the number of bytes read from the file.
-   */
-  AbstractFile.read = function read(path, bytes, options = {}) {
-    if (bytes && typeof bytes == "object") {
-      options = bytes;
-      bytes = options.bytes || null;
-    }
-    if ("encoding" in options && typeof options.encoding != "string") {
-      throw new TypeError("Invalid type for option encoding");
-    }
-    if ("compression" in options && typeof options.compression != "string") {
-      throw new TypeError(
-        "Invalid type for option compression: " + options.compression
-      );
-    }
-    if ("bytes" in options && typeof options.bytes != "number") {
-      throw new TypeError("Invalid type for option bytes");
-    }
-    let file = exports.OS.File.open(path);
-    try {
-      let buffer = file.read(bytes, options);
-      if ("compression" in options) {
-        if (options.compression == "lz4") {
-          options = Object.create(options);
-          options.path = path;
-          buffer = Lz4.decompressFileContent(buffer, options);
-        } else {
-          throw OS.File.Error.invalidArgument("Compression");
-        }
-      }
-      if (!("encoding" in options)) {
-        return buffer;
-      }
-      let decoder;
-      try {
-        decoder = new TextDecoder(options.encoding);
-      } catch (ex) {
-        if (ex instanceof RangeError) {
-          throw OS.File.Error.invalidArgument("Decode");
-        } else {
-          throw ex;
-        }
-      }
-      return decoder.decode(buffer);
-    } finally {
-      file.close();
-    }
-  };
-
-  /**
-   * Write a file, atomically.
-   *
-   * By opposition to a regular |write|, this operation ensures that,
-   * until the contents are fully written, the destination file is
-   * not modified.
-   *
-   * Limitation: In a few extreme cases (hardware failure during the
-   * write, user unplugging disk during the write, etc.), data may be
-   * corrupted. If your data is user-critical (e.g. preferences,
-   * application data, etc.), you may wish to consider adding options
-   * |tmpPath| and/or |flush| to reduce the likelihood of corruption, as
-   * detailed below. Note that no combination of options can be
-   * guaranteed to totally eliminate the risk of corruption.
-   *
-   * @param {string} path The path of the file to modify.
-   * @param {Typed Array | C pointer} buffer A buffer containing the bytes to write.
-   * @param {*=} options Optionally, an object determining the behavior
-   * of this function. This object may contain the following fields:
-   * - {number} bytes The number of bytes to write. If unspecified,
-   * |buffer.byteLength|. Required if |buffer| is a C pointer.
-   * - {string} tmpPath If |null| or unspecified, write all data directly
-   * to |path|. If specified, write all data to a temporary file called
-   * |tmpPath| and, once this write is complete, rename the file to
-   * replace |path|. Performing this additional operation is a little
-   * slower but also a little safer.
-   * - {bool} noOverwrite - If set, this function will fail if a file already
-   * exists at |path|.
-   * - {bool} flush - If |false| or unspecified, return immediately once the
-   * write is complete. If |true|, before writing, force the operating system
-   * to write its internal disk buffers to the disk. This is considerably slower
-   * (not just for the application but for the whole system) but also safer:
-   * if the system shuts down improperly (typically due to a kernel freeze
-   * or a power failure) or if the device is disconnected before the buffer
-   * is flushed, the file has more chances of not being corrupted.
-   * - {string} compression - If empty or unspecified, do not compress the file.
-   * If "lz4", compress the contents of the file atomically using lz4. For the
-   * time being, the container format is specific to Mozilla and cannot be read
-   * by means other than OS.File.read(..., { compression: "lz4"})
-   * - {string} backupTo - If specified, backup the destination file as |backupTo|.
-   * Note that this function renames the destination file before overwriting it.
-   * If the process or the operating system freezes or crashes
-   * during the short window between these operations,
-   * the destination file will have been moved to its backup.
-   *
-   * @return {number} The number of bytes actually written.
-   */
-  AbstractFile.writeAtomic = function writeAtomic(path, buffer, options = {}) {
-    // Verify that path is defined and of the correct type
-    if (typeof path != "string" || path == "") {
-      throw new TypeError("File path should be a (non-empty) string");
-    }
-    let noOverwrite = options.noOverwrite;
-    if (noOverwrite && OS.File.exists(path)) {
-      throw OS.File.Error.exists("writeAtomic", path);
-    }
-
-    if (typeof buffer == "string") {
-      // Normalize buffer to a C buffer by encoding it
-      buffer = new TextEncoder().encode(buffer);
-    }
-
-    if ("compression" in options && options.compression == "lz4") {
-      buffer = Lz4.compressFileContent(buffer, options);
-      options = Object.create(options);
-      options.bytes = buffer.byteLength;
-    }
-
-    let bytesWritten = 0;
-
-    if (!options.tmpPath) {
-      if (options.backupTo) {
-        try {
-          OS.File.move(path, options.backupTo, { noCopy: true });
-        } catch (ex) {
-          if (ex.becauseNoSuchFile) {
-            // The file doesn't exist, nothing to backup.
-          } else {
-            throw ex;
-          }
-        }
-      }
-      // Just write, without any renaming trick
-      let dest = OS.File.open(path, { write: true, truncate: true });
-      try {
-        bytesWritten = dest.write(buffer, options);
-        if (options.flush) {
-          dest.flush();
-        }
-      } finally {
-        dest.close();
-      }
-      return bytesWritten;
-    }
-
-    let tmpFile = OS.File.open(options.tmpPath, {
-      write: true,
-      truncate: true,
-    });
-    try {
-      bytesWritten = tmpFile.write(buffer, options);
-      if (options.flush) {
-        tmpFile.flush();
-      }
-    } catch (x) {
-      OS.File.remove(options.tmpPath);
-      throw x;
-    } finally {
-      tmpFile.close();
-    }
-
-    if (options.backupTo) {
-      try {
-        OS.File.move(path, options.backupTo, { noCopy: true });
-      } catch (ex) {
-        if (ex.becauseNoSuchFile) {
-          // The file doesn't exist, nothing to backup.
-        } else {
-          throw ex;
-        }
-      }
-    }
-
-    OS.File.move(options.tmpPath, path, { noCopy: true });
-    return bytesWritten;
-  };
-
-  /**
-   * This function is used by removeDir to avoid calling lstat for each
-   * files under the specified directory. External callers should not call
-   * this function directly.
-   */
-  AbstractFile.removeRecursive = function(path, options = {}) {
-    let iterator = new OS.File.DirectoryIterator(path);
-    if (!iterator.exists()) {
-      if (!("ignoreAbsent" in options) || options.ignoreAbsent) {
-        return;
-      }
-    }
-
-    try {
-      for (let entry of iterator) {
-        if (entry.isDir) {
-          if (entry.isLink) {
-            // Unlike Unix symlinks, NTFS junctions or NTFS symlinks to
-            // directories are directories themselves. OS.File.remove()
-            // will not work for them.
-            OS.File.removeEmptyDir(entry.path, options);
-          } else {
-            // Normal directories.
-            AbstractFile.removeRecursive(entry.path, options);
-          }
-        } else {
-          // NTFS symlinks to files, Unix symlinks, or regular files.
-          OS.File.remove(entry.path, options);
-        }
-      }
-    } finally {
-      iterator.close();
-    }
-
-    OS.File.removeEmptyDir(path);
-  };
-
-  /**
-   * Create a directory and, optionally, its parent directories.
-   *
-   * @param {string} path The name of the directory.
-   * @param {*=} options Additional options.
-   *
-   * - {string} from If specified, the call to |makeDir| creates all the
-   * ancestors of |path| that are descendants of |from|. Note that |path|
-   * must be a descendant of |from|, and that |from| and its existing
-   * subdirectories present in |path|  must be user-writeable.
-   * Example:
-   *   makeDir(Path.join(profileDir, "foo", "bar"), { from: profileDir });
-   *  creates directories profileDir/foo, profileDir/foo/bar
-   * - {bool} ignoreExisting If |false|, throw an error if the directory
-   * already exists. |true| by default. Ignored if |from| is specified.
-   * - {number} unixMode Under Unix, if specified, a file creation mode,
-   * as per libc function |mkdir|. If unspecified, dirs are
-   * created with a default mode of 0700 (dir is private to
-   * the user, the user can read, write and execute). Ignored under Windows
-   * or if the file system does not support file creation modes.
-   * - {C pointer} winSecurity Under Windows, if specified, security
-   * attributes as per winapi function |CreateDirectory|. If
-   * unspecified, use the default security descriptor, inherited from
-   * the parent directory. Ignored under Unix or if the file system
-   * does not support security descriptors.
-   */
-  AbstractFile.makeDir = function(path, options = {}) {
-    let from = options.from;
-    if (!from) {
-      OS.File._makeDir(path, options);
-      return;
-    }
-    if (!path.startsWith(from)) {
-      // Apparently, `from` is not a parent of `path`. However, we may
-      // have false negatives due to non-normalized paths, e.g.
-      // "foo//bar" is a parent of "foo/bar/sna".
-      path = Path.normalize(path);
-      from = Path.normalize(from);
-      if (!path.startsWith(from)) {
-        throw new Error(
-          "Incorrect use of option |from|: " +
-            path +
-            " is not a descendant of " +
-            from
-        );
-      }
-    }
-    let innerOptions = Object.create(options, {
-      ignoreExisting: {
-        value: true,
-      },
-    });
-    // Compute the elements that appear in |path| but not in |from|.
-    let items = Path.split(path).components.slice(
-      Path.split(from).components.length
-    );
-    let current = from;
-    for (let item of items) {
-      current = Path.join(current, item);
-      OS.File._makeDir(current, innerOptions);
-    }
-  };
-
-  if (!exports.OS.Shared) {
-    exports.OS.Shared = {};
-  }
-  exports.OS.Shared.AbstractFile = AbstractFile;
-})(this);
deleted file mode 100644
--- a/toolkit/components/osfile/modules/osfile_unix_allthreads.jsm
+++ /dev/null
@@ -1,412 +0,0 @@
-/* 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/. */
-
-/**
- * This module defines the thread-agnostic components of the Unix version
- * of OS.File. It depends on the thread-agnostic cross-platform components
- * of OS.File.
- *
- * It serves the following purposes:
- * - open libc;
- * - define OS.Unix.Error;
- * - define a few constants and types that need to be defined on all platforms.
- *
- * This module can be:
- * - opened from the main thread as a jsm module;
- * - opened from a chrome worker through require().
- */
-
-/* eslint-env node */
-
-"use strict";
-
-var SharedAll;
-if (typeof Components != "undefined") {
-  // Module is opened as a jsm module
-  const { ctypes } = ChromeUtils.importESModule(
-    "resource://gre/modules/ctypes.sys.mjs"
-  );
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.ctypes = ctypes;
-
-  SharedAll = ChromeUtils.import(
-    "resource://gre/modules/osfile/osfile_shared_allthreads.jsm"
-  );
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.exports = {};
-} else if (typeof module != "undefined" && typeof require != "undefined") {
-  // Module is loaded with require()
-  SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
-} else {
-  throw new Error(
-    "Please open this module with Component.utils.import or with require()"
-  );
-}
-
-SharedAll.LOG.bind(SharedAll, "Unix", "allthreads");
-var Const = SharedAll.Constants.libc;
-
-// Open libc
-var libc = new SharedAll.Library(
-  "libc",
-  "libc.so",
-  "libSystem.B.dylib",
-  "a.out"
-);
-exports.libc = libc;
-
-// Define declareFFI
-var declareFFI = SharedAll.declareFFI.bind(null, libc);
-exports.declareFFI = declareFFI;
-
-// Define lazy binding
-var LazyBindings = {};
-libc.declareLazy(
-  LazyBindings,
-  "strerror",
-  "strerror",
-  ctypes.default_abi,
-  /* return*/ ctypes.char.ptr,
-  /* errnum*/ ctypes.int
-);
-
-/**
- * A File-related error.
- *
- * To obtain a human-readable error message, use method |toString|.
- * To determine the cause of the error, use the various |becauseX|
- * getters. To determine the operation that failed, use field
- * |operation|.
- *
- * Additionally, this implementation offers a field
- * |unixErrno|, which holds the OS-specific error
- * constant. If you need this level of detail, you may match the value
- * of this field against the error constants of |OS.Constants.libc|.
- *
- * @param {string=} operation The operation that failed. If unspecified,
- * the name of the calling function is taken to be the operation that
- * failed.
- * @param {number=} lastError The OS-specific constant detailing the
- * reason of the error. If unspecified, this is fetched from the system
- * status.
- * @param {string=} path The file path that manipulated. If unspecified,
- * assign the empty string.
- *
- * @constructor
- * @extends {OS.Shared.Error}
- */
-var OSError = function OSError(
-  operation = "unknown operation",
-  errno = ctypes.errno,
-  path = ""
-) {
-  SharedAll.OSError.call(this, operation, path);
-  this.unixErrno = errno;
-};
-OSError.prototype = Object.create(SharedAll.OSError.prototype);
-OSError.prototype.toString = function toString() {
-  return (
-    "Unix error " +
-    this.unixErrno +
-    " during operation " +
-    this.operation +
-    (this.path ? " on file " + this.path : "") +
-    " (" +
-    LazyBindings.strerror(this.unixErrno).readStringReplaceMalformed() +
-    ")"
-  );
-};
-OSError.prototype.toMsg = function toMsg() {
-  return OSError.toMsg(this);
-};
-
-/**
- * |true| if the error was raised because a file or directory
- * already exists, |false| otherwise.
- */
-Object.defineProperty(OSError.prototype, "becauseExists", {
-  get: function becauseExists() {
-    return this.unixErrno == Const.EEXIST;
-  },
-});
-/**
- * |true| if the error was raised because a file or directory
- * does not exist, |false| otherwise.
- */
-Object.defineProperty(OSError.prototype, "becauseNoSuchFile", {
-  get: function becauseNoSuchFile() {
-    return this.unixErrno == Const.ENOENT;
-  },
-});
-
-/**
- * |true| if the error was raised because a directory is not empty
- * does not exist, |false| otherwise.
- */
-Object.defineProperty(OSError.prototype, "becauseNotEmpty", {
-  get: function becauseNotEmpty() {
-    return this.unixErrno == Const.ENOTEMPTY;
-  },
-});
-/**
- * |true| if the error was raised because a file or directory
- * is closed, |false| otherwise.
- */
-Object.defineProperty(OSError.prototype, "becauseClosed", {
-  get: function becauseClosed() {
-    return this.unixErrno == Const.EBADF;
-  },
-});
-/**
- * |true| if the error was raised because permission is denied to
- * access a file or directory, |false| otherwise.
- */
-Object.defineProperty(OSError.prototype, "becauseAccessDenied", {
-  get: function becauseAccessDenied() {
-    return this.unixErrno == Const.EACCES;
-  },
-});
-/**
- * |true| if the error was raised because some invalid argument was passed,
- * |false| otherwise.
- */
-Object.defineProperty(OSError.prototype, "becauseInvalidArgument", {
-  get: function becauseInvalidArgument() {
-    return this.unixErrno == Const.EINVAL;
-  },
-});
-
-/**
- * Serialize an instance of OSError to something that can be
- * transmitted across threads (not necessarily a string).
- */
-OSError.toMsg = function toMsg(error) {
-  return {
-    exn: "OS.File.Error",
-    fileName: error.moduleName,
-    lineNumber: error.lineNumber,
-    stack: error.moduleStack,
-    operation: error.operation,
-    unixErrno: error.unixErrno,
-    path: error.path,
-  };
-};
-
-/**
- * Deserialize a message back to an instance of OSError
- */
-OSError.fromMsg = function fromMsg(msg) {
-  let error = new OSError(msg.operation, msg.unixErrno, msg.path);
-  error.stack = msg.stack;
-  error.fileName = msg.fileName;
-  error.lineNumber = msg.lineNumber;
-  return error;
-};
-exports.Error = OSError;
-
-/**
- * Code shared by implementations of File.Info on Unix
- *
- * @constructor
- */
-var AbstractInfo = function AbstractInfo(
-  path,
-  isDir,
-  isSymLink,
-  size,
-  lastAccessDate,
-  lastModificationDate,
-  unixLastStatusChangeDate,
-  unixOwner,
-  unixGroup,
-  unixMode
-) {
-  this._path = path;
-  this._isDir = isDir;
-  this._isSymlLink = isSymLink;
-  this._size = size;
-  this._lastAccessDate = lastAccessDate;
-  this._lastModificationDate = lastModificationDate;
-  this._unixLastStatusChangeDate = unixLastStatusChangeDate;
-  this._unixOwner = unixOwner;
-  this._unixGroup = unixGroup;
-  this._unixMode = unixMode;
-};
-
-AbstractInfo.prototype = {
-  /**
-   * The path of the file, used for error-reporting.
-   *
-   * @type {string}
-   */
-  get path() {
-    return this._path;
-  },
-  /**
-   * |true| if this file is a directory, |false| otherwise
-   */
-  get isDir() {
-    return this._isDir;
-  },
-  /**
-   * |true| if this file is a symbolink link, |false| otherwise
-   */
-  get isSymLink() {
-    return this._isSymlLink;
-  },
-  /**
-   * The size of the file, in bytes.
-   *
-   * Note that the result may be |NaN| if the size of the file cannot be
-   * represented in JavaScript.
-   *
-   * @type {number}
-   */
-  get size() {
-    return this._size;
-  },
-  /**
-   * The date of last access to this file.
-   *
-   * Note that the definition of last access may depend on the
-   * underlying operating system and file system.
-   *
-   * @type {Date}
-   */
-  get lastAccessDate() {
-    return this._lastAccessDate;
-  },
-  /**
-   * Return the date of last modification of this file.
-   */
-  get lastModificationDate() {
-    return this._lastModificationDate;
-  },
-  /**
-   * Return the date at which the status of this file was last modified
-   * (this is the date of the latest write/renaming/mode change/...
-   * of the file)
-   */
-  get unixLastStatusChangeDate() {
-    return this._unixLastStatusChangeDate;
-  },
-  /*
-   * Return the Unix owner of this file
-   */
-  get unixOwner() {
-    return this._unixOwner;
-  },
-  /*
-   * Return the Unix group of this file
-   */
-  get unixGroup() {
-    return this._unixGroup;
-  },
-  /*
-   * Return the Unix group of this file
-   */
-  get unixMode() {
-    return this._unixMode;
-  },
-};
-exports.AbstractInfo = AbstractInfo;
-
-/**
- * Code shared by implementations of File.DirectoryIterator.Entry on Unix
- *
- * @constructor
- */
-var AbstractEntry = function AbstractEntry(isDir, isSymLink, name, path) {
-  this._isDir = isDir;
-  this._isSymlLink = isSymLink;
-  this._name = name;
-  this._path = path;
-};
-
-AbstractEntry.prototype = {
-  /**
-   * |true| if the entry is a directory, |false| otherwise
-   */
-  get isDir() {
-    return this._isDir;
-  },
-  /**
-   * |true| if the entry is a directory, |false| otherwise
-   */
-  get isSymLink() {
-    return this._isSymlLink;
-  },
-  /**
-   * The name of the entry
-   * @type {string}
-   */
-  get name() {
-    return this._name;
-  },
-  /**
-   * The full path to the entry
-   */
-  get path() {
-    return this._path;
-  },
-};
-exports.AbstractEntry = AbstractEntry;
-
-// Special constants that need to be defined on all platforms
-
-exports.POS_START = Const.SEEK_SET;
-exports.POS_CURRENT = Const.SEEK_CUR;
-exports.POS_END = Const.SEEK_END;
-
-// Special types that need to be defined for communication
-// between threads
-var Type = Object.create(SharedAll.Type);
-exports.Type = Type;
-
-/**
- * Native paths
- *
- * Under Unix, expressed as C strings
- */
-Type.path = Type.cstring.withName("[in] path");
-Type.out_path = Type.out_cstring.withName("[out] path");
-
-// Special constructors that need to be defined on all threads
-OSError.closed = function closed(operation, path) {
-  return new OSError(operation, Const.EBADF, path);
-};
-
-OSError.exists = function exists(operation, path) {
-  return new OSError(operation, Const.EEXIST, path);
-};
-
-OSError.noSuchFile = function noSuchFile(operation, path) {
-  return new OSError(operation, Const.ENOENT, path);
-};
-
-OSError.invalidArgument = function invalidArgument(operation) {
-  return new OSError(operation, Const.EINVAL);
-};
-
-var EXPORTED_SYMBOLS = [
-  "declareFFI",
-  "libc",
-  "Error",
-  "AbstractInfo",
-  "AbstractEntry",
-  "Type",
-  "POS_START",
-  "POS_CURRENT",
-  "POS_END",
-];
-
-// ////////// Boilerplate
-if (typeof Components != "undefined") {
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.EXPORTED_SYMBOLS = EXPORTED_SYMBOLS;
-  for (let symbol of EXPORTED_SYMBOLS) {
-    // eslint-disable-next-line mozilla/reject-global-this
-    this[symbol] = exports[symbol];
-  }
-}
deleted file mode 100644
--- a/toolkit/components/osfile/modules/osfile_unix_back.js
+++ /dev/null
@@ -1,1051 +0,0 @@
-/* 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/. */
-
-/* eslint-env mozilla/chrome-worker, node */
-/* global OS */
-
-// eslint-disable-next-line no-lone-blocks
-{
-  if (typeof Components != "undefined") {
-    // We do not wish osfile_unix_back.js to be used directly as a main thread
-    // module yet. When time comes, it will be loaded by a combination of
-    // a main thread front-end/worker thread implementation that makes sure
-    // that we are not executing synchronous IO code in the main thread.
-
-    throw new Error(
-      "osfile_unix_back.js cannot be used from the main thread yet"
-    );
-  }
-  (function(exports) {
-    "use strict";
-    if (exports.OS && exports.OS.Unix && exports.OS.Unix.File) {
-      return; // Avoid double initialization
-    }
-
-    let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
-    let SysAll = require("resource://gre/modules/osfile/osfile_unix_allthreads.jsm");
-    SharedAll.LOG.bind(SharedAll, "Unix", "back");
-    let libc = SysAll.libc;
-    let Const = SharedAll.Constants.libc;
-
-    /**
-     * Initialize the Unix module.
-     *
-     * @param {function=} declareFFI
-     */
-    // FIXME: Both |init| and |aDeclareFFI| are deprecated, we should remove them
-    let init = function init(aDeclareFFI) {
-      if (aDeclareFFI) {
-        aDeclareFFI.bind(null, libc);
-      } else {
-        SysAll.declareFFI;
-      }
-      SharedAll.declareLazyFFI;
-
-      // Initialize types that require additional OS-specific
-      // support - either finalization or matching against
-      // OS-specific constants.
-      let Type = Object.create(SysAll.Type);
-      let SysFile = (exports.OS.Unix.File = { Type });
-
-      /**
-       * A file descriptor.
-       */
-      Type.fd = Type.int.withName("fd");
-      Type.fd.importFromC = function importFromC(fd_int) {
-        return ctypes.CDataFinalizer(fd_int, SysFile._close);
-      };
-
-      /**
-       * A C integer holding -1 in case of error or a file descriptor
-       * in case of success.
-       */
-      Type.negativeone_or_fd = Type.fd.withName("negativeone_or_fd");
-      Type.negativeone_or_fd.importFromC = function importFromC(fd_int) {
-        if (fd_int == -1) {
-          return -1;
-        }
-        return ctypes.CDataFinalizer(fd_int, SysFile._close);
-      };
-
-      /**
-       * A C integer holding -1 in case of error or a meaningless value
-       * in case of success.
-       */
-      Type.negativeone_or_nothing = Type.int.withName("negativeone_or_nothing");
-
-      /**
-       * A C integer holding -1 in case of error or a positive integer
-       * in case of success.
-       */
-      Type.negativeone_or_ssize_t = Type.ssize_t.withName(
-        "negativeone_or_ssize_t"
-      );
-
-      /**
-       * Various libc integer types
-       */
-      Type.mode_t = Type.intn_t(Const.OSFILE_SIZEOF_MODE_T).withName("mode_t");
-      Type.uid_t = Type.intn_t(Const.OSFILE_SIZEOF_UID_T).withName("uid_t");
-      Type.gid_t = Type.intn_t(Const.OSFILE_SIZEOF_GID_T).withName("gid_t");
-
-      /**
-       * Type |time_t|
-       */
-      Type.time_t = Type.intn_t(Const.OSFILE_SIZEOF_TIME_T).withName("time_t");
-
-      // Structure |dirent|
-      // Building this type is rather complicated, as its layout varies between
-      // variants of Unix. For this reason, we rely on a number of constants
-      // (computed in C from the C data structures) that give us the layout.
-      // The structure we compute looks like
-      //  { int8_t[...] before_d_type; // ignored content
-      //    int8_t      d_type       ;
-      //    int8_t[...] before_d_name; // ignored content
-      //    char[...]   d_name;
-      //    };
-      {
-        let d_name_extra_size = 0;
-        if (Const.OSFILE_SIZEOF_DIRENT_D_NAME < 8) {
-          // d_name is defined like "char d_name[1];" on some platforms
-          // (e.g. Solaris), we need to give it more size for our structure.
-          d_name_extra_size = 256;
-        }
-
-        let dirent = new SharedAll.HollowStructure(
-          "dirent",
-          Const.OSFILE_SIZEOF_DIRENT + d_name_extra_size
-        );
-        if (Const.OSFILE_OFFSETOF_DIRENT_D_TYPE != undefined) {
-          // |dirent| doesn't have d_type on some platforms (e.g. Solaris).
-          dirent.add_field_at(
-            Const.OSFILE_OFFSETOF_DIRENT_D_TYPE,
-            "d_type",
-            ctypes.uint8_t
-          );
-        }
-        dirent.add_field_at(
-          Const.OSFILE_OFFSETOF_DIRENT_D_NAME,
-          "d_name",
-          ctypes.ArrayType(
-            ctypes.char,
-            Const.OSFILE_SIZEOF_DIRENT_D_NAME + d_name_extra_size
-          )
-        );
-
-        // We now have built |dirent|.
-        Type.dirent = dirent.getType();
-      }
-      Type.null_or_dirent_ptr = new SharedAll.Type(
-        "null_of_dirent",
-        Type.dirent.out_ptr.implementation
-      );
-
-      // Structure |stat|
-      // Same technique
-      {
-        let stat = new SharedAll.HollowStructure(
-          "stat",
-          Const.OSFILE_SIZEOF_STAT
-        );
-        stat.add_field_at(
-          Const.OSFILE_OFFSETOF_STAT_ST_MODE,
-          "st_mode",
-          Type.mode_t.implementation
-        );
-        stat.add_field_at(
-          Const.OSFILE_OFFSETOF_STAT_ST_UID,
-          "st_uid",
-          Type.uid_t.implementation
-        );
-        stat.add_field_at(
-          Const.OSFILE_OFFSETOF_STAT_ST_GID,
-          "st_gid",
-          Type.gid_t.implementation
-        );
-
-        // Here, things get complicated with different data structures.
-        // Some platforms have |time_t st_atime| and some platforms have
-        // |timespec st_atimespec|. However, since |timespec| starts with
-        // a |time_t|, followed by nanoseconds, we just cheat and pretend
-        // that everybody has |time_t st_atime|, possibly followed by padding
-        stat.add_field_at(
-          Const.OSFILE_OFFSETOF_STAT_ST_ATIME,
-          "st_atime",
-          Type.time_t.implementation
-        );
-        stat.add_field_at(
-          Const.OSFILE_OFFSETOF_STAT_ST_MTIME,
-          "st_mtime",
-          Type.time_t.implementation
-        );
-        stat.add_field_at(
-          Const.OSFILE_OFFSETOF_STAT_ST_CTIME,
-          "st_ctime",
-          Type.time_t.implementation
-        );
-
-        stat.add_field_at(
-          Const.OSFILE_OFFSETOF_STAT_ST_SIZE,
-          "st_size",
-          Type.off_t.implementation
-        );
-        Type.stat = stat.getType();
-      }
-
-      // Structure |DIR|
-      if ("OSFILE_SIZEOF_DIR" in Const) {
-        // On platforms for which we need to access the fields of DIR
-        // directly (e.g. because certain functions are implemented
-        // as macros), we need to define DIR as a hollow structure.
-        let DIR = new SharedAll.HollowStructure("DIR", Const.OSFILE_SIZEOF_DIR);
-
-        DIR.add_field_at(
-          Const.OSFILE_OFFSETOF_DIR_DD_FD,
-          "dd_fd",
-          Type.fd.implementation
-        );
-
-        Type.DIR = DIR.getType();
-      } else {
-        // On other platforms, we keep DIR as a blackbox
-        Type.DIR = new SharedAll.Type("DIR", ctypes.StructType("DIR"));
-      }
-
-      Type.null_or_DIR_ptr = Type.DIR.out_ptr.withName("null_or_DIR*");
-      Type.null_or_DIR_ptr.importFromC = function importFromC(dir) {
-        if (dir == null || dir.isNull()) {
-          return null;
-        }
-        return ctypes.CDataFinalizer(dir, SysFile._close_dir);
-      };
-
-      // Structure |timeval|
-      {
-        let timeval = new SharedAll.HollowStructure(
-          "timeval",
-          Const.OSFILE_SIZEOF_TIMEVAL
-        );
-        timeval.add_field_at(
-          Const.OSFILE_OFFSETOF_TIMEVAL_TV_SEC,
-          "tv_sec",
-          Type.long.implementation
-        );
-        timeval.add_field_at(
-          Const.OSFILE_OFFSETOF_TIMEVAL_TV_USEC,
-          "tv_usec",
-          Type.long.implementation
-        );
-        Type.timeval = timeval.getType();
-        Type.timevals = new SharedAll.Type(
-          "two timevals",
-          ctypes.ArrayType(Type.timeval.implementation, 2)
-        );
-      }
-
-      // Types fsblkcnt_t and fsfilcnt_t, used by structure |statvfs|
-      Type.fsblkcnt_t = Type.uintn_t(Const.OSFILE_SIZEOF_FSBLKCNT_T).withName(
-        "fsblkcnt_t"
-      );
-      // There is no guarantee of the size or order of members in sys-header structs
-      // It mostly is "unsigned long", but can be "unsigned int" as well.
-      // So it has its own "type".
-      // NOTE: This is still only partially correct, as signedness is also not guaranteed,
-      //       so assuming an unsigned int might still be wrong here.
-      //       But unsigned seems to have worked all those years, even though its signed
-      //       on various platforms.
-      Type.statvfs_f_frsize = Type.uintn_t(
-        Const.OSFILE_SIZEOF_STATVFS_F_FRSIZE
-      ).withName("statvfs_f_rsize");
-
-      // Structure |statvfs|
-      // Use an hollow structure
-      {
-        let statvfs = new SharedAll.HollowStructure(
-          "statvfs",
-          Const.OSFILE_SIZEOF_STATVFS
-        );
-
-        statvfs.add_field_at(
-          Const.OSFILE_OFFSETOF_STATVFS_F_FRSIZE,
-          "f_frsize",
-          Type.statvfs_f_frsize.implementation
-        );
-        statvfs.add_field_at(
-          Const.OSFILE_OFFSETOF_STATVFS_F_BAVAIL,
-          "f_bavail",
-          Type.fsblkcnt_t.implementation
-        );
-
-        Type.statvfs = statvfs.getType();
-      }
-
-      // Declare libc functions as functions of |OS.Unix.File|
-
-      // Finalizer-related functions
-      libc.declareLazy(
-        SysFile,
-        "_close",
-        "close",
-        ctypes.default_abi,
-        /* return */ ctypes.int,
-        ctypes.int
-      );
-
-      SysFile.close = function close(fd) {
-        // Detach the finalizer and call |_close|.
-        return fd.dispose();
-      };
-
-      libc.declareLazy(
-        SysFile,
-        "_close_dir",
-        "closedir",
-        ctypes.default_abi,
-        /* return */ ctypes.int,
-        Type.DIR.in_ptr.implementation
-      );
-
-      SysFile.closedir = function closedir(fd) {
-        // Detach the finalizer and call |_close_dir|.
-        return fd.dispose();
-      };
-
-      {
-        // Symbol free() is special.
-        // We override the definition of free() on several platforms.
-        let default_lib = new SharedAll.Library("default_lib", "a.out");
-
-        // On platforms for which we override free(), nspr defines
-        // a special library name "a.out" that will resolve to the
-        // correct implementation free().
-        // If it turns out we don't have an a.out library or a.out
-        // doesn't contain free, use the ordinary libc free.
-
-        default_lib.declareLazyWithFallback(
-          libc,
-          SysFile,
-          "free",
-          "free",
-          ctypes.default_abi,
-          /* return*/ ctypes.void_t,
-          ctypes.voidptr_t
-        );
-      }
-
-      // Other functions
-      libc.declareLazyFFI(
-        SysFile,
-        "access",
-        "access",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.path,
-        Type.int
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "chmod",
-        "chmod",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.path,
-        Type.mode_t
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "chown",
-        "chown",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.path,
-        Type.uid_t,
-        Type.gid_t
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "copyfile",
-        "copyfile",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        /* source*/ Type.path,
-        Type.path,
-        Type.void_t.in_ptr,
-        Type.uint32_t
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "dup",
-        "dup",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_fd,
-        Type.fd
-      );
-
-      if ("OSFILE_SIZEOF_DIR" in Const) {
-        // On platforms for which |dirfd| is a macro
-        SysFile.dirfd = function dirfd(DIRp) {
-          return Type.DIR.in_ptr.implementation(DIRp).contents.dd_fd;
-        };
-      } else {
-        // On platforms for which |dirfd| is a function
-        libc.declareLazyFFI(
-          SysFile,
-          "dirfd",
-          "dirfd",
-          ctypes.default_abi,
-          /* return*/ Type.negativeone_or_fd,
-          Type.DIR.in_ptr
-        );
-      }
-
-      libc.declareLazyFFI(
-        SysFile,
-        "chdir",
-        "chdir",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.path
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "fchdir",
-        "fchdir",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.fd
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "fchmod",
-        "fchmod",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.fd,
-        Type.mode_t
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "fchown",
-        "fchown",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.fd,
-        Type.uid_t,
-        Type.gid_t
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "fsync",
-        "fsync",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.fd
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "getcwd",
-        "getcwd",
-        ctypes.default_abi,
-        /* return*/ Type.out_path,
-        Type.out_path,
-        Type.size_t
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "getwd",
-        "getwd",
-        ctypes.default_abi,
-        /* return*/ Type.out_path,
-        Type.out_path
-      );
-
-      // Two variants of |getwd| which allocate the memory
-      // dynamically.
-
-      // Linux/Android version
-      libc.declareLazyFFI(
-        SysFile,
-        "get_current_dir_name",
-        "get_current_dir_name",
-        ctypes.default_abi,
-        /* return*/ Type.out_path.releaseWithLazy(() => SysFile.free)
-      );
-
-      // MacOS/BSD version (will return NULL on Linux/Android)
-      libc.declareLazyFFI(
-        SysFile,
-        "getwd_auto",
-        "getwd",
-        ctypes.default_abi,
-        /* return*/ Type.out_path.releaseWithLazy(() => SysFile.free),
-        Type.void_t.out_ptr
-      );
-
-      if (OS.Constants.Sys.Name == "Darwin") {
-        // At the time of writing we only need this on MacOS. If we generalize
-        // this, be sure to do so with the other xattr functions also.
-        libc.declareLazyFFI(
-          SysFile,
-          "getxattr",
-          "getxattr",
-          ctypes.default_abi,
-          /* return*/ Type.int,
-          Type.path,
-          Type.cstring,
-          Type.void_t.out_ptr,
-          Type.size_t,
-          Type.uint32_t,
-          Type.int
-        );
-      }
-
-      libc.declareLazyFFI(
-        SysFile,
-        "fdatasync",
-        "fdatasync",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.fd
-      ); // Note: MacOS/BSD-specific
-
-      libc.declareLazyFFI(
-        SysFile,
-        "ftruncate",
-        "ftruncate",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.fd,
-        /* length*/ Type.off_t
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "lchown",
-        "lchown",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.path,
-        Type.uid_t,
-        Type.gid_t
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "link",
-        "link",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        /* source*/ Type.path,
-        Type.path
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "lseek",
-        "lseek",
-        ctypes.default_abi,
-        /* return*/ Type.off_t,
-        Type.fd,
-        /* offset*/ Type.off_t,
-        /* whence*/ Type.int
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "mkdir",
-        "mkdir",
-        ctypes.default_abi,
-        /* return*/ Type.int,
-        /* path*/ Type.path,
-        /* mode*/ Type.int
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "mkstemp",
-        "mkstemp",
-        ctypes.default_abi,
-        Type.fd,
-        /* template*/ Type.out_path
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "open",
-        "open",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_fd,
-        Type.path,
-        /* oflags*/ Type.int,
-        "..."
-      );
-
-      if (OS.Constants.Sys.Name == "NetBSD") {
-        libc.declareLazyFFI(
-          SysFile,
-          "opendir",
-          "__opendir30",
-          ctypes.default_abi,
-          /* return*/ Type.null_or_DIR_ptr,
-          Type.path
-        );
-      } else {
-        libc.declareLazyFFI(
-          SysFile,
-          "opendir",
-          "opendir",
-          ctypes.default_abi,
-          /* return*/ Type.null_or_DIR_ptr,
-          Type.path
-        );
-      }
-
-      libc.declareLazyFFI(
-        SysFile,
-        "pread",
-        "pread",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_ssize_t,
-        Type.fd,
-        Type.void_t.out_ptr,
-        /* nbytes*/ Type.size_t,
-        /* offset*/ Type.off_t
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "pwrite",
-        "pwrite",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_ssize_t,
-        Type.fd,
-        Type.void_t.in_ptr,
-        /* nbytes*/ Type.size_t,
-        /* offset*/ Type.off_t
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "read",
-        "read",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_ssize_t,
-        Type.fd,
-        Type.void_t.out_ptr,
-        /* nbytes*/ Type.size_t
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "posix_fadvise",
-        "posix_fadvise",
-        ctypes.default_abi,
-        /* return*/ Type.int,
-        Type.fd,
-        /* offset*/ Type.off_t,
-        Type.off_t,
-        /* advise*/ Type.int
-      );
-
-      if (Const._DARWIN_INODE64_SYMBOLS) {
-        // Special case for MacOS X 10.5+
-        // Symbol name "readdir" still exists but is used for a
-        // deprecated function that does not match the
-        // constants of |Const|.
-        libc.declareLazyFFI(
-          SysFile,
-          "readdir",
-          "readdir$INODE64",
-          ctypes.default_abi,
-          /* return*/ Type.null_or_dirent_ptr,
-          Type.DIR.in_ptr
-        ); // For MacOS X
-      } else if (OS.Constants.Sys.Name == "NetBSD") {
-        libc.declareLazyFFI(
-          SysFile,
-          "readdir",
-          "__readdir30",
-          ctypes.default_abi,
-          /* return*/ Type.null_or_dirent_ptr,
-          Type.DIR.in_ptr
-        ); // Other Unices
-      } else {
-        libc.declareLazyFFI(
-          SysFile,
-          "readdir",
-          "readdir",
-          ctypes.default_abi,
-          /* return*/ Type.null_or_dirent_ptr,
-          Type.DIR.in_ptr
-        ); // Other Unices
-      }
-
-      if (OS.Constants.Sys.Name == "Darwin") {
-        // At the time of writing we only need this on MacOS. If we generalize
-        // this, be sure to do so with the other xattr functions also.
-        libc.declareLazyFFI(
-          SysFile,
-          "removexattr",
-          "removexattr",
-          ctypes.default_abi,
-          /* return*/ Type.negativeone_or_nothing,
-          Type.path,
-          Type.cstring,
-          Type.int
-        );
-      }
-
-      libc.declareLazyFFI(
-        SysFile,
-        "rename",
-        "rename",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.path,
-        Type.path
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "rmdir",
-        "rmdir",
-        ctypes.default_abi,
-        /* return*/ Type.int,
-        Type.path
-      );
-
-      if (OS.Constants.Sys.Name == "Darwin") {
-        // At the time of writing we only need this on MacOS. If we generalize
-        // this, be sure to do so with the other xattr functions also.
-        libc.declareLazyFFI(
-          SysFile,
-          "setxattr",
-          "setxattr",
-          ctypes.default_abi,
-          /* return*/ Type.negativeone_or_nothing,
-          Type.path,
-          Type.cstring,
-          Type.void_t.in_ptr,
-          Type.size_t,
-          Type.uint32_t,
-          Type.int
-        );
-      }
-
-      libc.declareLazyFFI(
-        SysFile,
-        "splice",
-        "splice",
-        ctypes.default_abi,
-        /* return*/ Type.long,
-        Type.fd,
-        /* off_in*/ Type.off_t.in_ptr,
-        /* fd_out*/ Type.fd,
-        /* off_out*/ Type.off_t.in_ptr,
-        Type.size_t,
-        Type.unsigned_int
-      ); // Linux/Android-specific
-
-      libc.declareLazyFFI(
-        SysFile,
-        "statfs",
-        "statfs",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.path,
-        Type.statvfs.out_ptr
-      ); // Android,B2G
-
-      libc.declareLazyFFI(
-        SysFile,
-        "statvfs",
-        "statvfs",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.path,
-        Type.statvfs.out_ptr
-      ); // Other platforms
-
-      libc.declareLazyFFI(
-        SysFile,
-        "symlink",
-        "symlink",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        /* source*/ Type.path,
-        Type.path
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "truncate",
-        "truncate",
-        ctypes.default_abi,
-        /* return*/ Type.negativeone_or_nothing,
-        Type.path,
-        /* length*/ Type.off_t
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "unlink",
-        "unlink",
-        ctypes.default_abi,
-        /* return */ Type.negativeone_or_nothing,
-        /* path */ Type.path
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "write",
-        "write",
-        ctypes.default_abi,
-        /* return */ Type.negativeone_or_ssize_t,
-        /* fd */ Type.fd,
-        /* buf */ Type.void_t.in_ptr,
-        /* nbytes */ Type.size_t
-      );
-
-      // Weird cases that require special treatment
-
-      // OSes use a variety of hacks to differentiate between
-      // 32-bits and 64-bits versions of |stat|, |lstat|, |fstat|.
-      if (Const._DARWIN_INODE64_SYMBOLS) {
-        // MacOS X 64-bits
-        libc.declareLazyFFI(
-          SysFile,
-          "stat",
-          "stat$INODE64",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* path */ Type.path,
-          /* buf */ Type.stat.out_ptr
-        );
-        libc.declareLazyFFI(
-          SysFile,
-          "lstat",
-          "lstat$INODE64",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* path */ Type.path,
-          /* buf */ Type.stat.out_ptr
-        );
-        libc.declareLazyFFI(
-          SysFile,
-          "fstat",
-          "fstat$INODE64",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* path */ Type.fd,
-          /* buf */ Type.stat.out_ptr
-        );
-      } else if (Const._STAT_VER != undefined) {
-        const ver = Const._STAT_VER;
-        let xstat_name, lxstat_name, fxstat_name;
-        if (OS.Constants.Sys.Name == "SunOS") {
-          // Solaris
-          xstat_name = "_xstat";
-          lxstat_name = "_lxstat";
-          fxstat_name = "_fxstat";
-        } else {
-          // Linux, all widths
-          xstat_name = "__xstat";
-          lxstat_name = "__lxstat";
-          fxstat_name = "__fxstat";
-        }
-
-        let Stat = {};
-        libc.declareLazyFFI(
-          Stat,
-          "xstat",
-          xstat_name,
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* _stat_ver */ Type.int,
-          /* path */ Type.path,
-          /* buf */ Type.stat.out_ptr
-        );
-        libc.declareLazyFFI(
-          Stat,
-          "lxstat",
-          lxstat_name,
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* _stat_ver */ Type.int,
-          /* path */ Type.path,
-          /* buf */ Type.stat.out_ptr
-        );
-        libc.declareLazyFFI(
-          Stat,
-          "fxstat",
-          fxstat_name,
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* _stat_ver */ Type.int,
-          /* fd */ Type.fd,
-          /* buf */ Type.stat.out_ptr
-        );
-
-        SysFile.stat = function stat(path, buf) {
-          return Stat.xstat(ver, path, buf);
-        };
-
-        SysFile.lstat = function lstat(path, buf) {
-          return Stat.lxstat(ver, path, buf);
-        };
-
-        SysFile.fstat = function fstat(fd, buf) {
-          return Stat.fxstat(ver, fd, buf);
-        };
-      } else if (OS.Constants.Sys.Name == "NetBSD") {
-        // NetBSD 5.0 and newer
-        libc.declareLazyFFI(
-          SysFile,
-          "stat",
-          "__stat50",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* path */ Type.path,
-          /* buf */ Type.stat.out_ptr
-        );
-        libc.declareLazyFFI(
-          SysFile,
-          "lstat",
-          "__lstat50",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* path */ Type.path,
-          /* buf */ Type.stat.out_ptr
-        );
-        libc.declareLazyFFI(
-          SysFile,
-          "fstat",
-          "__fstat50",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* fd */ Type.fd,
-          /* buf */ Type.stat.out_ptr
-        );
-      } else {
-        // Mac OS X 32-bits, other Unix
-        libc.declareLazyFFI(
-          SysFile,
-          "stat",
-          "stat",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* path */ Type.path,
-          /* buf */ Type.stat.out_ptr
-        );
-        libc.declareLazyFFI(
-          SysFile,
-          "lstat",
-          "lstat",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* path */ Type.path,
-          /* buf */ Type.stat.out_ptr
-        );
-        libc.declareLazyFFI(
-          SysFile,
-          "fstat",
-          "fstat",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* fd */ Type.fd,
-          /* buf */ Type.stat.out_ptr
-        );
-      }
-
-      // We cannot make a C array of CDataFinalizer, so
-      // pipe cannot be directly defined as a C function.
-
-      let Pipe = {};
-      libc.declareLazyFFI(
-        Pipe,
-        "_pipe",
-        "pipe",
-        ctypes.default_abi,
-        /* return */ Type.negativeone_or_nothing,
-        /* fds */ new SharedAll.Type(
-          "two file descriptors",
-          ctypes.ArrayType(ctypes.int, 2)
-        )
-      );
-
-      // A shared per-thread buffer used to communicate with |pipe|
-      let _pipebuf = new (ctypes.ArrayType(ctypes.int, 2))();
-
-      SysFile.pipe = function pipe(array) {
-        let result = Pipe._pipe(_pipebuf);
-        if (result == -1) {
-          return result;
-        }
-        array[0] = ctypes.CDataFinalizer(_pipebuf[0], SysFile._close);
-        array[1] = ctypes.CDataFinalizer(_pipebuf[1], SysFile._close);
-        return result;
-      };
-
-      if (OS.Constants.Sys.Name == "NetBSD") {
-        libc.declareLazyFFI(
-          SysFile,
-          "utimes",
-          "__utimes50",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* path */ Type.path,
-          /* timeval[2] */ Type.timevals.out_ptr
-        );
-      } else {
-        libc.declareLazyFFI(
-          SysFile,
-          "utimes",
-          "utimes",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* path */ Type.path,
-          /* timeval[2] */ Type.timevals.out_ptr
-        );
-      }
-      if (OS.Constants.Sys.Name == "NetBSD") {
-        libc.declareLazyFFI(
-          SysFile,
-          "futimes",
-          "__futimes50",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* fd */ Type.fd,
-          /* timeval[2] */ Type.timevals.out_ptr
-        );
-      } else {
-        libc.declareLazyFFI(
-          SysFile,
-          "futimes",
-          "futimes",
-          ctypes.default_abi,
-          /* return */ Type.negativeone_or_nothing,
-          /* fd */ Type.fd,
-          /* timeval[2] */ Type.timevals.out_ptr
-        );
-      }
-    };
-
-    exports.OS.Unix = {
-      File: {
-        _init: init,
-      },
-    };
-  })(this);
-}
deleted file mode 100644
--- a/toolkit/components/osfile/modules/osfile_unix_front.js
+++ /dev/null
@@ -1,1243 +0,0 @@
-/* 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/. */
-
-/**
- * Synchronous front-end for the JavaScript OS.File library.
- * Unix implementation.
- *
- * This front-end is meant to be imported by a worker thread.
- */
-
-/* eslint-env mozilla/chrome-worker, node */
-/* global OS */
-
-// eslint-disable-next-line no-lone-blocks
-{
-  if (typeof Components != "undefined") {
-    // We do not wish osfile_unix_front.js to be used directly as a main thread
-    // module yet.
-
-    throw new Error(
-      "osfile_unix_front.js cannot be used from the main thread yet"
-    );
-  }
-  (function(exports) {
-    "use strict";
-
-    // exports.OS.Unix is created by osfile_unix_back.js
-    if (exports.OS && exports.OS.File) {
-      return; // Avoid double-initialization
-    }
-
-    let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
-    let Path = require("resource://gre/modules/osfile/ospath.jsm");
-    let SysAll = require("resource://gre/modules/osfile/osfile_unix_allthreads.jsm");
-    exports.OS.Unix.File._init();
-    SharedAll.LOG.bind(SharedAll, "Unix front-end");
-    let Const = SharedAll.Constants.libc;
-    let UnixFile = exports.OS.Unix.File;
-    let Type = UnixFile.Type;
-
-    /**
-     * Representation of a file.
-     *
-     * You generally do not need to call this constructor yourself. Rather,
-     * to open a file, use function |OS.File.open|.
-     *
-     * @param fd A OS-specific file descriptor.
-     * @param {string} path File path of the file handle, used for error-reporting.
-     * @constructor
-     */
-    let File = function File(fd, path) {
-      exports.OS.Shared.AbstractFile.call(this, fd, path);
-      this._closeResult = null;
-    };
-    File.prototype = Object.create(exports.OS.Shared.AbstractFile.prototype);
-
-    /**
-     * Close the file.
-     *
-     * This method has no effect if the file is already closed. However,
-     * if the first call to |close| has thrown an error, further calls
-     * will throw the same error.
-     *
-     * @throws File.Error If closing the file revealed an error that could
-     * not be reported earlier.
-     */
-    File.prototype.close = function close() {
-      if (this._fd) {
-        let fd = this._fd;
-        this._fd = null;
-        // Call |close(fd)|, detach finalizer if any
-        // (|fd| may not be a CDataFinalizer if it has been
-        // instantiated from a controller thread).
-        let result = UnixFile._close(fd);
-        if (typeof fd == "object" && "forget" in fd) {
-          fd.forget();
-        }
-        if (result == -1) {
-          this._closeResult = new File.Error("close", ctypes.errno, this._path);
-        }
-      }
-      if (this._closeResult) {
-        throw this._closeResult;
-      }
-    };
-
-    /**
-     * Read some bytes from a file.
-     *
-     * @param {C pointer} buffer A buffer for holding the data
-     * once it is read.
-     * @param {number} nbytes The number of bytes to read. It must not
-     * exceed the size of |buffer| in bytes but it may exceed the number
-     * of bytes unread in the file.
-     * @param {*=} options Additional options for reading. Ignored in
-     * this implementation.
-     *
-     * @return {number} The number of bytes effectively read. If zero,
-     * the end of the file has been reached.
-     * @throws {OS.File.Error} In case of I/O error.
-     */
-    File.prototype._read = function _read(buffer, nbytes, options = {}) {
-      // Populate the page cache with data from a file so the subsequent reads
-      // from that file will not block on disk I/O.
-      if (
-        typeof UnixFile.posix_fadvise === "function" &&
-        (options.sequential || !("sequential" in options))
-      ) {
-        UnixFile.posix_fadvise(
-          this.fd,
-          0,
-          nbytes,
-          OS.Constants.libc.POSIX_FADV_SEQUENTIAL
-        );
-      }
-      return throw_on_negative(
-        "read",
-        UnixFile.read(this.fd, buffer, nbytes),
-        this._path
-      );
-    };
-
-    /**
-     * Write some bytes to a file.
-     *
-     * @param {Typed array} buffer A buffer holding the data that must be
-     * written.
-     * @param {number} nbytes The number of bytes to write. It must not
-     * exceed the size of |buffer| in bytes.
-     * @param {*=} options Additional options for writing. Ignored in
-     * this implementation.
-     *
-     * @return {number} The number of bytes effectively written.
-     * @throws {OS.File.Error} In case of I/O error.
-     */
-    File.prototype._write = function _write(buffer, nbytes, options = {}) {
-      return throw_on_negative(
-        "write",
-        UnixFile.write(this.fd, buffer, nbytes),
-        this._path
-      );
-    };
-
-    /**
-     * Return the current position in the file.
-     */
-    File.prototype.getPosition = function getPosition(pos) {
-      return this.setPosition(0, File.POS_CURRENT);
-    };
-
-    /**
-     * Change the current position in the file.
-     *
-     * @param {number} pos The new position. Whether this position
-     * is considered from the current position, from the start of
-     * the file or from the end of the file is determined by
-     * argument |whence|.  Note that |pos| may exceed the length of
-     * the file.
-     * @param {number=} whence The reference position. If omitted
-     * or |OS.File.POS_START|, |pos| is relative to the start of the
-     * file.  If |OS.File.POS_CURRENT|, |pos| is relative to the
-     * current position in the file. If |OS.File.POS_END|, |pos| is
-     * relative to the end of the file.
-     *
-     * @return The new position in the file.
-     */
-    File.prototype.setPosition = function setPosition(pos, whence) {
-      if (whence === undefined) {
-        whence = Const.SEEK_SET;
-      }
-      return throw_on_negative(
-        "setPosition",
-        UnixFile.lseek(this.fd, pos, whence),
-        this._path
-      );
-    };
-
-    /**
-     * Fetch the information on the file.
-     *
-     * @return File.Info The information on |this| file.
-     */
-    File.prototype.stat = function stat() {
-      throw_on_negative(
-        "stat",
-        UnixFile.fstat(this.fd, gStatDataPtr),
-        this._path
-      );
-      return new File.Info(gStatData, this._path);
-    };
-
-    /**
-     * Set the file's access permissions.
-     *
-     * This operation is likely to fail if applied to a file that was
-     * not created by the currently running program (more precisely,
-     * if it was created by a program running under a different OS-level
-     * user account).  It may also fail, or silently do nothing, if the
-     * filesystem containing the file does not support access permissions.
-     *
-     * @param {*=} options Object specifying the requested permissions:
-     *
-     * - {number} unixMode The POSIX file mode to set on the file.  If omitted,
-     *  the POSIX file mode is reset to the default used by |OS.file.open|.  If
-     *  specified, the permissions will respect the process umask as if they
-     *  had been specified as arguments of |OS.File.open|, unless the
-     *  |unixHonorUmask| parameter tells otherwise.
-     * - {bool} unixHonorUmask If omitted or true, any |unixMode| value is
-     *  modified by the process umask, as |OS.File.open| would have done.  If
-     *  false, the exact value of |unixMode| will be applied.
-     */
-    File.prototype.setPermissions = function setPermissions(options = {}) {
-      throw_on_negative(
-        "setPermissions",
-        UnixFile.fchmod(this.fd, unixMode(options)),
-        this._path
-      );
-    };
-
-    /**
-     * Set the last access and modification date of the file.
-     * The time stamp resolution is 1 second at best, but might be worse
-     * depending on the platform.
-     *
-     * WARNING: This method is not implemented on Android/B2G. On Android/B2G,
-     * you should use File.setDates instead.
-     *
-     * @param {Date,number=} accessDate The last access date. If numeric,
-     * milliseconds since epoch. If omitted or null, then the current date
-     * will be used.
-     * @param {Date,number=} modificationDate The last modification date. If
-     * numeric, milliseconds since epoch. If omitted or null, then the current
-     * date will be used.
-     *
-     * @throws {TypeError} In case of invalid parameters.
-     * @throws {OS.File.Error} In case of I/O error.
-     */
-    if (SharedAll.Constants.Sys.Name != "Android") {
-      File.prototype.setDates = function(accessDate, modificationDate) {
-        let { /* value, */ ptr } = datesToTimevals(
-          accessDate,
-          modificationDate
-        );
-        throw_on_negative(
-          "setDates",
-          UnixFile.futimes(this.fd, ptr),
-          this._path
-        );
-      };
-    }
-
-    /**
-     * Flushes the file's buffers and causes all buffered data
-     * to be written.
-     * Disk flushes are very expensive and therefore should be used carefully,
-     * sparingly and only in scenarios where it is vital that data survives
-     * system crashes. Even though the function will be executed off the
-     * main-thread, it might still affect the overall performance of any
-     * running application.
-     *
-     * @throws {OS.File.Error} In case of I/O error.
-     */
-    File.prototype.flush = function flush() {
-      throw_on_negative("flush", UnixFile.fsync(this.fd), this._path);
-    };
-
-    // The default unix mode for opening (0600)
-    const DEFAULT_UNIX_MODE = 384;
-
-    /**
-     * Open a file
-     *
-     * @param {string} path The path to the file.
-     * @param {*=} mode The opening mode for the file, as
-     * an object that may contain the following fields:
-     *
-     * - {bool} truncate If |true|, the file will be opened
-     *  for writing. If the file does not exist, it will be
-     *  created. If the file exists, its contents will be
-     *  erased. Cannot be specified with |create|.
-     * - {bool} create If |true|, the file will be opened
-     *  for writing. If the file exists, this function fails.
-     *  If the file does not exist, it will be created. Cannot
-     *  be specified with |truncate| or |existing|.
-     * - {bool} existing. If the file does not exist, this function
-     *  fails. Cannot be specified with |create|.
-     * - {bool} read If |true|, the file will be opened for
-     *  reading. The file may also be opened for writing, depending
-     *  on the other fields of |mode|.
-     * - {bool} write If |true|, the file will be opened for
-     *  writing. The file may also be opened for reading, depending
-     *  on the other fields of |mode|.
-     * - {bool} append If |true|, the file will be opened for appending,
-     *  meaning the equivalent of |.setPosition(0, POS_END)| is executed
-     *  before each write. The default is |true|, i.e. opening a file for
-     *  appending. Specify |append: false| to open the file in regular mode.
-     *
-     * If neither |truncate|, |create| or |write| is specified, the file
-     * is opened for reading.
-     *
-     * Note that |false|, |null| or |undefined| flags are simply ignored.
-     *
-     * @param {*=} options Additional options for file opening. This
-     * implementation interprets the following fields:
-     *
-     * - {number} unixFlags If specified, file opening flags, as
-     *  per libc function |open|. Replaces |mode|.
-     * - {number} unixMode If specified, a file creation mode,
-     *  as per libc function |open|. If unspecified, files are
-     *  created with a default mode of 0600 (file is private to the
-     *  user, the user can read and write).
-     *
-     * @return {File} A file object.
-     * @throws {OS.File.Error} If the file could not be opened.
-     */
-    File.open = function Unix_open(path, mode, options = {}) {
-      // We don't need to filter for the umask because "open" does this for us.
-      let omode =
-        options.unixMode !== undefined ? options.unixMode : DEFAULT_UNIX_MODE;
-      let flags;
-      if (options.unixFlags !== undefined) {
-        flags = options.unixFlags;
-      } else {
-        mode = OS.Shared.AbstractFile.normalizeOpenMode(mode);
-        // Handle read/write
-        if (!mode.write) {
-          flags = Const.O_RDONLY;
-        } else if (mode.read) {
-          flags = Const.O_RDWR;
-        } else {
-          flags = Const.O_WRONLY;
-        }
-        // Finally, handle create/existing/trunc
-        if (mode.trunc) {
-          if (mode.existing) {
-            flags |= Const.O_TRUNC;
-          } else {
-            flags |= Const.O_CREAT | Const.O_TRUNC;
-          }
-        } else if (mode.create) {
-          flags |= Const.O_CREAT | Const.O_EXCL;
-        } else if (mode.read && !mode.write) {
-          // flags are sufficient
-        } else if (!mode.existing) {
-          flags |= Const.O_CREAT;
-        }
-        if (mode.append) {
-          flags |= Const.O_APPEND;
-        }
-      }
-      return error_or_file(UnixFile.open(path, flags, ctypes.int(omode)), path);
-    };
-
-    /**
-     * Checks if a file exists
-     *
-     * @param {string} path The path to the file.
-     *
-     * @return {bool} true if the file exists, false otherwise.
-     */
-    File.exists = function Unix_exists(path) {
-      if (UnixFile.access(path, Const.F_OK) == -1) {
-        return false;
-      }
-      return true;
-    };
-
-    /**
-     * Remove an existing file.
-     *
-     * @param {string} path The name of the file.
-     * @param {*=} options Additional options.
-     *   - {bool} ignoreAbsent If |false|, throw an error if the file does
-     *     not exist. |true| by default.
-     *
-     * @throws {OS.File.Error} In case of I/O error.
-     */
-    File.remove = function remove(path, options = {}) {
-      let result = UnixFile.unlink(path);
-      if (result == -1) {
-        if (
-          (!("ignoreAbsent" in options) || options.ignoreAbsent) &&
-          ctypes.errno == Const.ENOENT
-        ) {
-          return;
-        }
-        throw new File.Error("remove", ctypes.errno, path);
-      }
-    };
-
-    /**
-     * Remove an empty directory.
-     *
-     * @param {string} path The name of the directory to remove.
-     * @param {*=} options Additional options.
-     *   - {bool} ignoreAbsent If |false|, throw an error if the directory
-     *     does not exist. |true| by default
-     */
-    File.removeEmptyDir = function removeEmptyDir(path, options = {}) {
-      let result = UnixFile.rmdir(path);
-      if (result == -1) {
-        if (
-          (!("ignoreAbsent" in options) || options.ignoreAbsent) &&
-          ctypes.errno == Const.ENOENT
-        ) {
-          return;
-        }
-        throw new File.Error("removeEmptyDir", ctypes.errno, path);
-      }
-    };
-
-    /**
-     * Default mode for opening directories.
-     */
-    const DEFAULT_UNIX_MODE_DIR = Const.S_IRWXU;
-
-    /**
-     * Create a directory.
-     *
-     * @param {string} path The name of the directory.
-     * @param {*=} options Additional options. This
-     * implementation interprets the following fields:
-     *
-     * - {number} unixMode If specified, a file creation mode,
-     * as per libc function |mkdir|. If unspecified, dirs are
-     * created with a default mode of 0700 (dir is private to
-     * the user, the user can read, write and execute).
-     * - {bool} ignoreExisting If |false|, throw error if the directory
-     * already exists. |true| by default
-     * - {string} from If specified, the call to |makeDir| creates all the
-     * ancestors of |path| that are descendants of |from|. Note that |from|
-     * and its existing descendants must be user-writeable and that |path|
-     * must be a descendant of |from|.
-     * Example:
-     *   makeDir(Path.join(profileDir, "foo", "bar"), { from: profileDir });
-     *  creates directories profileDir/foo, profileDir/foo/bar
-     */
-    File._makeDir = function makeDir(path, options = {}) {
-      let omode =
-        options.unixMode !== undefined
-          ? options.unixMode
-          : DEFAULT_UNIX_MODE_DIR;
-      let result = UnixFile.mkdir(path, omode);
-      if (result == -1) {
-        if (
-          (!("ignoreExisting" in options) || options.ignoreExisting) &&
-          (ctypes.errno == Const.EEXIST || ctypes.errno == Const.EISDIR)
-        ) {
-          return;
-        }
-        throw new File.Error("makeDir", ctypes.errno, path);
-      }
-    };
-
-    /**
-     * Copy a file to a destination.
-     *
-     * @param {string} sourcePath The platform-specific path at which
-     * the file may currently be found.
-     * @param {string} destPath The platform-specific path at which the
-     * file should be copied.
-     * @param {*=} options An object which may contain the following fields:
-     *
-     * @option {bool} noOverwrite - If set, this function will fail if
-     * a file already exists at |destPath|. Otherwise, if this file exists,
-     * it will be erased silently.
-     *
-     * @throws {OS.File.Error} In case of any error.
-     *
-     * General note: The behavior of this function is defined only when
-     * it is called on a single file. If it is called on a directory, the
-     * behavior is undefined and may not be the same across all platforms.
-     *
-     * General note: The behavior of this function with respect to metadata
-     * is unspecified. Metadata may or may not be copied with the file. The
-     * behavior may not be the same across all platforms.
-     */
-    File.copy = null;
-
-    /**
-     * Move a file to a destination.
-     *
-     * @param {string} sourcePath The platform-specific path at which
-     * the file may currently be found.
-     * @param {string} destPath The platform-specific path at which the
-     * file should be moved.
-     * @param {*=} options An object which may contain the following fields:
-     *
-     * @option {bool} noOverwrite - If set, this function will fail if
-     * a file already exists at |destPath|. Otherwise, if this file exists,
-     * it will be erased silently.
-     * @option {bool} noCopy - If set, this function will fail if the
-     * operation is more sophisticated than a simple renaming, i.e. if
-     * |sourcePath| and |destPath| are not situated on the same device.
-     *
-     * @throws {OS.File.Error} In case of any error.
-     *
-     * General note: The behavior of this function is defined only when
-     * it is called on a single file. If it is called on a directory, the
-     * behavior is undefined and may not be the same across all platforms.
-     *
-     * General note: The behavior of this function with respect to metadata
-     * is unspecified. Metadata may or may not be moved with the file. The
-     * behavior may not be the same across all platforms.
-     */
-    File.move = null;
-
-    if (UnixFile.copyfile) {
-      // This implementation uses |copyfile(3)|, from the BSD library.
-      // Adding copying of hierarchies and/or attributes is just a flag
-      // away.
-      File.copy = function copyfile(sourcePath, destPath, options = {}) {
-        let flags = Const.COPYFILE_DATA;
-        if (options.noOverwrite) {
-          flags |= Const.COPYFILE_EXCL;
-        }
-        throw_on_negative(
-          "copy",
-          UnixFile.copyfile(sourcePath, destPath, null, flags),
-          sourcePath
-        );
-      };
-    } else {
-      // If the OS does not implement file copying for us, we need to
-      // implement it ourselves. For this purpose, we need to define
-      // a pumping function.
-
-      /**
-       * Copy bytes from one file to another one.
-       *
-       * @param {File} source The file containing the data to be copied. It
-       * should be opened for reading.
-       * @param {File} dest The file to which the data should be written. It
-       * should be opened for writing.
-       * @param {*=} options An object which may contain the following fields:
-       *
-       * @option {number} nbytes The maximal number of bytes to
-       * copy. If unspecified, copy everything from the current
-       * position.
-       * @option {number} bufSize A hint regarding the size of the
-       * buffer to use for copying. The implementation may decide to
-       * ignore this hint.
-       * @option {bool} unixUserland Will force the copy operation to be
-       * caried out in user land, instead of using optimized syscalls such
-       * as splice(2).
-       *
-       * @throws {OS.File.Error} In case of error.
-       */
-      let pump;
-
-      // A buffer used by |pump_userland|
-      let pump_buffer = null;
-
-      // An implementation of |pump| using |read|/|write|
-      let pump_userland = function pump_userland(source, dest, options = {}) {
-        let bufSize = options.bufSize > 0 ? options.bufSize : 4096;
-        let nbytes = options.nbytes > 0 ? options.nbytes : Infinity;
-        if (!pump_buffer || pump_buffer.length < bufSize) {
-          pump_buffer = new (ctypes.ArrayType(ctypes.char))(bufSize);
-        }
-        let read = source._read.bind(source);
-        let write = dest._write.bind(dest);
-        // Perform actual copy
-        let total_read = 0;
-        while (true) {
-          let bytes_just_read = read(pump_buffer, bufSize);
-          if (bytes_just_read == 0) {
-            return total_read;
-          }
-          total_read += bytes_just_read;
-          let bytes_written = 0;
-          do {
-            bytes_written += write(
-              pump_buffer.addressOfElement(bytes_written),
-              bytes_just_read - bytes_written
-            );
-          } while (bytes_written < bytes_just_read);
-          nbytes -= bytes_written;
-          if (nbytes <= 0) {
-            return total_read;
-          }
-        }
-      };
-
-      // Fortunately, under Linux, that pumping function can be optimized.
-      if (UnixFile.splice) {
-        const BUFSIZE = 1 << 17;
-
-        // An implementation of |pump| using |splice| (for Linux/Android)
-        pump = function pump_splice(source, dest, options = {}) {
-          let nbytes = options.nbytes > 0 ? options.nbytes : Infinity;
-          let pipe = [];
-          throw_on_negative("pump", UnixFile.pipe(pipe));
-          let pipe_read = pipe[0];
-          let pipe_write = pipe[1];
-          let source_fd = source.fd;
-          let dest_fd = dest.fd;
-          let total_read = 0;
-          let total_written = 0;
-          try {
-            while (true) {
-              let chunk_size = Math.min(nbytes, BUFSIZE);
-              let bytes_read = throw_on_negative(
-                "pump",
-                UnixFile.splice(
-                  source_fd,
-                  null,
-                  pipe_write,
-                  null,
-                  chunk_size,
-                  0
-                )
-              );
-              if (!bytes_read) {
-                break;
-              }
-              total_read += bytes_read;
-              let bytes_written = throw_on_negative(
-                "pump",
-                UnixFile.splice(
-                  pipe_read,
-                  null,
-                  dest_fd,
-                  null,
-                  bytes_read,
-                  bytes_read == chunk_size ? Const.SPLICE_F_MORE : 0
-                )
-              );
-              if (!bytes_written) {
-                // This should never happen
-                throw new Error("Internal error: pipe disconnected");
-              }
-              total_written += bytes_written;
-              nbytes -= bytes_read;
-              if (!nbytes) {
-                break;
-              }
-            }
-            return total_written;
-          } catch (x) {
-            if (x.unixErrno == Const.EINVAL) {
-              // We *might* be on a file system that does not support splice.
-              // Try again with a fallback pump.
-              if (total_read) {
-                source.setPosition(-total_read, File.POS_CURRENT);
-              }
-              if (total_written) {
-                dest.setPosition(-total_written, File.POS_CURRENT);
-              }
-              return pump_userland(source, dest, options);
-            }
-            throw x;
-          } finally {
-            pipe_read.dispose();
-            pipe_write.dispose();
-          }
-        };
-      } else {
-        // Fallback implementation of pump for other Unix platforms.
-        pump = pump_userland;
-      }
-
-      // Implement |copy| using |pump|.
-      // This implementation would require some work before being able to
-      // copy directories
-      File.copy = function copy(sourcePath, destPath, options = {}) {
-        let source, dest;
-        try {
-          source = File.open(sourcePath);
-          // Need to open the output file with |append:false|, or else |splice|
-          // won't work.
-          if (options.noOverwrite) {
-            dest = File.open(destPath, { create: true, append: false });
-          } else {
-            dest = File.open(destPath, { trunc: true, append: false });
-          }
-          if (options.unixUserland) {
-            pump_userland(source, dest, options);
-          } else {
-            pump(source, dest, options);
-          }
-        } catch (x) {
-          if (dest) {
-            dest.close();
-          }
-          if (source) {
-            source.close();
-          }
-          throw x;
-        }
-      };
-    } // End of definition of copy
-
-    // Implement |move| using |rename| (wherever possible) or |copy|
-    // (if files are on distinct devices).
-    File.move = function move(sourcePath, destPath, options = {}) {
-      // An implementation using |rename| whenever possible or
-      // |File.pump| when required, for other Unices.
-      // It can move directories on one file system, not
-      // across file systems
-
-      // If necessary, fail if the destination file exists
-      if (options.noOverwrite) {
-        let fd = UnixFile.open(destPath, Const.O_RDONLY);
-        if (fd != -1) {
-          fd.dispose();
-          // The file exists and we have access
-          throw new File.Error("move", Const.EEXIST, sourcePath);
-        } else if (ctypes.errno == Const.EACCESS) {
-          // The file exists and we don't have access
-          throw new File.Error("move", Const.EEXIST, sourcePath);
-        }
-      }
-
-      // If we can, rename the file.
-      let result = UnixFile.rename(sourcePath, destPath);
-      if (result != -1) {
-        // Succeeded.
-        return;
-      }
-
-      // In some cases, we cannot rename, e.g. because we're crossing
-      // devices. In such cases, if permitted, we'll need to copy then
-      // erase the original.
-      if (options.noCopy) {
-        throw new File.Error("move", ctypes.errno, sourcePath);
-      }
-
-      File.copy(sourcePath, destPath, options);
-      // Note that we do not attempt to clean-up in case of copy error.
-      // I'm sure that there are edge cases in which this could end up
-      // removing an important file by accident. I'd rather leave
-      // a file lying around by error than removing a critical file.
-
-      File.remove(sourcePath);
-    };
-
-    File.unixSymLink = function unixSymLink(sourcePath, destPath) {
-      throw_on_negative(
-        "symlink",
-        UnixFile.symlink(sourcePath, destPath),
-        sourcePath
-      );
-    };
-
-    /**
-     * Iterate on one directory.
-     *
-     * This iterator will not enter subdirectories.
-     *
-     * @param {string} path The directory upon which to iterate.
-     * @param {*=} options Ignored in this implementation.
-     *
-     * @throws {File.Error} If |path| does not represent a directory or
-     * if the directory cannot be iterated.
-     * @constructor
-     */
-    File.DirectoryIterator = function DirectoryIterator(path, options) {
-      exports.OS.Shared.AbstractFile.AbstractIterator.call(this);
-      this._path = path;
-      this._dir = UnixFile.opendir(this._path);
-      if (this._dir == null) {
-        let error = ctypes.errno;
-        if (error != Const.ENOENT) {
-          throw new File.Error("DirectoryIterator", error, path);
-        }
-        this._exists = false;
-        this._closed = true;
-      } else {
-        this._exists = true;
-        this._closed = false;
-      }
-    };
-    File.DirectoryIterator.prototype = Object.create(
-      exports.OS.Shared.AbstractFile.AbstractIterator.prototype
-    );
-
-    /**
-     * Return the next entry in the directory, if any such entry is
-     * available.
-     *
-     * Skip special directories "." and "..".
-     *
-     * @return By definition of the iterator protocol, either
-     * `{value: {File.Entry}, done: false}` if there is an unvisited entry
-     * in the directory, or `{value: undefined, done: true}`, otherwise.
-     */
-    File.DirectoryIterator.prototype.next = function next() {
-      if (!this._exists) {
-        throw File.Error.noSuchFile(
-          "DirectoryIterator.prototype.next",
-          this._path
-        );
-      }
-      if (this._closed) {
-        return { value: undefined, done: true };
-      }
-      for (
-        let entry = UnixFile.readdir(this._dir);
-        entry != null && !entry.isNull();
-        entry = UnixFile.readdir(this._dir)
-      ) {
-        let contents = entry.contents;
-        let name = contents.d_name.readString();
-        if (name == "." || name == "..") {
-          continue;
-        }
-
-        let isDir, isSymLink;
-        if (
-          !("d_type" in contents) ||
-          !("DT_UNKNOWN" in Const) ||
-          contents.d_type == Const.DT_UNKNOWN
-        ) {
-          // File type information is not available in d_type. The cases are:
-          // 1. |dirent| doesn't have d_type on some platforms (e.g. Solaris).
-          // 2. DT_UNKNOWN and other DT_ constants are not defined.
-          // 3. d_type is set to unknown (e.g. not supported by the
-          //    filesystem).
-          let path = Path.join(this._path, name);
-          throw_on_negative(
-            "lstat",
-            UnixFile.lstat(path, gStatDataPtr),
-            this._path
-          );
-          isDir = (gStatData.st_mode & Const.S_IFMT) == Const.S_IFDIR;
-          isSymLink = (gStatData.st_mode & Const.S_IFMT) == Const.S_IFLNK;
-        } else {
-          isDir = contents.d_type == Const.DT_DIR;
-          isSymLink = contents.d_type == Const.DT_LNK;
-        }
-
-        return {
-          value: new File.DirectoryIterator.Entry(
-            isDir,
-            isSymLink,
-            name,
-            this._path
-          ),
-          done: false,
-        };
-      }
-      this.close();
-      return { value: undefined, done: true };
-    };
-
-    /**
-     * Close the iterator and recover all resources.
-     * You should call this once you have finished iterating on a directory.
-     */
-    File.DirectoryIterator.prototype.close = function close() {
-      if (this._closed) {
-        return;
-      }
-      this._closed = true;
-      UnixFile.closedir(this._dir);
-      this._dir = null;
-    };
-
-    /**
-     * Determine whether the directory exists.
-     *
-     * @return {boolean}
-     */
-    File.DirectoryIterator.prototype.exists = function exists() {
-      return this._exists;
-    };
-
-    /**
-     * Return directory as |File|
-     */
-    File.DirectoryIterator.prototype.unixAsFile = function unixAsFile() {
-      if (!this._dir) {
-        throw File.Error.closed("unixAsFile", this._path);
-      }
-      return error_or_file(UnixFile.dirfd(this._dir), this._path);
-    };
-
-    /**
-     * An entry in a directory.
-     */
-    File.DirectoryIterator.Entry = function Entry(
-      isDir,
-      isSymLink,
-      name,
-      parent
-    ) {
-      // Copy the relevant part of |unix_entry| to ensure that
-      // our data is not overwritten prematurely.
-      this._parent = parent;
-      let path = Path.join(this._parent, name);
-
-      SysAll.AbstractEntry.call(this, isDir, isSymLink, name, path);
-    };
-    File.DirectoryIterator.Entry.prototype = Object.create(
-      SysAll.AbstractEntry.prototype
-    );
-
-    /**
-     * Return a version of an instance of
-     * File.DirectoryIterator.Entry that can be sent from a worker
-     * thread to the main thread. Note that deserialization is
-     * asymmetric and returns an object with a different
-     * implementation.
-     */
-    File.DirectoryIterator.Entry.toMsg = function toMsg(value) {
-      if (!(value instanceof File.DirectoryIterator.Entry)) {
-        throw new TypeError(
-          "parameter of " +
-            "File.DirectoryIterator.Entry.toMsg must be a " +
-            "File.DirectoryIterator.Entry"
-        );
-      }
-      let serialized = {};
-      for (let key in File.DirectoryIterator.Entry.prototype) {
-        serialized[key] = value[key];
-      }
-      return serialized;
-    };
-
-    let gStatData = new Type.stat.implementation();
-    let gStatDataPtr = gStatData.address();
-
-    let MODE_MASK = 4095; /* = 07777*/
-    File.Info = function Info(stat, path) {
-      let isDir = (stat.st_mode & Const.S_IFMT) == Const.S_IFDIR;
-      let isSymLink = (stat.st_mode & Const.S_IFMT) == Const.S_IFLNK;
-      let size = Type.off_t.importFromC(stat.st_size);
-
-      let lastAccessDate = new Date(stat.st_atime * 1000);
-      let lastModificationDate = new Date(stat.st_mtime * 1000);
-      let unixLastStatusChangeDate = new Date(stat.st_ctime * 1000);
-
-      let unixOwner = Type.uid_t.importFromC(stat.st_uid);
-      let unixGroup = Type.gid_t.importFromC(stat.st_gid);
-      let unixMode = Type.mode_t.importFromC(stat.st_mode & MODE_MASK);
-
-      SysAll.AbstractInfo.call(
-        this,
-        path,
-        isDir,
-        isSymLink,
-        size,
-        lastAccessDate,
-        lastModificationDate,
-        unixLastStatusChangeDate,
-        unixOwner,
-        unixGroup,
-        unixMode
-      );
-    };
-    File.Info.prototype = Object.create(SysAll.AbstractInfo.prototype);
-
-    /**
-     * Return a version of an instance of File.Info that can be sent
-     * from a worker thread to the main thread. Note that deserialization
-     * is asymmetric and returns an object with a different implementation.
-     */
-    File.Info.toMsg = function toMsg(stat) {
-      if (!(stat instanceof File.Info)) {
-        throw new TypeError("parameter of File.Info.toMsg must be a File.Info");
-      }
-      let serialized = {};
-      for (let key in File.Info.prototype) {
-        serialized[key] = stat[key];
-      }
-      return serialized;
-    };
-
-    /**
-     * Fetch the information on a file.
-     *
-     * @param {string} path The full name of the file to open.
-     * @param {*=} options Additional options. In this implementation:
-     *
-     * - {bool} unixNoFollowingLinks If set and |true|, if |path|
-     * represents a symbolic link, the call will return the information
-     * of the link itself, rather than that of the target file.
-     *
-     * @return {File.Information}
-     */
-    File.stat = function stat(path, options = {}) {
-      if (options.unixNoFollowingLinks) {
-        throw_on_negative("stat", UnixFile.lstat(path, gStatDataPtr), path);
-      } else {
-        throw_on_negative("stat", UnixFile.stat(path, gStatDataPtr), path);
-      }
-      return new File.Info(gStatData, path);
-    };
-
-    /**
-     * Set the file's access permissions.
-     *
-     * This operation is likely to fail if applied to a file that was
-     * not created by the currently running program (more precisely,
-     * if it was created by a program running under a different OS-level
-     * user account).  It may also fail, or silently do nothing, if the
-     * filesystem containing the file does not support access permissions.
-     *
-     * @param {string} path The name of the file to reset the permissions of.
-     * @param {*=} options Object specifying the requested permissions:
-     *
-     * - {number} unixMode The POSIX file mode to set on the file.  If omitted,
-     *  the POSIX file mode is reset to the default used by |OS.file.open|.  If
-     *  specified, the permissions will respect the process umask as if they
-     *  had been specified as arguments of |OS.File.open|, unless the
-     *  |unixHonorUmask| parameter tells otherwise.
-     * - {bool} unixHonorUmask If omitted or true, any |unixMode| value is
-     *  modified by the process umask, as |OS.File.open| would have done.  If
-     *  false, the exact value of |unixMode| will be applied.
-     */
-    File.setPermissions = function setPermissions(path, options = {}) {
-      throw_on_negative(
-        "setPermissions",
-        UnixFile.chmod(path, unixMode(options)),
-        path
-      );
-    };
-
-    /**
-     * Convert an access date and a modification date to an array
-     * of two |timeval|.
-     */
-    function datesToTimevals(accessDate, modificationDate) {
-      accessDate = normalizeDate("File.setDates", accessDate);
-      modificationDate = normalizeDate("File.setDates", modificationDate);
-
-      let timevals = new Type.timevals.implementation();
-      let timevalsPtr = timevals.address();
-
-      // JavaScript date values are expressed in milliseconds since epoch.
-      // Split this up into second and microsecond components.
-      timevals[0].tv_sec = (accessDate / 1000) | 0;
-      timevals[0].tv_usec = ((accessDate % 1000) * 1000) | 0;
-      timevals[1].tv_sec = (modificationDate / 1000) | 0;
-      timevals[1].tv_usec = ((modificationDate % 1000) * 1000) | 0;
-
-      return { value: timevals, ptr: timevalsPtr };
-    }
-
-    /**
-     * Set the last access and modification date of the file.
-     * The time stamp resolution is 1 second at best, but might be worse
-     * depending on the platform.
-     *
-     * @param {string} path The full name of the file to set the dates for.
-     * @param {Date,number=} accessDate The last access date. If numeric,
-     * milliseconds since epoch. If omitted or null, then the current date
-     * will be used.
-     * @param {Date,number=} modificationDate The last modification date. If
-     * numeric, milliseconds since epoch. If omitted or null, then the current
-     * date will be used.
-     *
-     * @throws {TypeError} In case of invalid paramters.
-     * @throws {OS.File.Error} In case of I/O error.
-     */
-    File.setDates = function setDates(path, accessDate, modificationDate) {
-      let { /* value, */ ptr } = datesToTimevals(accessDate, modificationDate);
-      throw_on_negative("setDates", UnixFile.utimes(path, ptr), path);
-    };
-
-    File.read = exports.OS.Shared.AbstractFile.read;
-    File.writeAtomic = exports.OS.Shared.AbstractFile.writeAtomic;
-    File.openUnique = exports.OS.Shared.AbstractFile.openUnique;
-    File.makeDir = exports.OS.Shared.AbstractFile.makeDir;
-
-    /**
-     * Remove an existing directory and its contents.
-     *
-     * @param {string} path The name of the directory.
-     * @param {*=} options Additional options.
-     *   - {bool} ignoreAbsent If |false|, throw an error if the directory doesn't
-     *     exist. |true| by default.
-     *   - {boolean} ignorePermissions If |true|, remove the file even when lacking write
-     *     permission.
-     *
-     * @throws {OS.File.Error} In case of I/O error, in particular if |path| is
-     *         not a directory.
-     *
-     * Note: This function will remove a symlink even if it points a directory.
-     */
-    File.removeDir = function(path, options = {}) {
-      let isSymLink;
-      try {
-        let info = File.stat(path, { unixNoFollowingLinks: true });
-        isSymLink = info.isSymLink;
-      } catch (e) {
-        if (
-          (!("ignoreAbsent" in options) || options.ignoreAbsent) &&
-          ctypes.errno == Const.ENOENT
-        ) {
-          return;
-        }
-        throw e;
-      }
-      if (isSymLink) {
-        // A Unix symlink itself is not a directory even if it points
-        // a directory.
-        File.remove(path, options);
-        return;
-      }
-      exports.OS.Shared.AbstractFile.removeRecursive(path, options);
-    };
-
-    /**
-     * Get the current directory by getCurrentDirectory.
-     */
-    File.getCurrentDirectory = function getCurrentDirectory() {
-      let path, buf;
-      if (UnixFile.get_current_dir_name) {
-        path = UnixFile.get_current_dir_name();
-      } else if (UnixFile.getwd_auto) {
-        path = UnixFile.getwd_auto(null);
-      } else {
-        for (let length = Const.PATH_MAX; !path; length *= 2) {
-          buf = new (ctypes.char.array(length))();
-          path = UnixFile.getcwd(buf, length);
-        }
-      }
-      throw_on_null("getCurrentDirectory", path);
-      return path.readString();
-    };
-
-    /**
-     * Get/set the current directory.
-     */
-    Object.defineProperty(File, "curDir", {
-      set(path) {
-        this.setCurrentDirectory(path);
-      },
-      get() {
-        return this.getCurrentDirectory();
-      },
-    });
-
-    // Utility functions
-
-    /**
-     * Turn the result of |open| into an Error or a File
-     * @param {number} maybe The result of the |open| operation that may
-     * represent either an error or a success. If -1, this function raises
-     * an error holding ctypes.errno, otherwise it returns the opened file.
-     * @param {string=} path The path of the file.
-     */
-    function error_or_file(maybe, path) {
-      if (maybe == -1) {
-        throw new File.Error("open", ctypes.errno, path);
-      }
-      return new File(maybe, path);
-    }
-
-    /**
-     * Utility function to sort errors represented as "-1" from successes.
-     *
-     * @param {string=} operation The name of the operation. If unspecified,
-     * the name of the caller function.
-     * @param {number} result The result of the operation that may
-     * represent either an error or a success. If -1, this function raises
-     * an error holding ctypes.errno, otherwise it returns |result|.
-     * @param {string=} path The path of the file.
-     */
-    function throw_on_negative(operation, result, path) {
-      if (result < 0) {
-        throw new File.Error(operation, ctypes.errno, path);
-      }
-      return result;
-    }
-
-    /**
-     * Utility function to sort errors represented as |null| from successes.
-     *
-     * @param {string=} operation The name of the operation. If unspecified,
-     * the name of the caller function.
-     * @param {pointer} result The result of the operation that may
-     * represent either an error or a success. If |null|, this function raises
-     * an error holding ctypes.errno, otherwise it returns |result|.
-     * @param {string=} path The path of the file.
-     */
-    function throw_on_null(operation, result, path) {
-      if (result == null || (result.isNull && result.isNull())) {
-        throw new File.Error(operation, ctypes.errno, path);
-      }
-      return result;
-    }
-
-    /**
-     * Normalize and verify a Date or numeric date value.
-     *
-     * @param {string} fn Function name of the calling function.
-     * @param {Date,number} date The date to normalize. If omitted or null,
-     * then the current date will be used.
-     *
-     * @throws {TypeError} Invalid date provided.
-     *
-     * @return {number} Sanitized, numeric date in milliseconds since epoch.
-     */
-    function normalizeDate(fn, date) {
-      if (typeof date !== "number" && !date) {
-        // |date| was Omitted or null.
-        date = Date.now();
-      } else if (typeof date.getTime === "function") {
-        // Input might be a date or date-like object.
-        date = date.getTime();
-      }
-
-      if (typeof date !== "number" || Number.isNaN(date)) {
-        throw new TypeError(
-          "|date| parameter of " +
-            fn +
-            " must be a " +
-            "|Date| instance or number"
-        );
-      }
-      return date;
-    }
-
-    /**
-     * Helper used by both versions of setPermissions.
-     */
-    function unixMode(options) {
-      let mode =
-        options.unixMode !== undefined ? options.unixMode : DEFAULT_UNIX_MODE;
-      let unixHonorUmask = true;
-      if ("unixHonorUmask" in options) {
-        unixHonorUmask = options.unixHonorUmask;
-      }
-      if (unixHonorUmask) {
-        mode &= ~SharedAll.Constants.Sys.umask;
-      }
-      return mode;
-    }
-
-    File.Unix = exports.OS.Unix.File;
-    File.Error = SysAll.Error;
-    exports.OS.File = File;
-    exports.OS.Shared.Type = Type;
-
-    Object.defineProperty(File, "POS_START", { value: SysAll.POS_START });
-    Object.defineProperty(File, "POS_CURRENT", { value: SysAll.POS_CURRENT });
-    Object.defineProperty(File, "POS_END", { value: SysAll.POS_END });
-  })(this);
-}
deleted file mode 100644
--- a/toolkit/components/osfile/modules/osfile_win_allthreads.jsm
+++ /dev/null
@@ -1,444 +0,0 @@
-/* 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/. */
-
-/**
- * This module defines the thread-agnostic components of the Win version
- * of OS.File. It depends on the thread-agnostic cross-platform components
- * of OS.File.
- *
- * It serves the following purposes:
- * - open kernel32;
- * - define OS.Shared.Win.Error;
- * - define a few constants and types that need to be defined on all platforms.
- *
- * This module can be:
- * - opened from the main thread as a jsm module;
- * - opened from a chrome worker through require().
- */
-
-/* eslint-env node */
-
-"use strict";
-
-var SharedAll;
-if (typeof Components != "undefined") {
-  // Module is opened as a jsm module
-  const { ctypes } = ChromeUtils.importESModule(
-    "resource://gre/modules/ctypes.sys.mjs"
-  );
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.ctypes = ctypes;
-
-  SharedAll = ChromeUtils.import(
-    "resource://gre/modules/osfile/osfile_shared_allthreads.jsm"
-  );
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.exports = {};
-} else if (typeof module != "undefined" && typeof require != "undefined") {
-  // Module is loaded with require()
-  SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
-} else {
-  throw new Error(
-    "Please open this module with Component.utils.import or with require()"
-  );
-}
-
-SharedAll.LOG.bind(SharedAll, "Win", "allthreads");
-var Const = SharedAll.Constants.Win;
-
-// Open libc
-var libc = new SharedAll.Library("libc", "kernel32.dll");
-exports.libc = libc;
-
-// Define declareFFI
-var declareFFI = SharedAll.declareFFI.bind(null, libc);
-exports.declareFFI = declareFFI;
-
-var Scope = {};
-
-// Define Error
-libc.declareLazy(
-  Scope,
-  "FormatMessage",
-  "FormatMessageW",
-  ctypes.winapi_abi,
-  /* return*/ ctypes.uint32_t,
-  ctypes.uint32_t,
-  /* source*/ ctypes.voidptr_t,
-  ctypes.uint32_t,
-  /* langid*/ ctypes.uint32_t,
-  ctypes.char16_t.ptr,
-  ctypes.uint32_t,
-  /* Arguments*/ ctypes.voidptr_t
-);
-
-/**
- * A File-related error.
- *
- * To obtain a human-readable error message, use method |toString|.
- * To determine the cause of the error, use the various |becauseX|
- * getters. To determine the operation that failed, use field
- * |operation|.
- *
- * Additionally, this implementation offers a field
- * |winLastError|, which holds the OS-specific error
- * constant. If you need this level of detail, you may match the value
- * of this field against the error constants of |OS.Constants.Win|.
- *
- * @param {string=} operation The operation that failed. If unspecified,
- * the name of the calling function is taken to be the operation that
- * failed.
- * @param {number=} lastError The OS-specific constant detailing the
- * reason of the error. If unspecified, this is fetched from the system
- * status.
- * @param {string=} path The file path that manipulated. If unspecified,
- * assign the empty string.
- *
- * @constructor
- * @extends {OS.Shared.Error}
- */
-var OSError = function OSError(
-  operation = "unknown operation",
-  lastError = ctypes.winLastError,
-  path = ""
-) {
-  SharedAll.OSError.call(this, operation, path);
-  this.winLastError = lastError;
-};
-OSError.prototype = Object.create(SharedAll.OSError.prototype);
-OSError.prototype.toString = function toString() {
-  let buf = new (ctypes.ArrayType(ctypes.char16_t, 1024))();
-  let result = Scope.FormatMessage(
-    Const.FORMAT_MESSAGE_FROM_SYSTEM | Const.FORMAT_MESSAGE_IGNORE_INSERTS,
-    null,
-    /* The error number */ this.winLastError,
-    /* Default language */ 0,
-    buf,
-    /* Minimum size of buffer */ 1024,
-    null
-  );
-  if (!result) {
-    buf =
-      "additional error " +
-      ctypes.winLastError +
-      " while fetching system error message";
-  }
-  return (
-    "Win error " +
-    this.winLastError +
-    " during operation " +
-    this.operation +
-    (this.path ? " on file " + this.path : "") +
-    " (" +
-    buf.readString() +
-    ")"
-  );
-};
-OSError.prototype.toMsg = function toMsg() {
-  return OSError.toMsg(this);
-};
-
-/**
- * |true| if the error was raised because a file or directory
- * already exists, |false| otherwise.
- */
-Object.defineProperty(OSError.prototype, "becauseExists", {
-  get: function becauseExists() {
-    return (
-      this.winLastError == Const.ERROR_FILE_EXISTS ||
-      this.winLastError == Const.ERROR_ALREADY_EXISTS
-    );
-  },
-});
-/**
- * |true| if the error was raised because a file or directory
- * does not exist, |false| otherwise.
- */
-Object.defineProperty(OSError.prototype, "becauseNoSuchFile", {
-  get: function becauseNoSuchFile() {
-    return (
-      this.winLastError == Const.ERROR_FILE_NOT_FOUND ||
-      this.winLastError == Const.ERROR_PATH_NOT_FOUND
-    );
-  },
-});
-/**
- * |true| if the error was raised because a directory is not empty
- * does not exist, |false| otherwise.
- */
-Object.defineProperty(OSError.prototype, "becauseNotEmpty", {
-  get: function becauseNotEmpty() {
-    return this.winLastError == Const.ERROR_DIR_NOT_EMPTY;
-  },
-});
-/**
- * |true| if the error was raised because a file or directory
- * is closed, |false| otherwise.
- */
-Object.defineProperty(OSError.prototype, "becauseClosed", {
-  get: function becauseClosed() {
-    return this.winLastError == Const.ERROR_INVALID_HANDLE;
-  },
-});
-/**
- * |true| if the error was raised because permission is denied to
- * access a file or directory, |false| otherwise.
- */
-Object.defineProperty(OSError.prototype, "becauseAccessDenied", {
-  get: function becauseAccessDenied() {
-    return this.winLastError == Const.ERROR_ACCESS_DENIED;
-  },
-});
-/**
- * |true| if the error was raised because some invalid argument was passed,
- * |false| otherwise.
- */
-Object.defineProperty(OSError.prototype, "becauseInvalidArgument", {
-  get: function becauseInvalidArgument() {
-    return (
-      this.winLastError == Const.ERROR_NOT_SUPPORTED ||
-      this.winLastError == Const.ERROR_BAD_ARGUMENTS
-    );
-  },
-});
-
-/**
- * Serialize an instance of OSError to something that can be
- * transmitted across threads (not necessarily a string).
- */
-OSError.toMsg = function toMsg(error) {
-  return {
-    exn: "OS.File.Error",
-    fileName: error.moduleName,
-    lineNumber: error.lineNumber,
-    stack: error.moduleStack,
-    operation: error.operation,
-    winLastError: error.winLastError,
-    path: error.path,
-  };
-};
-
-/**
- * Deserialize a message back to an instance of OSError
- */
-OSError.fromMsg = function fromMsg(msg) {
-  let error = new OSError(msg.operation, msg.winLastError, msg.path);
-  error.stack = msg.stack;
-  error.fileName = msg.fileName;
-  error.lineNumber = msg.lineNumber;
-  return error;
-};
-exports.Error = OSError;
-
-/**
- * Code shared by implementation of File.Info on Windows
- *
- * @constructor
- */
-var AbstractInfo = function AbstractInfo(
-  path,
-  isDir,
-  isSymLink,
-  size,
-  lastAccessDate,
-  lastWriteDate,
-  winAttributes
-) {
-  this._path = path;
-  this._isDir = isDir;
-  this._isSymLink = isSymLink;
-  this._size = size;
-  this._lastAccessDate = lastAccessDate;
-  this._lastModificationDate = lastWriteDate;
-  this._winAttributes = winAttributes;
-};
-
-AbstractInfo.prototype = {
-  /**
-   * The path of the file, used for error-reporting.
-   *
-   * @type {string}
-   */
-  get path() {
-    return this._path;
-  },
-  /**
-   * |true| if this file is a directory, |false| otherwise
-   */
-  get isDir() {
-    return this._isDir;
-  },
-  /**
-   * |true| if this file is a symbolic link, |false| otherwise
-   */
-  get isSymLink() {
-    return this._isSymLink;
-  },
-  /**
-   * The size of the file, in bytes.
-   *
-   * Note that the result may be |NaN| if the size of the file cannot be
-   * represented in JavaScript.
-   *
-   * @type {number}
-   */
-  get size() {
-    return this._size;
-  },
-  /**
-   * The date of last access to this file.
-   *
-   * Note that the definition of last access may depend on the underlying
-   * operating system and file system.
-   *
-   * @type {Date}
-   */
-  get lastAccessDate() {
-    return this._lastAccessDate;
-  },
-  /**
-   * The date of last modification of this file.
-   *
-   * Note that the definition of last access may depend on the underlying
-   * operating system and file system.
-   *
-   * @type {Date}
-   */
-  get lastModificationDate() {
-    return this._lastModificationDate;
-  },
-  /**
-   * The Object with following boolean properties of this file.
-   * {readOnly, system, hidden}
-   *
-   * @type {object}
-   */
-  get winAttributes() {
-    return this._winAttributes;
-  },
-};
-exports.AbstractInfo = AbstractInfo;
-
-/**
- * Code shared by implementation of File.DirectoryIterator.Entry on Windows
- *
- * @constructor
- */
-var AbstractEntry = function AbstractEntry(
-  isDir,
-  isSymLink,
-  name,
-  winLastWriteDate,
-  winLastAccessDate,
-  path
-) {
-  this._isDir = isDir;
-  this._isSymLink = isSymLink;
-  this._name = name;
-  this._winLastWriteDate = winLastWriteDate;
-  this._winLastAccessDate = winLastAccessDate;
-  this._path = path;
-};
-
-AbstractEntry.prototype = {
-  /**
-   * |true| if the entry is a directory, |false| otherwise
-   */
-  get isDir() {
-    return this._isDir;
-  },
-  /**
-   * |true| if the entry is a symbolic link, |false| otherwise
-   */
-  get isSymLink() {
-    return this._isSymLink;
-  },
-  /**
-   * The name of the entry.
-   * @type {string}
-   */
-  get name() {
-    return this._name;
-  },
-  /**
-   * The last modification time of this file.
-   * @type {Date}
-   */
-  get winLastWriteDate() {
-    return this._winLastWriteDate;
-  },
-  /**
-   * The last access time of this file.
-   * @type {Date}
-   */
-  get winLastAccessDate() {
-    return this._winLastAccessDate;
-  },
-  /**
-   * The full path of the entry
-   * @type {string}
-   */
-  get path() {
-    return this._path;
-  },
-};
-exports.AbstractEntry = AbstractEntry;
-
-// Special constants that need to be defined on all platforms
-
-exports.POS_START = Const.FILE_BEGIN;
-exports.POS_CURRENT = Const.FILE_CURRENT;
-exports.POS_END = Const.FILE_END;
-
-// Special types that need to be defined for communication
-// between threads
-var Type = Object.create(SharedAll.Type);
-exports.Type = Type;
-
-/**
- * Native paths
- *
- * Under Windows, expressed as wide strings
- */
-Type.path = Type.wstring.withName("[in] path");
-Type.out_path = Type.out_wstring.withName("[out] path");
-
-// Special constructors that need to be defined on all threads
-OSError.closed = function closed(operation, path) {
-  return new OSError(operation, Const.ERROR_INVALID_HANDLE, path);
-};
-
-OSError.exists = function exists(operation, path) {
-  return new OSError(operation, Const.ERROR_FILE_EXISTS, path);
-};
-
-OSError.noSuchFile = function noSuchFile(operation, path) {
-  return new OSError(operation, Const.ERROR_FILE_NOT_FOUND, path);
-};
-
-OSError.invalidArgument = function invalidArgument(operation) {
-  return new OSError(operation, Const.ERROR_NOT_SUPPORTED);
-};
-
-var EXPORTED_SYMBOLS = [
-  "declareFFI",
-  "libc",
-  "Error",
-  "AbstractInfo",
-  "AbstractEntry",
-  "Type",
-  "POS_START",
-  "POS_CURRENT",
-  "POS_END",
-];
-
-// ////////// Boilerplate
-if (typeof Components != "undefined") {
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.EXPORTED_SYMBOLS = EXPORTED_SYMBOLS;
-  for (let symbol of EXPORTED_SYMBOLS) {
-    // eslint-disable-next-line mozilla/reject-global-this
-    this[symbol] = exports[symbol];
-  }
-}
deleted file mode 100644
--- a/toolkit/components/osfile/modules/osfile_win_back.js
+++ /dev/null
@@ -1,542 +0,0 @@
-/* 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/. */
-
-/**
- * This file can be used in the following contexts:
- *
- *  1. included from a non-osfile worker thread using importScript
- *   (it serves to define a synchronous API for that worker thread)
- *   (bug 707681)
- *
- *  2. included from the main thread using Components.utils.import
- *   (it serves to define the asynchronous API, whose implementation
- *    resides in the worker thread)
- *   (bug 729057)
- *
- * 3. included from the osfile worker thread using importScript
- *   (it serves to define the implementation of the asynchronous API)
- *   (bug 729057)
- */
-
-/* eslint-env mozilla/chrome-worker, node */
-
-// eslint-disable-next-line no-lone-blocks
-{
-  if (typeof Components != "undefined") {
-    // We do not wish osfile_win_back.js to be used directly as a main thread
-    // module yet. When time comes, it will be loaded by a combination of
-    // a main thread front-end/worker thread implementation that makes sure
-    // that we are not executing synchronous IO code in the main thread.
-
-    throw new Error(
-      "osfile_win_back.js cannot be used from the main thread yet"
-    );
-  }
-
-  (function(exports) {
-    "use strict";
-    if (exports.OS && exports.OS.Win && exports.OS.Win.File) {
-      return; // Avoid double initialization
-    }
-
-    let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
-    let SysAll = require("resource://gre/modules/osfile/osfile_win_allthreads.jsm");
-    SharedAll.LOG.bind(SharedAll, "Unix", "back");
-    let libc = SysAll.libc;
-    let advapi32 = new SharedAll.Library("advapi32", "advapi32.dll");
-    let Const = SharedAll.Constants.Win;
-
-    /**
-     * Initialize the Windows module.
-     *
-     * @param {function=} declareFFI
-     */
-    // FIXME: Both |init| and |aDeclareFFI| are deprecated, we should remove them
-    let init = function init(aDeclareFFI) {
-      let declareFFI;
-      if (aDeclareFFI) {
-        declareFFI = aDeclareFFI.bind(null, libc);
-      } else {
-        declareFFI = SysAll.declareFFI; // eslint-disable-line no-unused-vars
-      }
-      let declareLazyFFI = SharedAll.declareLazyFFI; // eslint-disable-line no-unused-vars
-
-      // Initialize types that require additional OS-specific
-      // support - either finalization or matching against
-      // OS-specific constants.
-      let Type = Object.create(SysAll.Type);
-      let SysFile = (exports.OS.Win.File = { Type });
-
-      // Initialize types
-
-      /**
-       * A C integer holding INVALID_HANDLE_VALUE in case of error or
-       * a file descriptor in case of success.
-       */
-      Type.HANDLE = Type.voidptr_t.withName("HANDLE");
-      Type.HANDLE.importFromC = function importFromC(maybe) {
-        if (Type.int.cast(maybe).value == INVALID_HANDLE) {
-          // Ensure that API clients can effectively compare against
-          // Const.INVALID_HANDLE_VALUE. Without this cast,
-          // == would always return |false|.
-          return INVALID_HANDLE;
-        }
-        return ctypes.CDataFinalizer(maybe, this.finalizeHANDLE);
-      };
-      Type.HANDLE.finalizeHANDLE = function placeholder() {
-        throw new Error("finalizeHANDLE should be implemented");
-      };
-      let INVALID_HANDLE = Const.INVALID_HANDLE_VALUE;
-
-      Type.file_HANDLE = Type.HANDLE.withName("file HANDLE");
-      SharedAll.defineLazyGetter(
-        Type.file_HANDLE,
-        "finalizeHANDLE",
-        function() {
-          return SysFile._CloseHandle;
-        }
-      );
-
-      Type.find_HANDLE = Type.HANDLE.withName("find HANDLE");
-      SharedAll.defineLazyGetter(
-        Type.find_HANDLE,
-        "finalizeHANDLE",
-        function() {
-          return SysFile._FindClose;
-        }
-      );
-
-      Type.DWORD = Type.uint32_t.withName("DWORD");
-
-      /* A special type used to represent flags passed as DWORDs to a function.
-       * In JavaScript, bitwise manipulation of numbers, such as or-ing flags,
-       * can produce negative numbers. Since DWORD is unsigned, these negative
-       * numbers simply cannot be converted to DWORD. For this reason, whenever
-       * bit manipulation is called for, you should rather use DWORD_FLAGS,
-       * which is represented as a signed integer, hence has the correct
-       * semantics.
-       */
-      Type.DWORD_FLAGS = Type.int32_t.withName("DWORD_FLAGS");
-
-      /**
-       * A C integer holding 0 in case of error or a positive integer
-       * in case of success.
-       */
-      Type.zero_or_DWORD = Type.DWORD.withName("zero_or_DWORD");
-
-      /**
-       * A C integer holding 0 in case of error, any other value in
-       * case of success.
-       */
-      Type.zero_or_nothing = Type.int.withName("zero_or_nothing");
-
-      /**
-       * A C integer holding flags related to NTFS security.
-       */
-      Type.SECURITY_ATTRIBUTES = Type.void_t.withName("SECURITY_ATTRIBUTES");
-
-      /**
-       * A C integer holding pointers related to NTFS security.
-       */
-      Type.PSID = Type.voidptr_t.withName("PSID");
-
-      Type.PACL = Type.voidptr_t.withName("PACL");
-
-      Type.PSECURITY_DESCRIPTOR = Type.voidptr_t.withName(
-        "PSECURITY_DESCRIPTOR"
-      );
-
-      /**
-       * A C integer holding Win32 local memory handle.
-       */
-      Type.HLOCAL = Type.voidptr_t.withName("HLOCAL");
-
-      Type.FILETIME = new SharedAll.Type(
-        "FILETIME",
-        ctypes.StructType("FILETIME", [
-          { lo: Type.DWORD.implementation },
-          { hi: Type.DWORD.implementation },
-        ])
-      );
-
-      Type.FindData = new SharedAll.Type(
-        "FIND_DATA",
-        ctypes.StructType("FIND_DATA", [
-          { dwFileAttributes: ctypes.uint32_t },
-          { ftCreationTime: Type.FILETIME.implementation },
-          { ftLastAccessTime: Type.FILETIME.implementation },
-          { ftLastWriteTime: Type.FILETIME.implementation },
-          { nFileSizeHigh: Type.DWORD.implementation },
-          { nFileSizeLow: Type.DWORD.implementation },
-          { dwReserved0: Type.DWORD.implementation },
-          { dwReserved1: Type.DWORD.implementation },
-          { cFileName: ctypes.ArrayType(ctypes.char16_t, Const.MAX_PATH) },
-          { cAlternateFileName: ctypes.ArrayType(ctypes.char16_t, 14) },
-        ])
-      );
-
-      Type.FILE_INFORMATION = new SharedAll.Type(
-        "FILE_INFORMATION",
-        ctypes.StructType("FILE_INFORMATION", [
-          { dwFileAttributes: ctypes.uint32_t },
-          { ftCreationTime: Type.FILETIME.implementation },
-          { ftLastAccessTime: Type.FILETIME.implementation },
-          { ftLastWriteTime: Type.FILETIME.implementation },
-          { dwVolumeSerialNumber: ctypes.uint32_t },
-          { nFileSizeHigh: Type.DWORD.implementation },
-          { nFileSizeLow: Type.DWORD.implementation },
-          { nNumberOfLinks: ctypes.uint32_t },
-          { nFileIndex: ctypes.uint64_t },
-        ])
-      );
-
-      Type.SystemTime = new SharedAll.Type(
-        "SystemTime",
-        ctypes.StructType("SystemTime", [
-          { wYear: ctypes.int16_t },
-          { wMonth: ctypes.int16_t },
-          { wDayOfWeek: ctypes.int16_t },
-          { wDay: ctypes.int16_t },
-          { wHour: ctypes.int16_t },
-          { wMinute: ctypes.int16_t },
-          { wSecond: ctypes.int16_t },
-          { wMilliSeconds: ctypes.int16_t },
-        ])
-      );
-
-      // Special case: these functions are used by the
-      // finalizer
-      libc.declareLazy(
-        SysFile,
-        "_CloseHandle",
-        "CloseHandle",
-        ctypes.winapi_abi,
-        /* return */ ctypes.bool,
-        /* handle*/ ctypes.voidptr_t
-      );
-
-      SysFile.CloseHandle = function(fd) {
-        if (fd == INVALID_HANDLE) {
-          return true;
-        }
-        return fd.dispose(); // Returns the value of |CloseHandle|.
-      };
-
-      libc.declareLazy(
-        SysFile,
-        "_FindClose",
-        "FindClose",
-        ctypes.winapi_abi,
-        /* return */ ctypes.bool,
-        /* handle*/ ctypes.voidptr_t
-      );
-
-      SysFile.FindClose = function(handle) {
-        if (handle == INVALID_HANDLE) {
-          return true;
-        }
-        return handle.dispose(); // Returns the value of |FindClose|.
-      };
-
-      // Declare libc functions as functions of |OS.Win.File|
-
-      libc.declareLazyFFI(
-        SysFile,
-        "CopyFile",
-        "CopyFileW",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_nothing,
-        /* sourcePath*/ Type.path,
-        Type.path,
-        /* bailIfExist*/ Type.bool
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "CreateDirectory",
-        "CreateDirectoryW",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_nothing,
-        Type.char16_t.in_ptr,
-        /* security*/ Type.SECURITY_ATTRIBUTES.in_ptr
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "CreateFile",
-        "CreateFileW",
-        ctypes.winapi_abi,
-        Type.file_HANDLE,
-        Type.path,
-        Type.DWORD_FLAGS,
-        Type.DWORD_FLAGS,
-        /* security*/ Type.SECURITY_ATTRIBUTES.in_ptr,
-        /* creation*/ Type.DWORD_FLAGS,
-        Type.DWORD_FLAGS,
-        /* template*/ Type.HANDLE
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "DeleteFile",
-        "DeleteFileW",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_nothing,
-        Type.path
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "FileTimeToSystemTime",
-        "FileTimeToSystemTime",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_nothing,
-        /* filetime*/ Type.FILETIME.in_ptr,
-        /* systime*/ Type.SystemTime.out_ptr
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "SystemTimeToFileTime",
-        "SystemTimeToFileTime",
-        ctypes.winapi_abi,
-        Type.zero_or_nothing,
-        Type.SystemTime.in_ptr,
-        /* filetime*/ Type.FILETIME.out_ptr
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "FindFirstFile",
-        "FindFirstFileW",
-        ctypes.winapi_abi,
-        /* return*/ Type.find_HANDLE,
-        /* pattern*/ Type.path,
-        Type.FindData.out_ptr
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "FindNextFile",
-        "FindNextFileW",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_nothing,
-        Type.find_HANDLE,
-        Type.FindData.out_ptr
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "FormatMessage",
-        "FormatMessageW",
-        ctypes.winapi_abi,
-        /* return*/ Type.DWORD,
-        Type.DWORD_FLAGS,
-        /* source*/ Type.void_t.in_ptr,
-        Type.DWORD_FLAGS,
-        /* langid*/ Type.DWORD_FLAGS,
-        Type.out_wstring,
-        Type.DWORD,
-        /* Arguments*/ Type.void_t.in_ptr
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "GetCurrentDirectory",
-        "GetCurrentDirectoryW",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_DWORD,
-        /* length*/ Type.DWORD,
-        Type.out_path
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "GetFullPathName",
-        "GetFullPathNameW",
-        ctypes.winapi_abi,
-        Type.zero_or_DWORD,
-        /* fileName*/ Type.path,
-        Type.DWORD,
-        Type.out_path,
-        /* filePart*/ Type.DWORD
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "GetDiskFreeSpaceEx",
-        "GetDiskFreeSpaceExW",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_nothing,
-        /* directoryName*/ Type.path,
-        /* freeBytesForUser*/ Type.uint64_t.out_ptr,
-        /* totalBytesForUser*/ Type.uint64_t.out_ptr,
-        /* freeTotalBytesOnDrive*/ Type.uint64_t.out_ptr
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "GetFileInformationByHandle",
-        "GetFileInformationByHandle",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_nothing,
-        /* handle*/ Type.HANDLE,
-        Type.FILE_INFORMATION.out_ptr
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "MoveFileEx",
-        "MoveFileExW",
-        ctypes.winapi_abi,
-        Type.zero_or_nothing,
-        /* sourcePath*/ Type.path,
-        /* destPath*/ Type.path,
-        Type.DWORD
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "ReadFile",
-        "ReadFile",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_nothing,
-        Type.HANDLE,
-        /* buffer*/ Type.voidptr_t,
-        /* nbytes*/ Type.DWORD,
-        /* nbytes_read*/ Type.DWORD.out_ptr,
-        /* overlapped*/ Type.void_t.inout_ptr // FIXME: Implement?
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "RemoveDirectory",
-        "RemoveDirectoryW",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_nothing,
-        Type.path
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "SetEndOfFile",
-        "SetEndOfFile",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_nothing,
-        Type.HANDLE
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "SetFilePointer",
-        "SetFilePointer",
-        ctypes.winapi_abi,
-        /* return*/ Type.DWORD,
-        Type.HANDLE,
-        /* distlow*/ Type.long,
-        /* disthi*/ Type.long.in_ptr,
-        /* method*/ Type.DWORD
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "SetFileTime",
-        "SetFileTime",
-        ctypes.winapi_abi,
-        Type.zero_or_nothing,
-        Type.HANDLE,
-        /* creation*/ Type.FILETIME.in_ptr,
-        Type.FILETIME.in_ptr,
-        Type.FILETIME.in_ptr
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "WriteFile",
-        "WriteFile",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_nothing,
-        Type.HANDLE,
-        /* buffer*/ Type.voidptr_t,
-        /* nbytes*/ Type.DWORD,
-        /* nbytes_wr*/ Type.DWORD.out_ptr,
-        /* overlapped*/ Type.void_t.inout_ptr // FIXME: Implement?
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "FlushFileBuffers",
-        "FlushFileBuffers",
-        ctypes.winapi_abi,
-        /* return*/ Type.zero_or_nothing,
-        Type.HANDLE
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "GetFileAttributes",
-        "GetFileAttributesW",
-        ctypes.winapi_abi,
-        Type.DWORD_FLAGS,
-        /* fileName*/ Type.path
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "SetFileAttributes",
-        "SetFileAttributesW",
-        ctypes.winapi_abi,
-        Type.zero_or_nothing,
-        Type.path,
-        /* fileAttributes*/ Type.DWORD_FLAGS
-      );
-
-      advapi32.declareLazyFFI(
-        SysFile,
-        "GetNamedSecurityInfo",
-        "GetNamedSecurityInfoW",
-        ctypes.winapi_abi,
-        Type.DWORD,
-        Type.path,
-        Type.DWORD,
-        /* securityInfo*/ Type.DWORD,
-        Type.PSID.out_ptr,
-        Type.PSID.out_ptr,
-        Type.PACL.out_ptr,
-        Type.PACL.out_ptr,
-        /* securityDesc*/ Type.PSECURITY_DESCRIPTOR.out_ptr
-      );
-
-      advapi32.declareLazyFFI(
-        SysFile,
-        "SetNamedSecurityInfo",
-        "SetNamedSecurityInfoW",
-        ctypes.winapi_abi,
-        Type.DWORD,
-        Type.path,
-        Type.DWORD,
-        /* securityInfo*/ Type.DWORD,
-        Type.PSID,
-        Type.PSID,
-        Type.PACL,
-        Type.PACL
-      );
-
-      libc.declareLazyFFI(
-        SysFile,
-        "LocalFree",
-        "LocalFree",
-        ctypes.winapi_abi,
-        Type.HLOCAL,
-        Type.HLOCAL
-      );
-    };
-
-    exports.OS.Win = {
-      File: {
-        _init: init,
-      },
-    };
-  })(this);
-}
deleted file mode 100644
--- a/toolkit/components/osfile/modules/osfile_win_front.js
+++ /dev/null
@@ -1,1322 +0,0 @@
-/* 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/. */
-
-/**
- * Synchronous front-end for the JavaScript OS.File library.
- * Windows implementation.
- *
- * This front-end is meant to be imported by a worker thread.
- */
-
-/* eslint-env mozilla/chrome-worker, node */
-/* global OS */
-
-// eslint-disable-next-line no-lone-blocks
-{
-  if (typeof Components != "undefined") {
-    // We do not wish osfile_win_front.js to be used directly as a main thread
-    // module yet.
-    throw new Error(
-      "osfile_win_front.js cannot be used from the main thread yet"
-    );
-  }
-
-  (function(exports) {
-    "use strict";
-
-    // exports.OS.Win is created by osfile_win_back.js
-    if (exports.OS && exports.OS.File) {
-      return; // Avoid double-initialization
-    }
-
-    let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
-    let Path = require("resource://gre/modules/osfile/ospath.jsm");
-    let SysAll = require("resource://gre/modules/osfile/osfile_win_allthreads.jsm");
-    exports.OS.Win.File._init();
-    let Const = exports.OS.Constants.Win;
-    let WinFile = exports.OS.Win.File;
-    let Type = WinFile.Type;
-
-    // Mutable thread-global data
-    // In the Windows implementation, methods |read| and |write|
-    // require passing a pointer to an uint32 to determine how many
-    // bytes have been read/written. In C, this is a benigne operation,
-    // but in js-ctypes, this has a cost. Rather than re-allocating a
-    // C uint32 and a C uint32* for each |read|/|write|, we take advantage
-    // of the fact that the state is thread-private -- hence that two
-    // |read|/|write| operations cannot take place at the same time --
-    // and we use the following global mutable values:
-    let gBytesRead = new ctypes.uint32_t(0);
-    let gBytesReadPtr = gBytesRead.address();
-    let gBytesWritten = new ctypes.uint32_t(0);
-    let gBytesWrittenPtr = gBytesWritten.address();
-
-    // Same story for GetFileInformationByHandle
-    let gFileInfo = new Type.FILE_INFORMATION.implementation();
-    let gFileInfoPtr = gFileInfo.address();
-
-    /**
-     * Representation of a file.
-     *
-     * You generally do not need to call this constructor yourself. Rather,
-     * to open a file, use function |OS.File.open|.
-     *
-     * @param fd A OS-specific file descriptor.
-     * @param {string} path File path of the file handle, used for error-reporting.
-     * @constructor
-     */
-    let File = function File(fd, path) {
-      exports.OS.Shared.AbstractFile.call(this, fd, path);
-      this._closeResult = null;
-    };
-    File.prototype = Object.create(exports.OS.Shared.AbstractFile.prototype);
-
-    /**
-     * Close the file.
-     *
-     * This method has no effect if the file is already closed. However,
-     * if the first call to |close| has thrown an error, further calls
-     * will throw the same error.
-     *
-     * @throws File.Error If closing the file revealed an error that could
-     * not be reported earlier.
-     */
-    File.prototype.close = function close() {
-      if (this._fd) {
-        let fd = this._fd;
-        this._fd = null;
-        // Call |close(fd)|, detach finalizer if any
-        // (|fd| may not be a CDataFinalizer if it has been
-        // instantiated from a controller thread).
-        let result = WinFile._CloseHandle(fd);
-        if (typeof fd == "object" && "forget" in fd) {
-          fd.forget();
-        }
-        if (result == -1) {
-          this._closeResult = new File.Error(
-            "close",
-            ctypes.winLastError,
-            this._path
-          );
-        }
-      }
-      if (this._closeResult) {
-        throw this._closeResult;
-      }
-    };
-
-    /**
-     * Read some bytes from a file.
-     *
-     * @param {C pointer} buffer A buffer for holding the data
-     * once it is read.
-     * @param {number} nbytes The number of bytes to read. It must not
-     * exceed the size of |buffer| in bytes but it may exceed the number
-     * of bytes unread in the file.
-     * @param {*=} options Additional options for reading. Ignored in
-     * this implementation.
-     *
-     * @return {number} The number of bytes effectively read. If zero,
-     * the end of the file has been reached.
-     * @throws {OS.File.Error} In case of I/O error.
-     */
-    File.prototype._read = function _read(buffer, nbytes, options) {
-      // |gBytesReadPtr| is a pointer to |gBytesRead|.
-      throw_on_zero(
-        "read",
-        WinFile.ReadFile(this.fd, buffer, nbytes, gBytesReadPtr, null),
-        this._path
-      );
-      return gBytesRead.value;
-    };
-
-    /**
-     * Write some bytes to a file.
-     *
-     * @param {Typed array} buffer A buffer holding the data that must be
-     * written.
-     * @param {number} nbytes The number of bytes to write. It must not
-     * exceed the size of |buffer| in bytes.
-     * @param {*=} options Additional options for writing. Ignored in
-     * this implementation.
-     *
-     * @return {number} The number of bytes effectively written.
-     * @throws {OS.File.Error} In case of I/O error.
-     */
-    File.prototype._write = function _write(buffer, nbytes, options) {
-      if (this._appendMode) {
-        // Need to manually seek on Windows, as O_APPEND is not supported.
-        // This is, of course, a race, but there is no real way around this.
-        this.setPosition(0, File.POS_END);
-      }
-      // |gBytesWrittenPtr| is a pointer to |gBytesWritten|.
-      throw_on_zero(
-        "write",
-        WinFile.WriteFile(this.fd, buffer, nbytes, gBytesWrittenPtr, null),
-        this._path
-      );
-      return gBytesWritten.value;
-    };
-
-    /**
-     * Return the current position in the file.
-     */
-    File.prototype.getPosition = function getPosition(pos) {
-      return this.setPosition(0, File.POS_CURRENT);
-    };
-
-    /**
-     * Change the current position in the file.
-     *
-     * @param {number} pos The new position. Whether this position
-     * is considered from the current position, from the start of
-     * the file or from the end of the file is determined by
-     * argument |whence|.  Note that |pos| may exceed the length of
-     * the file.
-     * @param {number=} whence The reference position. If omitted
-     * or |OS.File.POS_START|, |pos| is relative to the start of the
-     * file.  If |OS.File.POS_CURRENT|, |pos| is relative to the
-     * current position in the file. If |OS.File.POS_END|, |pos| is
-     * relative to the end of the file.
-     *
-     * @return The new position in the file.
-     */
-    File.prototype.setPosition = function setPosition(pos, whence) {
-      if (whence === undefined) {
-        whence = Const.FILE_BEGIN;
-      }
-      let pos64 = ctypes.Int64(pos);
-      // Per MSDN, while |lDistanceToMove| (low) is declared as int32_t, when
-      // providing |lDistanceToMoveHigh| as well, it should countain the
-      // bottom 32 bits of the 64-bit integer. Hence the following |posLo|
-      // cast is OK.
-      let posLo = new ctypes.uint32_t(ctypes.Int64.lo(pos64));
-      posLo = ctypes.cast(posLo, ctypes.int32_t);
-      let posHi = new ctypes.int32_t(ctypes.Int64.hi(pos64));
-      let result = WinFile.SetFilePointer(
-        this.fd,
-        posLo.value,
-        posHi.address(),
-        whence
-      );
-      // INVALID_SET_FILE_POINTER might be still a valid result, as it
-      // represents the lower 32 bit of the int64 result. MSDN says to check
-      // both, INVALID_SET_FILE_POINTER and a non-zero winLastError.
-      if (result == Const.INVALID_SET_FILE_POINTER && ctypes.winLastError) {
-        throw new File.Error("setPosition", ctypes.winLastError, this._path);
-      }
-      pos64 = ctypes.Int64.join(posHi.value, result);
-      return Type.int64_t.project(pos64);
-    };
-
-    /**
-     * Fetch the information on the file.
-     *
-     * @return File.Info The information on |this| file.
-     */
-    File.prototype.stat = function stat() {
-      throw_on_zero(
-        "stat",
-        WinFile.GetFileInformationByHandle(this.fd, gFileInfoPtr),
-        this._path
-      );
-      return new File.Info(gFileInfo, this._path);
-    };
-
-    /**
-     * Set the last access and modification date of the file.
-     * The time stamp resolution is 1 second at best, but might be worse
-     * depending on the platform.
-     *
-     * @param {Date,number=} accessDate The last access date. If numeric,
-     * milliseconds since epoch. If omitted or null, then the current date
-     * will be used.
-     * @param {Date,number=} modificationDate The last modification date. If
-     * numeric, milliseconds since epoch. If omitted or null, then the current
-     * date will be used.
-     *
-     * @throws {TypeError} In case of invalid parameters.
-     * @throws {OS.File.Error} In case of I/O error.
-     */
-    File.prototype.setDates = function setDates(accessDate, modificationDate) {
-      accessDate = Date_to_FILETIME(
-        "File.prototype.setDates",
-        accessDate,
-        this._path
-      );
-      modificationDate = Date_to_FILETIME(
-        "File.prototype.setDates",
-        modificationDate,
-        this._path
-      );
-      throw_on_zero(
-        "setDates",
-        WinFile.SetFileTime(
-          this.fd,
-          null,
-          accessDate.address(),
-          modificationDate.address()
-        ),
-        this._path
-      );
-    };
-
-    /**
-     * Set the file's access permission bits.
-     */
-    File.prototype.setPermissions = function setPermissions(options = {}) {
-      if (!("winAttributes" in options)) {
-        return;
-      }
-      let oldAttributes = WinFile.GetFileAttributes(this._path);
-      if (oldAttributes == Const.INVALID_FILE_ATTRIBUTES) {
-        throw new File.Error("setPermissions", ctypes.winLastError, this._path);
-      }
-      let newAttributes = toFileAttributes(
-        options.winAttributes,
-        oldAttributes
-      );
-      throw_on_zero(
-        "setPermissions",
-        WinFile.SetFileAttributes(this._path, newAttributes),
-        this._path
-      );
-    };
-
-    /**
-     * Flushes the file's buffers and causes all buffered data
-     * to be written.
-     * Disk flushes are very expensive and therefore should be used carefully,
-     * sparingly and only in scenarios where it is vital that data survives
-     * system crashes. Even though the function will be executed off the
-     * main-thread, it might still affect the overall performance of any
-     * running application.
-     *
-     * @throws {OS.File.Error} In case of I/O error.
-     */
-    File.prototype.flush = function flush() {
-      throw_on_zero("flush", WinFile.FlushFileBuffers(this.fd), this._path);
-    };
-
-    // The default sharing mode for opening files: files are not
-    // locked against being reopened for reading/writing or against
-    // being deleted by the same process or another process.
-    // This is consistent with the default Unix policy.
-    const DEFAULT_SHARE =
-      Const.FILE_SHARE_READ | Const.FILE_SHARE_WRITE | Const.FILE_SHARE_DELETE;
-
-    // The default flags for opening files.
-    const DEFAULT_FLAGS = Const.FILE_ATTRIBUTE_NORMAL;
-
-    /**
-     * Open a file
-     *
-     * @param {string} path The path to the file.
-     * @param {*=} mode The opening mode for the file, as
-     * an object that may contain the following fields:
-     *
-     * - {bool} truncate If |true|, the file will be opened
-     *  for writing. If the file does not exist, it will be
-     *  created. If the file exists, its contents will be
-     *  erased. Cannot be specified with |create|.
-     * - {bool} create If |true|, the file will be opened
-     *  for writing. If the file exists, this function fails.
-     *  If the file does not exist, it will be created. Cannot
-     *  be specified with |truncate| or |existing|.
-     * - {bool} existing. If the file does not exist, this function
-     *  fails. Cannot be specified with |create|.
-     * - {bool} read If |true|, the file will be opened for
-     *  reading. The file may also be opened for writing, depending
-     *  on the other fields of |mode|.
-     * - {bool} write If |true|, the file will be opened for
-     *  writing. The file may also be opened for reading, depending
-     *  on the other fields of |mode|.
-     * - {bool} append If |true|, the file will be opened for appending,
-     *  meaning the equivalent of |.setPosition(0, POS_END)| is executed
-     *  before each write. The default is |true|, i.e. opening a file for
-     *  appending. Specify |append: false| to open the file in regular mode.
-     *
-     * If neither |truncate|, |create| or |write| is specified, the file
-     * is opened for reading.
-     *
-     * Note that |false|, |null| or |undefined| flags are simply ignored.
-     *
-     * @param {*=} options Additional options for file opening. This
-     * implementation interprets the following fields:
-     *
-     * - {number} winShare If specified, a share mode, as per
-     * Windows function |CreateFile|. You can build it from
-     * constants |OS.Constants.Win.FILE_SHARE_*|. If unspecified,
-     * the file uses the default sharing policy: it can be opened
-     * for reading and/or writing and it can be removed by other
-     * processes and by the same process.
-     * - {number} winSecurity If specified, Windows security
-     * attributes, as per Windows function |CreateFile|. If unspecified,
-     * no security attributes.
-     * - {number} winAccess If specified, Windows access mode, as
-     * per Windows function |CreateFile|. This also requires option
-     * |winDisposition| and this replaces argument |mode|. If unspecified,
-     * uses the string |mode|.
-     * - {number} winDisposition If specified, Windows disposition mode,
-     * as per Windows function |CreateFile|. This also requires option
-     * |winAccess| and this replaces argument |mode|. If unspecified,
-     * uses the string |mode|.
-     *
-     * @return {File} A file object.
-     * @throws {OS.File.Error} If the file could not be opened.
-     */
-    File.open = function Win_open(path, mode = {}, options = {}) {
-      let share =
-        options.winShare !== undefined ? options.winShare : DEFAULT_SHARE;
-      let security = options.winSecurity || null;
-      let flags =
-        options.winFlags !== undefined ? options.winFlags : DEFAULT_FLAGS;
-      let template = options.winTemplate ? options.winTemplate._fd : null;
-      let access;
-      let disposition;
-
-      mode = OS.Shared.AbstractFile.normalizeOpenMode(mode);
-
-      // The following option isn't a generic implementation of access to paths
-      // of arbitrary lengths. It allows for the specific case of writing to an
-      // Alternate Data Stream on a file whose path length is already close to
-      // MAX_PATH. This implementation is safe with a full path as input, if
-      // the first part of the path comes from local configuration and the
-      // file without the ADS was successfully opened before, so we know the
-      // path is valid.
-      if (options.winAllowLengthBeyondMaxPathWithCaveats) {
-        // Use the \\?\ syntax to allow lengths beyond MAX_PATH. This limited
-        // implementation only supports a DOS local path or UNC path as input.
-        let isUNC =
-          path.length >= 2 &&
-          (path[0] == "\\" || path[0] == "/") &&
-          (path[1] == "\\" || path[1] == "/");
-        let pathToUse = "\\\\?\\" + (isUNC ? "UNC\\" + path.slice(2) : path);
-        // Use GetFullPathName to normalize slashes into backslashes. This is
-        // required because CreateFile won't do this for the \\?\ syntax.
-        let buffer_size = 512;
-        let array = new (ctypes.ArrayType(ctypes.char16_t, buffer_size))();
-        let expected_size = throw_on_zero(
-          "open",
-          WinFile.GetFullPathName(pathToUse, buffer_size, array, 0)
-        );
-        if (expected_size > buffer_size) {
-          // We don't need to allow an arbitrary path length for now.
-          throw new File.Error("open", ctypes.winLastError, path);
-        }
-        path = array.readString();
-      }
-
-      if ("winAccess" in options && "winDisposition" in options) {
-        access = options.winAccess;
-        disposition = options.winDisposition;
-      } else if (
-        ("winAccess" in options && !("winDisposition" in options)) ||
-        (!("winAccess" in options) && "winDisposition" in options)
-      ) {
-        throw new TypeError(
-          "OS.File.open requires either both options " +
-            "winAccess and winDisposition or neither"
-        );
-      } else {
-        if (mode.read) {
-          access |= Const.GENERIC_READ;
-        }
-        if (mode.write) {
-          access |= Const.GENERIC_WRITE;
-        }
-        // Finally, handle create/existing/trunc
-        if (mode.trunc) {
-          if (mode.existing) {
-            // It seems that Const.TRUNCATE_EXISTING is broken
-            // in presence of links (source, anyone?). We need
-            // to open normally, then perform truncation manually.
-            disposition = Const.OPEN_EXISTING;
-          } else {
-            disposition = Const.CREATE_ALWAYS;
-          }
-        } else if (mode.create) {
-          disposition = Const.CREATE_NEW;
-        } else if (mode.read && !mode.write) {
-          disposition = Const.OPEN_EXISTING;
-        } else if (mode.existing) {
-          disposition = Const.OPEN_EXISTING;
-        } else {
-          disposition = Const.OPEN_ALWAYS;
-        }
-      }
-
-      let file = error_or_file(
-        WinFile.CreateFile(
-          path,
-          access,
-          share,
-          security,
-          disposition,
-          flags,
-          template
-        ),
-        path
-      );
-
-      file._appendMode = !!mode.append;
-
-      if (!(mode.trunc && mode.existing)) {
-        return file;
-      }
-      // Now, perform manual truncation
-      file.setPosition(0, File.POS_START);
-      throw_on_zero("open", WinFile.SetEndOfFile(file.fd), path);
-      return file;
-    };
-
-    /**
-     * Checks if a file or directory exists
-     *
-     * @param {string} path The path to the file.
-     *
-     * @return {bool} true if the file exists, false otherwise.
-     */
-    File.exists = function Win_exists(path) {
-      try {
-        let file = File.open(path, FILE_STAT_MODE, FILE_STAT_OPTIONS);
-        file.close();
-        return true;
-      } catch (x) {
-        return false;
-      }
-    };
-
-    /**
-     * Remove an existing file.
-     *
-     * @param {string} path The name of the file.
-     * @param {*=} options Additional options.
-     *   - {bool} ignoreAbsent If |false|, throw an error if the file does
-     *     not exist. |true| by default.
-     *
-     * @throws {OS.File.Error} In case of I/O error.
-     */
-    File.remove = function remove(path, options = {}) {
-      if (WinFile.DeleteFile(path)) {
-        return;
-      }
-
-      if (
-        ctypes.winLastError == Const.ERROR_FILE_NOT_FOUND ||
-        ctypes.winLastError == Const.ERROR_PATH_NOT_FOUND
-      ) {
-        if (!("ignoreAbsent" in options) || options.ignoreAbsent) {
-          return;
-        }
-      } else if (ctypes.winLastError == Const.ERROR_ACCESS_DENIED) {
-        // Save winLastError before another ctypes call.
-        let lastError = ctypes.winLastError;
-        let attributes = WinFile.GetFileAttributes(path);
-        if (attributes != Const.INVALID_FILE_ATTRIBUTES) {
-          if (!(attributes & Const.FILE_ATTRIBUTE_READONLY)) {
-            throw new File.Error("remove", lastError, path);
-          }
-          let newAttributes = attributes & ~Const.FILE_ATTRIBUTE_READONLY;
-          if (
-            WinFile.SetFileAttributes(path, newAttributes) &&
-            WinFile.DeleteFile(path)
-          ) {
-            return;
-          }
-        }
-      }
-
-      throw new File.Error("remove", ctypes.winLastError, path);
-    };
-
-    /**
-     * Remove an empty directory.
-     *
-     * @param {string} path The name of the directory to remove.
-     * @param {*=} options Additional options.
-     *   - {bool} ignoreAbsent If |false|, throw an error if the directory
-     *     does not exist. |true| by default
-     */
-    File.removeEmptyDir = function removeEmptyDir(path, options = {}) {
-      let result = WinFile.RemoveDirectory(path);
-      if (!result) {
-        if (
-          (!("ignoreAbsent" in options) || options.ignoreAbsent) &&
-          ctypes.winLastError == Const.ERROR_FILE_NOT_FOUND
-        ) {
-          return;
-        }
-        throw new File.Error("removeEmptyDir", ctypes.winLastError, path);
-      }
-    };
-
-    /**
-     * Create a directory and, optionally, its parent directories.
-     *
-     * @param {string} path The name of the directory.
-     * @param {*=} options Additional options. This
-     * implementation interprets the following fields:
-     *
-     * - {C pointer} winSecurity If specified, security attributes
-     * as per winapi function |CreateDirectory|. If unspecified,
-     * use the default security descriptor, inherited from the
-     * parent directory.
-     * - {bool} ignoreExisting If |false|, throw an error if the directory
-     * already exists. |true| by default
-     * - {string} from If specified, the call to |makeDir| creates all the
-     * ancestors of |path| that are descendants of |from|. Note that |from|
-     * and its existing descendants must be user-writeable and that |path|
-     * must be a descendant of |from|.
-     * Example:
-     *   makeDir(Path.join(profileDir, "foo", "bar"), { from: profileDir });
-     *  creates directories profileDir/foo, profileDir/foo/bar
-     */
-    File._makeDir = function makeDir(path, options = {}) {
-      let security = options.winSecurity || null;
-      let result = WinFile.CreateDirectory(path, security);
-
-      if (result) {
-        return;
-      }
-
-      if ("ignoreExisting" in options && !options.ignoreExisting) {
-        throw new File.Error("makeDir", ctypes.winLastError, path);
-      }
-
-      if (ctypes.winLastError == Const.ERROR_ALREADY_EXISTS) {
-        return;
-      }
-
-      // If the user has no access, but it's a root directory, no error should be thrown
-      let splitPath = OS.Path.split(path);
-      // Removing last component if it's empty
-      // An empty last component is caused by trailing slashes in path
-      // This is always the case with root directories
-      if (splitPath.components[splitPath.components.length - 1].length === 0) {
-        splitPath.components.pop();
-      }
-      // One component consisting of a drive letter implies a directory root.
-      if (
-        ctypes.winLastError == Const.ERROR_ACCESS_DENIED &&
-        splitPath.winDrive &&
-        splitPath.components.length === 1
-      ) {
-        return;
-      }
-
-      throw new File.Error("makeDir", ctypes.winLastError, path);
-    };
-
-    /**
-     * Copy a file to a destination.
-     *
-     * @param {string} sourcePath The platform-specific path at which
-     * the file may currently be found.
-     * @param {string} destPath The platform-specific path at which the
-     * file should be copied.
-     * @param {*=} options An object which may contain the following fields:
-     *
-     * @option {bool} noOverwrite - If true, this function will fail if
-     * a file already exists at |destPath|. Otherwise, if this file exists,
-     * it will be erased silently.
-     *
-     * @throws {OS.File.Error} In case of any error.
-     *
-     * General note: The behavior of this function is defined only when
-     * it is called on a single file. If it is called on a directory, the
-     * behavior is undefined and may not be the same across all platforms.
-     *
-     * General note: The behavior of this function with respect to metadata
-     * is unspecified. Metadata may or may not be copied with the file. The
-     * behavior may not be the same across all platforms.
-     */
-    File.copy = function copy(sourcePath, destPath, options = {}) {
-      throw_on_zero(
-        "copy",
-        WinFile.CopyFile(sourcePath, destPath, options.noOverwrite || false),
-        sourcePath
-      );
-    };
-
-    /**
-     * Move a file to a destination.
-     *
-     * @param {string} sourcePath The platform-specific path at which
-     * the file may currently be found.
-     * @param {string} destPath The platform-specific path at which the
-     * file should be moved.
-     * @param {*=} options An object which may contain the following fields:
-     *
-     * @option {bool} noOverwrite - If set, this function will fail if
-     * a file already exists at |destPath|. Otherwise, if this file exists,
-     * it will be erased silently.
-     * @option {bool} noCopy - If set, this function will fail if the
-     * operation is more sophisticated than a simple renaming, i.e. if
-     * |sourcePath| and |destPath| are not situated on the same drive.
-     *
-     * @throws {OS.File.Error} In case of any error.
-     *
-     * General note: The behavior of this function is defined only when
-     * it is called on a single file. If it is called on a directory, the
-     * behavior is undefined and may not be the same across all platforms.
-     *
-     * General note: The behavior of this function with respect to metadata
-     * is unspecified. Metadata may or may not be moved with the file. The
-     * behavior may not be the same across all platforms.
-     */
-    File.move = function move(sourcePath, destPath, options = {}) {
-      let flags = 0;
-      if (!options.noCopy) {
-        flags = Const.MOVEFILE_COPY_ALLOWED;
-      }
-      if (!options.noOverwrite) {
-        flags = flags | Const.MOVEFILE_REPLACE_EXISTING;
-      }
-      throw_on_zero(
-        "move",
-        WinFile.MoveFileEx(sourcePath, destPath, flags),
-        sourcePath
-      );
-
-      // Inherit NTFS permissions from the destination directory
-      // if possible.
-      if (Path.dirname(sourcePath) === Path.dirname(destPath)) {
-        // Skip if the move operation was the simple rename,
-        return;
-      }
-      // The function may fail for various reasons (e.g. not all
-      // filesystems support NTFS permissions or the user may not
-      // have the enough rights to read/write permissions).
-      // However we can safely ignore errors. The file was already
-      // moved. Setting permissions is not mandatory.
-      let dacl = new ctypes.voidptr_t();
-      let sd = new ctypes.voidptr_t();
-      WinFile.GetNamedSecurityInfo(
-        destPath,
-        Const.SE_FILE_OBJECT,
-        Const.DACL_SECURITY_INFORMATION,
-        null /* sidOwner*/,
-        null /* sidGroup*/,
-        dacl.address(),
-        null /* sacl*/,
-        sd.address()
-      );
-      // dacl will be set only if the function succeeds.
-      if (!dacl.isNull()) {
-        WinFile.SetNamedSecurityInfo(
-          destPath,
-          Const.SE_FILE_OBJECT,
-          Const.DACL_SECURITY_INFORMATION |
-            Const.UNPROTECTED_DACL_SECURITY_INFORMATION,
-          null /* sidOwner*/,
-          null /* sidGroup*/,
-          dacl,
-          null /* sacl*/
-        );
-      }
-      // sd will be set only if the function succeeds.
-      if (!sd.isNull()) {
-        WinFile.LocalFree(Type.HLOCAL.cast(sd));
-      }
-    };
-
-    /**
-     * A global value used to receive data during time conversions.
-     */
-    let gSystemTime = new Type.SystemTime.implementation();
-    let gSystemTimePtr = gSystemTime.address();
-
-    /**
-     * Utility function: convert a FILETIME to a JavaScript Date.
-     */
-    let FILETIME_to_Date = function FILETIME_to_Date(fileTime, path) {
-      if (fileTime == null) {
-        throw new TypeError("Expecting a non-null filetime");
-      }
-      throw_on_zero(
-        "FILETIME_to_Date",
-        WinFile.FileTimeToSystemTime(fileTime.address(), gSystemTimePtr),
-        path
-      );
-      // Windows counts hours, minutes, seconds from UTC,
-      // JS counts from local time, so we need to go through UTC.
-      let utc = Date.UTC(
-        gSystemTime.wYear,
-        gSystemTime.wMonth - 1,
-        /* Windows counts months from 1, JS from 0*/ gSystemTime.wDay,
-        gSystemTime.wHour,
-        gSystemTime.wMinute,
-        gSystemTime.wSecond,
-        gSystemTime.wMilliSeconds
-      );
-      return new Date(utc);
-    };
-
-    /**
-     * Utility function: convert Javascript Date to FileTime.
-     *
-     * @param {string} fn Name of the calling function.
-     * @param {Date,number} date The date to be converted. If omitted or null,
-     * then the current date will be used. If numeric, assumed to be the date
-     * in milliseconds since epoch.
-     */
-    let Date_to_FILETIME = function Date_to_FILETIME(fn, date, path) {
-      if (typeof date === "number") {
-        date = new Date(date);
-      } else if (!date) {
-        date = new Date();
-      } else if (typeof date.getUTCFullYear !== "function") {
-        throw new TypeError(
-          "|date| parameter of " +
-            fn +
-            " must be a " +
-            "|Date| instance or number"
-        );
-      }
-      gSystemTime.wYear = date.getUTCFullYear();
-      // Windows counts months from 1, JS from 0.
-      gSystemTime.wMonth = date.getUTCMonth() + 1;
-      gSystemTime.wDay = date.getUTCDate();
-      gSystemTime.wHour = date.getUTCHours();
-      gSystemTime.wMinute = date.getUTCMinutes();
-      gSystemTime.wSecond = date.getUTCSeconds();
-      gSystemTime.wMilliseconds = date.getUTCMilliseconds();
-      let result = new OS.Shared.Type.FILETIME.implementation();
-      throw_on_zero(
-        "Date_to_FILETIME",
-        WinFile.SystemTimeToFileTime(gSystemTimePtr, result.address()),
-        path
-      );
-      return result;
-    };
-
-    /**
-     * Iterate on one directory.
-     *
-     * This iterator will not enter subdirectories.
-     *
-     * @param {string} path The directory upon which to iterate.
-     * @param {*=} options An object that may contain the following field:
-     * @option {string} winPattern Windows file name pattern; if set,
-     * only files matching this pattern are returned.
-     *
-     * @throws {File.Error} If |path| does not represent a directory or
-     * if the directory cannot be iterated.
-     * @constructor
-     */
-    File.DirectoryIterator = function DirectoryIterator(path, options) {
-      exports.OS.Shared.AbstractFile.AbstractIterator.call(this);
-      if (options && options.winPattern) {
-        this._pattern = path + "\\" + options.winPattern;
-      } else {
-        this._pattern = path + "\\*";
-      }
-      this._path = path;
-
-      // Pre-open the first item.
-      this._first = true;
-      this._findData = new Type.FindData.implementation();
-      this._findDataPtr = this._findData.address();
-      this._handle = WinFile.FindFirstFile(this._pattern, this._findDataPtr);
-      if (this._handle == Const.INVALID_HANDLE_VALUE) {
-        let error = ctypes.winLastError;
-        this._findData = null;
-        this._findDataPtr = null;
-        if (error == Const.ERROR_FILE_NOT_FOUND) {
-          // Directory is empty, let's behave as if it were closed
-          SharedAll.LOG("Directory is empty");
-          this._closed = true;
-          this._exists = true;
-        } else if (error == Const.ERROR_PATH_NOT_FOUND) {
-          // Directory does not exist, let's throw if we attempt to walk it
-          SharedAll.LOG("Directory does not exist");
-          this._closed = true;
-          this._exists = false;
-        } else {
-          throw new File.Error("DirectoryIterator", error, this._path);
-        }
-      } else {
-        this._closed = false;
-        this._exists = true;
-      }
-    };
-
-    File.DirectoryIterator.prototype = Object.create(
-      exports.OS.Shared.AbstractFile.AbstractIterator.prototype
-    );
-
-    /**
-     * Fetch the next entry in the directory.
-     *
-     * @return null If we have reached the end of the directory.
-     */
-    File.DirectoryIterator.prototype._next = function _next() {
-      // Bailout if the directory does not exist
-      if (!this._exists) {
-        throw File.Error.noSuchFile(
-          "DirectoryIterator.prototype.next",
-          this._path
-        );
-      }
-      // Bailout if the iterator is closed.
-      if (this._closed) {
-        return null;
-      }
-      // If this is the first entry, we have obtained it already
-      // during construction.
-      if (this._first) {
-        this._first = false;
-        return this._findData;
-      }
-
-      if (WinFile.FindNextFile(this._handle, this._findDataPtr)) {
-        return this._findData;
-      }
-      let error = ctypes.winLastError;
-      this.close();
-      if (error == Const.ERROR_NO_MORE_FILES) {
-        return null;
-      }
-      throw new File.Error("iter (FindNextFile)", error, this._path);
-    };
-
-    /**
-     * Return the next entry in the directory, if any such entry is
-     * available.
-     *
-     * Skip special directories "." and "..".
-     *
-     * @return By definition of the iterator protocol, either
-     * `{value: {File.Entry}, done: false}` if there is an unvisited entry
-     * in the directory, or `{value: undefined, done: true}`, otherwise.
-     */
-    File.DirectoryIterator.prototype.next = function next() {
-      // FIXME: If we start supporting "\\?\"-prefixed paths, do not forget
-      // that "." and ".." are absolutely normal file names if _path starts
-      // with such prefix
-      for (let entry = this._next(); entry != null; entry = this._next()) {
-        let name = entry.cFileName.readString();
-        if (name == "." || name == "..") {
-          continue;
-        }
-        return {
-          value: new File.DirectoryIterator.Entry(entry, this._path),
-          done: false,
-        };
-      }
-      return { value: undefined, done: true };
-    };
-
-    File.DirectoryIterator.prototype.close = function close() {
-      if (this._closed) {
-        return;
-      }
-      this._closed = true;
-      if (this._handle) {
-        // We might not have a handle if the iterator is closed
-        // before being used.
-        throw_on_zero("FindClose", WinFile.FindClose(this._handle), this._path);
-        this._handle = null;
-      }
-    };
-
-    /**
-     * Determine whether the directory exists.
-     *
-     * @return {boolean}
-     */
-    File.DirectoryIterator.prototype.exists = function exists() {
-      return this._exists;
-    };
-
-    File.DirectoryIterator.Entry = function Entry(win_entry, parent) {
-      if (
-        !win_entry.dwFileAttributes ||
-        !win_entry.ftLastAccessTime ||
-        !win_entry.ftLastWriteTime
-      ) {
-        throw new TypeError();
-      }
-
-      // Copy the relevant part of |win_entry| to ensure that
-      // our data is not overwritten prematurely.
-      let isDir = !!(
-        win_entry.dwFileAttributes & Const.FILE_ATTRIBUTE_DIRECTORY
-      );
-      let isSymLink = !!(
-        win_entry.dwFileAttributes & Const.FILE_ATTRIBUTE_REPARSE_POINT
-      );
-
-      let winLastWriteDate = FILETIME_to_Date(
-        win_entry.ftLastWriteTime,
-        this._path
-      );
-      let winLastAccessDate = FILETIME_to_Date(
-        win_entry.ftLastAccessTime,
-        this._path
-      );
-
-      let name = win_entry.cFileName.readString();
-      if (!name) {
-        throw new TypeError("Empty name");
-      }
-
-      if (!parent) {
-        throw new TypeError("Empty parent");
-      }
-      this._parent = parent;
-
-      let path = Path.join(this._parent, name);
-
-      SysAll.AbstractEntry.call(
-        this,
-        isDir,
-        isSymLink,
-        name,
-        winLastWriteDate,
-        winLastAccessDate,
-        path
-      );
-    };
-    File.DirectoryIterator.Entry.prototype = Object.create(
-      SysAll.AbstractEntry.prototype
-    );
-
-    /**
-     * Return a version of an instance of
-     * File.DirectoryIterator.Entry that can be sent from a worker
-     * thread to the main thread. Note that deserialization is
-     * asymmetric and returns an object with a different
-     * implementation.
-     */
-    File.DirectoryIterator.Entry.toMsg = function toMsg(value) {
-      if (!(value instanceof File.DirectoryIterator.Entry)) {
-        throw new TypeError(
-          "parameter of " +
-            "File.DirectoryIterator.Entry.toMsg must be a " +
-            "File.DirectoryIterator.Entry"
-        );
-      }
-      let serialized = {};
-      for (let key in File.DirectoryIterator.Entry.prototype) {
-        serialized[key] = value[key];
-      }
-      return serialized;
-    };
-
-    /**
-     * Information on a file.
-     *
-     * To obtain the latest information on a file, use |File.stat|
-     * (for an unopened file) or |File.prototype.stat| (for an
-     * already opened file).
-     *
-     * @constructor
-     */
-    File.Info = function Info(stat, path) {
-      let isDir = !!(stat.dwFileAttributes & Const.FILE_ATTRIBUTE_DIRECTORY);
-      let isSymLink = !!(
-        stat.dwFileAttributes & Const.FILE_ATTRIBUTE_REPARSE_POINT
-      );
-
-      let lastAccessDate = FILETIME_to_Date(stat.ftLastAccessTime, this._path);
-      let lastWriteDate = FILETIME_to_Date(stat.ftLastWriteTime, this._path);
-
-      let value = ctypes.UInt64.join(stat.nFileSizeHigh, stat.nFileSizeLow);
-      let size = Type.uint64_t.importFromC(value);
-      let winAttributes = {
-        readOnly: !!(stat.dwFileAttributes & Const.FILE_ATTRIBUTE_READONLY),
-        system: !!(stat.dwFileAttributes & Const.FILE_ATTRIBUTE_SYSTEM),
-        hidden: !!(stat.dwFileAttributes & Const.FILE_ATTRIBUTE_HIDDEN),
-      };
-
-      SysAll.AbstractInfo.call(
-        this,
-        path,
-        isDir,
-        isSymLink,
-        size,
-        lastAccessDate,
-        lastWriteDate,
-        winAttributes
-      );
-    };
-    File.Info.prototype = Object.create(SysAll.AbstractInfo.prototype);
-
-    /**
-     * Return a version of an instance of File.Info that can be sent
-     * from a worker thread to the main thread. Note that deserialization
-     * is asymmetric and returns an object with a different implementation.
-     */
-    File.Info.toMsg = function toMsg(stat) {
-      if (!(stat instanceof File.Info)) {
-        throw new TypeError("parameter of File.Info.toMsg must be a File.Info");
-      }
-      let serialized = {};
-      for (let key in File.Info.prototype) {
-        serialized[key] = stat[key];
-      }
-      return serialized;
-    };
-
-    /**
-     * Fetch the information on a file.
-     *
-     * Performance note: if you have opened the file already,
-     * method |File.prototype.stat| is generally much faster
-     * than method |File.stat|.
-     *
-     * Platform-specific note: under Windows, if the file is
-     * already opened without sharing of the read capability,
-     * this function will fail.
-     *
-     * @return {File.Information}
-     */
-    File.stat = function stat(path) {
-      let file = File.open(path, FILE_STAT_MODE, FILE_STAT_OPTIONS);
-      try {
-        return file.stat();
-      } finally {
-        file.close();
-      }
-    };
-    // All of the following is required to ensure that File.stat
-    // also works on directories.
-    const FILE_STAT_MODE = {
-      read: true,
-    };
-    const FILE_STAT_OPTIONS = {
-      // Directories can be opened neither for reading(!) nor for writing
-      winAccess: 0,
-      // Directories can only be opened with backup semantics(!)
-      winFlags: Const.FILE_FLAG_BACKUP_SEMANTICS,
-      winDisposition: Const.OPEN_EXISTING,
-    };
-
-    /**
-     * Set the file's access permission bits.
-     */
-    File.setPermissions = function setPermissions(path, options = {}) {
-      if (!("winAttributes" in options)) {
-        return;
-      }
-      let oldAttributes = WinFile.GetFileAttributes(path);
-      if (oldAttributes == Const.INVALID_FILE_ATTRIBUTES) {
-        throw new File.Error("setPermissions", ctypes.winLastError, path);
-      }
-      let newAttributes = toFileAttributes(
-        options.winAttributes,
-        oldAttributes
-      );
-      throw_on_zero(
-        "setPermissions",
-        WinFile.SetFileAttributes(path, newAttributes),
-        path
-      );
-    };
-
-    /**
-     * Set the last access and modification date of the file.
-     * The time stamp resolution is 1 second at best, but might be worse
-     * depending on the platform.
-     *
-     * Performance note: if you have opened the file already in write mode,
-     * method |File.prototype.stat| is generally much faster
-     * than method |File.stat|.
-     *
-     * Platform-specific note: under Windows, if the file is
-     * already opened without sharing of the write capability,
-     * this function will fail.
-     *
-     * @param {string} path The full name of the file to set the dates for.
-     * @param {Date,number=} accessDate The last access date. If numeric,
-     * milliseconds since epoch. If omitted or null, then the current date
-     * will be used.
-     * @param {Date,number=} modificationDate The last modification date. If
-     * numeric, milliseconds since epoch. If omitted or null, then the current
-     * date will be used.
-     *
-     * @throws {TypeError} In case of invalid paramters.
-     * @throws {OS.File.Error} In case of I/O error.
-     */
-    File.setDates = function setDates(path, accessDate, modificationDate) {
-      let file = File.open(path, FILE_SETDATES_MODE, FILE_SETDATES_OPTIONS);
-      try {
-        return file.setDates(accessDate, modificationDate);
-      } finally {
-        file.close();
-      }
-    };
-    // All of the following is required to ensure that File.setDates
-    // also works on directories.
-    const FILE_SETDATES_MODE = {
-      write: true,
-    };
-    const FILE_SETDATES_OPTIONS = {
-      winAccess: Const.GENERIC_WRITE,
-      // Directories can only be opened with backup semantics(!)
-      winFlags: Const.FILE_FLAG_BACKUP_SEMANTICS,
-      winDisposition: Const.OPEN_EXISTING,
-    };
-
-    File.read = exports.OS.Shared.AbstractFile.read;
-    File.writeAtomic = exports.OS.Shared.AbstractFile.writeAtomic;
-    File.openUnique = exports.OS.Shared.AbstractFile.openUnique;
-    File.makeDir = exports.OS.Shared.AbstractFile.makeDir;
-
-    /**
-     * Remove an existing directory and its contents.
-     *
-     * @param {string} path The name of the directory.
-     * @param {*=} options Additional options.
-     *   - {bool} ignoreAbsent If |false|, throw an error if the directory doesn't
-     *     exist. |true| by default.
-     *   - {boolean} ignorePermissions If |true|, remove the file even when lacking write
-     *     permission.
-     *
-     * @throws {OS.File.Error} In case of I/O error, in particular if |path| is
-     *         not a directory.
-     */
-    File.removeDir = function(path, options = {}) {
-      // We can't use File.stat here because it will follow the symlink.
-      let attributes = WinFile.GetFileAttributes(path);
-      if (attributes == Const.INVALID_FILE_ATTRIBUTES) {
-        if (
-          (!("ignoreAbsent" in options) || options.ignoreAbsent) &&
-          ctypes.winLastError == Const.ERROR_FILE_NOT_FOUND
-        ) {
-          return;
-        }
-        throw new File.Error("removeEmptyDir", ctypes.winLastError, path);
-      }
-      if (attributes & Const.FILE_ATTRIBUTE_REPARSE_POINT) {
-        // Unlike Unix symlinks, NTFS junctions or NTFS symlinks to
-        // directories are directories themselves. OS.File.remove()
-        // will not work for them.
-        OS.File.removeEmptyDir(path, options);
-        return;
-      }
-      exports.OS.Shared.AbstractFile.removeRecursive(path, options);
-    };
-
-    /**
-     * Get the current directory by getCurrentDirectory.
-     */
-    File.getCurrentDirectory = function getCurrentDirectory() {
-      // This function is more complicated than one could hope.
-      //
-      // This is due to two facts:
-      // - the maximal length of a path under Windows is not completely
-      //  specified (there is a constant MAX_PATH, but it is quite possible
-      //  to create paths that are much larger, see bug 744413);
-      // - if we attempt to call |GetCurrentDirectory| with a buffer that
-      //  is too short, it returns the length of the current directory, but
-      //  this length might be insufficient by the time we can call again
-      //  the function with a larger buffer, in the (unlikely but possible)
-      //  case in which the process changes directory to a directory with
-      //  a longer name between both calls.
-      //
-      let buffer_size = 4096;
-      while (true) {
-        let array = new (ctypes.ArrayType(ctypes.char16_t, buffer_size))();
-        let expected_size = throw_on_zero(
-          "getCurrentDirectory",
-          WinFile.GetCurrentDirectory(buffer_size, array)
-        );
-        if (expected_size <= buffer_size) {
-          return array.readString();
-        }
-        // At this point, we are in a case in which our buffer was not
-        // large enough to hold the name of the current directory.
-        // Consequently, we need to increase the size of the buffer.
-        // Note that, even in crazy scenarios, the loop will eventually
-        // converge, as the length of the paths cannot increase infinitely.
-        buffer_size = expected_size + 1 /* to store \0 */;
-      }
-    };
-
-    /**
-     * Get/set the current directory by |curDir|.
-     */
-    Object.defineProperty(File, "curDir", {
-      set(path) {
-        this.setCurrentDirectory(path);
-      },
-      get() {
-        return this.getCurrentDirectory();
-      },
-    });
-
-    // Utility functions, used for error-handling
-
-    /**
-     * Turn the result of |open| into an Error or a File
-     * @param {number} maybe The result of the |open| operation that may
-     * represent either an error or a success. If -1, this function raises
-     * an error holding ctypes.winLastError, otherwise it returns the opened file.
-     * @param {string=} path The path of the file.
-     */
-    function error_or_file(maybe, path) {
-      if (maybe == Const.INVALID_HANDLE_VALUE) {
-        throw new File.Error("open", ctypes.winLastError, path);
-      }
-      return new File(maybe, path);
-    }
-
-    /**
-     * Utility function to sort errors represented as "0" from successes.
-     *
-     * @param {string=} operation The name of the operation. If unspecified,
-     * the name of the caller function.
-     * @param {number} result The result of the operation that may
-     * represent either an error or a success. If 0, this function raises
-     * an error holding ctypes.winLastError, otherwise it returns |result|.
-     * @param {string=} path The path of the file.
-     */
-    function throw_on_zero(operation, result, path) {
-      if (result == 0) {
-        throw new File.Error(operation, ctypes.winLastError, path);
-      }
-      return result;
-    }
-
-    /**
-     * Helper used by both versions of setPermissions
-     */
-    function toFileAttributes(winAttributes, oldDwAttrs) {
-      if ("readOnly" in winAttributes) {
-        if (winAttributes.readOnly) {
-          oldDwAttrs |= Const.FILE_ATTRIBUTE_READONLY;
-        } else {
-          oldDwAttrs &= ~Const.FILE_ATTRIBUTE_READONLY;
-        }
-      }
-      if ("system" in winAttributes) {
-        if (winAttributes.system) {
-          oldDwAttrs |= Const.FILE_ATTRIBUTE_SYSTEM;
-        } else {
-          oldDwAttrs &= ~Const.FILE_ATTRIBUTE_SYSTEM;
-        }
-      }
-      if ("hidden" in winAttributes) {
-        if (winAttributes.hidden) {
-          oldDwAttrs |= Const.FILE_ATTRIBUTE_HIDDEN;
-        } else {
-          oldDwAttrs &= ~Const.FILE_ATTRIBUTE_HIDDEN;
-        }
-      }
-      return oldDwAttrs;
-    }
-
-    File.Win = exports.OS.Win.File;
-    File.Error = SysAll.Error;
-    exports.OS.File = File;
-    exports.OS.Shared.Type = Type;
-
-    Object.defineProperty(File, "POS_START", { value: SysAll.POS_START });
-    Object.defineProperty(File, "POS_CURRENT", { value: SysAll.POS_CURRENT });
-    Object.defineProperty(File, "POS_END", { value: SysAll.POS_END });
-  })(this);
-}
deleted file mode 100644
--- a/toolkit/components/osfile/modules/ospath.jsm
+++ /dev/null
@@ -1,50 +0,0 @@
-/* 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/. */
-
-/**
- * Handling native paths.
- *
- * This module contains a number of functions destined to simplify
- * working with native paths through a cross-platform API. Functions
- * of this module will only work with the following assumptions:
- *
- * - paths are valid;
- * - paths are defined with one of the grammars that this module can
- *   parse (see later);
- * - all path concatenations go through function |join|.
- */
-
-/* global OS */
-/* eslint-env node */
-
-"use strict";
-
-if (typeof Components == "undefined") {
-  let Path;
-  if (OS.Constants.Win) {
-    Path = require("resource://gre/modules/osfile/ospath_win.jsm");
-  } else {
-    Path = require("resource://gre/modules/osfile/ospath_unix.jsm");
-  }
-  module.exports = Path;
-} else {
-  let Scope = ChromeUtils.import(
-    "resource://gre/modules/osfile/osfile_shared_allthreads.jsm"
-  );
-
-  let Path;
-  if (Scope.OS.Constants.Win) {
-    Path = ChromeUtils.import("resource://gre/modules/osfile/ospath_win.jsm");
-  } else {
-    Path = ChromeUtils.import("resource://gre/modules/osfile/ospath_unix.jsm");
-  }
-
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.EXPORTED_SYMBOLS = [];
-  for (let k in Path) {
-    EXPORTED_SYMBOLS.push(k);
-    // eslint-disable-next-line mozilla/reject-global-this
-    this[k] = Path[k];
-  }
-}
deleted file mode 100644
--- a/toolkit/components/osfile/modules/ospath_unix.jsm
+++ /dev/null
@@ -1,204 +0,0 @@
-/* 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/. */
-
-/**
- * Handling native paths.
- *
- * This module contains a number of functions destined to simplify
- * working with native paths through a cross-platform API. Functions
- * of this module will only work with the following assumptions:
- *
- * - paths are valid;
- * - paths are defined with one of the grammars that this module can
- *   parse (see later);
- * - all path concatenations go through function |join|.
- */
-
-"use strict";
-
-// Boilerplate used to be able to import this module both from the main
-// thread and from worker threads.
-if (typeof Components != "undefined") {
-  // Global definition of |exports|, to keep everybody happy.
-  // In non-main thread, |exports| is provided by the module
-  // loader.
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.exports = {};
-} else if (typeof module == "undefined" || typeof exports == "undefined") {
-  throw new Error("Please load this module using require()");
-}
-
-var EXPORTED_SYMBOLS = [
-  "basename",
-  "dirname",
-  "join",
-  "normalize",
-  "split",
-  "toFileURI",
-  "fromFileURI",
-];
-
-/**
- * Return the final part of the path.
- * The final part of the path is everything after the last "/".
- */
-var basename = function(path) {
-  return path.slice(path.lastIndexOf("/") + 1);
-};
-exports.basename = basename;
-
-/**
- * Return the directory part of the path.
- * The directory part of the path is everything before the last
- * "/". If the last few characters of this part are also "/",
- * they are ignored.
- *
- * If the path contains no directory, return ".".
- */
-var dirname = function(path) {
-  let index = path.lastIndexOf("/");
-  if (index == -1) {
-    return ".";
-  }
-  while (index >= 0 && path[index] == "/") {
-    --index;
-  }
-  return path.slice(0, index + 1);
-};
-exports.dirname = dirname;
-
-/**
- * Join path components.
- * This is the recommended manner of getting the path of a file/subdirectory
- * in a directory.
- *
- * Example: Obtaining $TMP/foo/bar in an OS-independent manner
- *  var tmpDir = OS.Constants.Path.tmpDir;
- *  var path = OS.Path.join(tmpDir, "foo", "bar");
- *
- * Under Unix, this will return "/tmp/foo/bar".
- *
- * Empty components are ignored, i.e. `OS.Path.join("foo", "", "bar)` is the
- * same as `OS.Path.join("foo", "bar")`.
- */
-var join = function(...path) {
-  // If there is a path that starts with a "/", eliminate everything before
-  let paths = [];
-  for (let subpath of path) {
-    if (subpath == null) {
-      throw new TypeError("invalid path component");
-    }
-    if (!subpath.length) {
-      continue;
-    } else if (subpath[0] == "/") {
-      paths = [subpath];
-    } else {
-      paths.push(subpath);
-    }
-  }
-  return paths.join("/");
-};
-exports.join = join;
-
-/**
- * Normalize a path by removing any unneeded ".", "..", "//".
- */
-var normalize = function(path) {
-  let stack = [];
-  let absolute;
-  if (path.length >= 0 && path[0] == "/") {
-    absolute = true;
-  } else {
-    absolute = false;
-  }
-  path.split("/").forEach(function(v) {
-    switch (v) {
-      case "":
-      case ".": // fallthrough
-        break;
-      case "..":
-        if (!stack.length) {
-          if (absolute) {
-            throw new Error("Path is ill-formed: attempting to go past root");
-          } else {
-            stack.push("..");
-          }
-        } else if (stack[stack.length - 1] == "..") {
-          stack.push("..");
-        } else {
-          stack.pop();
-        }
-        break;
-      default:
-        stack.push(v);
-    }
-  });
-  let string = stack.join("/");
-  return absolute ? "/" + string : string;
-};
-exports.normalize = normalize;
-
-/**
- * Return the components of a path.
- * You should generally apply this function to a normalized path.
- *
- * @return {{
- *   {bool} absolute |true| if the path is absolute, |false| otherwise
- *   {array} components the string components of the path
- * }}
- *
- * Other implementations may add additional OS-specific informations.
- */
-var split = function(path) {
-  return {
-    absolute: path.length && path[0] == "/",
-    components: path.split("/"),
-  };
-};
-exports.split = split;
-
-/**
- * Returns the file:// URI file path of the given local file path.
- */
-// The case of %3b is designed to match Services.io, but fundamentally doesn't matter.
-var toFileURIExtraEncodings = { ";": "%3b", "?": "%3F", "#": "%23" };
-var toFileURI = function toFileURI(path) {
-  // Per https://url.spec.whatwg.org we should not encode [] in the path
-  let dontNeedEscaping = { "%5B": "[", "%5D": "]" };
-  let uri = encodeURI(this.normalize(path)).replace(
-    /%(5B|5D)/gi,
-    match => dontNeedEscaping[match]
-  );
-
-  // add a prefix, and encodeURI doesn't escape a few characters that we do
-  // want to escape, so fix that up
-  let prefix = "file://";
-  uri = prefix + uri.replace(/[;?#]/g, match => toFileURIExtraEncodings[match]);
-
-  return uri;
-};
-exports.toFileURI = toFileURI;
-
-/**
- * Returns the local file path from a given file URI.
- */
-var fromFileURI = function fromFileURI(uri) {
-  let url = new URL(uri);
-  if (url.protocol != "file:") {
-    throw new Error("fromFileURI expects a file URI");
-  }
-  let path = this.normalize(decodeURIComponent(url.pathname));
-  return path;
-};
-exports.fromFileURI = fromFileURI;
-
-// ////////// Boilerplate
-if (typeof Components != "undefined") {
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.EXPORTED_SYMBOLS = EXPORTED_SYMBOLS;
-  for (let symbol of EXPORTED_SYMBOLS) {
-    // eslint-disable-next-line mozilla/reject-global-this
-    this[symbol] = exports[symbol];
-  }
-}
deleted file mode 100644
--- a/toolkit/components/osfile/modules/ospath_win.jsm
+++ /dev/null
@@ -1,382 +0,0 @@
-/* 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/. */
-
-/**
- * Handling native paths.
- *
- * This module contains a number of functions destined to simplify
- * working with native paths through a cross-platform API. Functions
- * of this module will only work with the following assumptions:
- *
- * - paths are valid;
- * - paths are defined with one of the grammars that this module can
- *   parse (see later);
- * - all path concatenations go through function |join|.
- *
- * Limitations of this implementation.
- *
- * Windows supports 6 distinct grammars for paths. For the moment, this
- * implementation supports the following subset:
- *
- * - drivename:backslash-separated components
- * - backslash-separated components
- * - \\drivename\ followed by backslash-separated components
- *
- * Additionally, |normalize| can convert a path containing slash-
- * separated components to a path containing backslash-separated
- * components.
- */
-
-"use strict";
-
-// Boilerplate used to be able to import this module both from the main
-// thread and from worker threads.
-if (typeof Components != "undefined") {
-  // Global definition of |exports|, to keep everybody happy.
-  // In non-main thread, |exports| is provided by the module
-  // loader.
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.exports = {};
-} else if (typeof module == "undefined" || typeof exports == "undefined") {
-  throw new Error("Please load this module using require()");
-}
-
-var EXPORTED_SYMBOLS = [
-  "basename",
-  "dirname",
-  "join",
-  "normalize",
-  "split",
-  "winGetDrive",
-  "winIsAbsolute",
-  "toFileURI",
-  "fromFileURI",
-];
-
-/**
- * Return the final part of the path.
- * The final part of the path is everything after the last "\\".
- */
-var basename = function(path) {
-  if (path.startsWith("\\\\")) {
-    // UNC-style path
-    let index = path.lastIndexOf("\\");
-    if (index != 1) {
-      return path.slice(index + 1);
-    }
-    return ""; // Degenerate case
-  }
-  return path.slice(
-    Math.max(path.lastIndexOf("\\"), path.lastIndexOf(":")) + 1
-  );
-};
-exports.basename = basename;
-
-/**
- * Return the directory part of the path.
- *
- * If the path contains no directory, return the drive letter,
- * or "." if the path contains no drive letter or if option
- * |winNoDrive| is set.
- *
- * Otherwise, return everything before the last backslash,
- * including the drive/server name.
- *
- *
- * @param {string} path The path.
- * @param {*=} options Platform-specific options controlling the behavior
- * of this function. This implementation supports the following options:
- *  - |winNoDrive| If |true|, also remove the letter from the path name.
- */
-var dirname = function(path, options) {
-  let noDrive = options && options.winNoDrive;
-
-  // Find the last occurrence of "\\"
-  let index = path.lastIndexOf("\\");
-  if (index == -1) {
-    // If there is no directory component...
-    if (!noDrive) {
-      // Return the drive path if possible, falling back to "."
-      return this.winGetDrive(path) || ".";
-    }
-    // Or just "."
-    return ".";
-  }
-
-  if (index == 1 && path.charAt(0) == "\\") {
-    // The path is reduced to a UNC drive
-    if (noDrive) {
-      return ".";
-    }
-    return path;
-  }
-
-  // Ignore any occurrence of "\\: immediately before that one
-  while (index >= 0 && path[index] == "\\") {
-    --index;
-  }
-
-  // Compute what is left, removing the drive name if necessary
-  let start;
-  if (noDrive) {
-    start = (this.winGetDrive(path) || "").length;
-  } else {
-    start = 0;
-  }
-  return path.slice(start, index + 1);
-};
-exports.dirname = dirname;
-
-/**
- * Join path components.
- * This is the recommended manner of getting the path of a file/subdirectory
- * in a directory.
- *
- * Example: Obtaining $TMP/foo/bar in an OS-independent manner
- *  var tmpDir = OS.Constants.Path.tmpDir;
- *  var path = OS.Path.join(tmpDir, "foo", "bar");
- *
- * Under Windows, this will return "$TMP\foo\bar".
- *
- * Empty components are ignored, i.e. `OS.Path.join("foo", "", "bar)` is the
- * same as `OS.Path.join("foo", "bar")`.
- */
-var join = function(...path) {
-  let paths = [];
-  let root;
-  let absolute = false;
-  for (let subpath of path) {
-    if (subpath == null) {
-      throw new TypeError("invalid path component");
-    }
-    if (subpath == "") {
-      continue;
-    }
-    let drive = this.winGetDrive(subpath);
-    if (drive) {
-      root = drive;
-      let component = trimBackslashes(subpath.slice(drive.length));
-      if (component) {
-        paths = [component];
-      } else {
-        paths = [];
-      }
-      absolute = true;
-    } else if (this.winIsAbsolute(subpath)) {
-      paths = [trimBackslashes(subpath)];
-      absolute = true;
-    } else {
-      paths.push(trimBackslashes(subpath));
-    }
-  }
-  let result = "";
-  if (root) {
-    result += root;
-  }
-  if (absolute) {
-    result += "\\";
-  }
-  result += paths.join("\\");
-  return result;
-};
-exports.join = join;
-
-/**
- * Return the drive name of a path, or |null| if the path does
- * not contain a drive name.
- *
- * Drive name appear either as "DriveName:..." (the return drive
- * name includes the ":") or "\\\\DriveName..." (the returned drive name
- * includes "\\\\").
- */
-var winGetDrive = function(path) {
-  if (path == null) {
-    throw new TypeError("path is invalid");
-  }
-
-  if (path.startsWith("\\\\")) {
-    // UNC path
-    if (path.length == 2) {
-      return null;
-    }
-    let index = path.indexOf("\\", 2);
-    if (index == -1) {
-      return path;
-    }
-    return path.slice(0, index);
-  }
-  // Non-UNC path
-  let index = path.indexOf(":");
-  if (index <= 0) {
-    return null;
-  }
-  return path.slice(0, index + 1);
-};
-exports.winGetDrive = winGetDrive;
-
-/**
- * Return |true| if the path is absolute, |false| otherwise.
- *
- * We consider that a path is absolute if it starts with "\\"
- * or "driveletter:\\".
- */
-var winIsAbsolute = function(path) {
-  let index = path.indexOf(":");
-  return path.length > index + 1 && path[index + 1] == "\\";
-};
-exports.winIsAbsolute = winIsAbsolute;
-
-/**
- * Normalize a path by removing any unneeded ".", "..", "\\".
- * Also convert any "/" to a "\\".
- */
-var normalize = function(path) {
-  let stack = [];
-
-  if (!path.startsWith("\\\\")) {
-    // Normalize "/" to "\\"
-    path = path.replace(/\//g, "\\");
-  }
-
-  // Remove the drive (we will put it back at the end)
-  let root = this.winGetDrive(path);
-  if (root) {
-    path = path.slice(root.length);
-  }
-
-  // Remember whether we need to restore a leading "\\" or drive name.
-  let absolute = this.winIsAbsolute(path);
-
-  // And now, fill |stack| from the components,
-  // popping whenever there is a ".."
-  path.split("\\").forEach(function loop(v) {
-    switch (v) {
-      case "":
-      case ".": // Ignore
-        break;
-      case "..":
-        if (!stack.length) {
-          if (absolute) {
-            throw new Error("Path is ill-formed: attempting to go past root");
-          } else {
-            stack.push("..");
-          }
-        } else if (stack[stack.length - 1] == "..") {
-          stack.push("..");
-        } else {
-          stack.pop();
-        }
-        break;
-      default:
-        stack.push(v);
-    }
-  });
-
-  // Put everything back together
-  let result = stack.join("\\");
-  if (absolute || root) {
-    result = "\\" + result;
-  }
-  if (root) {
-    result = root + result;
-  }
-  return result;
-};
-exports.normalize = normalize;
-
-/**
- * Return the components of a path.
- * You should generally apply this function to a normalized path.
- *
- * @return {{
- *   {bool} absolute |true| if the path is absolute, |false| otherwise
- *   {array} components the string components of the path
- *   {string?} winDrive the drive or server for this path
- * }}
- *
- * Other implementations may add additional OS-specific informations.
- */
-var split = function(path) {
-  return {
-    absolute: this.winIsAbsolute(path),
-    winDrive: this.winGetDrive(path),
-    components: path.split("\\"),
-  };
-};
-exports.split = split;
-
-/**
- * Return the file:// URI file path of the given local file path.
- */
-// The case of %3b is designed to match Services.io, but fundamentally doesn't matter.
-var toFileURIExtraEncodings = { ";": "%3b", "?": "%3F", "#": "%23" };
-var toFileURI = function toFileURI(path) {
-  // URI-escape forward slashes and convert backward slashes to forward
-  path = this.normalize(path).replace(/[\\\/]/g, m =>
-    m == "\\" ? "/" : "%2F"
-  );
-  // Per https://url.spec.whatwg.org we should not encode [] in the path
-  let dontNeedEscaping = { "%5B": "[", "%5D": "]" };
-  let uri = encodeURI(path).replace(
-    /%(5B|5D)/gi,
-    match => dontNeedEscaping[match]
-  );
-
-  // add a prefix, and encodeURI doesn't escape a few characters that we do
-  // want to escape, so fix that up
-  let prefix = "file:///";
-  uri = prefix + uri.replace(/[;?#]/g, match => toFileURIExtraEncodings[match]);
-
-  // turn e.g., file:///C: into file:///C:/
-  if (uri.charAt(uri.length - 1) === ":") {
-    uri += "/";
-  }
-
-  return uri;
-};
-exports.toFileURI = toFileURI;
-
-/**
- * Returns the local file path from a given file URI.
- */
-var fromFileURI = function fromFileURI(uri) {
-  let url = new URL(uri);
-  if (url.protocol != "file:") {
-    throw new Error("fromFileURI expects a file URI");
-  }
-
-  // strip leading slash, since Windows paths don't start with one
-  uri = url.pathname.substr(1);
-
-  let path = decodeURI(uri);
-  // decode a few characters where URL's parsing is overzealous
-  path = path.replace(/%(3b|3f|23)/gi, match => decodeURIComponent(match));
-  path = this.normalize(path);
-
-  // this.normalize() does not remove the trailing slash if the path
-  // component is a drive letter. eg. 'C:\'' will not get normalized.
-  if (path.endsWith(":\\")) {
-    path = path.substr(0, path.length - 1);
-  }
-  return this.normalize(path);
-};
-exports.fromFileURI = fromFileURI;
-
-/**
- * Utility function: Remove any leading/trailing backslashes
- * from a string.
- */
-var trimBackslashes = function trimBackslashes(string) {
-  return string.replace(/^\\+|\\+$/g, "");
-};
-
-// ////////// Boilerplate
-if (typeof Components != "undefined") {
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.EXPORTED_SYMBOLS = EXPORTED_SYMBOLS;
-  for (let symbol of EXPORTED_SYMBOLS) {
-    // eslint-disable-next-line mozilla/reject-global-this
-    this[symbol] = exports[symbol];
-  }
-}
deleted file mode 100644
--- a/toolkit/components/osfile/moz.build
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- 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/.
-
-DIRS += [
-    "modules",
-]
-
-MOCHITEST_CHROME_MANIFESTS += ["tests/mochi/chrome.ini"]
-XPCSHELL_TESTS_MANIFESTS += ["tests/xpcshell/xpcshell.ini"]
-
-SOURCES += [
-    "NativeOSFileInternals.cpp",
-]
-
-XPIDL_MODULE = "toolkit_osfile"
-
-XPIDL_SOURCES += [
-    "nsINativeOSFileInternals.idl",
-]
-
-EXPORTS.mozilla += [
-    "NativeOSFileInternals.h",
-]
-
-EXTRA_JS_MODULES += [
-    "osfile.jsm",
-]
-
-FINAL_LIBRARY = "xul"
-
-with Files("**"):
-    BUG_COMPONENT = ("Toolkit", "OS.File")
deleted file mode 100644
--- a/toolkit/components/osfile/nsINativeOSFileInternals.idl
+++ /dev/null
@@ -1,120 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* vim: set ts=2 et sw=2 tw=40: */
-/* 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 "nsISupports.idl"
-
-/**
- * The result of a successful asynchronous operation.
- */
-[scriptable, builtinclass, uuid(08B4CF29-3D65-4E79-B522-A694C322ED07)]
-interface nsINativeOSFileResult: nsISupports
-{
-  /**
-   * The actual value produced by the operation.
-   *
-   * Actual type of this value depends on the options passed to the
-   * operation.
-   */
-  [implicit_jscontext]
-  readonly attribute jsval result;
-
-  /**
-   * Delay between when the operation was requested on the main thread and
-   * when the operation was started off main thread.
-   */
-  readonly attribute double dispatchDurationMS;
-
-  /**
-   * Duration of the off main thread execution.
-   */
-  readonly attribute double executionDurationMS;
-};
-
-/**
- * A callback invoked in case of success.
- */
-[scriptable, function, uuid(2C1922CA-CA1B-4099-8B61-EC23CFF49412)]
-interface nsINativeOSFileSuccessCallback: nsISupports
-{
-  void complete(in nsINativeOSFileResult result);
-};
-
-/**
- * A callback invoked in case of error.
- */
-[scriptable, function, uuid(F612E0FC-6736-4D24-AA50-FD661B3B40B6)]
-interface nsINativeOSFileErrorCallback: nsISupports
-{
-  /**
-   * @param operation The name of the failed operation. Provided to aid
-   * debugging only, may change without notice.
-   * @param OSstatus The OS status of the operation (errno under Unix,
-   * GetLastError under Windows).
-   */
-  void complete(in ACString operation, in long OSstatus);
-};
-
-/**
- * A service providing native implementations of some of the features
- * of OS.File.
- */
-[scriptable, builtinclass, uuid(913362AD-1526-4623-9E6B-A2EB08AFBBB9)]
-interface nsINativeOSFileInternalsService: nsISupports
-{
-  /**
-   * Implementation of OS.File.read
-   *
-   * @param path The absolute path to the file to read.
-   * @param options An object that may contain some of the following fields
-   * - {number} bytes The maximal number of bytes to read.
-   * - {string} encoding If provided, return the result as a string, decoded
-   *   using this encoding. Otherwise, pass the result as an ArrayBuffer.
-   *   Invalid encodings cause onError to be called with the platform-specific
-   *   "invalid argument" constant.
-   * - {string} compression Unimplemented at the moment.
-   * @param onSuccess The success callback.
-   * @param onError The error callback.
-   */
-  [implicit_jscontext]
-  void read(in AString path, in jsval options,
-            in nsINativeOSFileSuccessCallback onSuccess,
-            in nsINativeOSFileErrorCallback onError);
-
-  /**
-   * Implementation of OS.File.writeAtomic
-   *
-   * @param path the absolute path of the file to write to.
-   * @param buffer the data as an array buffer to be written to the file.
-   * @param options An object that may contain the following fields
-   * - {number} bytes If provided, the number of bytes written is equal to this.
-   *   The default value is the size of the |buffer|.
-   * - {string} tmpPath If provided and not null, first write to this path, and
-   *   move to |path| after writing.
-   * - {string} backupPath if provided, backup file at |path| to this path
-   *   before overwriting it.
-   * - {bool} flush if provided and true, flush the contents of the buffer after
-   *   writing. This is slower, but safer.
-   * - {bool} noOverwrite if provided and true, do not write if a file already
-   *   exists at |path|.
-   * @param onSuccess The success callback.
-   * @param onError The error callback.
-   */
-  [implicit_jscontext]
-  void writeAtomic(in AString path,
-                   in jsval buffer,
-                   in jsval options,
-                   in nsINativeOSFileSuccessCallback onSuccess,
-                   in nsINativeOSFileErrorCallback onError);
-
-};
-
-
-%{ C++
-
-#define NATIVE_OSFILE_INTERNALS_SERVICE_CID {0x63A69303,0x8A64,0x45A9,{0x84, 0x8C, 0xD4, 0xE2, 0x79, 0x27, 0x94, 0xE6}}
-#define NATIVE_OSFILE_INTERNALS_SERVICE_CONTRACTID "@mozilla.org/toolkit/osfile/native-internals;1"
-
-%}
deleted file mode 100644
--- a/toolkit/components/osfile/osfile.jsm
+++ /dev/null
@@ -1,46 +0,0 @@
-/* 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/. */
-
-/**
- * Common front for various implementations of OS.File
- */
-
-if (typeof Components != "undefined") {
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.EXPORTED_SYMBOLS = ["OS"];
-  const { OS } = ChromeUtils.import(
-    "resource://gre/modules/osfile/osfile_async_front.jsm"
-  );
-  // eslint-disable-next-line mozilla/reject-global-this
-  this.OS = OS;
-} else {
-  /* eslint-env worker */
-  /* import-globals-from /toolkit/components/workerloader/require.js */
-  importScripts("resource://gre/modules/workers/require.js");
-
-  var SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
-
-  /* eslint-disable no-unused-vars */
-
-  // At this stage, we need to import all sources at once to avoid
-  // a unique failure on tbpl + talos that seems caused by a
-  // what looks like a nested event loop bug (see bug 794091).
-  if (SharedAll.Constants.Win) {
-    importScripts(
-      "resource://gre/modules/osfile/osfile_win_back.js",
-      "resource://gre/modules/osfile/osfile_shared_front.js",
-      "resource://gre/modules/osfile/osfile_win_front.js"
-    );
-  } else {
-    importScripts(
-      "resource://gre/modules/osfile/osfile_unix_back.js",
-      "resource://gre/modules/osfile/osfile_shared_front.js",
-      "resource://gre/modules/osfile/osfile_unix_front.js"
-    );
-  }
-
-  /* eslint-enable no-unused-vars */
-
-  OS.Path = require("resource://gre/modules/osfile/ospath.jsm");
-}
deleted file mode 100644
--- a/toolkit/components/osfile/tests/mochi/chrome.ini
+++ /dev/null
@@ -1,15 +0,0 @@
-[DEFAULT]
-skip-if = os == 'android'
-support-files =
-  main_test_osfile_async.js
-  worker_test_osfile_comms.js
-  worker_test_osfile_front.js
-  worker_test_osfile_unix.js
-  worker_test_osfile_win.js
-
-[test_osfile_async.xhtml]
-[test_osfile_back.xhtml]
-[test_osfile_comms.xhtml]
-[test_osfile_front.xhtml]
-skip-if =
-  win11_2009 && bits == 32  # Bug 1809355
deleted file mode 100644
--- a/toolkit/components/osfile/tests/mochi/main_test_osfile_async.js
+++ /dev/null
@@ -1,501 +0,0 @@
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-// The following are used to compare against a well-tested reference
-// implementation of file I/O.
-const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-const { FileUtils } = ChromeUtils.importESModule(
-  "resource://gre/modules/FileUtils.sys.mjs"
-);
-
-var myok = ok;
-var myis = is;
-var myinfo = info;
-var myisnot = isnot;
-
-var isPromise = function ispromise(value) {
-  return value != null && typeof value == "object" && "then" in value;
-};
-
-var maketest = function(prefix, test) {
-  let utils = {
-    ok: function ok(t, m) {
-      myok(t, prefix + ": " + m);
-    },
-    is: function is(l, r, m) {
-      myis(l, r, prefix + ": " + m);
-    },
-    isnot: function isnot(l, r, m) {
-      myisnot(l, r, prefix + ": " + m);
-    },
-    info: function info(m) {
-      myinfo(prefix + ": " + m);
-    },
-    fail: function fail(m) {
-      utils.ok(false, m);
-    },
-    okpromise: function okpromise(t, m) {
-      return t.then(
-        function onSuccess() {
-          utils.ok(true, m);
-        },
-        function onFailure() {
-          utils.ok(false, m);
-        }
-      );
-    },
-  };
-  return function runtest() {
-    utils.info("Entering");
-    try {
-      let result = test.call(this, utils);
-      if (!isPromise(result)) {
-        throw new TypeError("The test did not return a promise");
-      }
-      utils.info("This was a promise");
-      // The test returns a promise
-      result = result.then(
-        function test_complete() {
-          utils.info("Complete");
-        },
-        function catch_uncaught_errors(err) {
-          utils.fail("Uncaught error " + err);
-          if (err && typeof err == "object" && "message" in err) {
-            utils.fail("(" + err.message + ")");
-          }
-          if (err && typeof err == "object" && "stack" in err) {
-            utils.fail("at " + err.stack);
-          }
-        }
-      );
-      return result;
-    } catch (x) {
-      utils.fail("Error " + x + " at " + x.stack);
-      return null;
-    }
-  };
-};
-
-/**
- * Fetch asynchronously the contents of a file using xpcom.
- *
- * Used for comparing xpcom-based results to os.file-based results.
- *
- * @param {string} path The _absolute_ path to the file.
- * @return {promise}
- * @resolves {string} The contents of the file.
- */
-var reference_fetch_file = function reference_fetch_file(path, test) {
-  test.info("Fetching file " + path);
-  return new Promise((resolve, reject) => {
-    let file = new FileUtils.File(path);
-    NetUtil.asyncFetch(
-      {
-        uri: NetUtil.newURI(file),
-        loadUsingSystemPrincipal: true,
-      },
-      function(stream, status) {
-        if (!Components.isSuccessCode(status)) {
-          reject(status);
-          return;
-        }
-        let result, reject;
-        try {
-          result = NetUtil.readInputStreamToString(stream, stream.available());
-        } catch (x) {
-          reject = x;
-        }
-        stream.close();
-        if (reject) {
-          reject(reject);
-        } else {
-          resolve(result);
-        }
-      }
-    );
-  });
-};
-
-var reference_dir_contents = function reference_dir_contents(path) {
-  let result = [];
-  let entries = new FileUtils.File(path).directoryEntries;
-  while (entries.hasMoreElements()) {
-    let entry = entries.nextFile;
-    result.push(entry.path);
-  }
-  return result;
-};
-
-// Set/Unset OS.Shared.DEBUG, OS.Shared.TEST and a console listener.
-function toggleDebugTest(pref, consoleListener) {
-  Services.prefs.setBoolPref("toolkit.osfile.log", pref);
-  Services.prefs.setBoolPref("toolkit.osfile.log.redirect", pref);
-  Services.console[pref ? "registerListener" : "unregisterListener"](
-    consoleListener
-  );
-}
-
-var test = maketest("Main", function main(test) {
-  return (async function() {
-    SimpleTest.waitForExplicitFinish();
-    await test_stat();
-    await test_debug();
-    await test_info_features_detect();
-    await test_position();
-    await test_iter();
-    await test_exists();
-    await test_debug_test();
-    info("Test is over");
-    SimpleTest.finish();
-  })();
-});
-
-/**
- * A file that we know exists and that can be used for reading.
- */
-var EXISTING_FILE = OS.Path.join(
-  "chrome",
-  "toolkit",
-  "components",
-  "osfile",
-  "tests",
-  "mochi",
-  "main_test_osfile_async.js"
-);
-
-/**
- * Test OS.File.stat and OS.File.prototype.stat
- */
-var test_stat = maketest("stat", function stat(test) {
-  return (async function() {
-    // Open a file and stat it
-    let file = await OS.File.open(EXISTING_FILE);
-    let stat1;
-
-    try {
-      test.info("Stating file");
-      stat1 = await file.stat();
-      test.ok(true, "stat has worked " + stat1);
-      test.ok(stat1, "stat is not empty");
-    } finally {
-      await file.close();
-    }
-
-    // Stat the same file without opening it
-    test.info("Stating a file without opening it");
-    let stat2 = await OS.File.stat(EXISTING_FILE);
-    test.ok(true, "stat 2 has worked " + stat2);
-    test.ok(stat2, "stat 2 is not empty");
-    for (let key in stat2) {
-      test.is(
-        "" + stat1[key],
-        "" + stat2[key],
-        "Stat field " + key + "is the same"
-      );
-    }
-  })();
-});
-
-/**
- * Test feature detection using OS.File.Info.prototype on main thread
- */
-var test_info_features_detect = maketest(
-  "features_detect",
-  function features_detect(test) {
-    return (async function() {
-      if (!OS.Constants.Win && OS.Constants.libc) {
-        // see if unixGroup is defined
-        if ("unixGroup" in OS.File.Info.prototype) {
-          test.ok(true, "unixGroup is defined");
-        } else {
-          test.fail("unixGroup is not defined though we are under Unix");
-        }
-      }
-    })();
-  }
-);
-
-/**
- * Test file.{getPosition, setPosition}
- */
-var test_position = maketest("position", function position(test) {
-  return (async function() {
-    let file = await OS.File.open(EXISTING_FILE);
-
-    try {
-      let view = await file.read();
-      test.info("First batch of content read");
-      let CHUNK_SIZE = 178; // An arbitrary number of bytes to read from the file
-      let pos = await file.getPosition();
-      test.info("Obtained position");
-      test.is(pos, view.byteLength, "getPosition returned the end of the file");
-      pos = await file.setPosition(-CHUNK_SIZE, OS.File.POS_END);
-      test.info("Changed position");
-      test.is(
-        pos,
-        view.byteLength - CHUNK_SIZE,
-        "setPosition returned the correct position"
-      );
-
-      let view2 = await file.read();
-      test.info("Read the end of the file");
-      for (let i = 0; i < CHUNK_SIZE; ++i) {
-        if (view2[i] != view[i + view.byteLength - CHUNK_SIZE]) {
-          test.is(
-            view2[i],
-            view[i],
-            "setPosition put us in the right position"
-          );
-        }
-      }
-    } finally {
-      await file.close();
-    }
-  })();
-});
-
-/**
- * Test OS.File.prototype.{DirectoryIterator}
- */
-var test_iter = maketest("iter", function iter(test) {
-  return (async function() {
-    let currentDir = await OS.File.getCurrentDirectory();
-
-    // Trivial walks through the directory
-    test.info("Preparing iteration");
-    let iterator = new OS.File.DirectoryIterator(currentDir);
-    let temporary_file_name = OS.Path.join(
-      currentDir,
-      "empty-temporary-file.tmp"
-    );
-    try {
-      await OS.File.remove(temporary_file_name);
-    } catch (err) {
-      // Ignore errors removing file
-    }
-    let allFiles1 = await iterator.nextBatch();
-    test.info("Obtained all files through nextBatch");
-    test.isnot(allFiles1.length, 0, "There is at least one file");
-    test.isnot(allFiles1[0].path, null, "Files have a path");
-
-    // Ensure that we have the same entries with |reference_dir_contents|
-    let referenceEntries = new Set();
-    for (let entry of reference_dir_contents(currentDir)) {
-      referenceEntries.add(entry);
-    }
-    test.is(
-      referenceEntries.size,
-      allFiles1.length,
-      "All the entries in the directory have been listed"
-    );
-    for (let entry of allFiles1) {
-      test.ok(
-        referenceEntries.has(entry.path),
-        "File " + entry.path + " effectively exists"
-      );
-      // Ensure that we have correct isDir and isSymLink
-      // Current directory is {objdir}/_tests/testing/mochitest/, assume it has some dirs and symlinks.
-      var f = new FileUtils.File(entry.path);
-      test.is(
-        entry.isDir,
-        f.isDirectory(),
-        "Get file " + entry.path + " isDir correctly"
-      );
-      test.is(
-        entry.isSymLink,
-        f.isSymlink(),
-        "Get file " + entry.path + " isSymLink correctly"
-      );
-    }
-
-    await iterator.close();
-    test.info("Closed iterator");
-
-    test.info("Double closing DirectoryIterator");
-    iterator = new OS.File.DirectoryIterator(currentDir);
-    await iterator.close();
-    await iterator.close(); // double closing |DirectoryIterator|
-    test.ok(true, "|DirectoryIterator| was closed twice successfully");
-
-    let allFiles2 = [];
-    let i = 0;
-    iterator = new OS.File.DirectoryIterator(currentDir);
-    await iterator.forEach(function(entry, index) {
-      test.is(i++, index, "Getting the correct index");
-      allFiles2.push(entry);
-    });
-    test.info("Obtained all files through forEach");
-    is(
-      allFiles1.length,
-      allFiles2.length,
-      "Both runs returned the same number of files"
-    );
-    for (let i = 0; i < allFiles1.length; ++i) {
-      if (allFiles1[i].path != allFiles2[i].path) {
-        test.is(
-          allFiles1[i].path,
-          allFiles2[i].path,
-          "Both runs return the same files"
-        );
-        break;
-      }
-    }
-
-    // Testing batch iteration + whether an iteration can be stopped early
-    let BATCH_LENGTH = 10;
-    test.info("Getting some files through nextBatch");
-    await iterator.close();
-
-    iterator = new OS.File.DirectoryIterator(currentDir);
-    let someFiles1 = await iterator.nextBatch(BATCH_LENGTH);
-    let someFiles2 = await iterator.nextBatch(BATCH_LENGTH);
-    await iterator.close();
-
-    iterator = new OS.File.DirectoryIterator(currentDir);
-    await iterator.forEach(function cb(entry, index, iterator) {
-      if (index < BATCH_LENGTH) {
-        test.is(
-          entry.path,
-          someFiles1[index].path,
-          "Both runs return the same files (part 1)"
-        );
-      } else if (index < 2 * BATCH_LENGTH) {
-        test.is(
-          entry.path,
-          someFiles2[index - BATCH_LENGTH].path,
-          "Both runs return the same files (part 2)"
-        );
-      } else if (index == 2 * BATCH_LENGTH) {
-        test.info("Attempting to stop asynchronous forEach");
-        return iterator.close();
-      } else {
-        test.fail("Can we stop an asynchronous forEach? " + index);
-      }
-      return null;
-    });
-    await iterator.close();
-
-    // Ensuring that we find new files if they appear
-    let file = await OS.File.open(temporary_file_name, { write: true });
-    file.close();
-    iterator = new OS.File.DirectoryIterator(currentDir);
-    try {
-      let files = await iterator.nextBatch();
-      is(
-        files.length,
-        allFiles1.length + 1,
-        "The directory iterator has noticed the new file"
-      );
-      let exists = await iterator.exists();
-      test.ok(
-        exists,
-        "After nextBatch, iterator detects that the directory exists"
-      );
-    } finally {
-      await iterator.close();
-    }
-
-    // Ensuring that opening a non-existing directory fails consistently
-    // once iteration starts.
-    try {
-      iterator = null;
-      iterator = new OS.File.DirectoryIterator("/I do not exist");
-      let exists = await iterator.exists();
-      test.ok(
-        !exists,
-        "Before any iteration, iterator detects that the directory doesn't exist"
-      );
-      let exn = null;
-      try {
-        await iterator.next();
-      } catch (ex) {
-        if (ex instanceof OS.File.Error && ex.becauseNoSuchFile) {
-          exn = ex;
-          let exists = await iterator.exists();
-          test.ok(
-            !exists,
-            "After one iteration, iterator detects that the directory doesn't exist"
-          );
-        } else {
-          throw ex;
-        }
-      }
-      test.ok(
-        exn,
-        "Iterating through a directory that does not exist has failed with becauseNoSuchFile"
-      );
-    } finally {
-      if (iterator) {
-        iterator.close();
-      }
-    }
-    test.ok(
-      !!iterator,
-      "The directory iterator for a non-existing directory was correctly created"
-    );
-  })();
-});
-
-/**
- * Test OS.File.prototype.{exists}
- */
-var test_exists = maketest("exists", function exists(test) {
-  return (async function() {
-    let fileExists = await OS.File.exists(EXISTING_FILE);
-    test.ok(fileExists, "file exists");
-    fileExists = await OS.File.exists(EXISTING_FILE + ".tmp");
-    test.ok(!fileExists, "file does not exists");
-  })();
-});
-
-/**
- * Test changes to OS.Shared.DEBUG flag.
- */
-var test_debug = maketest("debug", function debug(test) {
-  return (async function() {
-    function testSetDebugPref(pref) {
-      try {
-        Services.prefs.setBoolPref("toolkit.osfile.log", pref);
-      } catch (x) {
-        test.fail(
-          "Setting OS.Shared.DEBUG to " + pref + " should not cause error."
-        );
-      } finally {
-        test.is(OS.Shared.DEBUG, pref, "OS.Shared.DEBUG is set correctly.");
-      }
-    }
-    testSetDebugPref(true);
-    let workerDEBUG = await OS.File.GET_DEBUG();
-    test.is(workerDEBUG, true, "Worker's DEBUG is set.");
-    testSetDebugPref(false);
-    workerDEBUG = await OS.File.GET_DEBUG();
-    test.is(workerDEBUG, false, "Worker's DEBUG is unset.");
-  })();
-});
-
-/**
- * Test logging in the main thread with set OS.Shared.DEBUG and
- * OS.Shared.TEST flags.
- */
-var test_debug_test = maketest("debug_test", function debug_test(test) {
-  return (async function() {
-    // Create a console listener.
-    let consoleListener = {
-      observe(aMessage) {
-        // Ignore unexpected messages.
-        if (!(aMessage instanceof Ci.nsIConsoleMessage)) {
-          return;
-        }
-        if (!aMessage.message.includes("TEST OS")) {
-          return;
-        }
-        test.ok(true, "DEBUG TEST messages are logged correctly.");
-      },
-    };
-    toggleDebugTest(true, consoleListener);
-    // Execution of OS.File.exist method will trigger OS.File.LOG several times.
-    await OS.File.exists(EXISTING_FILE);
-    toggleDebugTest(false, consoleListener);
-  })();
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/mochi/test_osfile_async.xhtml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0"?>
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<window title="Testing async I/O with OS.File"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="test();">
-
-  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
-  <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
-  <script type="application/javascript"
-          src="main_test_osfile_async.js"/>
-
-  <body xmlns="http://www.w3.org/1999/xhtml">
-    <p id="display"></p>
-    <div id="content" style="display:none;"></div>
-    <pre id="test"></pre>
-  </body>
-  <label id="test-result"/>
-</window>
deleted file mode 100644
--- a/toolkit/components/osfile/tests/mochi/test_osfile_back.xhtml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0"?>
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<window title="Testing OS.File on a chrome worker thread"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="test();">
-
-  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
-  <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/WorkerHandler.js"/>
-  <script type="application/javascript">
-  <![CDATA[
-
-let worker;
-
-function test() {
-  ok(true, "test_osfile.xul: Starting test");
-  if (navigator.platform.includes("Win")) {
-    ok(true, "test_osfile.xul: Using Windows test suite");
-    worker = new ChromeWorker("worker_test_osfile_win.js");
-  } else {
-    ok(true, "test_osfile.xul: Using Unix test suite");
-    worker = new ChromeWorker("worker_test_osfile_unix.js");
-  }
-  SimpleTest.waitForExplicitFinish();
-  ok(true, "test_osfile.xul: Chrome worker created");
-  dump("MAIN: go\n");
-  listenForTests(worker);
-  worker.postMessage(0);
-  ok(true, "test_osfile.xul: Test in progress");
-};
-]]>
-  </script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml">
-    <p id="display"></p>
-    <div id="content" style="display:none;"></div>
-    <pre id="test"></pre>
-  </body>
-  <label id="test-result"/>
-</window>
deleted file mode 100644
--- a/toolkit/components/osfile/tests/mochi/test_osfile_comms.xhtml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0"?>
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<window title="Testing OS.File on a chrome worker thread"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="test();">
-
-  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
-  <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
-  <script type="application/javascript">
-  <![CDATA[
-
-"use strict";
-
-let worker;
-
-SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
-                                    true]]});
-let test = function test() {
-  SimpleTest.info("test_osfile_comms.xhtml: Starting test");
-  // These are used in the worker.
-  // eslint-disable-next-line no-unused-vars
-  let { ctypes } = ChromeUtils.import("resource://gre/modules/ctypes.jsm");
-  // eslint-disable-next-line no-unused-vars
-  let { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-  worker = new ChromeWorker("worker_test_osfile_comms.js");
-  SimpleTest.waitForExplicitFinish();
-  try {
-    worker.onerror = function onerror(error) {
-      SimpleTest.ok(false, "received error "+error);
-    }
-    worker.onmessage = function onmessage(msg) {
-      Cu.forceShrinkingGC();
-      switch (msg.data.kind) {
-        case "is":
-          SimpleTest.ok(msg.data.outcome, msg.data.description +
-          " ("+ msg.data.a + " ==? " + msg.data.b + ")" );
-          return;
-        case "isnot":
-          SimpleTest.ok(msg.data.outcome, msg.data.description +
-          " ("+ msg.data.a + " !=? " + msg.data.b + ")" );
-          return;
-        case "ok":
-          SimpleTest.ok(msg.data.condition, msg.data.description);
-          return;
-        case "info":
-          SimpleTest.info(msg.data.description);
-          return;
-        case "finish":
-          SimpleTest.finish();
-          return;
-        case "value":
-          SimpleTest.ok(true, "test_osfile_comms.xhtml: Received value " + JSON.stringify(msg.data.value));
-          // eslint-disable-next-line no-eval
-          let type = eval(msg.data.typename);
-          // eslint-disable-next-line no-eval
-          let check = eval(msg.data.check);
-          let value = msg.data.value;
-          let deserialized = type.fromMsg(value);
-          check(deserialized, "Main thread test: ");
-          return;
-      default:
-        SimpleTest.ok(false, "test_osfile_comms.xhtml: wrong message "+JSON.stringify(msg.data));
-      }
-    };
-    worker.postMessage(0)
-    ok(true, "Worker launched");
-  } catch(x) {
-    // As we have set |waitForExplicitFinish|, we add this fallback
-    // in case of uncaught error, to ensure that the test does not
-    // just freeze.
-    ok(false, "Caught exception " + x + " at " + x.stack);
-    SimpleTest.finish();
-  }
-};
-
-]]>
-  </script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml">
-    <p id="display"></p>
-    <div id="content" style="display:none;"></div>
-    <pre id="test"></pre>
-  </body>
-  <label id="test-result"/>
-</window>
deleted file mode 100644
--- a/toolkit/components/osfile/tests/mochi/test_osfile_front.xhtml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0"?>
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<window title="Testing OS.File on a chrome worker thread"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="test();">
-
-  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
-  <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/WorkerHandler.js"/>
-  <script type="application/javascript">
-  <![CDATA[
-
-let worker;
-let main = this;
-
-function test() {
-  info("test_osfile_front.xhtml: Starting test");
-
-  // Test the OS.File worker
-
-  worker = new ChromeWorker("worker_test_osfile_front.js");
-  SimpleTest.waitForExplicitFinish();
-  info("test_osfile_front.xhtml: Chrome worker created");
-  dump("MAIN: go\n");
-  listenForTests(worker);
-  worker.postMessage(0);
-  ok(true, "test_osfile_front.xhtml: Test in progress");
-};
-]]>
-  </script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml">
-    <p id="display"></p>
-    <div id="content" style="display:none;"></div>
-    <pre id="test"></pre>
-  </body>
-  <label id="test-result"/>
-</window>
deleted file mode 100644
--- a/toolkit/components/osfile/tests/mochi/worker_test_osfile_comms.js
+++ /dev/null
@@ -1,205 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/* eslint-env mozilla/chrome-worker, node */
-
-"use strict";
-
-/* import-globals-from /testing/mochitest/tests/SimpleTest/WorkerSimpleTest.js */
-importScripts("chrome://mochikit/content/tests/SimpleTest/WorkerSimpleTest.js");
-
-// The set of samples for communications test. Declare as a global
-// variable to prevent this from being garbage-collected too early.
-var samples;
-
-self.onmessage = function(msg) {
-  info("Initializing");
-  self.onmessage = function on_unexpected_message(msg) {
-    throw new Error("Unexpected message " + JSON.stringify(msg.data));
-  };
-  /* import-globals-from /toolkit/components/osfile/osfile.jsm */
-  importScripts("resource://gre/modules/osfile.jsm");
-  info("Initialization complete");
-
-  samples = [
-    {
-      typename: "OS.Shared.Type.char.in_ptr",
-      valuedescr: "String",
-      value: "This is a test",
-      type: OS.Shared.Type.char.in_ptr,
-      check: function check_string(candidate, prefix) {
-        is(candidate, "This is a test", prefix);
-      },
-    },
-    {
-      typename: "OS.Shared.Type.char.in_ptr",
-      valuedescr: "Typed array",
-      value: (function() {
-        let view = new Uint8Array(15);
-        for (let i = 0; i < 15; ++i) {
-          view[i] = i;
-        }
-        return view;
-      })(),
-      type: OS.Shared.Type.char.in_ptr,
-      check: function check_ArrayBuffer(candidate, prefix) {
-        for (let i = 0; i < 15; ++i) {
-          is(
-            candidate[i],
-            i % 256,
-            prefix +
-              "Checking that the contents of the ArrayBuffer were preserved"
-          );
-        }
-      },
-    },
-    {
-      typename: "OS.Shared.Type.char.in_ptr",
-      valuedescr: "Pointer",
-      value: new OS.Shared.Type.char.in_ptr.implementation(1),
-      type: OS.Shared.Type.char.in_ptr,
-      check: function check_ptr(candidate, prefix) {
-        let address = ctypes.cast(candidate, ctypes.uintptr_t).value.toString();
-        is(
-          address,
-          "1",
-          prefix + "Checking that the pointer address was preserved"
-        );
-      },
-    },
-    {
-      typename: "OS.Shared.Type.char.in_ptr",
-      valuedescr: "C array",
-      value: (function() {
-        let buf = new (ctypes.ArrayType(ctypes.uint8_t, 15))();
-        for (let i = 0; i < 15; ++i) {
-          buf[i] = i % 256;
-        }
-        return buf;
-      })(),
-      type: OS.Shared.Type.char.in_ptr,
-      check: function check_array(candidate, prefix) {
-        let cast = ctypes.cast(candidate, ctypes.uint8_t.ptr);
-        for (let i = 0; i < 15; ++i) {
-          is(
-            cast.contents,
-            i % 256,
-            prefix +
-              "Checking that the contents of the C array were preserved, index " +
-              i
-          );
-          cast = cast.increment();
-        }
-      },
-    },
-    {
-      typename: "OS.File.Error",
-      valuedescr: "OS Error",
-      type: OS.File.Error,
-      value: new OS.File.Error("foo", 1),
-      check: function check_error(candidate, prefix) {
-        ok(
-          candidate instanceof OS.File.Error,
-          prefix + "Error is an OS.File.Error"
-        );
-        ok(
-          candidate.unixErrno == 1 || candidate.winLastError == 1,
-          prefix + "Error code is correct"
-        );
-        try {
-          let string = candidate.toString();
-          info(prefix + ".toString() works " + string);
-        } catch (x) {
-          ok(false, prefix + ".toString() fails " + x);
-        }
-      },
-    },
-  ];
-  samples.forEach(function test(sample) {
-    let type = sample.type;
-    let value = sample.value;
-    let check = sample.check;
-    info(
-      "Testing handling of type " +
-        sample.typename +
-        " communicating " +
-        sample.valuedescr
-    );
-
-    // 1. Test serialization
-    let serialized;
-    let exn;
-    try {
-      serialized = type.toMsg(value);
-    } catch (ex) {
-      exn = ex;
-    }
-    is(
-      exn,
-      null,
-      "Can I serialize the following value? " +
-        value +
-        " aka " +
-        JSON.stringify(value)
-    );
-    if (exn) {
-      return;
-    }
-
-    if ("data" in serialized) {
-      // Unwrap from `Meta`
-      serialized = serialized.data;
-    }
-
-    // 2. Test deserialization
-    let deserialized;
-    try {
-      deserialized = type.fromMsg(serialized);
-    } catch (ex) {
-      exn = ex;
-    }
-    is(
-      exn,
-      null,
-      "Can I deserialize the following message? " +
-        serialized +
-        " aka " +
-        JSON.stringify(serialized)
-    );
-    if (exn) {
-      return;
-    }
-
-    // 3. Local test deserialized value
-    info(
-      "Running test on deserialized value " +
-        deserialized +
-        " aka " +
-        JSON.stringify(deserialized)
-    );
-    check(deserialized, "Local test: ");
-
-    // 4. Test sending serialized
-    info("Attempting to send message");
-    try {
-      self.postMessage({
-        kind: "value",
-        typename: sample.typename,
-        value: serialized,
-        check: check.toSource(),
-      });
-    } catch (ex) {
-      exn = ex;
-    }
-    is(
-      exn,
-      null,
-      "Can I send the following message? " +
-        serialized +
-        " aka " +
-        JSON.stringify(serialized)
-    );
-  });
-
-  finish();
-};
deleted file mode 100644
--- a/toolkit/components/osfile/tests/mochi/worker_test_osfile_front.js
+++ /dev/null
@@ -1,696 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/* eslint-env mozilla/chrome-worker, node */
-
-/* import-globals-from /testing/mochitest/tests/SimpleTest/WorkerSimpleTest.js */
-importScripts("chrome://mochikit/content/tests/SimpleTest/WorkerSimpleTest.js");
-/* import-globals-from /toolkit/components/workerloader/require.js */
-importScripts("resource://gre/modules/workers/require.js");
-
-var SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
-SharedAll.Config.DEBUG = true;
-
-function should_throw(f) {
-  try {
-    f();
-  } catch (x) {
-    return x;
-  }
-  return null;
-}
-
-self.onmessage = function onmessage_start(msg) {
-  self.onmessage = function onmessage_ignored(msg) {
-    log("ignored message " + JSON.stringify(msg.data));
-  };
-  try {
-    test_init();
-    test_open_existing_file();
-    test_open_non_existing_file();
-    test_flush_open_file();
-    test_copy_existing_file();
-    test_position();
-    test_move_file();
-    test_iter_dir();
-    test_info();
-    test_path();
-    test_exists_file();
-    test_remove_file();
-  } catch (x) {
-    log("Catching error: " + x);
-    log("Stack: " + x.stack);
-    log("Source: " + x.toSource());
-    ok(false, x.toString() + "\n" + x.stack);
-  }
-  finish();
-};
-
-function test_init() {
-  info("Starting test_init");
-  /* import-globals-from /toolkit/components/osfile/osfile.jsm */
-  importScripts("resource://gre/modules/osfile.jsm");
-}
-
-/**
- * Test that we can open an existing file.
- */
-function test_open_existing_file() {
-  info("Starting test_open_existing");
-  let file = OS.File.open(
-    "chrome/toolkit/components/osfile/tests/mochi/worker_test_osfile_unix.js"
-  );
-  file.close();
-}
-
-/**
- * Test that opening a file that does not exist fails with the right error.
- */
-function test_open_non_existing_file() {
-  info("Starting test_open_non_existing");
-  let exn;
-  try {
-    OS.File.open("/I do not exist");
-  } catch (x) {
-    exn = x;
-    info("test_open_non_existing_file: Exception detail " + exn);
-  }
-  ok(!!exn, "test_open_non_existing_file: Exception was raised ");
-  ok(
-    exn instanceof OS.File.Error,
-    "test_open_non_existing_file: Exception was a OS.File.Error"
-  );
-  ok(
-    exn.becauseNoSuchFile,
-    "test_open_non_existing_file: Exception confirms that the file does not exist"
-  );
-}
-
-/**
- * Test that to ensure that |foo.flush()| does not
- * cause an error, where |foo| is an open file.
- */
-function test_flush_open_file() {
-  info("Starting test_flush_open_file");
-  let tmp = "test_flush.tmp";
-  let file = OS.File.open(tmp, { create: true, write: true });
-  file.flush();
-  file.close();
-  OS.File.remove(tmp);
-}
-
-/**
- * Utility function for comparing two files (or a prefix of two files).
- *
- * This function returns nothing but fails of both files (or prefixes)
- * are not identical.
- *
- * @param {string} test The name of the test (used for logging).
- * @param {string} sourcePath The name of the first file.
- * @param {string} destPath The name of the second file.
- * @param {number=} prefix If specified, only compare the |prefix|
- * first bytes of |sourcePath| and |destPath|.
- */
-function compare_files(test, sourcePath, destPath, prefix) {
-  info(test + ": Comparing " + sourcePath + " and " + destPath);
-  let source = OS.File.open(sourcePath);
-  let dest = OS.File.open(destPath);
-  info("Files are open");
-  let sourceResult, destResult;
-  try {
-    if (prefix != undefined) {
-      sourceResult = source.read(prefix);
-      destResult = dest.read(prefix);
-    } else {
-      sourceResult = source.read();
-      destResult = dest.read();
-    }
-    is(
-      sourceResult.length,
-      destResult.length,
-      test + ": Both files have the same size"
-    );
-    for (let i = 0; i < sourceResult.length; ++i) {
-      if (sourceResult[i] != destResult[i]) {
-        is(sourceResult[i] != destResult[i], test + ": Comparing char " + i);
-        break;
-      }
-    }
-  } finally {
-    source.close();
-    dest.close();
-  }
-  info(test + ": Comparison complete");
-}
-
-/**
- * Test that copying a file using |copy| works.
- */
-function test_copy_existing_file() {
-  let src_file_name = OS.Path.join(
-    "chrome",
-    "toolkit",
-    "components",
-    "osfile",
-    "tests",
-    "mochi",
-    "worker_test_osfile_front.js"
-  );
-  let tmp_file_name = "test_osfile_front.tmp";
-  info("Starting test_copy_existing");
-  OS.File.copy(src_file_name, tmp_file_name);
-
-  info("test_copy_existing: Copy complete");
-  compare_files("test_copy_existing", src_file_name, tmp_file_name);
-
-  // Create a bogus file with arbitrary content, then attempt to overwrite
-  // it with |copy|.
-  let dest = OS.File.open(tmp_file_name, { trunc: true });
-  let buf = new Uint8Array(50);
-  dest.write(buf);
-  dest.close();
-
-  OS.File.copy(src_file_name, tmp_file_name);
-
-  compare_files("test_copy_existing 2", src_file_name, tmp_file_name);
-
-  // Attempt to overwrite with noOverwrite
-  let exn;
-  try {
-    OS.File.copy(src_file_name, tmp_file_name, { noOverwrite: true });
-  } catch (x) {
-    exn = x;
-  }
-  ok(
-    !!exn,
-    "test_copy_existing: noOverwrite prevents overwriting existing files"
-  );
-
-  info("test_copy_existing: Cleaning up");
-  OS.File.remove(tmp_file_name);
-}
-
-/**
- * Test that moving a file works.
- */
-function test_move_file() {
-  info("test_move_file: Starting");
-  // 1. Copy file into a temporary file
-  let src_file_name = OS.Path.join(
-    "chrome",
-    "toolkit",
-    "components",
-    "osfile",
-    "tests",
-    "mochi",
-    "worker_test_osfile_front.js"
-  );
-  let tmp_file_name = "test_osfile_front.tmp";
-  let tmp2_file_name = "test_osfile_front.tmp2";
-  OS.File.copy(src_file_name, tmp_file_name);
-
-  info("test_move_file: Copy complete");
-
-  // 2. Move
-  OS.File.move(tmp_file_name, tmp2_file_name);
-
-  info("test_move_file: Move complete");
-
-  // 3. Check that destination exists
-  compare_files("test_move_file", src_file_name, tmp2_file_name);
-
-  // 4. Check that original file does not exist anymore
-  let exn;
-  try {
-    OS.File.open(tmp_file_name);
-  } catch (x) {
-    exn = x;
-  }
-  ok(!!exn, "test_move_file: Original file has been removed");
-
-  info("test_move_file: Cleaning up");
-  OS.File.remove(tmp2_file_name);
-}
-
-function test_iter_dir() {
-  info("test_iter_dir: Starting");
-
-  // Create a file, to be sure that it exists
-  let tmp_file_name = "test_osfile_front.tmp";
-  let tmp_file = OS.File.open(tmp_file_name, { write: true, trunc: true });
-  tmp_file.close();
-
-  let parent = OS.File.getCurrentDirectory();
-  info("test_iter_dir: directory " + parent);
-  let iterator = new OS.File.DirectoryIterator(parent);
-  info("test_iter_dir: iterator created");
-  let encountered_tmp_file = false;
-  for (let entry of iterator) {
-    // Checking that |name| can be decoded properly
-    info("test_iter_dir: encountering entry " + entry.name);
-
-    if (entry.name == tmp_file_name) {
-      encountered_tmp_file = true;
-      isnot(
-        entry.isDir,
-        "test_iter_dir: The temporary file is not a directory"
-      );
-      isnot(entry.isSymLink, "test_iter_dir: The temporary file is not a link");
-    }
-
-    let file;
-    let success = true;
-    try {
-      file = OS.File.open(entry.path);
-    } catch (x) {
-      if (x.becauseNoSuchFile) {
-        success = false;
-      }
-    }
-    if (file) {
-      file.close();
-    }
-    ok(success, "test_iter_dir: Entry " + entry.path + " exists");
-
-    if (OS.Win) {
-      // We assume that the files are at least as recent as 2009.
-      // Since this test was written in 2011 and some of our packaging
-      // sets dates arbitrarily to 2010, this should be safe.
-      let year = new Date().getFullYear();
-
-      let lastWrite = entry.winLastWriteDate;
-      ok(
-        lastWrite,
-        "test_iter_dir: Windows lastWrite date exists: " + lastWrite
-      );
-      ok(
-        lastWrite.getFullYear() >= 2009 && lastWrite.getFullYear() <= year,
-        "test_iter_dir: consistent lastWrite date"
-      );
-
-      let lastAccess = entry.winLastAccessDate;
-      ok(
-        lastAccess,
-        "test_iter_dir: Windows lastAccess date exists: " + lastAccess
-      );
-      ok(
-        lastAccess.getFullYear() >= 2009 && lastAccess.getFullYear() <= year,
-        "test_iter_dir: consistent lastAccess date"
-      );
-    }
-  }
-  ok(encountered_tmp_file, "test_iter_dir: We have found the temporary file");
-
-  info("test_iter_dir: Cleaning up");
-  iterator.close();
-
-  // Testing nextBatch()
-  iterator = new OS.File.DirectoryIterator(parent);
-  let allentries = [];
-  for (let x of iterator) {
-    allentries.push(x);
-  }
-  iterator.close();
-
-  ok(
-    allentries.length >= 14,
-    "test_iter_dir: Meta-check: the test directory should contain at least 14 items"
-  );
-
-  iterator = new OS.File.DirectoryIterator(parent);
-  let firstten = iterator.nextBatch(10);
-  is(firstten.length, 10, "test_iter_dir: nextBatch(10) returns 10 items");
-  for (let i = 0; i < firstten.length; ++i) {
-    is(
-      allentries[i].path,
-      firstten[i].path,
-      "test_iter_dir: Checking that batch returns the correct entries"
-    );
-  }
-  let nextthree = iterator.nextBatch(3);
-  is(nextthree.length, 3, "test_iter_dir: nextBatch(3) returns 3 items");
-  for (let i = 0; i < nextthree.length; ++i) {
-    is(
-      allentries[i + firstten.length].path,
-      nextthree[i].path,
-      "test_iter_dir: Checking that batch 2 returns the correct entries"
-    );
-  }
-  let everythingelse = iterator.nextBatch();
-  ok(
-    everythingelse.length >= 1,
-    "test_iter_dir: nextBatch() returns at least one item"
-  );
-  for (let i = 0; i < everythingelse.length; ++i) {
-    is(
-      allentries[i + firstten.length + nextthree.length].path,
-      everythingelse[i].path,
-      "test_iter_dir: Checking that batch 3 returns the correct entries"
-    );
-  }
-  is(
-    iterator.nextBatch().length,
-    0,
-    "test_iter_dir: Once there is nothing left, nextBatch returns an empty array"
-  );
-  iterator.close();
-
-  iterator = new OS.File.DirectoryIterator(parent);
-  iterator.close();
-  is(
-    iterator.nextBatch().length,
-    0,
-    "test_iter_dir: nextBatch on closed iterator returns an empty array"
-  );
-
-  iterator = new OS.File.DirectoryIterator(parent);
-  let allentries2 = iterator.nextBatch();
-  is(
-    allentries.length,
-    allentries2.length,
-    "test_iter_dir: Checking that getBatch(null) returns the right number of entries"
-  );
-  for (let i = 0; i < allentries.length; ++i) {
-    is(
-      allentries[i].path,
-      allentries2[i].path,
-      "test_iter_dir: Checking that getBatch(null) returns everything in the right order"
-    );
-  }
-  iterator.close();
-
-  // Test forEach
-  iterator = new OS.File.DirectoryIterator(parent);
-  let index = 0;
-  iterator.forEach(function cb(entry, aIndex, aIterator) {
-    is(index, aIndex, "test_iter_dir: Checking that forEach index is correct");
-    ok(
-      iterator == aIterator,
-      "test_iter_dir: Checking that right iterator is passed"
-    );
-    if (index < 10) {
-      is(
-        allentries[index].path,
-        entry.path,
-        "test_iter_dir: Checking that forEach entry is correct"
-      );
-    } else if (index == 10) {
-      iterator.close();
-    } else {
-      ok(false, "test_iter_dir: Checking that forEach can be stopped early");
-    }
-    ++index;
-  });
-  iterator.close();
-
-  // test for prototype |OS.File.DirectoryIterator.unixAsFile|
-  if ("unixAsFile" in OS.File.DirectoryIterator.prototype) {
-    info("testing property unixAsFile");
-    let path = OS.Path.join(
-      "chrome",
-      "toolkit",
-      "components",
-      "osfile",
-      "tests",
-      "mochi"
-    );
-    iterator = new OS.File.DirectoryIterator(path);
-
-    let dir_file = iterator.unixAsFile(); // return |File|
-    let stat0 = dir_file.stat();
-    let stat1 = OS.File.stat(path);
-
-    let unix_info_to_string = function unix_info_to_string(info) {
-      return (
-        "| " +
-        info.unixMode +
-        " | " +
-        info.unixOwner +
-        " | " +
-        info.unixGroup +
-        " | " +
-        info.lastModificationDate +
-        " | " +
-        info.lastAccessDate +
-        " | " +
-        info.size +
-        " |"
-      );
-    };
-
-    let s0_string = unix_info_to_string(stat0);
-    let s1_string = unix_info_to_string(stat1);
-
-    ok(stat0.isDir, "unixAsFile returned a directory");
-    is(s0_string, s1_string, "unixAsFile returned the correct file");
-    dir_file.close();
-    iterator.close();
-  }
-  info("test_iter_dir: Complete");
-}
-
-function test_position() {
-  info("test_position: Starting");
-
-  ok("POS_START" in OS.File, "test_position: POS_START exists");
-  ok("POS_CURRENT" in OS.File, "test_position: POS_CURRENT exists");
-  ok("POS_END" in OS.File, "test_position: POS_END exists");
-
-  let ARBITRARY_POSITION = 321;
-  let src_file_name = OS.Path.join(
-    "chrome",
-    "toolkit",
-    "components",
-    "osfile",
-    "tests",
-    "mochi",
-    "worker_test_osfile_front.js"
-  );
-
-  let file = OS.File.open(src_file_name);
-  is(file.getPosition(), 0, "test_position: Initial position is 0");
-
-  let size = 0 + file.stat().size; // Hack: We can remove this 0 + once 776259 has landed
-
-  file.setPosition(ARBITRARY_POSITION, OS.File.POS_START);
-  is(
-    file.getPosition(),
-    ARBITRARY_POSITION,
-    "test_position: Setting position from start"
-  );
-
-  file.setPosition(0, OS.File.POS_START);
-  is(
-    file.getPosition(),
-    0,
-    "test_position: Setting position from start back to 0"
-  );
-
-  file.setPosition(ARBITRARY_POSITION);
-  is(
-    file.getPosition(),
-    ARBITRARY_POSITION,
-    "test_position: Setting position without argument"
-  );
-
-  file.setPosition(-ARBITRARY_POSITION, OS.File.POS_END);
-  is(
-    file.getPosition(),
-    size - ARBITRARY_POSITION,
-    "test_position: Setting position from end"
-  );
-
-  file.setPosition(ARBITRARY_POSITION, OS.File.POS_CURRENT);
-  is(file.getPosition(), size, "test_position: Setting position from current");
-
-  file.close();
-  info("test_position: Complete");
-}
-
-function test_info() {
-  info("test_info: Starting");
-
-  let filename = "test_info.tmp";
-  let size = 261; // An arbitrary file length
-  let start = new Date();
-
-  // Cleanup any leftover from previous tests
-  try {
-    OS.File.remove(filename);
-    info("test_info: Cleaned up previous garbage");
-  } catch (x) {
-    if (!x.becauseNoSuchFile) {
-      throw x;
-    }
-    info("test_info: No previous garbage");
-  }
-
-  let file = OS.File.open(filename, { trunc: true });
-  let buf = new ArrayBuffer(size);
-  file._write(buf, size);
-  file.close();
-
-  // Test OS.File.stat on new file
-  let stat = OS.File.stat(filename);
-  ok(!!stat, "test_info: info acquired");
-  ok(!stat.isDir, "test_info: file is not a directory");
-  is(stat.isSymLink, false, "test_info: file is not a link");
-  is(stat.size.toString(), size, "test_info: correct size");
-
-  let stop = new Date();
-
-  // We round down/up by 1s as file system precision is lower than
-  // Date precision (no clear specifications about that, but it seems
-  // that this can be a little over 1 second under ext3 and 2 seconds
-  // under FAT).
-  let SLOPPY_FILE_SYSTEM_ADJUSTMENT = 3000;
-  let startMs = start.getTime() - SLOPPY_FILE_SYSTEM_ADJUSTMENT;
-  let stopMs = stop.getTime() + SLOPPY_FILE_SYSTEM_ADJUSTMENT;
-  info("Testing stat with bounds [ " + startMs + ", " + stopMs + " ]");
-
-  let change = stat.lastModificationDate;
-  info("Testing lastModificationDate: " + change);
-  ok(
-    change.getTime() >= startMs && change.getTime() <= stopMs,
-    "test_info: lastModificationDate is consistent"
-  );
-
-  // Test OS.File.prototype.stat on new file
-  file = OS.File.open(filename);
-  try {
-    stat = file.stat();
-  } finally {
-    file.close();
-  }
-
-  ok(!!stat, "test_info: info acquired 2");
-  ok(!stat.isDir, "test_info: file is not a directory 2");
-  ok(!stat.isSymLink, "test_info: file is not a link 2");
-  is(stat.size.toString(), size, "test_info: correct size 2");
-
-  stop = new Date();
-
-  // Round up/down as above
-  startMs = start.getTime() - SLOPPY_FILE_SYSTEM_ADJUSTMENT;
-  stopMs = stop.getTime() + SLOPPY_FILE_SYSTEM_ADJUSTMENT;
-  info("Testing stat 2 with bounds [ " + startMs + ", " + stopMs + " ]");
-
-  let access = stat.lastAccessDate;
-  info("Testing lastAccessDate: " + access);
-  ok(
-    access.getTime() >= startMs && access.getTime() <= stopMs,
-    "test_info: lastAccessDate is consistent"
-  );
-
-  change = stat.lastModificationDate;
-  info("Testing lastModificationDate 2: " + change);
-  ok(
-    change.getTime() >= startMs && change.getTime() <= stopMs,
-    "test_info: lastModificationDate 2 is consistent"
-  );
-
-  // Test OS.File.stat on directory
-  stat = OS.File.stat(OS.File.getCurrentDirectory());
-  ok(!!stat, "test_info: info on directory acquired");
-  ok(stat.isDir, "test_info: directory is a directory");
-
-  info("test_info: Complete");
-}
-
-// Note that most of the features of path are tested in
-// worker_test_osfile_{unix, win}.js
-function test_path() {
-  info("test_path: starting");
-  let abcd = OS.Path.join("a", "b", "c", "d");
-  is(OS.Path.basename(abcd), "d", "basename of a/b/c/d");
-
-  let abc = OS.Path.join("a", "b", "c");
-  is(OS.Path.dirname(abcd), abc, "dirname of a/b/c/d");
-
-  let abdotsc = OS.Path.join("a", "b", "..", "c");
-  is(OS.Path.normalize(abdotsc), OS.Path.join("a", "c"), "normalize a/b/../c");
-
-  let adotsdotsdots = OS.Path.join("a", "..", "..", "..");
-  is(
-    OS.Path.normalize(adotsdotsdots),
-    OS.Path.join("..", ".."),
-    "normalize a/../../.."
-  );
-
-  info("test_path: Complete");
-}
-
-/**
- * Test the file |exists| method.
- */
-function test_exists_file() {
-  let file_name = OS.Path.join(
-    "chrome",
-    "toolkit",
-    "components",
-    "osfile",
-    "tests",
-    "mochi",
-    "test_osfile_front.xhtml"
-  );
-  info("test_exists_file: starting");
-  ok(
-    OS.File.exists(file_name),
-    "test_exists_file: file exists (OS.File.exists)"
-  );
-  ok(
-    !OS.File.exists(file_name + ".tmp"),
-    "test_exists_file: file does not exists (OS.File.exists)"
-  );
-
-  let dir_name = OS.Path.join(
-    "chrome",
-    "toolkit",
-    "components",
-    "osfile",
-    "tests",
-    "mochi"
-  );
-  ok(OS.File.exists(dir_name), "test_exists_file: directory exists");
-  ok(
-    !OS.File.exists(dir_name) + ".tmp",
-    "test_exists_file: directory does not exist"
-  );
-
-  info("test_exists_file: complete");
-}
-
-/**
- * Test the file |remove| method.
- */
-function test_remove_file() {
-  let absent_file_name = "test_osfile_front_absent.tmp";
-
-  // Check that removing absent files is handled correctly
-  let exn = should_throw(function() {
-    OS.File.remove(absent_file_name, { ignoreAbsent: false });
-  });
-  ok(!!exn, "test_remove_file: throws if there is no such file");
-
-  exn = should_throw(function() {
-    OS.File.remove(absent_file_name, { ignoreAbsent: true });
-    OS.File.remove(absent_file_name);
-  });
-  ok(!exn, "test_remove_file: ignoreAbsent works");
-
-  if (OS.Win) {
-    let file_name = "test_osfile_front_file_to_remove.tmp";
-    let file = OS.File.open(file_name, { write: true });
-    file.close();
-    ok(OS.File.exists(file_name), "test_remove_file: test file exists");
-    OS.Win.File.SetFileAttributes(
-      file_name,
-      OS.Constants.Win.FILE_ATTRIBUTE_READONLY
-    );
-    OS.File.remove(file_name);
-    ok(
-      !OS.File.exists(file_name),
-      "test_remove_file: test file has been removed"
-    );
-  }
-}
deleted file mode 100644
--- a/toolkit/components/osfile/tests/mochi/worker_test_osfile_unix.js
+++ /dev/null
@@ -1,257 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/* eslint-env mozilla/chrome-worker, node */
-
-/* import-globals-from /testing/mochitest/tests/SimpleTest/WorkerSimpleTest.js */
-importScripts("chrome://mochikit/content/tests/SimpleTest/WorkerSimpleTest.js");
-
-self.onmessage = function(msg) {
-  log("received message " + JSON.stringify(msg.data));
-  self.onmessage = function(msg) {
-    log("ignored message " + JSON.stringify(msg.data));
-  };
-  test_init();
-  test_getcwd();
-  test_open_close();
-  test_create_file();
-  test_access();
-  test_read_write();
-  test_passing_undefined();
-  finish();
-};
-
-function test_init() {
-  info("Starting test_init");
-  /* import-globals-from /toolkit/components/osfile/osfile.jsm */
-  importScripts("resource://gre/modules/osfile.jsm");
-}
-
-function test_open_close() {
-  info("Starting test_open_close");
-  is(typeof OS.Unix.File.open, "function", "OS.Unix.File.open is a function");
-  let file = OS.Unix.File.open(
-    "chrome/toolkit/components/osfile/tests/mochi/worker_test_osfile_unix.js",
-    OS.Constants.libc.O_RDONLY
-  );
-  isnot(file, -1, "test_open_close: opening succeeded");
-  info("Close: " + OS.Unix.File.close.toSource());
-  let result = OS.Unix.File.close(file);
-  is(result, 0, "test_open_close: close succeeded");
-
-  file = OS.Unix.File.open("/i do not exist", OS.Constants.libc.O_RDONLY);
-  is(file, -1, "test_open_close: opening of non-existing file failed");
-  is(
-    ctypes.errno,
-    OS.Constants.libc.ENOENT,
-    "test_open_close: error is ENOENT"
-  );
-}
-
-function test_create_file() {
-  info("Starting test_create_file");
-  let file = OS.Unix.File.open(
-    "test.tmp",
-    OS.Constants.libc.O_RDWR |
-      OS.Constants.libc.O_CREAT |
-      OS.Constants.libc.O_TRUNC,
-    ctypes.int(OS.Constants.libc.S_IRWXU)
-  );
-  isnot(file, -1, "test_create_file: file created");
-  OS.Unix.File.close(file);
-}
-
-function test_access() {
-  info("Starting test_access");
-  let file = OS.Unix.File.open(
-    "test1.tmp",
-    OS.Constants.libc.O_RDWR |
-      OS.Constants.libc.O_CREAT |
-      OS.Constants.libc.O_TRUNC,
-    ctypes.int(OS.Constants.libc.S_IRWXU)
-  );
-  let result = OS.Unix.File.access(
-    "test1.tmp",
-    OS.Constants.libc.R_OK |
-      OS.Constants.libc.W_OK |
-      OS.Constants.libc.X_OK |
-      OS.Constants.libc.F_OK
-  );
-  is(result, 0, "first call to access() succeeded");
-  OS.Unix.File.close(file);
-
-  file = OS.Unix.File.open(
-    "test1.tmp",
-    OS.Constants.libc.O_WRONLY |
-      OS.Constants.libc.O_CREAT |
-      OS.Constants.libc.O_TRUNC,
-    ctypes.int(OS.Constants.libc.S_IWUSR)
-  );
-
-  info("test_access: preparing second call to access()");
-  result = OS.Unix.File.access(
-    "test2.tmp",
-    OS.Constants.libc.R_OK |
-      OS.Constants.libc.W_OK |
-      OS.Constants.libc.X_OK |
-      OS.Constants.libc.F_OK
-  );
-  is(result, -1, "test_access: second call to access() failed as expected");
-  is(ctypes.errno, OS.Constants.libc.ENOENT, "This is the correct error");
-  OS.Unix.File.close(file);
-}
-
-function test_getcwd() {
-  let array = new (ctypes.ArrayType(ctypes.char, 32768))();
-  let path = OS.Unix.File.getcwd(array, array.length);
-  if (ctypes.char.ptr(path).isNull()) {
-    ok(false, "test_get_cwd: getcwd returned null, errno: " + ctypes.errno);
-  }
-  let path2;
-  if (OS.Unix.File.get_current_dir_name) {
-    path2 = OS.Unix.File.get_current_dir_name();
-  } else {
-    path2 = OS.Unix.File.getwd_auto(null);
-  }
-  if (ctypes.char.ptr(path2).isNull()) {
-    ok(
-      false,
-      "test_get_cwd: getwd_auto/get_current_dir_name returned null, errno: " +
-        ctypes.errno
-    );
-  }
-  is(
-    path.readString(),
-    path2.readString(),
-    "test_get_cwd: getcwd and getwd return the same path"
-  );
-}
-
-function test_read_write() {
-  let output_name = "osfile_copy.tmp";
-  // Copy file
-  let input = OS.Unix.File.open(
-    "chrome/toolkit/components/osfile/tests/mochi/worker_test_osfile_unix.js",
-    OS.Constants.libc.O_RDONLY
-  );
-  isnot(input, -1, "test_read_write: input file opened");
-  let output = OS.Unix.File.open(
-    "osfile_copy.tmp",
-    OS.Constants.libc.O_RDWR |
-      OS.Constants.libc.O_CREAT |
-      OS.Constants.libc.O_TRUNC,
-    ctypes.int(OS.Constants.libc.S_IRWXU)
-  );
-  isnot(output, -1, "test_read_write: output file opened");
-
-  let array = new (ctypes.ArrayType(ctypes.char, 4096))();
-  let bytes = -1;
-  let total = 0;
-  while (true) {
-    bytes = OS.Unix.File.read(input, array, 4096);
-    ok(bytes != undefined, "test_read_write: bytes is defined");
-    isnot(bytes, -1, "test_read_write: no read error");
-    let write_from = 0;
-    if (bytes == 0) {
-      break;
-    }
-    while (bytes > 0) {
-      array.addressOfElement(write_from);
-      // Note: |write| launches an exception in case of error
-      let written = OS.Unix.File.write(output, array, bytes);
-      isnot(written, -1, "test_read_write: no write error");
-      write_from += written;
-      bytes -= written;
-    }
-    total += write_from;
-  }
-  info("test_read_write: copy complete " + total);
-
-  // Compare files
-  let result;
-  info("SEEK_SET: " + OS.Constants.libc.SEEK_SET);
-  info("Input: " + input + "(" + input.toSource() + ")");
-  info("Output: " + output + "(" + output.toSource() + ")");
-  result = OS.Unix.File.lseek(input, 0, OS.Constants.libc.SEEK_SET);
-  info("Result of lseek: " + result);
-  isnot(result, -1, "test_read_write: input seek succeeded " + ctypes.errno);
-  result = OS.Unix.File.lseek(output, 0, OS.Constants.libc.SEEK_SET);
-  isnot(result, -1, "test_read_write: output seek succeeded " + ctypes.errno);
-
-  let array2 = new (ctypes.ArrayType(ctypes.char, 4096))();
-  let bytes2 = -1;
-  let pos = 0;
-  while (true) {
-    bytes = OS.Unix.File.read(input, array, 4096);
-    isnot(bytes, -1, "test_read_write: input read succeeded");
-    bytes2 = OS.Unix.File.read(output, array2, 4096);
-    isnot(bytes, -1, "test_read_write: output read succeeded");
-    is(
-      bytes > 0,
-      bytes2 > 0,
-      "Both files contain data or neither does " + bytes + ", " + bytes2
-    );
-    if (bytes == 0) {
-      break;
-    }
-    if (bytes != bytes2) {
-      // This would be surprising, but theoretically possible with a
-      // remote file system, I believe.
-      bytes = Math.min(bytes, bytes2);
-      pos += bytes;
-      result = OS.Unix.File.lseek(input, pos, OS.Constants.libc.SEEK_SET);
-      isnot(result, -1, "test_read_write: input seek succeeded");
-      result = OS.Unix.File.lseek(output, pos, OS.Constants.libc.SEEK_SET);
-      isnot(result, -1, "test_read_write: output seek succeeded");
-    } else {
-      pos += bytes;
-    }
-    for (let i = 0; i < bytes; ++i) {
-      if (array[i] != array2[i]) {
-        ok(
-          false,
-          "Files do not match at position " +
-            i +
-            " (" +
-            array[i] +
-            "/" +
-            array2[i] +
-            ")"
-        );
-      }
-    }
-  }
-  info("test_read_write test complete");
-  result = OS.Unix.File.close(input);
-  isnot(result, -1, "test_read_write: input close succeeded");
-  result = OS.Unix.File.close(output);
-  isnot(result, -1, "test_read_write: output close succeeded");
-  result = OS.Unix.File.unlink(output_name);
-  isnot(result, -1, "test_read_write: input remove succeeded");
-  info("test_read_write cleanup complete");
-}
-
-function test_passing_undefined() {
-  info(
-    "Testing that an exception gets thrown when an FFI function is passed undefined"
-  );
-  let exceptionRaised = false;
-
-  try {
-    OS.Unix.File.open(
-      undefined,
-      OS.Constants.libc.O_RDWR |
-        OS.Constants.libc.O_CREAT |
-        OS.Constants.libc.O_TRUNC,
-      ctypes.int(OS.Constants.libc.S_IRWXU)
-    );
-  } catch (e) {
-    if (e instanceof TypeError && e.message.indexOf("open") > -1) {
-      exceptionRaised = true;
-    } else {
-      throw e;
-    }
-  }
-
-  ok(exceptionRaised, "test_passing_undefined: exception gets thrown");
-}
deleted file mode 100644
--- a/toolkit/components/osfile/tests/mochi/worker_test_osfile_win.js
+++ /dev/null
@@ -1,310 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/* eslint-env mozilla/chrome-worker, node */
-
-/* import-globals-from /testing/mochitest/tests/SimpleTest/WorkerSimpleTest.js */
-importScripts("chrome://mochikit/content/tests/SimpleTest/WorkerSimpleTest.js");
-
-self.onmessage = function(msg) {
-  self.onmessage = function(msg) {
-    log("ignored message " + JSON.stringify(msg.data));
-  };
-
-  test_init();
-  test_GetCurrentDirectory();
-  test_OpenClose();
-  test_CreateFile();
-  test_ReadWrite();
-  test_passing_undefined();
-  finish();
-};
-
-function test_init() {
-  info("Starting test_init");
-  /* import-globals-from /toolkit/components/osfile/osfile.jsm */
-  importScripts("resource://gre/modules/osfile.jsm");
-}
-
-function test_OpenClose() {
-  info("Starting test_OpenClose");
-  is(
-    typeof OS.Win.File.CreateFile,
-    "function",
-    "OS.Win.File.CreateFile is a function"
-  );
-  is(
-    OS.Win.File.CloseHandle(OS.Constants.Win.INVALID_HANDLE_VALUE),
-    true,
-    "CloseHandle returns true given the invalid handle"
-  );
-  is(
-    OS.Win.File.FindClose(OS.Constants.Win.INVALID_HANDLE_VALUE),
-    true,
-    "FindClose returns true given the invalid handle"
-  );
-  isnot(OS.Constants.Win.GENERIC_READ, undefined, "GENERIC_READ exists");
-  isnot(OS.Constants.Win.FILE_SHARE_READ, undefined, "FILE_SHARE_READ exists");
-  isnot(
-    OS.Constants.Win.FILE_ATTRIBUTE_NORMAL,
-    undefined,
-    "FILE_ATTRIBUTE_NORMAL exists"
-  );
-  let file = OS.Win.File.CreateFile(
-    "chrome\\toolkit\\components\\osfile\\tests\\mochi\\worker_test_osfile_win.js",
-    OS.Constants.Win.GENERIC_READ,
-    0,
-    null,
-    OS.Constants.Win.OPEN_EXISTING,
-    0,
-    null
-  );
-  info("test_OpenClose: Passed open");
-  isnot(
-    file,
-    OS.Constants.Win.INVALID_HANDLE_VALUE,
-    "test_OpenClose: file opened"
-  );
-  let result = OS.Win.File.CloseHandle(file);
-  isnot(result, 0, "test_OpenClose: close succeeded");
-
-  file = OS.Win.File.CreateFile(
-    "\\I do not exist",
-    OS.Constants.Win.GENERIC_READ,
-    OS.Constants.Win.FILE_SHARE_READ,
-    null,
-    OS.Constants.Win.OPEN_EXISTING,
-    OS.Constants.Win.FILE_ATTRIBUTE_NORMAL,
-    null
-  );
-  is(
-    file,
-    OS.Constants.Win.INVALID_HANDLE_VALUE,
-    "test_OpenClose: cannot open non-existing file"
-  );
-  is(
-    ctypes.winLastError,
-    OS.Constants.Win.ERROR_FILE_NOT_FOUND,
-    "test_OpenClose: error is ERROR_FILE_NOT_FOUND"
-  );
-}
-
-function test_CreateFile() {
-  info("Starting test_CreateFile");
-  let file = OS.Win.File.CreateFile(
-    "test.tmp",
-    OS.Constants.Win.GENERIC_READ | OS.Constants.Win.GENERIC_WRITE,
-    OS.Constants.Win.FILE_SHARE_READ | OS.Constants.FILE_SHARE_WRITE,
-    null,
-    OS.Constants.Win.CREATE_ALWAYS,
-    OS.Constants.Win.FILE_ATTRIBUTE_NORMAL,
-    null
-  );
-  isnot(
-    file,
-    OS.Constants.Win.INVALID_HANDLE_VALUE,
-    "test_CreateFile: opening succeeded"
-  );
-  let result = OS.Win.File.CloseHandle(file);
-  isnot(result, 0, "test_CreateFile: close succeeded");
-}
-
-function test_GetCurrentDirectory() {
-  let array = new (ctypes.ArrayType(ctypes.char16_t, 4096))();
-  let result = OS.Win.File.GetCurrentDirectory(4096, array);
-  ok(result < array.length, "test_GetCurrentDirectory: length sufficient");
-  ok(result > 0, "test_GetCurrentDirectory: length != 0");
-}
-
-function test_ReadWrite() {
-  info("Starting test_ReadWrite");
-  let output_name = "osfile_copy.tmp";
-  // Copy file
-  let input = OS.Win.File.CreateFile(
-    "chrome\\toolkit\\components\\osfile\\tests\\mochi\\worker_test_osfile_win.js",
-    OS.Constants.Win.GENERIC_READ,
-    0,
-    null,
-    OS.Constants.Win.OPEN_EXISTING,
-    0,
-    null
-  );
-  isnot(
-    input,
-    OS.Constants.Win.INVALID_HANDLE_VALUE,
-    "test_ReadWrite: input file opened"
-  );
-  let output = OS.Win.File.CreateFile(
-    "osfile_copy.tmp",
-    OS.Constants.Win.GENERIC_READ | OS.Constants.Win.GENERIC_WRITE,
-    0,
-    null,
-    OS.Constants.Win.CREATE_ALWAYS,
-    OS.Constants.Win.FILE_ATTRIBUTE_NORMAL,
-    null
-  );
-  isnot(
-    output,
-    OS.Constants.Win.INVALID_HANDLE_VALUE,
-    "test_ReadWrite: output file opened"
-  );
-  let array = new (ctypes.ArrayType(ctypes.char, 4096))();
-  let bytes_read = new ctypes.uint32_t(0);
-  let bytes_read_ptr = bytes_read.address();
-  log("We have a pointer for bytes read: " + bytes_read_ptr);
-  let bytes_written = new ctypes.uint32_t(0);
-  let bytes_written_ptr = bytes_written.address();
-  log("We have a pointer for bytes written: " + bytes_written_ptr);
-  log("test_ReadWrite: buffer and pointers ready");
-  let result;
-  while (true) {
-    log("test_ReadWrite: reading");
-    result = OS.Win.File.ReadFile(input, array, 4096, bytes_read_ptr, null);
-    isnot(result, 0, "test_ReadWrite: read success");
-    let write_from = 0;
-    let bytes_left = bytes_read;
-    log("test_ReadWrite: read chunk complete " + bytes_left.value);
-    if (bytes_left.value == 0) {
-      break;
-    }
-    while (bytes_left.value > 0) {
-      log("test_ReadWrite: writing " + bytes_left.value);
-      array.addressOfElement(write_from);
-      // Note: |WriteFile| launches an exception in case of error
-      result = OS.Win.File.WriteFile(
-        output,
-        array,
-        bytes_left,
-        bytes_written_ptr,
-        null
-      );
-      isnot(result, 0, "test_ReadWrite: write success");
-      write_from += bytes_written;
-      bytes_left -= bytes_written;
-    }
-  }
-  info("test_ReadWrite: copy complete");
-
-  // Compare files
-  result = OS.Win.File.SetFilePointer(
-    input,
-    0,
-    null,
-    OS.Constants.Win.FILE_BEGIN
-  );
-  isnot(
-    result,
-    OS.Constants.Win.INVALID_SET_FILE_POINTER,
-    "test_ReadWrite: input reset"
-  );
-
-  result = OS.Win.File.SetFilePointer(
-    output,
-    0,
-    null,
-    OS.Constants.Win.FILE_BEGIN
-  );
-  isnot(
-    result,
-    OS.Constants.Win.INVALID_SET_FILE_POINTER,
-    "test_ReadWrite: output reset"
-  );
-
-  let array2 = new (ctypes.ArrayType(ctypes.char, 4096))();
-  let bytes_read2 = new ctypes.uint32_t(0);
-  let bytes_read2_ptr = bytes_read2.address();
-  let pos = 0;
-  while (true) {
-    result = OS.Win.File.ReadFile(input, array, 4096, bytes_read_ptr, null);
-    isnot(result, 0, "test_ReadWrite: input read succeeded");
-
-    result = OS.Win.File.ReadFile(output, array2, 4096, bytes_read2_ptr, null);
-    isnot(result, 0, "test_ReadWrite: output read succeeded");
-
-    is(
-      bytes_read.value > 0,
-      bytes_read2.value > 0,
-      "Both files contain data or neither does " +
-        bytes_read.value +
-        ", " +
-        bytes_read2.value
-    );
-    if (bytes_read.value == 0) {
-      break;
-    }
-    let bytes;
-    if (bytes_read.value != bytes_read2.value) {
-      // This would be surprising, but theoretically possible with a
-      // remote file system, I believe.
-      bytes = Math.min(bytes_read.value, bytes_read2.value);
-      pos += bytes;
-      result = OS.Win.File.SetFilePointer(
-        input,
-        pos,
-        null,
-        OS.Constants.Win.FILE_BEGIN
-      );
-      isnot(result, 0, "test_ReadWrite: input seek succeeded");
-
-      result = OS.Win.File.SetFilePointer(
-        output,
-        pos,
-        null,
-        OS.Constants.Win.FILE_BEGIN
-      );
-      isnot(result, 0, "test_ReadWrite: output seek succeeded");
-    } else {
-      bytes = bytes_read.value;
-      pos += bytes;
-    }
-    for (let i = 0; i < bytes; ++i) {
-      if (array[i] != array2[i]) {
-        ok(
-          false,
-          "Files do not match at position " +
-            i +
-            " (" +
-            array[i] +
-            "/" +
-            array2[i] +
-            ")"
-        );
-      }
-    }
-  }
-  info("test_ReadWrite test complete");
-  result = OS.Win.File.CloseHandle(input);
-  isnot(result, 0, "test_ReadWrite: inpout close succeeded");
-  result = OS.Win.File.CloseHandle(output);
-  isnot(result, 0, "test_ReadWrite: outpout close succeeded");
-  result = OS.Win.File.DeleteFile(output_name);
-  isnot(result, 0, "test_ReadWrite: output remove succeeded");
-  info("test_ReadWrite cleanup complete");
-}
-
-function test_passing_undefined() {
-  info(
-    "Testing that an exception gets thrown when an FFI function is passed undefined"
-  );
-  let exceptionRaised = false;
-
-  try {
-    OS.Win.File.CreateFile(
-      undefined,
-      OS.Constants.Win.GENERIC_READ,
-      0,
-      null,
-      OS.Constants.Win.OPEN_EXISTING,
-      0,
-      null
-    );
-  } catch (e) {
-    if (e instanceof TypeError && e.message.indexOf("CreateFile") > -1) {
-      exceptionRaised = true;
-    } else {
-      throw e;
-    }
-  }
-
-  ok(exceptionRaised, "test_passing_undefined: exception gets thrown");
-}
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/.eslintrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-"use strict";
-
-module.exports = {
-  rules: {
-    "no-shadow": "off",
-  },
-};
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/head.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var { XPCOMUtils } = ChromeUtils.importESModule(
-  "resource://gre/modules/XPCOMUtils.sys.mjs"
-);
-
-// Bug 1014484 can only be reproduced by loading OS.File first from the
-// CommonJS loader, so we do not want OS.File to be loaded eagerly for
-// all the tests in this directory.
-ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
-ChromeUtils.defineESModuleGetters(this, {
-  FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
-});
-ChromeUtils.defineModuleGetter(
-  this,
-  "NetUtil",
-  "resource://gre/modules/NetUtil.jsm"
-);
-
-Services.prefs.setBoolPref("toolkit.osfile.log", true);
-
-/**
- * As add_task, but execute the test both with native operations and
- * without.
- */
-function add_test_pair(generator) {
-  add_task(async function() {
-    info("Executing test " + generator.name + " with native operations");
-    Services.prefs.setBoolPref("toolkit.osfile.native", true);
-    return generator();
-  });
-  add_task(async function() {
-    info("Executing test " + generator.name + " without native operations");
-    Services.prefs.setBoolPref("toolkit.osfile.native", false);
-    return generator();
-  });
-}
-
-/**
- * Fetch asynchronously the contents of a file using xpcom.
- *
- * Used for comparing xpcom-based results to os.file-based results.
- *
- * @param {string} path The _absolute_ path to the file.
- * @return {promise}
- * @resolves {string} The contents of the file.
- */
-function reference_fetch_file(path, test) {
-  info("Fetching file " + path);
-  return new Promise((resolve, reject) => {
-    let file = new FileUtils.File(path);
-    NetUtil.asyncFetch(
-      {
-        uri: NetUtil.newURI(file),
-        loadUsingSystemPrincipal: true,
-      },
-      function(stream, status) {
-        if (!Components.isSuccessCode(status)) {
-          reject(status);
-          return;
-        }
-        let result, reject;
-        try {
-          result = NetUtil.readInputStreamToString(stream, stream.available());
-        } catch (x) {
-          reject = x;
-        }
-        stream.close();
-        if (reject) {
-          reject(reject);
-        } else {
-          resolve(result);
-        }
-      }
-    );
-  });
-}
-
-/**
- * Compare asynchronously the contents two files using xpcom.
- *
- * Used for comparing xpcom-based results to os.file-based results.
- *
- * @param {string} a The _absolute_ path to the first file.
- * @param {string} b The _absolute_ path to the second file.
- *
- * @resolves {null}
- */
-function reference_compare_files(a, b, test) {
-  return (async function() {
-    info("Comparing files " + a + " and " + b);
-    let a_contents = await reference_fetch_file(a, test);
-    let b_contents = await reference_fetch_file(b, test);
-    Assert.equal(a_contents, b_contents);
-  })();
-}
-
-async function removeTestFile(filePath, ignoreNoSuchFile = true) {
-  try {
-    await OS.File.remove(filePath);
-  } catch (ex) {
-    if (!ignoreNoSuchFile || !ex.becauseNoSuchFile) {
-      do_throw(ex);
-    }
-  }
-}
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_compression.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-function run_test() {
-  do_test_pending();
-  run_next_test();
-}
-
-add_task(async function test_compress_lz4() {
-  let path = OS.Path.join(OS.Constants.Path.tmpDir, "compression.lz");
-  let length = 1024;
-  let array = new Uint8Array(length);
-  for (let i = 0; i < array.byteLength; ++i) {
-    array[i] = i;
-  }
-  let arrayAsString = Array.prototype.join.call(array);
-
-  info("Writing data with lz4 compression");
-  let bytes = await OS.File.writeAtomic(path, array, { compression: "lz4" });
-  info("Compressed " + length + " bytes into " + bytes);
-
-  info("Reading back with lz4 decompression");
-  let decompressed = await OS.File.read(path, { compression: "lz4" });
-  info("Decompressed into " + decompressed.byteLength + " bytes");
-  Assert.equal(arrayAsString, Array.prototype.join.call(decompressed));
-});
-
-add_task(async function test_uncompressed() {
-  info("Writing data without compression");
-  let path = OS.Path.join(OS.Constants.Path.tmpDir, "no_compression.tmp");
-  let array = new Uint8Array(1024);
-  for (let i = 0; i < array.byteLength; ++i) {
-    array[i] = i;
-  }
-  await OS.File.writeAtomic(path, array); // No compression
-
-  let exn;
-  // Force decompression, reading should fail
-  try {
-    await OS.File.read(path, { compression: "lz4" });
-  } catch (ex) {
-    exn = ex;
-  }
-  Assert.ok(!!exn);
-  // Check the exception message (and that it contains the file name)
-  Assert.ok(
-    exn.message.includes(`Invalid header (no magic number) - Data: ${path}`)
-  );
-});
-
-add_task(async function test_no_header() {
-  let path = OS.Path.join(OS.Constants.Path.tmpDir, "no_header.tmp");
-  let array = new Uint8Array(8).fill(0, 0); // Small array with no header
-
-  info("Writing data with no header");
-
-  await OS.File.writeAtomic(path, array); // No compression
-  let exn;
-  // Force decompression, reading should fail
-  try {
-    await OS.File.read(path, { compression: "lz4" });
-  } catch (ex) {
-    exn = ex;
-  }
-  Assert.ok(!!exn);
-  // Check the exception message (and that it contains the file name)
-  Assert.ok(
-    exn.message.includes(`Buffer is too short (no header) - Data: ${path}`)
-  );
-});
-
-add_task(async function test_invalid_content() {
-  let path = OS.Path.join(OS.Constants.Path.tmpDir, "invalid_content.tmp");
-  let arr1 = new Uint8Array([109, 111, 122, 76, 122, 52, 48, 0]);
-  let arr2 = new Uint8Array(248).fill(1, 0);
-
-  let array = new Uint8Array(arr1.length + arr2.length);
-  array.set(arr1);
-  array.set(arr2, arr1.length);
-
-  info("Writing invalid data (with a valid header and only ones after that)");
-
-  await OS.File.writeAtomic(path, array); // No compression
-  let exn;
-  // Force decompression, reading should fail
-  try {
-    await OS.File.read(path, { compression: "lz4" });
-  } catch (ex) {
-    exn = ex;
-  }
-  Assert.ok(!!exn);
-  // Check the exception message (and that it contains the file name)
-  Assert.ok(
-    exn.message.includes(
-      `Invalid content: Decompression stopped at 0 - Data: ${path}`
-    )
-  );
-});
-
-add_task(function() {
-  do_test_finished();
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_constants.js
+++ /dev/null
@@ -1,20 +0,0 @@
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-// Test that OS.Constants is defined correctly.
-add_task(async function check_definition() {
-  Assert.ok(OS.Constants != null);
-  Assert.ok(!!OS.Constants.Win || !!OS.Constants.libc);
-  Assert.ok(OS.Constants.Path != null);
-  Assert.ok(OS.Constants.Sys != null);
-  // check system name
-  Assert.equal(Services.appinfo.OS, OS.Constants.Sys.Name);
-
-  // check if using DEBUG build
-  if (Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2).isDebugBuild) {
-    Assert.ok(OS.Constants.Sys.DEBUG);
-  } else {
-    Assert.ok(typeof OS.Constants.Sys.DEBUG == "undefined");
-  }
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_duration.js
+++ /dev/null
@@ -1,127 +0,0 @@
-var { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-/**
- * Test optional duration reporting that can be used for telemetry.
- */
-add_task(async function duration() {
-  const availableDurations = [
-    "outSerializationDuration",
-    "outExecutionDuration",
-  ];
-  Services.prefs.setBoolPref("toolkit.osfile.log", true);
-  // Options structure passed to a OS.File copy method.
-  let copyOptions = {
-    // These fields should be overwritten with the actual duration
-    // measurements.
-    outSerializationDuration: null,
-    outExecutionDuration: null,
-  };
-  let currentDir = await OS.File.getCurrentDirectory();
-  let pathSource = OS.Path.join(currentDir, "test_duration.js");
-  let copyFile = pathSource + ".bak";
-  function testOptions(options, name, durations = availableDurations) {
-    for (let duration of durations) {
-      info(`Checking ${duration} for operation: ${name}`);
-      info(`${name}: Gathered method duration time: ${options[duration]} ms`);
-      // Making sure that duration was updated.
-      Assert.equal(typeof options[duration], "number");
-      Assert.ok(options[duration] >= 0);
-    }
-  }
-
-  function testOptionIncrements(
-    options,
-    name,
-    backupDuration,
-    durations = availableDurations
-  ) {
-    for (let duration of durations) {
-      info(`Checking ${duration} increment for operation: ${name}`);
-      info(`${name}: Gathered method duration time: ${options[duration]} ms`);
-      info(`${name}: Previous duration: ${backupDuration[duration]} ms`);
-      // Making sure that duration was incremented.
-      Assert.ok(options[duration] >= backupDuration[duration]);
-    }
-  }
-
-  // Testing duration of OS.File.copy.
-  await OS.File.copy(pathSource, copyFile, copyOptions);
-  testOptions(copyOptions, "OS.File.copy");
-  await OS.File.remove(copyFile);
-
-  // Trying an operation where options are cloned.
-  let pathDest = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "osfile async test read writeAtomic.tmp"
-  );
-  let tmpPath = pathDest + ".tmp";
-  let readOptions = {
-    // We do not check for |outSerializationDuration| since |Scheduler.post|
-    // may not be called whenever |read| is called.
-    outExecutionDuration: null,
-  };
-  let contents = await OS.File.read(pathSource, undefined, readOptions);
-  testOptions(readOptions, "OS.File.read", ["outExecutionDuration"]);
-  // Options structure passed to a OS.File writeAtomic method.
-  let writeAtomicOptions = {
-    // This field should be first initialized with the actual
-    // duration measurement then progressively incremented.
-    outExecutionDuration: null,
-    tmpPath,
-  };
-  // Note that |contents| cannot be reused after this call since it is detached.
-  await OS.File.writeAtomic(pathDest, contents, writeAtomicOptions);
-  testOptions(writeAtomicOptions, "OS.File.writeAtomic", [
-    "outExecutionDuration",
-  ]);
-  await OS.File.remove(pathDest);
-
-  info(
-    `Ensuring that we can use ${availableDurations.join(
-      ", "
-    )} to accumulate durations`
-  );
-
-  let ARBITRARY_BASE_DURATION = 5;
-  copyOptions = {
-    // This field should now be incremented with the actual duration
-    // measurement.
-    outSerializationDuration: ARBITRARY_BASE_DURATION,
-    outExecutionDuration: ARBITRARY_BASE_DURATION,
-  };
-
-  // We need to copy the object, since having a reference would make this pointless.
-  let backupDuration = Object.assign({}, copyOptions);
-
-  // Testing duration of OS.File.copy.
-  await OS.File.copy(pathSource, copyFile, copyOptions);
-  testOptionIncrements(copyOptions, "copy", backupDuration);
-
-  backupDuration = Object.assign({}, copyOptions);
-  await OS.File.remove(copyFile, copyOptions);
-  testOptionIncrements(copyOptions, "remove", backupDuration);
-
-  // Trying an operation where options are cloned.
-  // Options structure passed to a OS.File writeAtomic method.
-  writeAtomicOptions = {
-    // We do not check for |outSerializationDuration| since |Scheduler.post|
-    // may not be called whenever |writeAtomic| is called.
-    outExecutionDuration: ARBITRARY_BASE_DURATION,
-  };
-  writeAtomicOptions.tmpPath = tmpPath;
-  backupDuration = Object.assign({}, writeAtomicOptions);
-  contents = await OS.File.read(pathSource, undefined, readOptions);
-  await OS.File.writeAtomic(pathDest, contents, writeAtomicOptions);
-  testOptionIncrements(
-    writeAtomicOptions,
-    "writeAtomicOptions",
-    backupDuration,
-    ["outExecutionDuration"]
-  );
-  OS.File.remove(pathDest);
-
-  // Testing an operation that doesn't take arguments at all
-  let file = await OS.File.open(pathSource);
-  await file.stat();
-  await file.close();
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_exception.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Test that functions throw the appropriate exceptions.
- */
-
-"use strict";
-
-var EXISTING_FILE = do_get_file("xpcshell.ini").path;
-
-// Tests on |open|
-
-add_test_pair(async function test_typeerror() {
-  let exn;
-  try {
-    let fd = await OS.File.open("/tmp", { no_such_key: 1 });
-    info("Fd: " + fd);
-  } catch (ex) {
-    exn = ex;
-  }
-  info("Exception: " + exn);
-  Assert.ok(exn.constructor.name == "TypeError");
-});
-
-// Tests on |read|
-
-add_test_pair(async function test_bad_encoding() {
-  info("Testing with a wrong encoding");
-  try {
-    await OS.File.read(EXISTING_FILE, { encoding: "baby-speak-encoded" });
-    do_throw("Should have thrown with an ex.becauseInvalidArgument");
-  } catch (ex) {
-    if (ex.becauseInvalidArgument) {
-      info("Wrong encoding caused the correct exception");
-    } else {
-      throw ex;
-    }
-  }
-
-  try {
-    await OS.File.read(EXISTING_FILE, { encoding: 4 });
-    do_throw("Should have thrown a TypeError");
-  } catch (ex) {
-    if (ex.constructor.name == "TypeError") {
-      // Note that TypeError doesn't carry across compartments
-      info("Non-string encoding caused the correct exception");
-    } else {
-      throw ex;
-    }
-  }
-});
-
-add_test_pair(async function test_bad_compression() {
-  info("Testing with a non-existing compression");
-  try {
-    await OS.File.read(EXISTING_FILE, { compression: "mmmh-crunchy" });
-    do_throw("Should have thrown with an ex.becauseInvalidArgument");
-  } catch (ex) {
-    if (ex.becauseInvalidArgument) {
-      info("Wrong encoding caused the correct exception");
-    } else {
-      throw ex;
-    }
-  }
-
-  info("Testing with a bad type for option compression");
-  try {
-    await OS.File.read(EXISTING_FILE, { compression: 5 });
-    do_throw("Should have thrown a TypeError");
-  } catch (ex) {
-    if (ex.constructor.name == "TypeError") {
-      // Note that TypeError doesn't carry across compartments
-      info("Non-string encoding caused the correct exception");
-    } else {
-      throw ex;
-    }
-  }
-});
-
-add_test_pair(async function test_bad_bytes() {
-  info("Testing with a bad type for option bytes");
-  try {
-    await OS.File.read(EXISTING_FILE, { bytes: "five" });
-    do_throw("Should have thrown a TypeError");
-  } catch (ex) {
-    if (ex.constructor.name == "TypeError") {
-      // Note that TypeError doesn't carry across compartments
-      info("Non-number bytes caused the correct exception");
-    } else {
-      throw ex;
-    }
-  }
-});
-
-add_test_pair(async function read_non_existent() {
-  info("Testing with a non-existent file");
-  try {
-    await OS.File.read("I/do/not/exist");
-    do_throw("Should have thrown with an ex.becauseNoSuchFile");
-  } catch (ex) {
-    if (ex.becauseNoSuchFile) {
-      info("Correct exceptions");
-    } else {
-      throw ex;
-    }
-  }
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_file_URL_conversion.js
+++ /dev/null
@@ -1,119 +0,0 @@
-/* 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/. */
-
-function run_test() {
-  const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-  const { FileUtils } = ChromeUtils.importESModule(
-    "resource://gre/modules/FileUtils.sys.mjs"
-  );
-
-  let isWindows = "@mozilla.org/windows-registry-key;1" in Cc;
-
-  // Test cases for filePathToURI
-  let paths = isWindows
-    ? [
-        "C:\\",
-        "C:\\test",
-        "C:\\test\\",
-        "C:\\test%2f",
-        "C:\\test\\test\\test",
-        "C:\\test;+%",
-        "C:\\test?action=index\\",
-        "C:\\test test",
-        "\\\\C:\\a\\b\\c",
-        "\\\\Server\\a\\b\\c",
-
-        // note that per http://support.microsoft.com/kb/177506 (under more info),
-        // the following characters are allowed on Windows:
-        "C:\\char^",
-        "C:\\char&",
-        "C:\\char'",
-        "C:\\char@",
-        "C:\\char{",
-        "C:\\char}",
-        "C:\\char[",
-        "C:\\char]",
-        "C:\\char,",
-        "C:\\char$",
-        "C:\\char=",
-        "C:\\char!",
-        "C:\\char-",
-        "C:\\char#",
-        "C:\\char(",
-        "C:\\char)",
-        "C:\\char%",
-        "C:\\char.",
-        "C:\\char+",
-        "C:\\char~",
-        "C:\\char_",
-      ]
-    : [
-        "/",
-        "/test",
-        "/test/",
-        "/test%2f",
-        "/test/test/test",
-        "/test;+%",
-        "/test?action=index/",
-        "/test test",
-        "/punctuation/;,/?:@&=+$-_.!~*'()[]\"#",
-        "/CasePreserving",
-      ];
-
-  // some additional URIs to test, beyond those generated from paths
-  let uris = isWindows
-    ? [
-        "file:///C:/test/",
-        "file://localhost/C:/test",
-        "file:///c:/test/test.txt",
-        // 'file:///C:/foo%2f', // trailing, encoded slash
-        "file:///C:/%3f%3F",
-        "file:///C:/%3b%3B",
-        "file:///C:/%3c%3C", // not one of the special-cased ? or ;
-        "file:///C:/%78", // 'x', not usually uri encoded
-        "file:///C:/test#frag", // a fragment identifier
-        "file:///C:/test?action=index", // an actual query component
-      ]
-    : [
-        "file:///test/",
-        "file://localhost/test",
-        "file:///test/test.txt",
-        "file:///foo%2f", // trailing, encoded slash
-        "file:///%3f%3F",
-        "file:///%3b%3B",
-        "file:///%3c%3C", // not one of the special-cased ? or ;
-        "file:///%78", // 'x', not usually uri encoded
-        "file:///test#frag", // a fragment identifier
-        "file:///test?action=index", // an actual query component
-      ];
-
-  for (let path of paths) {
-    // convert that to a uri using FileUtils and Services, which toFileURI is trying to model
-    let file = FileUtils.File(path);
-    let uri = Services.io.newFileURI(file).spec;
-    Assert.equal(uri, OS.Path.toFileURI(path));
-
-    // keep the resulting URI to try the reverse, except for "C:\" for which the
-    // behavior of nsIFileURL and OS.File is inconsistent
-    if (path != "C:\\") {
-      uris.push(uri);
-    }
-  }
-
-  for (let uri of uris) {
-    // convert URIs to paths with nsIFileURI, which fromFileURI is trying to model
-    let path = Services.io.newURI(uri).QueryInterface(Ci.nsIFileURL).file.path;
-    Assert.equal(path, OS.Path.fromFileURI(uri));
-  }
-
-  // check that non-file URLs aren't allowed
-  let thrown = false;
-  try {
-    OS.Path.fromFileURI("http://test.com");
-  } catch (e) {
-    Assert.equal(e.message, "fromFileURI expects a file URI");
-    thrown = true;
-  }
-  Assert.ok(thrown);
-}
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_logging.js
+++ /dev/null
@@ -1,73 +0,0 @@
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-/**
- * Tests logging by passing OS.Shared.LOG both an object with its own
- * toString method, and one with the default.
- */
-function run_test() {
-  do_test_pending();
-  let messageCount = 0;
-
-  info("Test starting");
-
-  // Create a console listener.
-  let consoleListener = {
-    observe(aMessage) {
-      // Ignore unexpected messages.
-      if (!(aMessage instanceof Ci.nsIConsoleMessage)) {
-        return;
-      }
-      // This is required, as printing to the |Services.console|
-      // while in the observe function causes an exception.
-      executeSoon(function() {
-        info("Observing message " + aMessage.message);
-        if (!aMessage.message.includes("TEST OS")) {
-          return;
-        }
-
-        ++messageCount;
-        if (messageCount == 1) {
-          Assert.equal(aMessage.message, 'TEST OS {"name":"test"}\n');
-        }
-        if (messageCount == 2) {
-          Assert.equal(aMessage.message, "TEST OS name is test\n");
-          toggleConsoleListener(false);
-          do_test_finished();
-        }
-      });
-    },
-  };
-
-  // Set/Unset the console listener.
-  function toggleConsoleListener(pref) {
-    info("Setting console listener: " + pref);
-    Services.prefs.setBoolPref("toolkit.osfile.log", pref);
-    Services.prefs.setBoolPref("toolkit.osfile.log.redirect", pref);
-    Services.console[pref ? "registerListener" : "unregisterListener"](
-      consoleListener
-    );
-  }
-
-  toggleConsoleListener(true);
-
-  let objectDefault = { name: "test" };
-  let CustomToString = function() {
-    this.name = "test";
-  };
-  CustomToString.prototype.toString = function() {
-    return "name is " + this.name;
-  };
-  let objectCustom = new CustomToString();
-
-  info(OS.Shared.LOG.toSource());
-
-  info("Logging 1");
-  OS.Shared.LOG(objectDefault);
-
-  info("Logging 2");
-  OS.Shared.LOG(objectCustom);
-  // Once both messages are observed OS.Shared.DEBUG, and OS.Shared.TEST
-  // are reset to false.
-}
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_makeDir.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-var Path = OS.Path;
-var profileDir;
-
-registerCleanupFunction(function() {
-  Services.prefs.setBoolPref("toolkit.osfile.log", false);
-});
-
-/**
- * Test OS.File.makeDir
- */
-
-add_task(function init() {
-  // Set up profile. We create the directory in the profile, because the profile
-  // is removed after every test run.
-  do_get_profile();
-  profileDir = OS.Constants.Path.profileDir;
-  Services.prefs.setBoolPref("toolkit.osfile.log", true);
-});
-
-/**
- * Basic use
- */
-
-add_task(async function test_basic() {
-  let dir = Path.join(profileDir, "directory");
-
-  // Sanity checking for the test
-  Assert.equal(false, await OS.File.exists(dir));
-
-  // Make a directory
-  await OS.File.makeDir(dir);
-
-  // check if the directory exists
-  await OS.File.stat(dir);
-
-  // Make a directory that already exists, this should succeed
-  await OS.File.makeDir(dir);
-
-  // Make a directory with ignoreExisting
-  await OS.File.makeDir(dir, { ignoreExisting: true });
-
-  // Make a directory with ignoreExisting false
-  let exception = null;
-  try {
-    await OS.File.makeDir(dir, { ignoreExisting: false });
-  } catch (ex) {
-    exception = ex;
-  }
-
-  Assert.ok(!!exception);
-  Assert.ok(exception instanceof OS.File.Error);
-  Assert.ok(exception.becauseExists);
-});
-
-// Make a root directory that already exists
-add_task(async function test_root() {
-  if (OS.Constants.Win) {
-    await OS.File.makeDir("C:");
-    await OS.File.makeDir("C:\\");
-  } else {
-    await OS.File.makeDir("/");
-  }
-});
-
-/**
- * Creating subdirectories
- */
-add_task(async function test_option_from() {
-  let dir = Path.join(profileDir, "a", "b", "c");
-
-  // Sanity checking for the test
-  Assert.equal(false, await OS.File.exists(dir));
-
-  // Make a directory
-  await OS.File.makeDir(dir, { from: profileDir });
-
-  // check if the directory exists
-  await OS.File.stat(dir);
-
-  // Make a directory that already exists, this should succeed
-  await OS.File.makeDir(dir);
-
-  // Make a directory with ignoreExisting
-  await OS.File.makeDir(dir, { ignoreExisting: true });
-
-  // Make a directory with ignoreExisting false
-  let exception = null;
-  try {
-    await OS.File.makeDir(dir, { ignoreExisting: false });
-  } catch (ex) {
-    exception = ex;
-  }
-
-  Assert.ok(!!exception);
-  Assert.ok(exception instanceof OS.File.Error);
-  Assert.ok(exception.becauseExists);
-
-  // Make a directory without |from| and fail
-  let dir2 = Path.join(profileDir, "g", "h", "i");
-  exception = null;
-  try {
-    await OS.File.makeDir(dir2);
-  } catch (ex) {
-    exception = ex;
-  }
-
-  Assert.ok(!!exception);
-  Assert.ok(exception instanceof OS.File.Error);
-  Assert.ok(exception.becauseNoSuchFile);
-
-  // Test edge cases on paths
-
-  let dir3 = Path.join(profileDir, "d", "", "e", "f");
-  Assert.equal(false, await OS.File.exists(dir3));
-  await OS.File.makeDir(dir3, { from: profileDir });
-  Assert.ok(await OS.File.exists(dir3));
-
-  let dir4;
-  if (OS.Constants.Win) {
-    // Test that we can create a directory recursively even
-    // if we have too many "\\".
-    dir4 = profileDir + "\\\\g";
-  } else {
-    dir4 = profileDir + "////g";
-  }
-  Assert.equal(false, await OS.File.exists(dir4));
-  await OS.File.makeDir(dir4, { from: profileDir });
-  Assert.ok(await OS.File.exists(dir4));
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_open.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-/**
- * Test OS.File.open for reading:
- * - with an existing file (should succeed);
- * - with a non-existing file (should fail);
- * - with inconsistent arguments (should fail).
- */
-add_task(async function() {
-  // Attempt to open a file that does not exist, ensure that it yields the
-  // appropriate error.
-  try {
-    await OS.File.open(OS.Path.join(".", "This file does not exist"));
-    Assert.ok(false, "File opening 1 succeeded (it should fail)");
-  } catch (err) {
-    if (err instanceof OS.File.Error && err.becauseNoSuchFile) {
-      info("File opening 1 failed " + err);
-    } else {
-      throw err;
-    }
-  }
-  // Attempt to open a file with the wrong args, so that it fails before
-  // serialization, ensure that it yields the appropriate error.
-  info("Attempting to open a file with wrong arguments");
-  try {
-    let fd = await OS.File.open(1, 2, 3);
-    Assert.ok(false, "File opening 2 succeeded (it should fail)" + fd);
-  } catch (err) {
-    info("File opening 2 failed " + err);
-    Assert.equal(
-      false,
-      err instanceof OS.File.Error,
-      "File opening 2 returned something that is not a file error"
-    );
-    Assert.ok(
-      err.constructor.name == "TypeError",
-      "File opening 2 returned a TypeError"
-    );
-  }
-
-  // Attempt to open a file correctly
-  info("Attempting to open a file correctly");
-  let openedFile = await OS.File.open(
-    OS.Path.join(do_get_cwd().path, "test_open.js")
-  );
-  info("File opened correctly");
-
-  info("Attempting to close a file correctly");
-  await openedFile.close();
-
-  info("Attempting to close a file again");
-  await openedFile.close();
-});
-
-/**
- * Test the error thrown by OS.File.open when attempting to open a directory
- * that does not exist.
- */
-add_task(async function test_error_attributes() {
-  let dir = OS.Path.join(do_get_profile().path, "test_osfileErrorAttrs");
-  let fpath = OS.Path.join(dir, "test_error_attributes.txt");
-
-  try {
-    await OS.File.open(fpath, { truncate: true }, {});
-    Assert.ok(false, "Opening path suceeded (it should fail) " + fpath);
-  } catch (err) {
-    Assert.ok(err instanceof OS.File.Error);
-    Assert.ok(err.becauseNoSuchFile);
-  }
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_async.js
+++ /dev/null
@@ -1,13 +0,0 @@
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-/**
- * A trivial test ensuring that we can call osfile from xpcshell.
- * (see bug 808161)
- */
-
-function run_test() {
-  do_test_pending();
-  OS.File.getCurrentDirectory().then(do_test_finished, do_test_finished);
-}
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_async_append.js
+++ /dev/null
@@ -1,105 +0,0 @@
-"use strict";
-
-info("starting tests");
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-/**
- * A test to check that the |append| mode flag is correctly implemented.
- * (see bug 925865)
- */
-
-function setup_mode(mode) {
-  // Complete mode.
-  let realMode = {
-    read: true,
-    write: true,
-  };
-  for (let k in mode) {
-    realMode[k] = mode[k];
-  }
-  return realMode;
-}
-
-// Test append mode.
-async function test_append(mode) {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_append.tmp"
-  );
-
-  // Clear any left-over files from previous runs.
-  await removeTestFile(path);
-
-  try {
-    mode = setup_mode(mode);
-    mode.append = true;
-    if (mode.trunc) {
-      // Pre-fill file with some data to see if |trunc| actually works.
-      await OS.File.writeAtomic(path, new Uint8Array(500));
-    }
-    let file = await OS.File.open(path, mode);
-    try {
-      await file.write(new Uint8Array(1000));
-      await file.setPosition(0, OS.File.POS_START);
-      await file.read(100);
-      // Should be at offset 100, length 1000 now.
-      await file.write(new Uint8Array(100));
-      // Should be at offset 1100, length 1100 now.
-      let stat = await file.stat();
-      Assert.equal(1100, stat.size);
-    } finally {
-      await file.close();
-    }
-  } catch (ex) {
-    await removeTestFile(path);
-  }
-}
-
-// Test no-append mode.
-async function test_no_append(mode) {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_noappend.tmp"
-  );
-
-  // Clear any left-over files from previous runs.
-  await removeTestFile(path);
-
-  try {
-    mode = setup_mode(mode);
-    mode.append = false;
-    if (mode.trunc) {
-      // Pre-fill file with some data to see if |trunc| actually works.
-      await OS.File.writeAtomic(path, new Uint8Array(500));
-    }
-    let file = await OS.File.open(path, mode);
-    try {
-      await file.write(new Uint8Array(1000));
-      await file.setPosition(0, OS.File.POS_START);
-      await file.read(100);
-      // Should be at offset 100, length 1000 now.
-      await file.write(new Uint8Array(100));
-      // Should be at offset 200, length 1000 now.
-      let stat = await file.stat();
-      Assert.equal(1000, stat.size);
-    } finally {
-      await file.close();
-    }
-  } finally {
-    await removeTestFile(path);
-  }
-}
-
-var test_flags = [{}, { create: true }, { trunc: true }];
-function run_test() {
-  do_test_pending();
-
-  for (let t of test_flags) {
-    add_task(test_append.bind(null, t));
-    add_task(test_no_append.bind(null, t));
-  }
-  add_task(do_test_finished);
-
-  run_next_test();
-}
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_async_bytes.js
+++ /dev/null
@@ -1,40 +0,0 @@
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-function run_test() {
-  do_test_pending();
-  run_next_test();
-}
-
-/**
- * Test to ensure that {bytes:} in options to |write| is correctly
- * preserved.
- */
-add_task(async function test_bytes() {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_bytes.tmp"
-  );
-  let file = await OS.File.open(path, { trunc: true, read: true, write: true });
-  try {
-    try {
-      // 1. Test write, by supplying {bytes:} options smaller than the actual
-      // buffer.
-      await file.write(new Uint8Array(2048), { bytes: 1024 });
-      Assert.equal((await file.stat()).size, 1024);
-
-      // 2. Test that passing nullish values for |options| still works.
-      await file.setPosition(0, OS.File.POS_END);
-      await file.write(new Uint8Array(1024), null);
-      await file.write(new Uint8Array(1024), undefined);
-      Assert.equal((await file.stat()).size, 3072);
-    } finally {
-      await file.close();
-    }
-  } finally {
-    await OS.File.remove(path);
-  }
-});
-
-add_task(do_test_finished);
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_async_copy.js
+++ /dev/null
@@ -1,109 +0,0 @@
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-const { FileUtils } = ChromeUtils.importESModule(
-  "resource://gre/modules/FileUtils.sys.mjs"
-);
-const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-
-function run_test() {
-  do_test_pending();
-  run_next_test();
-}
-
-/**
- * A file that we know exists and that can be used for reading.
- */
-var EXISTING_FILE = "test_osfile_async_copy.js";
-
-/**
- * Fetch asynchronously the contents of a file using xpcom.
- *
- * Used for comparing xpcom-based results to os.file-based results.
- *
- * @param {string} path The _absolute_ path to the file.
- * @return {promise}
- * @resolves {string} The contents of the file.
- */
-var reference_fetch_file = function reference_fetch_file(path) {
-  return new Promise((resolve, reject) => {
-    let file = new FileUtils.File(path);
-    NetUtil.asyncFetch(
-      {
-        uri: NetUtil.newURI(file),
-        loadUsingSystemPrincipal: true,
-      },
-      function(stream, status) {
-        if (!Components.isSuccessCode(status)) {
-          reject(status);
-          return;
-        }
-        let result, reject;
-        try {
-          result = NetUtil.readInputStreamToString(stream, stream.available());
-        } catch (x) {
-          reject = x;
-        }
-        stream.close();
-        if (reject) {
-          reject(reject);
-        } else {
-          resolve(result);
-        }
-      }
-    );
-  });
-};
-
-/**
- * Compare asynchronously the contents two files using xpcom.
- *
- * Used for comparing xpcom-based results to os.file-based results.
- *
- * @param {string} a The _absolute_ path to the first file.
- * @param {string} b The _absolute_ path to the second file.
- *
- * @resolves {null}
- */
-var reference_compare_files = async function reference_compare_files(a, b) {
-  let a_contents = await reference_fetch_file(a);
-  let b_contents = await reference_fetch_file(b);
-  // Not using do_check_eq to avoid dumping the whole file to the log.
-  // It is OK to === compare here, as both variables contain a string.
-  Assert.ok(a_contents === b_contents);
-};
-
-/**
- * Test to ensure that OS.File.copy works.
- */
-async function test_copymove(options = {}) {
-  let source = OS.Path.join(await OS.File.getCurrentDirectory(), EXISTING_FILE);
-  let dest = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_copy_dest.tmp"
-  );
-  let dest2 = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_copy_dest2.tmp"
-  );
-  try {
-    // 1. Test copy.
-    await OS.File.copy(source, dest, options);
-    await reference_compare_files(source, dest);
-    // 2. Test subsequent move.
-    await OS.File.move(dest, dest2);
-    await reference_compare_files(source, dest2);
-    // 3. Check that the moved file was really moved.
-    Assert.equal(await OS.File.exists(dest), false);
-  } finally {
-    await removeTestFile(dest);
-    await removeTestFile(dest2);
-  }
-}
-
-// Regular copy test.
-add_task(test_copymove);
-// Userland copy test.
-add_task(test_copymove.bind(null, { unixUserland: true }));
-
-add_task(do_test_finished);
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_async_flush.js
+++ /dev/null
@@ -1,31 +0,0 @@
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-function run_test() {
-  do_test_pending();
-  run_next_test();
-}
-
-/**
- * Test to ensure that |File.prototype.flush| is available in the async API.
- */
-
-add_task(async function test_flush() {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_flush.tmp"
-  );
-  let file = await OS.File.open(path, { trunc: true, write: true });
-  try {
-    try {
-      await file.flush();
-    } finally {
-      await file.close();
-    }
-  } finally {
-    await OS.File.remove(path);
-  }
-});
-
-add_task(do_test_finished);
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_async_largefiles.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const { ctypes } = ChromeUtils.importESModule(
-  "resource://gre/modules/ctypes.sys.mjs"
-);
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-/**
- * A test to check that .getPosition/.setPosition work with large files.
- * (see bug 952997)
- */
-
-// Test setPosition/getPosition.
-async function test_setPosition(forward, current, backward) {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_largefiles.tmp"
-  );
-
-  // Clear any left-over files from previous runs.
-  await removeTestFile(path);
-
-  try {
-    let file = await OS.File.open(path, { write: true, append: false });
-    try {
-      let pos = 0;
-
-      // 1. seek forward from start
-      info("Moving forward: " + forward);
-      await file.setPosition(forward, OS.File.POS_START);
-      pos += forward;
-      Assert.equal(await file.getPosition(), pos);
-
-      // 2. seek forward from current position
-      info("Moving current: " + current);
-      await file.setPosition(current, OS.File.POS_CURRENT);
-      pos += current;
-      Assert.equal(await file.getPosition(), pos);
-
-      // 3. seek backward from current position
-      info("Moving current backward: " + backward);
-      await file.setPosition(-backward, OS.File.POS_CURRENT);
-      pos -= backward;
-      Assert.equal(await file.getPosition(), pos);
-    } finally {
-      await file.setPosition(0, OS.File.POS_START);
-      await file.close();
-    }
-  } catch (ex) {
-    await removeTestFile(path);
-  }
-}
-
-// Test setPosition/getPosition expected failures.
-async function test_setPosition_failures() {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_largefiles.tmp"
-  );
-
-  // Clear any left-over files from previous runs.
-  await removeTestFile(path);
-
-  try {
-    let file = await OS.File.open(path, { write: true, append: false });
-    try {
-      // 1. Use an invalid position value
-      try {
-        await file.setPosition(0.5, OS.File.POS_START);
-        do_throw("Shouldn't have succeeded");
-      } catch (ex) {
-        Assert.ok(ex.toString().includes("can't pass"));
-      }
-      // Since setPosition should have bailed, it shouldn't have moved the
-      // file pointer at all.
-      Assert.equal(await file.getPosition(), 0);
-
-      // 2. Use an invalid position value
-      try {
-        await file.setPosition(0xffffffff + 0.5, OS.File.POS_START);
-        do_throw("Shouldn't have succeeded");
-      } catch (ex) {
-        Assert.ok(ex.toString().includes("can't pass"));
-      }
-      // Since setPosition should have bailed, it shouldn't have moved the
-      // file pointer at all.
-      Assert.equal(await file.getPosition(), 0);
-
-      // 3. Use a position that cannot be represented as a double
-      try {
-        // Not all numbers after 9007199254740992 can be represented as a
-        // double. E.g. in js 9007199254740992 + 1 == 9007199254740992
-        await file.setPosition(9007199254740992, OS.File.POS_START);
-        await file.setPosition(1, OS.File.POS_CURRENT);
-        do_throw("Shouldn't have succeeded");
-      } catch (ex) {
-        info(ex.toString());
-        Assert.ok(!!ex);
-      }
-    } finally {
-      await file.setPosition(0, OS.File.POS_START);
-      await file.close();
-      await removeTestFile(path);
-    }
-  } catch (ex) {
-    do_throw(ex);
-  }
-}
-
-function run_test() {
-  // First verify stuff works for small values.
-  add_task(test_setPosition.bind(null, 0, 100, 50));
-  add_task(test_setPosition.bind(null, 1000, 100, 50));
-  add_task(test_setPosition.bind(null, 1000, -100, -50));
-
-  if (OS.Constants.Win || ctypes.off_t.size >= 8) {
-    // Now verify stuff still works for large values.
-    // 1. Multiple small seeks, which add up to > MAXINT32
-    add_task(test_setPosition.bind(null, 0x7fffffff, 0x7fffffff, 0));
-    // 2. Plain large seek, that should end up at 0 again.
-    // 0xffffffff also happens to be the INVALID_SET_FILE_POINTER value on
-    // Windows, so this also tests the error handling
-    add_task(test_setPosition.bind(null, 0, 0xffffffff, 0xffffffff));
-    // 3. Multiple large seeks that should end up > MAXINT32.
-    add_task(test_setPosition.bind(null, 0xffffffff, 0xffffffff, 0xffffffff));
-    // 5. Multiple large seeks with negative offsets.
-    add_task(test_setPosition.bind(null, 0xffffffff, -0x7fffffff, 0x7fffffff));
-
-    // 6. Check failures
-    add_task(test_setPosition_failures);
-  }
-
-  run_next_test();
-}
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_async_setDates.js
+++ /dev/null
@@ -1,214 +0,0 @@
-"use strict";
-
-/* eslint-disable no-lone-blocks */
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-/**
- * A test to ensure that OS.File.setDates and OS.File.prototype.setDates are
- * working correctly.
- * (see bug 924916)
- */
-
-// Non-prototypical tests, operating on path names.
-add_task(async function test_nonproto() {
-  // First, create a file we can mess with.
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_setDates_nonproto.tmp"
-  );
-  await OS.File.writeAtomic(path, new Uint8Array(1));
-
-  try {
-    // 1. Try to set some well known dates.
-    // We choose multiples of 2000ms, because the time stamp resolution of
-    // the underlying OS might not support something more precise.
-    const accDate = 2000;
-    const modDate = 4000;
-    {
-      await OS.File.setDates(path, accDate, modDate);
-      let stat = await OS.File.stat(path);
-      Assert.equal(accDate, stat.lastAccessDate.getTime());
-      Assert.equal(modDate, stat.lastModificationDate.getTime());
-    }
-
-    // 2.1 Try to omit modificationDate (which should then default to
-    // |Date.now()|, expect for resolution differences).
-    {
-      await OS.File.setDates(path, accDate);
-      let stat = await OS.File.stat(path);
-      Assert.equal(accDate, stat.lastAccessDate.getTime());
-      Assert.notEqual(modDate, stat.lastModificationDate.getTime());
-    }
-
-    // 2.2 Try to omit accessDate as well (which should then default to
-    // |Date.now()|, expect for resolution differences).
-    {
-      await OS.File.setDates(path);
-      let stat = await OS.File.stat(path);
-      Assert.notEqual(accDate, stat.lastAccessDate.getTime());
-      Assert.notEqual(modDate, stat.lastModificationDate.getTime());
-    }
-
-    // 3. Repeat 1., but with Date objects this time
-    {
-      await OS.File.setDates(path, new Date(accDate), new Date(modDate));
-      let stat = await OS.File.stat(path);
-      Assert.equal(accDate, stat.lastAccessDate.getTime());
-      Assert.equal(modDate, stat.lastModificationDate.getTime());
-    }
-
-    // 4. Check that invalid params will cause an exception/rejection.
-    {
-      for (let p of ["invalid", new Uint8Array(1), NaN]) {
-        try {
-          await OS.File.setDates(path, p, modDate);
-          do_throw("Invalid access date should have thrown for: " + p);
-        } catch (ex) {
-          let stat = await OS.File.stat(path);
-          Assert.equal(accDate, stat.lastAccessDate.getTime());
-          Assert.equal(modDate, stat.lastModificationDate.getTime());
-        }
-        try {
-          await OS.File.setDates(path, accDate, p);
-          do_throw("Invalid modification date should have thrown for: " + p);
-        } catch (ex) {
-          let stat = await OS.File.stat(path);
-          Assert.equal(accDate, stat.lastAccessDate.getTime());
-          Assert.equal(modDate, stat.lastModificationDate.getTime());
-        }
-        try {
-          await OS.File.setDates(path, p, p);
-          do_throw("Invalid dates should have thrown for: " + p);
-        } catch (ex) {
-          let stat = await OS.File.stat(path);
-          Assert.equal(accDate, stat.lastAccessDate.getTime());
-          Assert.equal(modDate, stat.lastModificationDate.getTime());
-        }
-      }
-    }
-  } finally {
-    // Remove the temp file again
-    await OS.File.remove(path);
-  }
-});
-
-// Prototypical tests, operating on |File| handles.
-add_task(async function test_proto() {
-  if (OS.Constants.Sys.Name == "Android") {
-    info("File.prototype.setDates is not implemented for Android");
-    Assert.equal(OS.File.prototype.setDates, undefined);
-    return;
-  }
-
-  // First, create a file we can mess with.
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_setDates_proto.tmp"
-  );
-  await OS.File.writeAtomic(path, new Uint8Array(1));
-
-  try {
-    let fd = await OS.File.open(path, { write: true });
-
-    try {
-      // 1. Try to set some well known dates.
-      // We choose multiples of 2000ms, because the time stamp resolution of
-      // the underlying OS might not support something more precise.
-      const accDate = 2000;
-      const modDate = 4000;
-      {
-        await fd.setDates(accDate, modDate);
-        let stat = await fd.stat();
-        Assert.equal(accDate, stat.lastAccessDate.getTime());
-        Assert.equal(modDate, stat.lastModificationDate.getTime());
-      }
-
-      // 2.1 Try to omit modificationDate (which should then default to
-      // |Date.now()|, expect for resolution differences).
-      {
-        await fd.setDates(accDate);
-        let stat = await fd.stat();
-        Assert.equal(accDate, stat.lastAccessDate.getTime());
-        Assert.notEqual(modDate, stat.lastModificationDate.getTime());
-      }
-
-      // 2.2 Try to omit accessDate as well (which should then default to
-      // |Date.now()|, expect for resolution differences).
-      {
-        await fd.setDates();
-        let stat = await fd.stat();
-        Assert.notEqual(accDate, stat.lastAccessDate.getTime());
-        Assert.notEqual(modDate, stat.lastModificationDate.getTime());
-      }
-
-      // 3. Repeat 1., but with Date objects this time
-      {
-        await fd.setDates(new Date(accDate), new Date(modDate));
-        let stat = await fd.stat();
-        Assert.equal(accDate, stat.lastAccessDate.getTime());
-        Assert.equal(modDate, stat.lastModificationDate.getTime());
-      }
-
-      // 4. Check that invalid params will cause an exception/rejection.
-      {
-        for (let p of ["invalid", new Uint8Array(1), NaN]) {
-          try {
-            await fd.setDates(p, modDate);
-            do_throw("Invalid access date should have thrown for: " + p);
-          } catch (ex) {
-            let stat = await fd.stat();
-            Assert.equal(accDate, stat.lastAccessDate.getTime());
-            Assert.equal(modDate, stat.lastModificationDate.getTime());
-          }
-          try {
-            await fd.setDates(accDate, p);
-            do_throw("Invalid modification date should have thrown for: " + p);
-          } catch (ex) {
-            let stat = await fd.stat();
-            Assert.equal(accDate, stat.lastAccessDate.getTime());
-            Assert.equal(modDate, stat.lastModificationDate.getTime());
-          }
-          try {
-            await fd.setDates(p, p);
-            do_throw("Invalid dates should have thrown for: " + p);
-          } catch (ex) {
-            let stat = await fd.stat();
-            Assert.equal(accDate, stat.lastAccessDate.getTime());
-            Assert.equal(modDate, stat.lastModificationDate.getTime());
-          }
-        }
-      }
-    } finally {
-      await fd.close();
-    }
-  } finally {
-    // Remove the temp file again
-    await OS.File.remove(path);
-  }
-});
-
-// Tests setting dates on directories.
-add_task(async function test_dirs() {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_setDates_dir"
-  );
-  await OS.File.makeDir(path);
-
-  try {
-    // 1. Try to set some well known dates.
-    // We choose multiples of 2000ms, because the time stamp resolution of
-    // the underlying OS might not support something more precise.
-    const accDate = 2000;
-    const modDate = 4000;
-    {
-      await OS.File.setDates(path, accDate, modDate);
-      let stat = await OS.File.stat(path);
-      Assert.equal(accDate, stat.lastAccessDate.getTime());
-      Assert.equal(modDate, stat.lastModificationDate.getTime());
-    }
-  } finally {
-    await OS.File.removeEmptyDir(path);
-  }
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_async_setPermissions.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-/**
- * A test to ensure that OS.File.setPermissions and
- * OS.File.prototype.setPermissions are all working correctly.
- * (see bug 1001849)
- * These functions are currently Unix-specific.  The manifest skips
- * the test on Windows.
- */
-
-/**
- * Helper function for test logging: prints a POSIX file permission mode as an
- * octal number, with a leading '0' per C (not JS) convention.  When the
- * numeric value is 0o777 or lower, it is padded on the left with zeroes to
- * four digits wide.
- * Sample outputs:  0022, 0644, 04755.
- */
-function format_mode(mode) {
-  if (mode <= 0o777) {
-    return ("0000" + mode.toString(8)).slice(-4);
-  }
-  return "0" + mode.toString(8);
-}
-
-const _umask = OS.Constants.Sys.umask;
-info("umask: " + format_mode(_umask));
-
-/**
- * Compute the mode that a file should have after applying the umask,
- * whatever it happens to be.
- */
-function apply_umask(mode) {
-  return mode & ~_umask;
-}
-
-// Sequence of setPermission parameters and expected file mode.  The first test
-// checks the permissions when the file is first created.
-var testSequence = [
-  [null, apply_umask(0o600)],
-  [{ unixMode: 0o4777 }, apply_umask(0o4777)],
-  [{ unixMode: 0o4777, unixHonorUmask: false }, 0o4777],
-  [{ unixMode: 0o4777, unixHonorUmask: true }, apply_umask(0o4777)],
-  [undefined, apply_umask(0o600)],
-  [{ unixMode: 0o666 }, apply_umask(0o666)],
-  [{ unixMode: 0o600 }, apply_umask(0o600)],
-  [{ unixMode: 0 }, 0],
-  [{}, apply_umask(0o600)],
-];
-
-// Test application to paths.
-add_task(async function test_path_setPermissions() {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_setPermissions_path.tmp"
-  );
-  await OS.File.writeAtomic(path, new Uint8Array(1));
-
-  try {
-    for (let [options, expectedMode] of testSequence) {
-      if (options !== null) {
-        info("Setting permissions to " + JSON.stringify(options));
-        await OS.File.setPermissions(path, options);
-      }
-
-      let stat = await OS.File.stat(path);
-      Assert.equal(format_mode(stat.unixMode), format_mode(expectedMode));
-    }
-  } finally {
-    await OS.File.remove(path);
-  }
-});
-
-// Test application to open files.
-add_task(async function test_file_setPermissions() {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_async_setPermissions_file.tmp"
-  );
-  await OS.File.writeAtomic(path, new Uint8Array(1));
-
-  try {
-    let fd = await OS.File.open(path, { write: true });
-    try {
-      for (let [options, expectedMode] of testSequence) {
-        if (options !== null) {
-          info("Setting permissions to " + JSON.stringify(options));
-          await fd.setPermissions(options);
-        }
-
-        let stat = await fd.stat();
-        Assert.equal(format_mode(stat.unixMode), format_mode(expectedMode));
-      }
-    } finally {
-      await fd.close();
-    }
-  } finally {
-    await OS.File.remove(path);
-  }
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_closed.js
+++ /dev/null
@@ -1,46 +0,0 @@
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-function run_test() {
-  do_test_pending();
-  run_next_test();
-}
-
-add_task(async function test_closed() {
-  OS.Shared.DEBUG = true;
-  let currentDir = await OS.File.getCurrentDirectory();
-  info("Open a file, ensure that we can call stat()");
-  let path = OS.Path.join(currentDir, "test_osfile_closed.js");
-  let file = await OS.File.open(path);
-  await file.stat();
-  Assert.ok(true);
-
-  await file.close();
-
-  info("Ensure that we cannot stat() on closed file");
-  let exn;
-  try {
-    await file.stat();
-  } catch (ex) {
-    exn = ex;
-  }
-  info("Ensure that this raises the correct error");
-  Assert.ok(!!exn);
-  Assert.ok(exn instanceof OS.File.Error);
-  Assert.ok(exn.becauseClosed);
-
-  info("Ensure that we cannot read() on closed file");
-  exn = null;
-  try {
-    await file.read();
-  } catch (ex) {
-    exn = ex;
-  }
-  info("Ensure that this raises the correct error");
-  Assert.ok(!!exn);
-  Assert.ok(exn instanceof OS.File.Error);
-  Assert.ok(exn.becauseClosed);
-});
-
-add_task(do_test_finished);
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_error.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var {
-  OS: { File, Path, Constants },
-} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-add_task(async function testFileError_with_writeAtomic() {
-  let DEFAULT_CONTENTS = "default contents" + Math.random();
-  let path = Path.join(Constants.Path.tmpDir, "testFileError.tmp");
-  await File.remove(path);
-  await File.writeAtomic(path, DEFAULT_CONTENTS);
-  let exception;
-  try {
-    await File.writeAtomic(path, DEFAULT_CONTENTS, { noOverwrite: true });
-  } catch (ex) {
-    exception = ex;
-  }
-  Assert.ok(exception instanceof File.Error);
-  Assert.ok(exception.path == path);
-});
-
-add_task(async function testFileError_with_makeDir() {
-  let path = Path.join(Constants.Path.tmpDir, "directory");
-  await File.removeDir(path);
-  await File.makeDir(path);
-  let exception;
-  try {
-    await File.makeDir(path, { ignoreExisting: false });
-  } catch (ex) {
-    exception = ex;
-  }
-  Assert.ok(exception instanceof File.Error);
-  Assert.ok(exception.path == path);
-});
-
-add_task(async function testFileError_with_move() {
-  let DEFAULT_CONTENTS = "default contents" + Math.random();
-  let sourcePath = Path.join(Constants.Path.tmpDir, "src.tmp");
-  let destPath = Path.join(Constants.Path.tmpDir, "dest.tmp");
-  await File.remove(sourcePath);
-  await File.remove(destPath);
-  await File.writeAtomic(sourcePath, DEFAULT_CONTENTS);
-  await File.writeAtomic(destPath, DEFAULT_CONTENTS);
-  let exception;
-  try {
-    await File.move(sourcePath, destPath, { noOverwrite: true });
-  } catch (ex) {
-    exception = ex;
-  }
-  info(exception);
-  Assert.ok(exception instanceof File.Error);
-  Assert.ok(exception.path == sourcePath);
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_kill.js
+++ /dev/null
@@ -1,97 +0,0 @@
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-// We want the actual global to get at the internals since Scheduler is not
-// exported.
-var { Scheduler } = ChromeUtils.import(
-  "resource://gre/modules/osfile/osfile_async_front.jsm"
-);
-
-/**
- * Verify that Scheduler.kill() interacts with other OS.File requests correctly,
- * and that no requests are lost.  This is relevant because on B2G we
- * auto-kill the worker periodically, making it very possible for valid requests
- * to be interleaved with the automatic kill().
- *
- * This test is being created with the fix for Bug 1125989 where `kill` queue
- * management was found to be buggy.  It is a glass-box test that explicitly
- * re-creates the observed failure situation; it is not guaranteed to prevent
- * all future regressions.  The following is a detailed explanation of the test
- * for your benefit if this test ever breaks or you are wondering what was the
- * point of all this.  You might want to skim the code below first.
- *
- * OS.File maintains a `queue` of operations to be performed.  This queue is
- * nominally implemented as a chain of promises.  Every time a new job is
- * OS.File.push()ed, it effectively becomes the new `queue` promise.  (An
- * extra promise is interposed with a rejection handler to avoid the rejection
- * cascading, but that does not matter for our purposes.)
- *
- * The flaw in `kill` was that it would wait for the `queue` to complete before
- * replacing `queue`.  As a result, another OS.File operation could use `push`
- * (by way of OS.File.post()) to also use .then() on the same `queue` promise.
- * Accordingly, assuming that promise was not yet resolved (due to a pending
- * OS.File request), when it was resolved, both the task scheduled in `kill`
- * and in `post` would be triggered.  Both of those tasks would run until
- * encountering a call to worker.post().
- *
- * Re-creating this race is not entirely trivial because of the large number of
- * promises used by the code causing control flow to repeatedly be deferred.  In
- * a slightly simpler world we could run the follwing in the same turn of the
- * event loop and trigger the problem.
- * - any OS.File request
- * - Scheduler.kill()
- * - any OS.File request
- *
- * However, we need the Scheduler.kill task to reach the point where it is
- * waiting on the same `queue` that another task has been scheduled against.
- * Since the `kill` task yields on the `killQueue` promise prior to yielding
- * on `queue`, however, some turns of the event loop are required.  Happily,
- * for us, as discussed above, the problem triggers when we have two promises
- * scheduled on the `queue`, so we can just wait to schedule the second OS.File
- * request on the queue.  (Note that because of the additional then() added to
- * eat rejections, there is an important difference between the value of
- * `queue` and the value returned by the first OS.File request.)
- */
-add_task(async function test_kill_race() {
-  // Ensure the worker has been created and that SET_DEBUG has taken effect.
-  // We have chosen OS.File.exists for our tests because it does not trigger
-  // a rejection and we absolutely do not care what the operation is other
-  // than it does not invoke a native fast-path.
-  await OS.File.exists("foo.foo");
-
-  info("issuing first request");
-  let firstRequest = OS.File.exists("foo.bar"); // eslint-disable-line no-unused-vars
-  let secondRequest;
-  let secondResolved = false;
-
-  // As noted in our big block comment, we want to wait to schedule the
-  // second request so that it races `kill`'s call to `worker.post`.  Having
-  // ourselves wait on the same promise, `queue`, and registering ourselves
-  // before we issue the kill request means we will get run before the `kill`
-  // task resumes and allow us to precisely create the desired race.
-  Scheduler.queue.then(function() {
-    info("issuing second request");
-    secondRequest = OS.File.exists("foo.baz");
-    secondRequest.then(function() {
-      secondResolved = true;
-    });
-  });
-
-  info("issuing kill request");
-  let killRequest = Scheduler.kill({ reset: true, shutdown: false });
-
-  // Wait on the killRequest so that we can schedule a new OS.File request
-  // after it completes...
-  await killRequest;
-  // ...because our ordering guarantee ensures that there is at most one
-  // worker (and this usage here should not be vulnerable even with the
-  // bug present), so when this completes the secondRequest has either been
-  // resolved or lost.
-  await OS.File.exists("foo.goz");
-
-  ok(
-    secondResolved,
-    "The second request was resolved so we avoided the bug. Victory!"
-  );
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_win_async_setPermissions.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-/**
- * A test to ensure that OS.File.setPermissions and
- * OS.File.prototype.setPermissions are all working correctly.
- * (see bug 1022816)
- * The manifest tests on Windows.
- */
-
-// Sequence of setPermission parameters.
-var testSequence = [
-  [
-    { winAttributes: { readOnly: true, system: true, hidden: true } },
-    { readOnly: true, system: true, hidden: true },
-  ],
-  [
-    { winAttributes: { readOnly: false } },
-    { readOnly: false, system: true, hidden: true },
-  ],
-  [
-    { winAttributes: { system: false } },
-    { readOnly: false, system: false, hidden: true },
-  ],
-  [
-    { winAttributes: { hidden: false } },
-    { readOnly: false, system: false, hidden: false },
-  ],
-  [
-    { winAttributes: { readOnly: true, system: false, hidden: false } },
-    { readOnly: true, system: false, hidden: false },
-  ],
-  [
-    { winAttributes: { readOnly: false, system: true, hidden: false } },
-    { readOnly: false, system: true, hidden: false },
-  ],
-  [
-    { winAttributes: { readOnly: false, system: false, hidden: true } },
-    { readOnly: false, system: false, hidden: true },
-  ],
-];
-
-// Test application to paths.
-add_task(async function test_path_setPermissions() {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_win_async_setPermissions_path.tmp"
-  );
-  await OS.File.writeAtomic(path, new Uint8Array(1));
-
-  try {
-    for (let [options, attributesExpected] of testSequence) {
-      if (options !== null) {
-        info("Setting permissions to " + JSON.stringify(options));
-        await OS.File.setPermissions(path, options);
-      }
-
-      let stat = await OS.File.stat(path);
-      info("Got stat winAttributes: " + JSON.stringify(stat.winAttributes));
-
-      Assert.equal(stat.winAttributes.readOnly, attributesExpected.readOnly);
-      Assert.equal(stat.winAttributes.system, attributesExpected.system);
-      Assert.equal(stat.winAttributes.hidden, attributesExpected.hidden);
-    }
-  } finally {
-    await OS.File.remove(path);
-  }
-});
-
-// Test application to open files.
-add_task(async function test_file_setPermissions() {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_win_async_setPermissions_file.tmp"
-  );
-  await OS.File.writeAtomic(path, new Uint8Array(1));
-
-  try {
-    let fd = await OS.File.open(path, { write: true });
-    try {
-      for (let [options, attributesExpected] of testSequence) {
-        if (options !== null) {
-          info("Setting permissions to " + JSON.stringify(options));
-          await fd.setPermissions(options);
-        }
-
-        let stat = await fd.stat();
-        info("Got stat winAttributes: " + JSON.stringify(stat.winAttributes));
-        Assert.equal(stat.winAttributes.readOnly, attributesExpected.readOnly);
-        Assert.equal(stat.winAttributes.system, attributesExpected.system);
-        Assert.equal(stat.winAttributes.hidden, attributesExpected.hidden);
-      }
-    } finally {
-      await fd.close();
-    }
-  } finally {
-    await OS.File.remove(path);
-  }
-});
-
-// Test application to Check setPermissions on a non-existant file path.
-add_task(async function test_non_existant_file_path_setPermissions() {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_win_async_setPermissions_path.tmp"
-  );
-  await Assert.rejects(
-    OS.File.setPermissions(path, { winAttributes: { readOnly: true } }),
-    /The system cannot find the file specified/,
-    "setPermissions failed as expected on a non-existant file path"
-  );
-});
-
-// Test application to Check setPermissions on a invalid file handle.
-add_task(async function test_closed_file_handle_setPermissions() {
-  let path = OS.Path.join(
-    OS.Constants.Path.tmpDir,
-    "test_osfile_win_async_setPermissions_path.tmp"
-  );
-  await OS.File.writeAtomic(path, new Uint8Array(1));
-
-  try {
-    let fd = await OS.File.open(path, { write: true });
-    await fd.close();
-    await Assert.rejects(
-      fd.setPermissions(path, { winAttributes: { readOnly: true } }),
-      /The handle is invalid/,
-      "setPermissions failed as expected on a invalid file handle"
-    );
-  } finally {
-    await OS.File.remove(path);
-  }
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_writeAtomic_backupTo_option.js
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var {
-  OS: { File, Path, Constants },
-} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-/**
- * Remove all temporary files and back up files, including
- * test_backupTo_option_with_tmpPath.tmp
- * test_backupTo_option_with_tmpPath.tmp.backup
- * test_backupTo_option_without_tmpPath.tmp
- * test_backupTo_option_without_tmpPath.tmp.backup
- * test_non_backupTo_option.tmp
- * test_non_backupTo_option.tmp.backup
- * test_backupTo_option_without_destination_file.tmp
- * test_backupTo_option_without_destination_file.tmp.backup
- * test_backupTo_option_with_backup_file.tmp
- * test_backupTo_option_with_backup_file.tmp.backup
- */
-async function clearFiles() {
-  let files = [
-    "test_backupTo_option_with_tmpPath.tmp",
-    "test_backupTo_option_without_tmpPath.tmp",
-    "test_non_backupTo_option.tmp",
-    "test_backupTo_option_without_destination_file.tmp",
-    "test_backupTo_option_with_backup_file.tmp",
-  ];
-  for (let file of files) {
-    let path = Path.join(Constants.Path.tmpDir, file);
-    await File.remove(path);
-    await File.remove(path + ".backup");
-  }
-}
-
-add_task(async function init() {
-  await clearFiles();
-});
-
-/**
- * test when
- * |backupTo| specified
- * |tmpPath| specified
- * destination file exists
- * @result destination file will be backed up
- */
-add_task(async function test_backupTo_option_with_tmpPath() {
-  let DEFAULT_CONTENTS = "default contents" + Math.random();
-  let WRITE_CONTENTS = "abc" + Math.random();
-  let path = Path.join(
-    Constants.Path.tmpDir,
-    "test_backupTo_option_with_tmpPath.tmp"
-  );
-  await File.writeAtomic(path, DEFAULT_CONTENTS);
-  await File.writeAtomic(path, WRITE_CONTENTS, {
-    tmpPath: path + ".tmp",
-    backupTo: path + ".backup",
-  });
-  Assert.ok(await File.exists(path + ".backup"));
-  let contents = await File.read(path + ".backup");
-  Assert.equal(DEFAULT_CONTENTS, new TextDecoder().decode(contents));
-});
-
-/**
- * test when
- * |backupTo| specified
- * |tmpPath| not specified
- * destination file exists
- * @result destination file will be backed up
- */
-add_task(async function test_backupTo_option_without_tmpPath() {
-  let DEFAULT_CONTENTS = "default contents" + Math.random();
-  let WRITE_CONTENTS = "abc" + Math.random();
-  let path = Path.join(
-    Constants.Path.tmpDir,
-    "test_backupTo_option_without_tmpPath.tmp"
-  );
-  await File.writeAtomic(path, DEFAULT_CONTENTS);
-  await File.writeAtomic(path, WRITE_CONTENTS, { backupTo: path + ".backup" });
-  Assert.ok(await File.exists(path + ".backup"));
-  let contents = await File.read(path + ".backup");
-  Assert.equal(DEFAULT_CONTENTS, new TextDecoder().decode(contents));
-});
-
-/**
- * test when
- * |backupTo| not specified
- * |tmpPath| not specified
- * destination file exists
- * @result destination file will not be backed up
- */
-add_task(async function test_non_backupTo_option() {
-  let DEFAULT_CONTENTS = "default contents" + Math.random();
-  let WRITE_CONTENTS = "abc" + Math.random();
-  let path = Path.join(Constants.Path.tmpDir, "test_non_backupTo_option.tmp");
-  await File.writeAtomic(path, DEFAULT_CONTENTS);
-  await File.writeAtomic(path, WRITE_CONTENTS);
-  Assert.equal(false, await File.exists(path + ".backup"));
-});
-
-/**
- * test when
- * |backupTo| specified
- * |tmpPath| not specified
- * destination file not exists
- * @result no back up file exists
- */
-add_task(async function test_backupTo_option_without_destination_file() {
-  let WRITE_CONTENTS = "abc" + Math.random();
-  let path = Path.join(
-    Constants.Path.tmpDir,
-    "test_backupTo_option_without_destination_file.tmp"
-  );
-  await File.remove(path);
-  await File.writeAtomic(path, WRITE_CONTENTS, { backupTo: path + ".backup" });
-  Assert.equal(false, await File.exists(path + ".backup"));
-});
-
-/**
- * test when
- * |backupTo| specified
- * |tmpPath| not specified
- * backup file exists
- * destination file exists
- * @result destination file will be backed up
- */
-add_task(async function test_backupTo_option_with_backup_file() {
-  let DEFAULT_CONTENTS = "default contents" + Math.random();
-  let WRITE_CONTENTS = "abc" + Math.random();
-  let path = Path.join(
-    Constants.Path.tmpDir,
-    "test_backupTo_option_with_backup_file.tmp"
-  );
-  await File.writeAtomic(path, DEFAULT_CONTENTS);
-
-  await File.writeAtomic(path + ".backup", new Uint8Array(1000));
-
-  await File.writeAtomic(path, WRITE_CONTENTS, { backupTo: path + ".backup" });
-  Assert.ok(await File.exists(path + ".backup"));
-  let contents = await File.read(path + ".backup");
-  Assert.equal(DEFAULT_CONTENTS, new TextDecoder().decode(contents));
-});
-
-add_task(async function cleanup() {
-  await clearFiles();
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_writeAtomic_unicode_filename.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * This test checks against failures that may occur while creating and/or
- * renaming files with Unicode paths on Windows.
- * See bug 1063635#c89 for a failure due to a Unicode filename being renamed.
- */
-
-"use strict";
-var profileDir;
-
-async function writeAndCheck(path, tmpPath) {
-  const encoder = new TextEncoder();
-  const content = "tmpContent";
-  const outBin = encoder.encode(content);
-  await OS.File.writeAtomic(path, outBin, { tmpPath });
-
-  const decoder = new TextDecoder();
-  const writtenBin = await OS.File.read(path);
-  const written = decoder.decode(writtenBin);
-
-  // Clean up
-  await OS.File.remove(path);
-  Assert.equal(
-    written,
-    content,
-    `Expected correct write/read for ${path} with tmpPath ${tmpPath}`
-  );
-}
-
-add_task(async function init() {
-  do_get_profile();
-  profileDir = OS.Constants.Path.profileDir;
-});
-
-add_test_pair(async function test_osfile_writeAtomic_unicode_filename() {
-  await writeAndCheck(OS.Path.join(profileDir, "☕") + ".tmp", undefined);
-  await writeAndCheck(OS.Path.join(profileDir, "☕"), undefined);
-  await writeAndCheck(
-    OS.Path.join(profileDir, "☕") + ".tmp",
-    OS.Path.join(profileDir, "☕")
-  );
-  await writeAndCheck(
-    OS.Path.join(profileDir, "☕"),
-    OS.Path.join(profileDir, "☕") + ".tmp"
-  );
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_osfile_writeAtomic_zerobytes.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-var SHARED_PATH;
-
-add_task(async function init() {
-  do_get_profile();
-  SHARED_PATH = OS.Path.join(
-    OS.Constants.Path.profileDir,
-    "test_osfile_write_zerobytes.tmp"
-  );
-});
-
-add_test_pair(async function test_osfile_writeAtomic_zerobytes() {
-  let encoder = new TextEncoder();
-  let string1 = "";
-  let outbin = encoder.encode(string1);
-  await OS.File.writeAtomic(SHARED_PATH, outbin);
-
-  let decoder = new TextDecoder();
-  let bin = await OS.File.read(SHARED_PATH);
-  let string2 = decoder.decode(bin);
-  // Checking if writeAtomic supports writing encoded zero-byte strings
-  Assert.equal(string2, string1, "Read the expected (empty) string.");
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_path.js
+++ /dev/null
@@ -1,187 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-Services.prefs.setBoolPref("toolkit.osfile.test.syslib_necessary", false);
-// We don't need libc/kernel32.dll for this test
-
-const Win = ChromeUtils.import("resource://gre/modules/osfile/ospath_win.jsm");
-const Unix = ChromeUtils.import(
-  "resource://gre/modules/osfile/ospath_unix.jsm"
-);
-
-function do_check_fail(f) {
-  try {
-    let result = f();
-    info("Failed do_check_fail: " + result);
-    Assert.ok(false);
-  } catch (ex) {
-    Assert.ok(true);
-  }
-}
-
-function run_test() {
-  info("Testing Windows paths");
-
-  info("Backslash-separated, no drive");
-  Assert.equal(Win.basename("a\\b"), "b");
-  Assert.equal(Win.basename("a\\b\\"), "");
-  Assert.equal(Win.basename("abc"), "abc");
-  Assert.equal(Win.dirname("a\\b"), "a");
-  Assert.equal(Win.dirname("a\\b\\"), "a\\b");
-  Assert.equal(Win.dirname("a\\\\\\\\b"), "a");
-  Assert.equal(Win.dirname("abc"), ".");
-  Assert.equal(Win.normalize("\\a\\b\\c"), "\\a\\b\\c");
-  Assert.equal(Win.normalize("\\a\\b\\\\\\\\c"), "\\a\\b\\c");
-  Assert.equal(Win.normalize("\\a\\b\\c\\\\\\"), "\\a\\b\\c");
-  Assert.equal(Win.normalize("\\a\\b\\c\\..\\..\\..\\d\\e\\f"), "\\d\\e\\f");
-  Assert.equal(Win.normalize("a\\b\\c\\..\\..\\..\\d\\e\\f"), "d\\e\\f");
-  do_check_fail(() => Win.normalize("\\a\\b\\c\\..\\..\\..\\..\\d\\e\\f"));
-
-  Assert.equal(
-    Win.join("\\tmp", "foo", "bar"),
-    "\\tmp\\foo\\bar",
-    "join \\tmp,foo,bar"
-  );
-  Assert.equal(
-    Win.join("\\tmp", "\\foo", "bar"),
-    "\\foo\\bar",
-    "join \\tmp,\\foo,bar"
-  );
-  Assert.equal(Win.winGetDrive("\\tmp"), null);
-  Assert.equal(Win.winGetDrive("\\tmp\\a\\b\\c\\d\\e"), null);
-  Assert.equal(Win.winGetDrive("\\"), null);
-
-  info("Backslash-separated, with a drive");
-  Assert.equal(Win.basename("c:a\\b"), "b");
-  Assert.equal(Win.basename("c:a\\b\\"), "");
-  Assert.equal(Win.basename("c:abc"), "abc");
-  Assert.equal(Win.dirname("c:a\\b"), "c:a");
-  Assert.equal(Win.dirname("c:a\\b\\"), "c:a\\b");
-  Assert.equal(Win.dirname("c:a\\\\\\\\b"), "c:a");
-  Assert.equal(Win.dirname("c:abc"), "c:");
-  let options = {
-    winNoDrive: true,
-  };
-  Assert.equal(Win.dirname("c:a\\b", options), "a");
-  Assert.equal(Win.dirname("c:a\\b\\", options), "a\\b");
-  Assert.equal(Win.dirname("c:a\\\\\\\\b", options), "a");
-  Assert.equal(Win.dirname("c:abc", options), ".");
-  Assert.equal(Win.join("c:", "abc"), "c:\\abc", "join c:,abc");
-
-  Assert.equal(Win.normalize("c:"), "c:\\");
-  Assert.equal(Win.normalize("c:\\"), "c:\\");
-  Assert.equal(Win.normalize("c:\\a\\b\\c"), "c:\\a\\b\\c");
-  Assert.equal(Win.normalize("c:\\a\\b\\\\\\\\c"), "c:\\a\\b\\c");
-  Assert.equal(Win.normalize("c:\\\\\\\\a\\b\\c"), "c:\\a\\b\\c");
-  Assert.equal(Win.normalize("c:\\a\\b\\c\\\\\\"), "c:\\a\\b\\c");
-  Assert.equal(
-    Win.normalize("c:\\a\\b\\c\\..\\..\\..\\d\\e\\f"),
-    "c:\\d\\e\\f"
-  );
-  Assert.equal(Win.normalize("c:a\\b\\c\\..\\..\\..\\d\\e\\f"), "c:\\d\\e\\f");
-  do_check_fail(() => Win.normalize("c:\\a\\b\\c\\..\\..\\..\\..\\d\\e\\f"));
-
-  Assert.equal(Win.join("c:\\", "foo"), "c:\\foo", "join c:,foo");
-  Assert.equal(
-    Win.join("c:\\tmp", "foo", "bar"),
-    "c:\\tmp\\foo\\bar",
-    "join c:\\tmp,foo,bar"
-  );
-  Assert.equal(
-    Win.join("c:\\tmp", "\\foo", "bar"),
-    "c:\\foo\\bar",
-    "join c:\\tmp,\\foo,bar"
-  );
-  Assert.equal(
-    Win.join("c:\\tmp", "c:\\foo", "bar"),
-    "c:\\foo\\bar",
-    "join c:\\tmp,c:\\foo,bar"
-  );
-  Assert.equal(
-    Win.join("c:\\tmp", "c:foo", "bar"),
-    "c:\\foo\\bar",
-    "join c:\\tmp,c:foo,bar"
-  );
-  Assert.equal(Win.winGetDrive("c:"), "c:");
-  Assert.equal(Win.winGetDrive("c:\\"), "c:");
-  Assert.equal(Win.winGetDrive("c:abc"), "c:");
-  Assert.equal(Win.winGetDrive("c:abc\\d\\e\\f\\g"), "c:");
-  Assert.equal(Win.winGetDrive("c:\\abc"), "c:");
-  Assert.equal(Win.winGetDrive("c:\\abc\\d\\e\\f\\g"), "c:");
-
-  info("Forwardslash-separated, no drive");
-  Assert.equal(Win.normalize("/a/b/c"), "\\a\\b\\c");
-  Assert.equal(Win.normalize("/a/b////c"), "\\a\\b\\c");
-  Assert.equal(Win.normalize("/a/b/c///"), "\\a\\b\\c");
-  Assert.equal(Win.normalize("/a/b/c/../../../d/e/f"), "\\d\\e\\f");
-  Assert.equal(Win.normalize("a/b/c/../../../d/e/f"), "d\\e\\f");
-
-  info("Forwardslash-separated, with a drive");
-  Assert.equal(Win.normalize("c:/"), "c:\\");
-  Assert.equal(Win.normalize("c:/a/b/c"), "c:\\a\\b\\c");
-  Assert.equal(Win.normalize("c:/a/b////c"), "c:\\a\\b\\c");
-  Assert.equal(Win.normalize("c:////a/b/c"), "c:\\a\\b\\c");
-  Assert.equal(Win.normalize("c:/a/b/c///"), "c:\\a\\b\\c");
-  Assert.equal(Win.normalize("c:/a/b/c/../../../d/e/f"), "c:\\d\\e\\f");
-  Assert.equal(Win.normalize("c:a/b/c/../../../d/e/f"), "c:\\d\\e\\f");
-
-  info("Backslash-separated, UNC-style");
-  Assert.equal(Win.basename("\\\\a\\b"), "b");
-  Assert.equal(Win.basename("\\\\a\\b\\"), "");
-  Assert.equal(Win.basename("\\\\abc"), "");
-  Assert.equal(Win.dirname("\\\\a\\b"), "\\\\a");
-  Assert.equal(Win.dirname("\\\\a\\b\\"), "\\\\a\\b");
-  Assert.equal(Win.dirname("\\\\a\\\\\\\\b"), "\\\\a");
-  Assert.equal(Win.dirname("\\\\abc"), "\\\\abc");
-  Assert.equal(Win.normalize("\\\\a\\b\\c"), "\\\\a\\b\\c");
-  Assert.equal(Win.normalize("\\\\a\\b\\\\\\\\c"), "\\\\a\\b\\c");
-  Assert.equal(Win.normalize("\\\\a\\b\\c\\\\\\"), "\\\\a\\b\\c");
-  Assert.equal(Win.normalize("\\\\a\\b\\c\\..\\..\\d\\e\\f"), "\\\\a\\d\\e\\f");
-  do_check_fail(() => Win.normalize("\\\\a\\b\\c\\..\\..\\..\\d\\e\\f"));
-
-  Assert.equal(Win.join("\\\\a\\tmp", "foo", "bar"), "\\\\a\\tmp\\foo\\bar");
-  Assert.equal(Win.join("\\\\a\\tmp", "\\foo", "bar"), "\\\\a\\foo\\bar");
-  Assert.equal(Win.join("\\\\a\\tmp", "\\\\foo\\", "bar"), "\\\\foo\\bar");
-  Assert.equal(Win.winGetDrive("\\\\"), null);
-  Assert.equal(Win.winGetDrive("\\\\c"), "\\\\c");
-  Assert.equal(Win.winGetDrive("\\\\c\\abc"), "\\\\c");
-
-  info("Testing unix paths");
-  Assert.equal(Unix.basename("a/b"), "b");
-  Assert.equal(Unix.basename("a/b/"), "");
-  Assert.equal(Unix.basename("abc"), "abc");
-  Assert.equal(Unix.dirname("a/b"), "a");
-  Assert.equal(Unix.dirname("a/b/"), "a/b");
-  Assert.equal(Unix.dirname("a////b"), "a");
-  Assert.equal(Unix.dirname("abc"), ".");
-  Assert.equal(Unix.normalize("/a/b/c"), "/a/b/c");
-  Assert.equal(Unix.normalize("/a/b////c"), "/a/b/c");
-  Assert.equal(Unix.normalize("////a/b/c"), "/a/b/c");
-  Assert.equal(Unix.normalize("/a/b/c///"), "/a/b/c");
-  Assert.equal(Unix.normalize("/a/b/c/../../../d/e/f"), "/d/e/f");
-  Assert.equal(Unix.normalize("a/b/c/../../../d/e/f"), "d/e/f");
-  do_check_fail(() => Unix.normalize("/a/b/c/../../../../d/e/f"));
-
-  Assert.equal(
-    Unix.join("/tmp", "foo", "bar"),
-    "/tmp/foo/bar",
-    "join /tmp,foo,bar"
-  );
-  Assert.equal(
-    Unix.join("/tmp", "/foo", "bar"),
-    "/foo/bar",
-    "join /tmp,/foo,bar"
-  );
-
-  info("Testing the presence of ospath.jsm");
-  let scope;
-  try {
-    scope = ChromeUtils.import("resource://gre/modules/osfile/ospath.jsm");
-  } catch (ex) {
-    // Can't load ospath
-  }
-  Assert.ok(!!scope.basename);
-}
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_path_constants.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-const { AppConstants } = ChromeUtils.importESModule(
-  "resource://gre/modules/AppConstants.sys.mjs"
-);
-const { ctypes } = ChromeUtils.importESModule(
-  "resource://gre/modules/ctypes.sys.mjs"
-);
-const { makeFakeAppDir } = ChromeUtils.importESModule(
-  "resource://testing-common/AppData.sys.mjs"
-);
-
-function compare_paths(ospath, key) {
-  let file;
-  try {
-    file = Services.dirsvc.get(key, Ci.nsIFile);
-  } catch (ex) {}
-
-  if (file) {
-    Assert.ok(!!ospath);
-    Assert.equal(ospath, file.path);
-  } else {
-    info(
-      "WARNING: " + key + " is not defined. Test may not be testing anything!"
-    );
-    Assert.ok(!ospath);
-  }
-}
-
-// Test simple paths
-add_task(async function test_simple_paths() {
-  Assert.ok(!!OS.Constants.Path.tmpDir);
-  compare_paths(OS.Constants.Path.tmpDir, "TmpD");
-});
-
-// Some path constants aren't set up until the profile is available. This
-// test verifies that behavior.
-add_task(async function test_before_after_profile() {
-  // On Android the profile is initialized during xpcshell init, so this test
-  // will fail.
-  if (AppConstants.platform != "android") {
-    Assert.equal(null, OS.Constants.Path.profileDir);
-    Assert.equal(null, OS.Constants.Path.localProfileDir);
-    Assert.equal(null, OS.Constants.Path.userApplicationDataDir);
-  }
-
-  do_get_profile();
-  Assert.ok(!!OS.Constants.Path.profileDir);
-  Assert.ok(!!OS.Constants.Path.localProfileDir);
-
-  // UAppData is still null because the xpcshell profile doesn't set it up.
-  // This test is mostly here to fail in case behavior of do_get_profile() ever
-  // changes. We want to know if our assumptions no longer hold!
-  Assert.equal(null, OS.Constants.Path.userApplicationDataDir);
-
-  await makeFakeAppDir();
-  Assert.ok(!!OS.Constants.Path.userApplicationDataDir);
-
-  // FUTURE: verify AppData too (bug 964291).
-});
-
-// Test presence of paths that only exist on Desktop platforms
-add_task(async function test_desktop_paths() {
-  if (OS.Constants.Sys.Name == "Android") {
-    return;
-  }
-  Assert.ok(!!OS.Constants.Path.homeDir);
-
-  compare_paths(OS.Constants.Path.homeDir, "Home");
-  compare_paths(OS.Constants.Path.userApplicationDataDir, "UAppData");
-
-  compare_paths(OS.Constants.Path.macUserLibDir, "ULibDir");
-});
-
-// Open libxul
-add_task(async function test_libxul() {
-  ctypes.open(OS.Constants.Path.libxul);
-  info("Linked to libxul");
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_queue.js
+++ /dev/null
@@ -1,34 +0,0 @@
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-// Check if Scheduler.queue returned by OS.File.queue is resolved initially.
-add_task(async function check_init() {
-  await OS.File.queue;
-  info("Function resolved");
-});
-
-// Check if Scheduler.queue returned by OS.File.queue is resolved
-// after an operation is successful.
-add_task(async function check_success() {
-  info("Attempting to open a file correctly");
-  await OS.File.open(OS.Path.join(do_get_cwd().path, "test_queue.js"));
-  info("File opened correctly");
-  await OS.File.queue;
-  info("Function resolved");
-});
-
-// Check if Scheduler.queue returned by OS.File.queue is resolved
-// after an operation fails.
-add_task(async function check_failure() {
-  let exception;
-  try {
-    info("Attempting to open a non existing file");
-    await OS.File.open(OS.Path.join(".", "Bigfoot"));
-  } catch (err) {
-    exception = err;
-    await OS.File.queue;
-  }
-  Assert.ok(exception != null);
-  info("Function resolved");
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_read_write.js
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var SHARED_PATH;
-
-var EXISTING_FILE = do_get_file("xpcshell.ini").path;
-
-add_task(async function init() {
-  do_get_profile();
-  SHARED_PATH = OS.Path.join(
-    OS.Constants.Path.profileDir,
-    "test_osfile_read.tmp"
-  );
-});
-
-// Check that OS.File.read() is executed after the previous operation
-add_test_pair(async function ordering() {
-  let string1 = "Initial state " + Math.random();
-  let string2 = "After writing " + Math.random();
-  await OS.File.writeAtomic(SHARED_PATH, string1);
-  OS.File.writeAtomic(SHARED_PATH, string2);
-  let string3 = await OS.File.read(SHARED_PATH, { encoding: "utf-8" });
-  Assert.equal(string3, string2);
-});
-
-add_test_pair(async function read_write_all() {
-  let DEST_PATH = SHARED_PATH + Math.random();
-  let TMP_PATH = DEST_PATH + ".tmp";
-
-  let test_with_options = function(options, suffix) {
-    return (async function() {
-      info(
-        "Running test read_write_all with options " + JSON.stringify(options)
-      );
-      let TEST = "read_write_all " + suffix;
-
-      let optionsBackup = JSON.parse(JSON.stringify(options));
-
-      // Check that read + writeAtomic performs a correct copy
-      let currentDir = await OS.File.getCurrentDirectory();
-      let pathSource = OS.Path.join(currentDir, EXISTING_FILE);
-      let contents = await OS.File.read(pathSource);
-      Assert.ok(!!contents); // Content is not empty
-      let bytesRead = contents.byteLength;
-
-      let bytesWritten = await OS.File.writeAtomic(
-        DEST_PATH,
-        contents,
-        options
-      );
-      Assert.equal(bytesRead, bytesWritten); // Correct number of bytes written
-
-      // Check that options are not altered
-      Assert.equal(JSON.stringify(options), JSON.stringify(optionsBackup));
-      await reference_compare_files(pathSource, DEST_PATH, TEST);
-
-      // Check that temporary file was removed or never created exist
-      Assert.ok(!new FileUtils.File(TMP_PATH).exists());
-
-      // Check that writeAtomic fails if noOverwrite is true and the destination
-      // file already exists!
-      contents = new Uint8Array(300);
-      let view = new Uint8Array(contents.buffer, 10, 200);
-      try {
-        let opt = JSON.parse(JSON.stringify(options));
-        opt.noOverwrite = true;
-        await OS.File.writeAtomic(DEST_PATH, view, opt);
-        do_throw(
-          "With noOverwrite, writeAtomic should have refused to overwrite file (" +
-            suffix +
-            ")"
-        );
-      } catch (err) {
-        if (err instanceof OS.File.Error && err.becauseExists) {
-          info(
-            "With noOverwrite, writeAtomic correctly failed (" + suffix + ")"
-          );
-        } else {
-          throw err;
-        }
-      }
-      await reference_compare_files(pathSource, DEST_PATH, TEST);
-
-      // Check that temporary file was removed or never created
-      Assert.ok(!new FileUtils.File(TMP_PATH).exists());
-
-      // Now write a subset
-      let START = 10;
-      let LENGTH = 100;
-      contents = new Uint8Array(300);
-      for (let i = 0; i < contents.byteLength; i++) {
-        contents[i] = i % 256;
-      }
-      view = new Uint8Array(contents.buffer, START, LENGTH);
-      bytesWritten = await OS.File.writeAtomic(DEST_PATH, view, options);
-      Assert.equal(bytesWritten, LENGTH);
-
-      let array2 = await OS.File.read(DEST_PATH);
-      Assert.equal(LENGTH, array2.length);
-      for (let j = 0; j < LENGTH; j++) {
-        Assert.equal(array2[j], (j + START) % 256);
-      }
-
-      // Cleanup.
-      await OS.File.remove(DEST_PATH);
-      await OS.File.remove(TMP_PATH);
-    })();
-  };
-
-  await test_with_options({ tmpPath: TMP_PATH }, "Renaming, not flushing");
-  await test_with_options(
-    { tmpPath: TMP_PATH, flush: true },
-    "Renaming, flushing"
-  );
-  await test_with_options({}, "Not renaming, not flushing");
-  await test_with_options({ flush: true }, "Not renaming, flushing");
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_remove.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-registerCleanupFunction(function() {
-  Services.prefs.setBoolPref("toolkit.osfile.log", false);
-});
-
-function run_test() {
-  Services.prefs.setBoolPref("toolkit.osfile.log", true);
-  run_next_test();
-}
-
-add_task(async function test_ignoreAbsent() {
-  let absent_file_name = "test_osfile_front_absent.tmp";
-
-  // Removing absent files should throw if "ignoreAbsent" is true.
-  await Assert.rejects(
-    OS.File.remove(absent_file_name, { ignoreAbsent: false }),
-    err => err.operation == "remove",
-    "OS.File.remove throws if there is no such file."
-  );
-
-  // Removing absent files should not throw if "ignoreAbsent" is true or not
-  // defined.
-  let exception = null;
-  try {
-    await OS.File.remove(absent_file_name, { ignoreAbsent: true });
-    await OS.File.remove(absent_file_name);
-  } catch (ex) {
-    exception = ex;
-  }
-  Assert.ok(!exception, "OS.File.remove should not throw when not requested.");
-});
-
-add_task(async function test_ignoreAbsent_directory_missing() {
-  let absent_file_name = OS.Path.join("absent_parent", "test.tmp");
-
-  // Removing absent files should throw if "ignoreAbsent" is true.
-  await Assert.rejects(
-    OS.File.remove(absent_file_name, { ignoreAbsent: false }),
-    err => err.operation == "remove",
-    "OS.File.remove throws if there is no such file."
-  );
-
-  // Removing files from absent directories should not throw if "ignoreAbsent"
-  // is true or not defined.
-  let exception = null;
-  try {
-    await OS.File.remove(absent_file_name, { ignoreAbsent: true });
-    await OS.File.remove(absent_file_name);
-  } catch (ex) {
-    exception = ex;
-  }
-  Assert.ok(!exception, "OS.File.remove should not throw when not requested.");
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_removeDir.js
+++ /dev/null
@@ -1,177 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-registerCleanupFunction(function() {
-  Services.prefs.setBoolPref("toolkit.osfile.log", false);
-});
-
-function run_test() {
-  Services.prefs.setBoolPref("toolkit.osfile.log", true);
-
-  run_next_test();
-}
-
-add_task(async function() {
-  // Set up profile. We create the directory in the profile, because the profile
-  // is removed after every test run.
-  do_get_profile();
-
-  let file = OS.Path.join(OS.Constants.Path.profileDir, "file");
-  let dir = OS.Path.join(OS.Constants.Path.profileDir, "directory");
-  let file1 = OS.Path.join(dir, "file1");
-  let file2 = OS.Path.join(dir, "file2");
-  let subDir = OS.Path.join(dir, "subdir");
-  let fileInSubDir = OS.Path.join(subDir, "file");
-
-  // Sanity checking for the test
-  Assert.equal(false, await OS.File.exists(dir));
-
-  // Remove non-existent directory
-  let exception = null;
-  try {
-    await OS.File.removeDir(dir, { ignoreAbsent: false });
-  } catch (ex) {
-    exception = ex;
-  }
-
-  Assert.ok(!!exception);
-  Assert.ok(exception instanceof OS.File.Error);
-
-  // Remove non-existent directory with ignoreAbsent
-  await OS.File.removeDir(dir, { ignoreAbsent: true });
-  await OS.File.removeDir(dir);
-
-  // Remove file with ignoreAbsent: false
-  await OS.File.writeAtomic(file, "content", { tmpPath: file + ".tmp" });
-  exception = null;
-  try {
-    await OS.File.removeDir(file, { ignoreAbsent: false });
-  } catch (ex) {
-    exception = ex;
-  }
-
-  Assert.ok(!!exception);
-  Assert.ok(exception instanceof OS.File.Error);
-
-  // Remove empty directory
-  await OS.File.makeDir(dir);
-  await OS.File.removeDir(dir);
-  Assert.equal(false, await OS.File.exists(dir));
-
-  // Remove directory that contains one file
-  await OS.File.makeDir(dir);
-  await OS.File.writeAtomic(file1, "content", { tmpPath: file1 + ".tmp" });
-  await OS.File.removeDir(dir);
-  Assert.equal(false, await OS.File.exists(dir));
-
-  // Remove directory that contains multiple files
-  await OS.File.makeDir(dir);
-  await OS.File.writeAtomic(file1, "content", { tmpPath: file1 + ".tmp" });
-  await OS.File.writeAtomic(file2, "content", { tmpPath: file2 + ".tmp" });
-  await OS.File.removeDir(dir);
-  Assert.equal(false, await OS.File.exists(dir));
-
-  // Remove directory that contains a file and a directory
-  await OS.File.makeDir(dir);
-  await OS.File.writeAtomic(file1, "content", { tmpPath: file1 + ".tmp" });
-  await OS.File.makeDir(subDir);
-  await OS.File.writeAtomic(fileInSubDir, "content", {
-    tmpPath: fileInSubDir + ".tmp",
-  });
-  await OS.File.removeDir(dir);
-  Assert.equal(false, await OS.File.exists(dir));
-});
-
-add_task(async function test_unix_symlink() {
-  // Windows does not implement OS.File.unixSymLink()
-  if (OS.Constants.Win) {
-    return;
-  }
-
-  // Android / B2G file systems typically don't support symlinks.
-  if (OS.Constants.Sys.Name == "Android") {
-    return;
-  }
-
-  let file = OS.Path.join(OS.Constants.Path.profileDir, "file");
-  let dir = OS.Path.join(OS.Constants.Path.profileDir, "directory");
-  let file1 = OS.Path.join(dir, "file1");
-
-  // This test will create the following directory structure:
-  // <profileDir>/file                             (regular file)
-  // <profileDir>/file.link => file                (symlink)
-  // <profileDir>/directory                        (directory)
-  // <profileDir>/linkdir => directory             (directory)
-  // <profileDir>/directory/file1                  (regular file)
-  // <profileDir>/directory3                       (directory)
-  // <profileDir>/directory3/file3                 (directory)
-  // <profileDir>/directory/link2 => ../directory3 (regular file)
-
-  // Sanity checking for the test
-  Assert.equal(false, await OS.File.exists(dir));
-
-  await OS.File.writeAtomic(file, "content", { tmpPath: file + ".tmp" });
-  Assert.ok(await OS.File.exists(file));
-  let info = await OS.File.stat(file, { unixNoFollowingLinks: true });
-  Assert.ok(!info.isDir);
-  Assert.ok(!info.isSymLink);
-
-  await OS.File.unixSymLink(file, file + ".link");
-  Assert.ok(await OS.File.exists(file + ".link"));
-  info = await OS.File.stat(file + ".link", { unixNoFollowingLinks: true });
-  Assert.ok(!info.isDir);
-  Assert.ok(info.isSymLink);
-  info = await OS.File.stat(file + ".link");
-  Assert.ok(!info.isDir);
-  Assert.ok(!info.isSymLink);
-  await OS.File.remove(file + ".link");
-  Assert.equal(false, await OS.File.exists(file + ".link"));
-
-  await OS.File.makeDir(dir);
-  Assert.ok(await OS.File.exists(dir));
-  info = await OS.File.stat(dir, { unixNoFollowingLinks: true });
-  Assert.ok(info.isDir);
-  Assert.ok(!info.isSymLink);
-
-  let link = OS.Path.join(OS.Constants.Path.profileDir, "linkdir");
-
-  await OS.File.unixSymLink(dir, link);
-  Assert.ok(await OS.File.exists(link));
-  info = await OS.File.stat(link, { unixNoFollowingLinks: true });
-  Assert.ok(!info.isDir);
-  Assert.ok(info.isSymLink);
-  info = await OS.File.stat(link);
-  Assert.ok(info.isDir);
-  Assert.ok(!info.isSymLink);
-
-  let dir3 = OS.Path.join(OS.Constants.Path.profileDir, "directory3");
-  let file3 = OS.Path.join(dir3, "file3");
-  let link2 = OS.Path.join(dir, "link2");
-
-  await OS.File.writeAtomic(file1, "content", { tmpPath: file1 + ".tmp" });
-  Assert.ok(await OS.File.exists(file1));
-  await OS.File.makeDir(dir3);
-  Assert.ok(await OS.File.exists(dir3));
-  await OS.File.writeAtomic(file3, "content", { tmpPath: file3 + ".tmp" });
-  Assert.ok(await OS.File.exists(file3));
-  await OS.File.unixSymLink("../directory3", link2);
-  Assert.ok(await OS.File.exists(link2));
-
-  await OS.File.removeDir(link);
-  Assert.equal(false, await OS.File.exists(link));
-  Assert.ok(await OS.File.exists(file1));
-  await OS.File.removeDir(dir);
-  Assert.equal(false, await OS.File.exists(dir));
-  Assert.ok(await OS.File.exists(file3));
-  await OS.File.removeDir(dir3);
-  Assert.equal(false, await OS.File.exists(dir3));
-
-  // This task will be executed only on Unix-like systems.
-  // Please do not add tests independent to operating systems here
-  // or implement symlink() on Windows.
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_removeEmptyDir.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-registerCleanupFunction(function() {
-  Services.prefs.setBoolPref("toolkit.osfile.log", false);
-});
-
-function run_test() {
-  Services.prefs.setBoolPref("toolkit.osfile.log", true);
-
-  run_next_test();
-}
-
-/**
- * Test OS.File.removeEmptyDir
- */
-add_task(async function() {
-  // Set up profile. We create the directory in the profile, because the profile
-  // is removed after every test run.
-  do_get_profile();
-
-  let dir = OS.Path.join(OS.Constants.Path.profileDir, "directory");
-
-  // Sanity checking for the test
-  Assert.equal(false, await OS.File.exists(dir));
-
-  // Remove non-existent directory
-  await OS.File.removeEmptyDir(dir);
-
-  // Remove non-existent directory with ignoreAbsent
-  await OS.File.removeEmptyDir(dir, { ignoreAbsent: true });
-
-  // Remove non-existent directory with ignoreAbsent false
-  let exception = null;
-  try {
-    await OS.File.removeEmptyDir(dir, { ignoreAbsent: false });
-  } catch (ex) {
-    exception = ex;
-  }
-
-  Assert.ok(!!exception);
-  Assert.ok(exception instanceof OS.File.Error);
-  Assert.ok(exception.becauseNoSuchFile);
-
-  // Remove empty directory
-  await OS.File.makeDir(dir);
-  await OS.File.removeEmptyDir(dir);
-  Assert.equal(false, await OS.File.exists(dir));
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_reset.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var Path = OS.Constants.Path;
-
-add_task(async function init() {
-  do_get_profile();
-});
-
-add_task(async function reset_before_launching() {
-  info("Reset without launching OS.File, it shouldn't break");
-  await OS.File.resetWorker();
-});
-
-add_task(async function transparent_reset() {
-  for (let i = 1; i < 3; ++i) {
-    info(
-      "Do stome stuff before and after " +
-        i +
-        " reset(s), " +
-        "it shouldn't break"
-    );
-    let CONTENT = "some content " + i;
-    let path = OS.Path.join(Path.profileDir, "tmp");
-    await OS.File.writeAtomic(path, CONTENT);
-    for (let j = 0; j < i; ++j) {
-      await OS.File.resetWorker();
-    }
-    let data = await OS.File.read(path);
-    let string = new TextDecoder().decode(data);
-    Assert.equal(string, CONTENT);
-  }
-});
-
-add_task(async function file_open_cannot_reset() {
-  let TEST_FILE = OS.Path.join(Path.profileDir, "tmp-" + Math.random());
-  info(
-    "Leaking file descriptor " + TEST_FILE + ", we shouldn't be able to reset"
-  );
-  let openedFile = await OS.File.open(TEST_FILE, { create: true });
-  let thrown = false;
-  try {
-    await OS.File.resetWorker();
-  } catch (ex) {
-    if (ex.message.includes(OS.Path.basename(TEST_FILE))) {
-      thrown = true;
-    } else {
-      throw ex;
-    }
-  }
-  Assert.ok(thrown);
-
-  info("Closing the file, we should now be able to reset");
-  await openedFile.close();
-  await OS.File.resetWorker();
-});
-
-add_task(async function dir_open_cannot_reset() {
-  let TEST_DIR = await OS.File.getCurrentDirectory();
-  info("Leaking directory " + TEST_DIR + ", we shouldn't be able to reset");
-  let iterator = new OS.File.DirectoryIterator(TEST_DIR);
-  let thrown = false;
-  try {
-    await OS.File.resetWorker();
-  } catch (ex) {
-    if (ex.message.includes(OS.Path.basename(TEST_DIR))) {
-      thrown = true;
-    } else {
-      throw ex;
-    }
-  }
-  Assert.ok(thrown);
-
-  info("Closing the directory, we should now be able to reset");
-  await iterator.close();
-  await OS.File.resetWorker();
-});
-
-add_task(async function race_against_itself() {
-  info("Attempt to get resetWorker() to race against itself");
-  // Arbitrary operation, just to wake up the worker
-  try {
-    await OS.File.read("/foo");
-  } catch (ex) {}
-
-  let all = [];
-  for (let i = 0; i < 100; ++i) {
-    all.push(OS.File.resetWorker());
-  }
-
-  await Promise.all(all);
-});
-
-add_task(async function finish_with_a_reset() {
-  info("Reset without waiting for the result");
-  // Arbitrary operation, just to wake up the worker
-  try {
-    await OS.File.read("/foo");
-  } catch (ex) {}
-  // Now reset
-  /* don't yield*/ OS.File.resetWorker();
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_shutdown.js
+++ /dev/null
@@ -1,103 +0,0 @@
-const { PromiseUtils } = ChromeUtils.importESModule(
-  "resource://gre/modules/PromiseUtils.sys.mjs"
-);
-
-add_task(function init() {
-  do_get_profile();
-});
-
-/**
- * Test logging of file descriptors leaks.
- */
-add_task(async function system_shutdown() {
-  // Test that unclosed files cause warnings
-  // Test that unclosed directories cause warnings
-  // Test that closed files do not cause warnings
-  // Test that closed directories do not cause warnings
-  function testLeaksOf(resource, topic) {
-    return (async function() {
-      let deferred = PromiseUtils.defer();
-
-      // Register observer
-      Services.prefs.setBoolPref("toolkit.asyncshutdown.testing", true);
-      Services.prefs.setBoolPref("toolkit.osfile.log", true);
-      Services.prefs.setBoolPref("toolkit.osfile.log.redirect", true);
-      Services.prefs.setCharPref(
-        "toolkit.osfile.test.shutdown.observer",
-        topic
-      );
-
-      let observer = function(aMessage) {
-        try {
-          info("Got message: " + aMessage);
-          if (!(aMessage instanceof Ci.nsIConsoleMessage)) {
-            return;
-          }
-          let message = aMessage.message;
-          info("Got message: " + message);
-          if (!message.includes("TEST OS Controller WARNING")) {
-            return;
-          }
-          info(
-            "Got message: " + message + ", looking for resource " + resource
-          );
-          if (!message.includes(resource)) {
-            return;
-          }
-          info("Resource: " + resource + " found");
-          executeSoon(deferred.resolve);
-        } catch (ex) {
-          executeSoon(function() {
-            deferred.reject(ex);
-          });
-        }
-      };
-      Services.console.registerListener(observer);
-      Services.obs.notifyObservers(null, topic);
-      do_timeout(1000, function() {
-        info("Timeout while waiting for resource: " + resource);
-        deferred.reject("timeout");
-      });
-
-      let resolved = false;
-      try {
-        await deferred.promise;
-        resolved = true;
-      } catch (ex) {
-        if (ex == "timeout") {
-          resolved = false;
-        } else {
-          throw ex;
-        }
-      }
-      Services.console.unregisterListener(observer);
-      Services.prefs.clearUserPref("toolkit.osfile.log");
-      Services.prefs.clearUserPref("toolkit.osfile.log.redirect");
-      Services.prefs.clearUserPref("toolkit.osfile.test.shutdown.observer");
-      Services.prefs.clearUserPref("toolkit.async_shutdown.testing");
-
-      return resolved;
-    })();
-  }
-
-  let TEST_DIR = OS.Path.join(await OS.File.getCurrentDirectory(), "..");
-  info("Testing for leaks of directory iterator " + TEST_DIR);
-  let iterator = new OS.File.DirectoryIterator(TEST_DIR);
-  info("At this stage, we leak the directory");
-  Assert.ok(await testLeaksOf(TEST_DIR, "test.shutdown.dir.leak"));
-  await iterator.close();
-  info("At this stage, we don't leak the directory anymore");
-  Assert.equal(false, await testLeaksOf(TEST_DIR, "test.shutdown.dir.noleak"));
-
-  let TEST_FILE = OS.Path.join(OS.Constants.Path.profileDir, "test");
-  info("Testing for leaks of file descriptor: " + TEST_FILE);
-  let openedFile = await OS.File.open(TEST_FILE, { create: true });
-  info("At this stage, we leak the file");
-  Assert.ok(await testLeaksOf(TEST_FILE, "test.shutdown.file.leak"));
-  await openedFile.close();
-  info("At this stage, we don't leak the file anymore");
-  Assert.equal(
-    false,
-    await testLeaksOf(TEST_FILE, "test.shutdown.file.leak.2")
-  );
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_telemetry.js
+++ /dev/null
@@ -1,61 +0,0 @@
-"use strict";
-
-var {
-  OS: { File, Path, Constants },
-} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-// Ensure that we have a profile but that the OS.File worker is not launched
-add_task(async function init() {
-  do_get_profile();
-  await File.resetWorker();
-});
-
-function getCount(histogram) {
-  if (histogram == null) {
-    return 0;
-  }
-
-  let total = 0;
-  for (let i of Object.values(histogram.values)) {
-    total += i;
-  }
-  return total;
-}
-
-// Ensure that launching the OS.File worker adds data to the relevant
-// histograms
-add_task(async function test_startup() {
-  let LAUNCH = "OSFILE_WORKER_LAUNCH_MS";
-  let READY = "OSFILE_WORKER_READY_MS";
-
-  let before = Services.telemetry.getSnapshotForHistograms("main", false)
-    .parent;
-
-  // Launch the OS.File worker
-  await File.getCurrentDirectory();
-
-  let after = Services.telemetry.getSnapshotForHistograms("main", false).parent;
-
-  info("Ensuring that we have recorded measures for histograms");
-  Assert.equal(getCount(after[LAUNCH]), getCount(before[LAUNCH]) + 1);
-  Assert.equal(getCount(after[READY]), getCount(before[READY]) + 1);
-
-  info("Ensuring that launh <= ready");
-  Assert.ok(after[LAUNCH].sum <= after[READY].sum);
-});
-
-// Ensure that calling writeAtomic adds data to the relevant histograms
-add_task(async function test_writeAtomic() {
-  let LABEL = "OSFILE_WRITEATOMIC_JANK_MS";
-
-  let before = Services.telemetry.getSnapshotForHistograms("main", false)
-    .parent;
-
-  // Perform a write.
-  let path = Path.join(Constants.Path.profileDir, "test_osfile_telemetry.tmp");
-  await File.writeAtomic(path, LABEL, { tmpPath: path + ".tmp" });
-
-  let after = Services.telemetry.getSnapshotForHistograms("main", false).parent;
-
-  Assert.equal(getCount(after[LABEL]), getCount(before[LABEL]) + 1);
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/test_unique.js
+++ /dev/null
@@ -1,87 +0,0 @@
-"use strict";
-
-const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
-
-function run_test() {
-  do_get_profile();
-  run_next_test();
-}
-
-function testFiles(filename) {
-  return (async function() {
-    const MAX_TRIES = 10;
-    let profileDir = OS.Constants.Path.profileDir;
-    let path = OS.Path.join(profileDir, filename);
-
-    // Ensure that openUnique() uses the file name if there is no file with that name already.
-    let openedFile = await OS.File.openUnique(path);
-    info("\nCreate new file: " + openedFile.path);
-    await openedFile.file.close();
-    let exists = await OS.File.exists(openedFile.path);
-    Assert.ok(exists);
-    Assert.equal(path, openedFile.path);
-    let fileInfo = await OS.File.stat(openedFile.path);
-    Assert.ok(fileInfo.size == 0);
-
-    // Ensure that openUnique() creates a new file name using a HEX number, as the original name is already taken.
-    openedFile = await OS.File.openUnique(path);
-    info("\nCreate unique HEX file: " + openedFile.path);
-    await openedFile.file.close();
-    exists = await OS.File.exists(openedFile.path);
-    Assert.ok(exists);
-    fileInfo = await OS.File.stat(openedFile.path);
-    Assert.ok(fileInfo.size == 0);
-
-    // Ensure that openUnique() generates different file names each time, using the HEX number algorithm
-    let filenames = new Set();
-    for (let i = 0; i < MAX_TRIES; i++) {
-      openedFile = await OS.File.openUnique(path);
-      await openedFile.file.close();
-      filenames.add(openedFile.path);
-    }
-
-    Assert.equal(filenames.size, MAX_TRIES);
-
-    // Ensure that openUnique() creates a new human readable file name using, as the original name is already taken.
-    openedFile = await OS.File.openUnique(path, { humanReadable: true });
-    info("\nCreate unique Human Readable file: " + openedFile.path);
-    await openedFile.file.close();
-    exists = await OS.File.exists(openedFile.path);
-    Assert.ok(exists);
-    fileInfo = await OS.File.stat(openedFile.path);
-    Assert.ok(fileInfo.size == 0);
-
-    // Ensure that openUnique() generates different human readable file names each time
-    filenames = new Set();
-    for (let i = 0; i < MAX_TRIES; i++) {
-      openedFile = await OS.File.openUnique(path, { humanReadable: true });
-      await openedFile.file.close();
-      filenames.add(openedFile.path);
-    }
-
-    Assert.equal(filenames.size, MAX_TRIES);
-
-    let exn;
-    try {
-      for (let i = 0; i < 100; i++) {
-        openedFile = await OS.File.openUnique(path, { humanReadable: true });
-        await openedFile.file.close();
-      }
-    } catch (ex) {
-      exn = ex;
-    }
-
-    info("Ensure that this raises the correct error");
-    Assert.ok(!!exn);
-    Assert.ok(exn instanceof OS.File.Error);
-    Assert.ok(exn.becauseExists);
-  })();
-}
-
-add_task(async function test_unique() {
-  OS.Shared.DEBUG = true;
-  // Tests files with extension
-  await testFiles("dummy_unique_file.txt");
-  // Tests files with no extension
-  await testFiles("dummy_unique_file_no_ext");
-});
deleted file mode 100644
--- a/toolkit/components/osfile/tests/xpcshell/xpcshell.ini
+++ /dev/null
@@ -1,48 +0,0 @@
-[DEFAULT]
-head = head.js
-
-[test_compression.js]
-[test_constants.js]
-[test_duration.js]
-[test_exception.js]
-[test_file_URL_conversion.js]
-[test_logging.js]
-[test_makeDir.js]
-[test_open.js]
-[test_osfile_async.js]
-[test_osfile_async_append.js]
-[test_osfile_async_bytes.js]
-[test_osfile_async_copy.js]
-[test_osfile_async_flush.js]
-[test_osfile_async_largefiles.js]
-[test_osfile_async_setDates.js]
-# Unimplemented on Windows (bug 1022816).
-# Spurious failure on Android test farm due to non-POSIX behavior of
-# filesystem backing /mnt/sdcard (not worth trying to fix).
-[test_osfile_async_setPermissions.js]
-skip-if = os == "win" || os == "android"
-[test_osfile_closed.js]
-[test_osfile_error.js]
-[test_osfile_kill.js]
-# Windows test
-[test_osfile_win_async_setPermissions.js]
-skip-if = os != "win"
-[test_osfile_writeAtomic_backupTo_option.js]
-[test_osfile_writeAtomic_zerobytes.js]
-[test_osfile_writeAtomic_unicode_filename.js]
-[test_path.js]
-[test_path_constants.js]
-[test_queue.js]
-[test_read_write.js]
-requesttimeoutfactor = 4
-[test_remove.js]
-[test_removeDir.js]
-requesttimeoutfactor = 4
-[test_removeEmptyDir.js]
-[test_reset.js]
-[test_shutdown.js]
-[test_telemetry.js]
-# On Android, we use OS.File during xpcshell initialization, so the expected
-# telemetry cannot be observed.
-skip-if = toolkit == "android"
-[test_unique.js]
--- a/tools/esmify/map.json
+++ b/tools/esmify/map.json
@@ -852,25 +852,16 @@
   "resource://gre/modules/mozIntl.jsm": "toolkit/components/mozintl/mozIntl.jsm",
   "resource://gre/modules/narrate/NarrateControls.jsm": "toolkit/components/narrate/NarrateControls.jsm",
   "resource://gre/modules/narrate/Narrator.jsm": "toolkit/components/narrate/Narrator.jsm",
   "resource://gre/modules/narrate/VoiceSelect.jsm": "toolkit/components/narrate/VoiceSelect.jsm",
   "resource://gre/modules/netwerk-dns/PublicSuffixList.jsm": "netwerk/dns/PublicSuffixList.jsm",
   "resource://gre/modules/nsAsyncShutdown.jsm": "toolkit/components/asyncshutdown/nsAsyncShutdown.jsm",
   "resource://gre/modules/nsCrashMonitor.jsm": "toolkit/components/crashmonitor/nsCrashMonitor.jsm",
   "resource://gre/modules/nsFormAutoCompleteResult.jsm": "toolkit/components/satchel/nsFormAutoCompleteResult.jsm",
-  "resource://gre/modules/osfile.jsm": "toolkit/components/osfile/osfile.jsm",
-  "resource://gre/modules/osfile/osfile_async_front.jsm": "toolkit/components/osfile/modules/osfile_async_front.jsm",
-  "resource://gre/modules/osfile/osfile_native.jsm": "toolkit/components/osfile/modules/osfile_native.jsm",
-  "resource://gre/modules/osfile/osfile_shared_allthreads.jsm": "toolkit/components/osfile/modules/osfile_shared_allthreads.jsm",
-  "resource://gre/modules/osfile/osfile_unix_allthreads.jsm": "toolkit/components/osfile/modules/osfile_unix_allthreads.jsm",
-  "resource://gre/modules/osfile/osfile_win_allthreads.jsm": "toolkit/components/osfile/modules/osfile_win_allthreads.jsm",
-  "resource://gre/modules/osfile/ospath.jsm": "toolkit/components/osfile/modules/ospath.jsm",
-  "resource://gre/modules/osfile/ospath_unix.jsm": "toolkit/components/osfile/modules/ospath_unix.jsm",
-  "resource://gre/modules/osfile/ospath_win.jsm": "toolkit/components/osfile/modules/ospath_win.jsm",
   "resource://gre/modules/pdfjs.js": "toolkit/components/pdfjs/pdfjs.js",
   "resource://gre/modules/policies/WindowsGPOParser.jsm": "toolkit/components/enterprisepolicies/WindowsGPOParser.jsm",
   "resource://gre/modules/policies/macOSPoliciesParser.jsm": "toolkit/components/enterprisepolicies/macOSPoliciesParser.jsm",
   "resource://gre/modules/psm/DER.jsm": "security/manager/ssl/DER.jsm",
   "resource://gre/modules/psm/RemoteSecuritySettings.jsm": "security/manager/ssl/RemoteSecuritySettings.jsm",
   "resource://gre/modules/psm/X509.jsm": "security/manager/ssl/X509.jsm",
   "resource://gre/modules/reader/ReaderWorker.jsm": "toolkit/components/reader/ReaderWorker.jsm",
   "resource://gre/modules/reflect.jsm": "toolkit/components/reflect/reflect.jsm",
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js
@@ -164,17 +164,16 @@ module.exports = {
     "mozilla/no-useless-parameters": "error",
     "mozilla/no-useless-removeEventListener": "error",
     "mozilla/prefer-boolean-length-check": "error",
     "mozilla/prefer-formatValues": "error",
     "mozilla/reject-addtask-only": "error",
     "mozilla/reject-chromeutils-import-params": "error",
     "mozilla/reject-importGlobalProperties": ["error", "allownonwebidl"],
     "mozilla/reject-multiple-getters-calls": "error",
-    "mozilla/reject-osfile": "warn",
     "mozilla/reject-scriptableunicodeconverter": "warn",
     "mozilla/rejects-requires-await": "error",
     "mozilla/use-cc-etc": "error",
     "mozilla/use-chromeutils-generateqi": "error",
     "mozilla/use-chromeutils-import": "error",
     "mozilla/use-default-preference-values": "error",
     "mozilla/use-includes-instead-of-indexOf": "error",
     "mozilla/use-isInstance": "error",
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
@@ -67,17 +67,16 @@ module.exports = {
     "reject-eager-module-in-lazy-getter": require("../lib/rules/reject-eager-module-in-lazy-getter"),
     "reject-global-this": require("../lib/rules/reject-global-this"),
     "reject-globalThis-modification": require("../lib/rules/reject-globalThis-modification"),
     "reject-import-system-module-from-non-system": require("../lib/rules/reject-import-system-module-from-non-system"),
     "reject-importGlobalProperties": require("../lib/rules/reject-importGlobalProperties"),
     "reject-lazy-imports-into-globals": require("../lib/rules/reject-lazy-imports-into-globals"),
     "reject-mixing-eager-and-lazy": require("../lib/rules/reject-mixing-eager-and-lazy"),
     "reject-multiple-getters-calls": require("../lib/rules/reject-multiple-getters-calls"),
-    "reject-osfile": require("../lib/rules/reject-osfile"),
     "reject-scriptableunicodeconverter": require("../lib/rules/reject-scriptableunicodeconverter"),
     "reject-relative-requires": require("../lib/rules/reject-relative-requires"),
     "reject-some-requires": require("../lib/rules/reject-some-requires"),
     "reject-top-level-await": require("../lib/rules/reject-top-level-await"),
     "rejects-requires-await": require("../lib/rules/rejects-requires-await"),
     "use-cc-etc": require("../lib/rules/use-cc-etc"),
     "use-chromeutils-generateqi": require("../lib/rules/use-chromeutils-generateqi"),
     "use-chromeutils-import": require("../lib/rules/use-chromeutils-import"),
deleted file mode 100644
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-osfile.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * @fileoverview Reject calls into OS.File. We're phasing this out in
- * favour of IOUtils.
- *
- * 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/.
- */
-
-"use strict";
-
-const { maybeGetMemberPropertyName } = require("../helpers");
-
-function isIdentifier(node, id) {
-  return node && node.type === "Identifier" && node.name === id;
-}
-
-function isOSProp(expr, prop) {
-  return (
-    maybeGetMemberPropertyName(expr.object) === "OS" &&
-    isIdentifier(expr.property, prop)
-  );
-}
-
-module.exports = {
-  meta: {
-    docs: {
-      url:
-        "https://firefox-source-docs.mozilla.org/code-quality/lint/linters/eslint-plugin-mozilla/reject-osfile.html",
-    },
-    schema: [],
-    type: "problem",
-  },
-
-  create(context) {
-    return {
-      MemberExpression(node) {
-        if (isOSProp(node, "File")) {
-          context.report({
-            node,
-            message: "OS.File is deprecated. You should use IOUtils instead.",
-          });
-        } else if (isOSProp(node, "Path")) {
-          context.report({
-            node,
-            message: "OS.Path is deprecated. You should use PathUtils instead.",
-          });
-        }
-      },
-    };
-  },
-};
deleted file mode 100644
--- a/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-osfile.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// ------------------------------------------------------------------------------
-// Requirements
-// ------------------------------------------------------------------------------
-
-var rule = require("../lib/rules/reject-osfile");
-var RuleTester = require("eslint").RuleTester;
-
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: "latest" } });
-
-// ------------------------------------------------------------------------------
-// Tests
-// ------------------------------------------------------------------------------
-
-function invalidError(os, util) {
-  let message = `${os} is deprecated. You should use ${util} instead.`;
-  return [{ message, type: "MemberExpression" }];
-}
-
-ruleTester.run("reject-osfile", rule, {
-  valid: ["IOUtils.write()"],
-  invalid: [
-    {
-      code: "OS.File.write()",
-      errors: invalidError("OS.File", "IOUtils"),
-    },
-    {
-      code: "lazy.OS.File.write()",
-      errors: invalidError("OS.File", "IOUtils"),
-    },
-  ],
-});
-
-ruleTester.run("reject-osfile", rule, {
-  valid: ["PathUtils.join()"],
-  invalid: [
-    {
-      code: "OS.Path.join()",
-      errors: invalidError("OS.Path", "PathUtils"),
-    },
-    {
-      code: "lazy.OS.Path.join()",
-      errors: invalidError("OS.Path", "PathUtils"),
-    },
-  ],
-});