Bug 1063962 - Replace jschar typedef with C++11 char16_t type. r=jandem
authorChris Peterson <cpeterson@mozilla.com>
Mon, 21 Jul 2014 21:43:21 -0700
changeset 204242 4663c05c869cfa1b6db2e8a82c81f1c7ce28c75b
parent 204241 004e5559149907ed0d326ee3f0f3e0b17ba08677
child 204243 22eb7571af8e9dd3415ff5bfb3fabc3361556d1f
push id27452
push usercbook@mozilla.com
push dateTue, 09 Sep 2014 13:57:12 +0000
treeherdermozilla-central@2eaf94a4f837 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1063962
milestone35.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 1063962 - Replace jschar typedef with C++11 char16_t type. r=jandem
addon-sdk/source/lib/sdk/system/child_process/subprocess.js
browser/components/preferences/advanced.js
content/base/src/nsContentUtils.cpp
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsScriptLoader.cpp
content/base/src/nsScriptLoader.h
content/base/src/nsXMLHttpRequest.cpp
content/xul/document/src/XULDocument.h
dom/asmjscache/AsmJSCache.cpp
dom/asmjscache/AsmJSCache.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsJSEnvironment.cpp
dom/bindings/BindingDeclarations.h
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/Codegen.py
dom/bindings/DOMJSProxyHandler.h
dom/crypto/WebCryptoTask.cpp
dom/indexedDB/KeyPath.cpp
dom/ipc/TabChild.cpp
dom/json/nsJSON.cpp
dom/plugins/test/mochitest/dialog_watcher.js
dom/plugins/test/mochitest/hangui_iface.js
dom/wifi/WifiUtils.cpp
dom/workers/ChromeWorkerScope.cpp
dom/workers/RuntimeService.cpp
dom/workers/ScriptLoader.cpp
dom/xbl/nsXBLProtoImpl.cpp
dom/xbl/nsXBLProtoImplField.cpp
dom/xbl/nsXBLProtoImplMethod.cpp
dom/xbl/nsXBLProtoImplProperty.cpp
js/ipc/JavaScriptShared.cpp
js/public/Anchor.h
js/public/CharacterEncoding.h
js/public/Class.h
js/public/GCAPI.h
js/public/OldDebugAPI.h
js/public/TypeDecls.h
js/public/UbiNode.h
js/src/asmjs/AsmJSLink.cpp
js/src/asmjs/AsmJSModule.cpp
js/src/builtin/Eval.cpp
js/src/builtin/Intl.cpp
js/src/builtin/Intl.h
js/src/builtin/Object.cpp
js/src/builtin/RegExp.cpp
js/src/builtin/TestingFunctions.cpp
js/src/ctypes/CTypes.cpp
js/src/ctypes/CTypes.h
js/src/ctypes/typedefs.h
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/BytecodeCompiler.h
js/src/frontend/ParseNode.cpp
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/frontend/TokenStream.cpp
js/src/frontend/TokenStream.h
js/src/gc/Statistics.cpp
js/src/gc/Statistics.h
js/src/gdb/README
js/src/gdb/TODO
js/src/gdb/mozilla/JSString.py
js/src/irregexp/NativeRegExpMacroAssembler.cpp
js/src/irregexp/NativeRegExpMacroAssembler.h
js/src/irregexp/RegExpAST.h
js/src/irregexp/RegExpEngine.cpp
js/src/irregexp/RegExpEngine.h
js/src/irregexp/RegExpInterpreter.cpp
js/src/irregexp/RegExpMacroAssembler.cpp
js/src/irregexp/RegExpMacroAssembler.h
js/src/irregexp/RegExpParser.cpp
js/src/irregexp/RegExpParser.h
js/src/jit/CodeGenerator.cpp
js/src/jit/MCallOptimize.cpp
js/src/jit/VMFunctions.cpp
js/src/jsapi-tests/testExternalStrings.cpp
js/src/jsapi-tests/testIndexToString.cpp
js/src/jsapi-tests/testOOM.cpp
js/src/jsapi-tests/testOriginPrincipals.cpp
js/src/jsapi-tests/testParseJSON.cpp
js/src/jsapi-tests/testScriptInfo.cpp
js/src/jsapi-tests/testScriptObject.cpp
js/src/jsapi-tests/testUTF8.cpp
js/src/jsapi-tests/testXDR.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsatom.cpp
js/src/jsatom.h
js/src/jsatominlines.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscompartment.cpp
js/src/jsdate.cpp
js/src/jsexn.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsnum.cpp
js/src/jsnum.h
js/src/json.cpp
js/src/jsonparser.cpp
js/src/jsopcode.cpp
js/src/jsopcode.h
js/src/jsprf.cpp
js/src/jsproxy.cpp
js/src/jsreflect.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsstr.cpp
js/src/jsstr.h
js/src/jstypes.h
js/src/jswrapper.cpp
js/src/shell/js.cpp
js/src/tests/js1_5/extensions/regress-328556.js
js/src/vm/CharacterEncoding.cpp
js/src/vm/Debugger.cpp
js/src/vm/Debugger.h
js/src/vm/DebuggerMemory.cpp
js/src/vm/HelperThreads.cpp
js/src/vm/HelperThreads.h
js/src/vm/MemoryMetrics.cpp
js/src/vm/OldDebugAPI.cpp
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
js/src/vm/String-inl.h
js/src/vm/String.cpp
js/src/vm/String.h
js/src/vm/StringBuffer.cpp
js/src/vm/StringBuffer.h
js/src/vm/StructuredClone.cpp
js/src/vm/TypedArrayObject.cpp
js/src/vm/TypedArrayObject.h
js/src/vm/UbiNode.cpp
js/src/vm/Unicode.cpp
js/src/vm/Unicode.h
js/src/vm/Xdr.cpp
js/src/vm/Xdr.h
js/src/vm/make_unicode.py
js/xpconnect/loader/mozJSSubScriptLoader.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCLocale.cpp
js/xpconnect/src/XPCString.cpp
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/xpcpublic.h
js/xpconnect/wrappers/AccessCheck.cpp
storage/src/mozStorageStatementRow.cpp
toolkit/components/ctypes/ctypes.cpp
toolkit/components/ctypes/tests/unit/test_jsctypes.js
toolkit/components/finalizationwitness/FinalizationWitnessService.cpp
toolkit/components/osfile/modules/osfile_shared_allthreads.jsm
toolkit/components/osfile/modules/osfile_win_allthreads.jsm
toolkit/components/osfile/modules/osfile_win_back.jsm
toolkit/components/osfile/modules/osfile_win_front.jsm
toolkit/components/osfile/tests/mochi/worker_test_osfile_win.js
toolkit/modules/GMPInstallManager.jsm
toolkit/mozapps/update/nsUpdateService.js
toolkit/mozapps/update/tests/unit_aus_update/canCheckForAndCanApplyUpdates.js
toolkit/mozapps/update/tests/unit_aus_update/head_update.js
toolkit/mozapps/update/tests/unit_aus_update/urlConstruction.js
toolkit/mozapps/update/tests/unit_base_updater/marAppApplyUpdateAppBinInUseStageSuccess_win.js
toolkit/mozapps/update/tests/unit_service_updater/marAppApplyUpdateAppBinInUseStageSuccessSvc_win.js
tools/profiler/ProfileEntry.cpp
tools/profiler/TableTicker.cpp
widget/android/NativeJSContainer.cpp
widget/xpwidgets/GfxInfoCollector.cpp
--- a/addon-sdk/source/lib/sdk/system/child_process/subprocess.js
+++ b/addon-sdk/source/lib/sdk/system/child_process/subprocess.js
@@ -188,19 +188,19 @@ const HANDLE = ctypes.size_t;
 const HWND = HANDLE;
 const HMODULE = HANDLE;
 const WPARAM = ctypes.size_t;
 const LPARAM = ctypes.size_t;
 const LRESULT = ctypes.size_t;
 const ULONG_PTR = ctypes.uintptr_t;
 const PVOID = ctypes.voidptr_t;
 const LPVOID = PVOID;
-const LPCTSTR = ctypes.jschar.ptr;
-const LPCWSTR = ctypes.jschar.ptr;
-const LPTSTR = ctypes.jschar.ptr;
+const LPCTSTR = ctypes.char16_t.ptr;
+const LPCWSTR = ctypes.char16_t.ptr;
+const LPTSTR = ctypes.char16_t.ptr;
 const LPSTR = ctypes.char.ptr;
 const LPCSTR = ctypes.char.ptr;
 const LPBYTE = ctypes.char.ptr;
 
 const CREATE_NEW_CONSOLE = 0x00000010;
 const CREATE_NO_WINDOW = 0x08000000;
 const CREATE_UNICODE_ENVIRONMENT = 0x00000400;
 const STARTF_USESHOWWINDOW = 0x00000001;
@@ -702,18 +702,18 @@ function subprocess_win32(options) {
           args[i] = args[i].replace(/\\\"/g, "\\\\\"");
         }
         command = args.join(' ');
 
         environment = environment || [];
         if(environment.length) {
             //An environment block consists of
             //a null-terminated block of null-terminated strings.
-            //Using CREATE_UNICODE_ENVIRONMENT so needs to be jschar
-            environment = ctypes.jschar.array()(environment.join('\0') + '\0');
+            //Using CREATE_UNICODE_ENVIRONMENT so needs to be char16_t
+            environment = ctypes.char16_t.array()(environment.join('\0') + '\0');
         } else {
             environment = null;
         }
 
         var hOutputReadTmp = new HANDLE(),
             hOutputRead = new HANDLE(),
             hOutputWrite = new HANDLE();
 
--- a/browser/components/preferences/advanced.js
+++ b/browser/components/preferences/advanced.js
@@ -654,17 +654,17 @@ var gAdvancedPane = {
       wrk.close();
     } catch(e) {
     }
     if (installed != 1) {
       document.getElementById("useService").hidden = true;
     }
     try {
       const DRIVE_FIXED = 3;
-      const LPCWSTR = ctypes.jschar.ptr;
+      const LPCWSTR = ctypes.char16_t.ptr;
       const UINT = ctypes.uint32_t;
       let kernel32 = ctypes.open("kernel32");
       let GetDriveType = kernel32.declare("GetDriveTypeW", ctypes.default_abi, UINT, LPCWSTR);
       var UpdatesDir = Components.classes["@mozilla.org/updates/update-service;1"].
                        getService(Components.interfaces.nsIApplicationUpdateService);
       let rootPath = UpdatesDir.getUpdatesDirectory();
       while (rootPath.parent != null) {
         rootPath = rootPath.parent;
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -6403,27 +6403,27 @@ nsContentUtils::IsPatternMatching(nsAStr
   JSAutoCompartment ac(cx, xpc::UnprivilegedJunkScope());
 
   // The pattern has to match the entire value.
   aPattern.Insert(NS_LITERAL_STRING("^(?:"), 0);
   aPattern.AppendLiteral(")$");
 
   JS::Rooted<JSObject*> re(cx,
     JS_NewUCRegExpObjectNoStatics(cx,
-                                  static_cast<jschar*>(aPattern.BeginWriting()),
+                                  static_cast<char16_t*>(aPattern.BeginWriting()),
                                   aPattern.Length(), 0));
   if (!re) {
     JS_ClearPendingException(cx);
     return true;
   }
 
   JS::Rooted<JS::Value> rval(cx, JS::NullValue());
   size_t idx = 0;
   if (!JS_ExecuteRegExpNoStatics(cx, re,
-                                 static_cast<jschar*>(aValue.BeginWriting()),
+                                 static_cast<char16_t*>(aValue.BeginWriting()),
                                  aValue.Length(), &idx, true, &rval)) {
     JS_ClearPendingException(cx);
     return true;
   }
 
   return !rval.isNull();
 }
 
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -507,17 +507,17 @@ nsFrameMessageManager::GetDelayedFrameSc
                    NS_ERROR_OUT_OF_MEMORY);
   }
 
   aList.setObject(*array);
   return NS_OK;
 }
 
 static bool
-JSONCreator(const jschar* aBuf, uint32_t aLen, void* aData)
+JSONCreator(const char16_t* aBuf, uint32_t aLen, void* aData)
 {
   nsAString* result = static_cast<nsAString*>(aData);
   result->Append(static_cast<const char16_t*>(aBuf),
                  static_cast<uint32_t>(aLen));
   return true;
 }
 
 static bool
@@ -537,17 +537,17 @@ GetParamsForMessage(JSContext* aCx,
   //    properly cases when interface is implemented in JS and used
   //    as a dictionary.
   nsAutoString json;
   NS_ENSURE_TRUE(JS_Stringify(aCx, &v, JS::NullPtr(), JS::NullHandleValue,
                               JSONCreator, &json), false);
   NS_ENSURE_TRUE(!json.IsEmpty(), false);
 
   JS::Rooted<JS::Value> val(aCx, JS::NullValue());
-  NS_ENSURE_TRUE(JS_ParseJSON(aCx, static_cast<const jschar*>(json.get()),
+  NS_ENSURE_TRUE(JS_ParseJSON(aCx, static_cast<const char16_t*>(json.get()),
                               json.Length(), &val), false);
 
   return WriteStructuredClone(aCx, val, aBuffer, aClosure);
 }
 
 
 // nsISyncMessageSender
 
@@ -633,17 +633,17 @@ nsFrameMessageManager::SendMessage(const
   NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
 
   for (uint32_t i = 0; i < len; ++i) {
     if (retval[i].IsEmpty()) {
       continue;
     }
 
     JS::Rooted<JS::Value> ret(aCx);
-    if (!JS_ParseJSON(aCx, static_cast<const jschar*>(retval[i].get()),
+    if (!JS_ParseJSON(aCx, static_cast<const char16_t*>(retval[i].get()),
                       retval[i].Length(), &ret)) {
       return NS_ERROR_UNEXPECTED;
     }
     NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, ret),
                    NS_ERROR_OUT_OF_MEMORY);
   }
 
   aRetval.setObject(*dataArray);
@@ -991,17 +991,17 @@ nsFrameMessageManager::ReceiveMessage(ns
       JS::Rooted<JS::Value> json(cx, JS::NullValue());
       if (aCloneData && aCloneData->mDataLength &&
           !ReadStructuredClone(cx, *aCloneData, &json)) {
         JS_ClearPendingException(cx);
         return NS_OK;
       }
       JS::Rooted<JSString*> jsMessage(cx,
         JS_NewUCStringCopyN(cx,
-                            static_cast<const jschar*>(aMessage.BeginReading()),
+                            static_cast<const char16_t*>(aMessage.BeginReading()),
                             aMessage.Length()));
       NS_ENSURE_TRUE(jsMessage, NS_ERROR_OUT_OF_MEMORY);
       JS::Rooted<JS::Value> syncv(cx, JS::BooleanValue(aIsSync));
       JS_DefineProperty(cx, param, "target", targetv, JSPROP_ENUMERATE);
       JS_DefineProperty(cx, param, "name", jsMessage, JSPROP_ENUMERATE);
       JS_DefineProperty(cx, param, "sync", syncv, JSPROP_ENUMERATE);
       JS_DefineProperty(cx, param, "json", json, JSPROP_ENUMERATE); // deprecated
       JS_DefineProperty(cx, param, "data", json, JSPROP_ENUMERATE);
@@ -1484,17 +1484,17 @@ nsFrameScriptExecutor::TryCacheLoadAndCo
   NS_NewChannel(getter_AddRefs(channel), uri);
   if (!channel) {
     return;
   }
 
   nsCOMPtr<nsIInputStream> input;
   channel->Open(getter_AddRefs(input));
   nsString dataString;
-  jschar* dataStringBuf = nullptr;
+  char16_t* dataStringBuf = nullptr;
   size_t dataStringLength = 0;
   uint64_t avail64 = 0;
   if (input && NS_SUCCEEDED(input->Available(&avail64)) && avail64) {
     if (avail64 > UINT32_MAX) {
       return;
     }
     nsCString buffer;
     uint32_t avail = (uint32_t)std::min(avail64, (uint64_t)UINT32_MAX);
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -104,17 +104,17 @@ public:
     return mElement == nullptr;
   }
 
   nsCOMPtr<nsIScriptElement> mElement;
   bool mLoading;          // Are we still waiting for a load to complete?
   bool mIsInline;         // Is the script inline or loaded?
   bool mHasSourceMapURL;  // Does the HTTP header have a source map url?
   nsString mSourceMapURL; // Holds source map url for loaded scripts
-  jschar* mScriptTextBuf;   // Holds script text for non-inline scripts. Don't
+  char16_t* mScriptTextBuf; // Holds script text for non-inline scripts. Don't
   size_t mScriptTextLength; // use nsString so we can give ownership to jsapi.
   uint32_t mJSVersion;
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIPrincipal> mOriginPrincipal;
   nsAutoCString mURL;   // Keep the URI's filename alive during off thread parsing.
   int32_t mLineNo;
   const CORSMode mCORSMode;
 };
@@ -893,17 +893,17 @@ nsScriptLoader::ProcessRequest(nsScriptL
   if (!aOffThreadToken) {
     nsresult rv = AttemptAsyncScriptParse(aRequest);
     if (rv != NS_ERROR_FAILURE)
       return rv;
   }
 
   NS_ENSURE_ARG(aRequest);
   nsAutoString textData;
-  const jschar* scriptBuf = nullptr;
+  const char16_t* scriptBuf = nullptr;
   size_t scriptLength = 0;
   JS::SourceBufferHolder::Ownership giveScriptOwnership =
     JS::SourceBufferHolder::NoOwnership;
 
   nsCOMPtr<nsIDocument> doc;
 
   nsCOMPtr<nsINode> scriptElem = do_QueryInterface(aRequest->mElement);
 
@@ -1273,17 +1273,17 @@ DetectByteOrderMark(const unsigned char*
   }
   return !oCharset.IsEmpty();
 }
 
 /* static */ nsresult
 nsScriptLoader::ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData,
                                uint32_t aLength, const nsAString& aHintCharset,
                                nsIDocument* aDocument,
-                               jschar*& aBufOut, size_t& aLengthOut)
+                               char16_t*& aBufOut, size_t& aLengthOut)
 {
   if (!aLength) {
     aBufOut = nullptr;
     aLengthOut = 0;
     return NS_OK;
   }
 
   // The encoding info precedence is as follows from high to low:
@@ -1330,17 +1330,17 @@ nsScriptLoader::ConvertToUTF16(nsIChanne
 
   int32_t unicodeLength = 0;
 
   nsresult rv =
     unicodeDecoder->GetMaxLength(reinterpret_cast<const char*>(aData),
                                  aLength, &unicodeLength);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  aBufOut = static_cast<jschar*>(js_malloc(unicodeLength * sizeof(jschar)));
+  aBufOut = static_cast<char16_t*>(js_malloc(unicodeLength * sizeof(char16_t)));
   if (!aBufOut) {
     aLengthOut = 0;
     return NS_ERROR_OUT_OF_MEMORY;
   }
   aLengthOut = unicodeLength;
 
   rv = unicodeDecoder->Convert(reinterpret_cast<const char*>(aData),
                                (int32_t *) &aLength, aBufOut,
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -165,27 +165,27 @@ public:
    * Convert the given buffer to a UTF-16 string.
    * @param aChannel     Channel corresponding to the data. May be null.
    * @param aData        The data to convert
    * @param aLength      Length of the data
    * @param aHintCharset Hint for the character set (e.g., from a charset
    *                     attribute). May be the empty string.
    * @param aDocument    Document which the data is loaded for. Must not be
    *                     null.
-   * @param aBufOut      [out] jschar array allocated by ConvertToUTF16 and
+   * @param aBufOut      [out] char16_t array allocated by ConvertToUTF16 and
    *                     containing data converted to unicode.  Caller must
    *                     js_free() this data when no longer needed.
    * @param aLengthOut   [out] Length of array returned in aBufOut in number
-   *                     of jschars.
+   *                     of char16_t code units.
    */
   static nsresult ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData,
                                  uint32_t aLength,
                                  const nsAString& aHintCharset,
                                  nsIDocument* aDocument,
-                                 jschar*& aBufOut, size_t& aLengthOut);
+                                 char16_t*& aBufOut, size_t& aLengthOut);
 
   /**
    * Processes any pending requests that are ready for processing.
    */
   void ProcessPendingRequests();
 
   /**
    * Check whether it's OK to load a script from aURI in
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -761,17 +761,17 @@ nsXMLHttpRequest::CreateResponseParsedJS
   if (!aCx) {
     return NS_ERROR_FAILURE;
   }
   RootJSResultObjects();
 
   // The Unicode converter has already zapped the BOM if there was one
   JS::Rooted<JS::Value> value(aCx);
   if (!JS_ParseJSON(aCx,
-                    static_cast<const jschar*>(mResponseText.get()), mResponseText.Length(),
+                    static_cast<const char16_t*>(mResponseText.get()), mResponseText.Length(),
                     &value)) {
     return NS_ERROR_FAILURE;
   }
 
   mResultJSON = value;
   return NS_OK;
 }
 
--- a/content/xul/document/src/XULDocument.h
+++ b/content/xul/document/src/XULDocument.h
@@ -450,17 +450,17 @@ protected:
      * The load event is blocked while this is in progress.
      */
     bool mOffThreadCompiling;
 
     /**
      * If the current transcluded script is being compiled off thread, the
      * source for that script.
      */
-    jschar* mOffThreadCompileStringBuf;
+    char16_t* mOffThreadCompileStringBuf;
     size_t mOffThreadCompileStringLength;
 
     /**
      * Check if a XUL template builder has already been hooked up.
      */
     static nsresult
     CheckTemplateBuilderHookup(nsIContent* aElement, bool* aNeedsHookup);
 
--- a/dom/asmjscache/AsmJSCache.cpp
+++ b/dom/asmjscache/AsmJSCache.cpp
@@ -1579,18 +1579,18 @@ OpenFile(nsIPrincipal* aPrincipal,
 
 } // anonymous namespace
 
 typedef uint32_t AsmJSCookieType;
 static const uint32_t sAsmJSCookie = 0x600d600d;
 
 bool
 OpenEntryForRead(nsIPrincipal* aPrincipal,
-                 const jschar* aBegin,
-                 const jschar* aLimit,
+                 const char16_t* aBegin,
+                 const char16_t* aLimit,
                  size_t* aSize,
                  const uint8_t** aMemory,
                  intptr_t* aFile)
 {
   if (size_t(aLimit - aBegin) < sMinCachedModuleLength) {
     return false;
   }
 
@@ -1638,18 +1638,18 @@ CloseEntryForRead(size_t aSize,
 
   MOZ_ASSERT(aSize + sizeof(AsmJSCookieType) == file->FileSize());
   MOZ_ASSERT(aMemory - sizeof(AsmJSCookieType) == file->MappedMemory());
 }
 
 bool
 OpenEntryForWrite(nsIPrincipal* aPrincipal,
                   bool aInstalled,
-                  const jschar* aBegin,
-                  const jschar* aEnd,
+                  const char16_t* aBegin,
+                  const char16_t* aEnd,
                   size_t aSize,
                   uint8_t** aMemory,
                   intptr_t* aFile)
 {
   if (size_t(aEnd - aBegin) < sMinCachedModuleLength) {
     return false;
   }
 
--- a/dom/asmjscache/AsmJSCache.h
+++ b/dom/asmjscache/AsmJSCache.h
@@ -75,18 +75,18 @@ struct WriteParams
     mFullHash(0),
     mInstalled(false)
   { }
 };
 
 // Parameters specific to opening a cache entry for reading
 struct ReadParams
 {
-  const jschar* mBegin;
-  const jschar* mLimit;
+  const char16_t* mBegin;
+  const char16_t* mLimit;
 
   ReadParams()
   : mBegin(nullptr),
     mLimit(nullptr)
   { }
 };
 
 // Implementation of AsmJSCacheOps, installed for the main JSRuntime by
@@ -98,30 +98,30 @@ struct ReadParams
 //
 // These methods may be called off the main thread and guarantee not to
 // access the given aPrincipal except on the main thread. In exchange, the
 // caller must ensure the given principal is alive from when OpenEntryForX is
 // called to when CloseEntryForX returns.
 
 bool
 OpenEntryForRead(nsIPrincipal* aPrincipal,
-                 const jschar* aBegin,
-                 const jschar* aLimit,
+                 const char16_t* aBegin,
+                 const char16_t* aLimit,
                  size_t* aSize,
                  const uint8_t** aMemory,
                  intptr_t *aHandle);
 void
 CloseEntryForRead(size_t aSize,
                   const uint8_t* aMemory,
                   intptr_t aHandle);
 bool
 OpenEntryForWrite(nsIPrincipal* aPrincipal,
                   bool aInstalled,
-                  const jschar* aBegin,
-                  const jschar* aEnd,
+                  const char16_t* aBegin,
+                  const char16_t* aEnd,
                   size_t aSize,
                   uint8_t** aMemory,
                   intptr_t* aHandle);
 void
 CloseEntryForWrite(size_t aSize,
                    uint8_t* aMemory,
                    intptr_t aHandle);
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1361,17 +1361,17 @@ nsDOMClassInfo::PostCreatePrototype(JSCo
     if (!win || !(global = win->GetGlobalJSObject()) ||
         win->IsClosedOrClosing()) {
       return NS_OK;
     }
   }
 
   // Don't overwrite a property set by content.
   bool contentDefinedProperty;
-  if (!::JS_AlreadyHasOwnUCProperty(cx, global, reinterpret_cast<const jschar*>(mData->mNameUTF16),
+  if (!::JS_AlreadyHasOwnUCProperty(cx, global, reinterpret_cast<const char16_t*>(mData->mNameUTF16),
                                     NS_strlen(mData->mNameUTF16),
                                     &contentDefinedProperty)) {
     return NS_ERROR_FAILURE;
   }
 
   nsScriptNameSpaceManager *nameSpaceManager = GetNameSpaceManager();
   NS_ENSURE_TRUE(nameSpaceManager, NS_OK);
 
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -927,17 +927,17 @@ nsJSContext::AddSupportsPrimitiveTojsval
     case nsISupportsPrimitive::TYPE_STRING : {
       nsCOMPtr<nsISupportsString> p(do_QueryInterface(argPrimitive));
       NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);
 
       nsAutoString data;
 
       p->GetData(data);
 
-      // cast is probably safe since wchar_t and jschar are expected
+      // cast is probably safe since wchar_t and char16_t are expected
       // to be equivalent; both unsigned 16-bit entities
       JSString *str =
         ::JS_NewUCStringCopyN(cx, data.get(), data.Length());
       NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
 
       *aArgv = STRING_TO_JSVAL(str);
       break;
     }
@@ -2314,18 +2314,18 @@ NotifyGCEndRunnable::Run()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
   if (!observerService) {
     return NS_OK;
   }
 
-  const jschar oomMsg[3] = { '{', '}', 0 };
-  const jschar *toSend = mMessage.get() ? mMessage.get() : oomMsg;
+  const char16_t oomMsg[3] = { '{', '}', 0 };
+  const char16_t *toSend = mMessage.get() ? mMessage.get() : oomMsg;
   observerService->NotifyObservers(nullptr, "garbage-collection-statistics", toSend);
 
   return NS_OK;
 }
 
 static void
 DOMGCSliceCallback(JSRuntime *aRt, JS::GCProgress aProgress, const JS::GCDescription &aDesc)
 {
@@ -2685,33 +2685,33 @@ NS_DOMStructuredCloneError(JSContext* cx
                            uint32_t errorid)
 {
   // We don't currently support any extensions to structured cloning.
   xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
 }
 
 static bool
 AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
-                           const jschar* aBegin,
-                           const jschar* aLimit,
+                           const char16_t* aBegin,
+                           const char16_t* aLimit,
                            size_t* aSize,
                            const uint8_t** aMemory,
                            intptr_t *aHandle)
 {
   nsIPrincipal* principal =
     nsJSPrincipals::get(JS_GetCompartmentPrincipals(js::GetObjectCompartment(aGlobal)));
   return asmjscache::OpenEntryForRead(principal, aBegin, aLimit, aSize, aMemory,
                                       aHandle);
 }
 
 static bool
 AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
                             bool aInstalled,
-                            const jschar* aBegin,
-                            const jschar* aEnd,
+                            const char16_t* aBegin,
+                            const char16_t* aEnd,
                             size_t aSize,
                             uint8_t** aMemory,
                             intptr_t* aHandle)
 {
   nsIPrincipal* principal =
     nsJSPrincipals::get(JS_GetCompartmentPrincipals(js::GetObjectCompartment(aGlobal)));
   return asmjscache::OpenEntryForWrite(principal, aInstalled, aBegin, aEnd,
                                        aSize, aMemory, aHandle);
--- a/dom/bindings/BindingDeclarations.h
+++ b/dom/bindings/BindingDeclarations.h
@@ -37,18 +37,18 @@ protected:
                  JS::MutableHandle<JS::Value> aVal);
 
   bool StringifyToJSON(JSContext* aCx,
                        JS::MutableHandle<JS::Value> aValue,
                        nsAString& aJSON);
 private:
   // aString is expected to actually be an nsAString*.  Should only be
   // called from StringifyToJSON.
-  static bool AppendJSONToString(const jschar* aJSONData, uint32_t aDataLength,
-                                 void* aString);
+  static bool AppendJSONToString(const char16_t* aJSONData,
+                                 uint32_t aDataLength, void* aString);
 };
 
 // Struct that serves as a base class for all typed arrays and array buffers and
 // array buffer views.  Particularly useful so we can use IsBaseOf to detect
 // typed array/buffer/view template arguments.
 struct AllTypedArraysBase {
 };
 
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -152,17 +152,17 @@ ErrorResult::ThrowTypeError(const dom::E
 
 void
 ErrorResult::ReportTypeError(JSContext* aCx)
 {
   MOZ_ASSERT(mMessage, "ReportTypeError() can be called only once");
 
   Message* message = mMessage;
   const uint32_t argCount = message->mArgs.Length();
-  const jschar* args[11];
+  const char16_t* args[11];
   for (uint32_t i = 0; i < argCount; ++i) {
     args[i] = message->mArgs.ElementAt(i).get();
   }
   args[argCount] = nullptr;
 
   JS_ReportErrorNumberUCArray(aCx, dom::GetErrorMessage, nullptr,
                               static_cast<const unsigned>(message->mErrorNumber),
                               argCount > 0 ? args : nullptr);
@@ -1624,44 +1624,39 @@ AppendNamedPropertyIds(JSContext* cx, JS
 bool
 DictionaryBase::ParseJSON(JSContext* aCx,
                           const nsAString& aJSON,
                           JS::MutableHandle<JS::Value> aVal)
 {
   if (aJSON.IsEmpty()) {
     return true;
   }
-  return JS_ParseJSON(aCx,
-                      static_cast<const jschar*>(PromiseFlatString(aJSON).get()),
-                      aJSON.Length(), aVal);
+  return JS_ParseJSON(aCx, PromiseFlatString(aJSON).get(), aJSON.Length(), aVal);
 }
 
 bool
 DictionaryBase::StringifyToJSON(JSContext* aCx,
                                 JS::MutableHandle<JS::Value> aValue,
                                 nsAString& aJSON)
 {
   return JS_Stringify(aCx, aValue, JS::NullPtr(), JS::NullHandleValue,
                       AppendJSONToString, &aJSON);
 }
 
 /* static */
 bool
-DictionaryBase::AppendJSONToString(const jschar* aJSONData,
+DictionaryBase::AppendJSONToString(const char16_t* aJSONData,
                                    uint32_t aDataLength,
                                    void* aString)
 {
   nsAString* string = static_cast<nsAString*>(aString);
-  string->Append(static_cast<const char16_t*>(aJSONData),
-                 aDataLength);
+  string->Append(aJSONData, aDataLength);
   return true;
 }
 
-
-
 static JSString*
 ConcatJSString(JSContext* cx, const char* pre, JS::Handle<JSString*> str, const char* post)
 {
   if (!str) {
     return nullptr;
   }
 
   JS::Rooted<JSString*> preString(cx, JS_NewStringCopyN(cx, pre, strlen(pre)));
@@ -2239,20 +2234,20 @@ ConvertJSValueToByteString(JSContext* cx
   // Conversion from Javascript string to ByteString is only valid if all
   // characters < 256. This is always the case for Latin1 strings.
   size_t length;
   if (!js::StringHasLatin1Chars(s)) {
     // ThrowErrorMessage can GC, so we first scan the string for bad chars
     // and report the error outside the AutoCheckCannotGC scope.
     bool foundBadChar = false;
     size_t badCharIndex;
-    jschar badChar;
+    char16_t badChar;
     {
       JS::AutoCheckCannotGC nogc;
-      const jschar* chars = JS_GetTwoByteStringCharsAndLength(cx, nogc, s, &length);
+      const char16_t* chars = JS_GetTwoByteStringCharsAndLength(cx, nogc, s, &length);
       if (!chars) {
         return false;
       }
 
       for (size_t i = 0; i < length; i++) {
         if (chars[i] > 255) {
           badCharIndex = i;
           badChar = chars[i];
@@ -2265,21 +2260,21 @@ ConvertJSValueToByteString(JSContext* cx
     if (foundBadChar) {
       MOZ_ASSERT(badCharIndex < length);
       MOZ_ASSERT(badChar > 255);
       // The largest unsigned 64 bit number (18,446,744,073,709,551,615) has
       // 20 digits, plus one more for the null terminator.
       char index[21];
       static_assert(sizeof(size_t) <= 8, "index array too small");
       PR_snprintf(index, sizeof(index), "%d", badCharIndex);
-      // A jschar is 16 bits long.  The biggest unsigned 16 bit
+      // A char16_t is 16 bits long.  The biggest unsigned 16 bit
       // number (65,535) has 5 digits, plus one more for the null
       // terminator.
       char badCharArray[6];
-      static_assert(sizeof(jschar) <= 2, "badCharArray too small");
+      static_assert(sizeof(char16_t) <= 2, "badCharArray too small");
       PR_snprintf(badCharArray, sizeof(badCharArray), "%d", badChar);
       ThrowErrorMessage(cx, MSG_INVALID_BYTESTRING, index, badCharArray);
       return false;
     }
   } else {
     length = js::GetStringLength(s);
   }
 
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1140,18 +1140,18 @@ FindEnumStringIndex(JSContext* cx, JS::H
       const JS::Latin1Char* chars = JS_GetLatin1StringCharsAndLength(cx, nogc, str,
                                                                      &length);
       if (!chars) {
         *ok = false;
         return 0;
       }
       index = FindEnumStringIndexImpl(chars, length, values);
     } else {
-      const jschar* chars = JS_GetTwoByteStringCharsAndLength(cx, nogc, str,
-                                                              &length);
+      const char16_t* chars = JS_GetTwoByteStringCharsAndLength(cx, nogc, str,
+                                                                &length);
       if (!chars) {
         *ok = false;
         return 0;
       }
       index = FindEnumStringIndexImpl(chars, length, values);
     }
     if (index >= 0) {
       *ok = true;
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3380,17 +3380,17 @@ class CGIsPermittedMethod(CGAbstractMeth
     crossOriginGetters/Setters/Methods are sets of names of the relevant members.
     """
     def __init__(self, descriptor, crossOriginGetters, crossOriginSetters,
                  crossOriginMethods):
         self.crossOriginGetters = crossOriginGetters
         self.crossOriginSetters = crossOriginSetters
         self.crossOriginMethods = crossOriginMethods
         args = [Argument("JSFlatString*", "prop"),
-                Argument("jschar", "propFirstChar"),
+                Argument("char16_t", "propFirstChar"),
                 Argument("bool", "set")]
         CGAbstractMethod.__init__(self, descriptor, "IsPermitted", "bool", args,
                                   inline=True)
 
     def definition_body(self):
         allNames = self.crossOriginGetters | self.crossOriginSetters | self.crossOriginMethods
         readwrite = self.crossOriginGetters & self.crossOriginSetters
         readonly = (self.crossOriginGetters - self.crossOriginSetters) | self.crossOriginMethods
--- a/dom/bindings/DOMJSProxyHandler.h
+++ b/dom/bindings/DOMJSProxyHandler.h
@@ -145,17 +145,17 @@ GetArrayIndexFromId(JSContext* cx, JS::H
   if (MOZ_LIKELY(JSID_IS_INT(id))) {
     return JSID_TO_INT(id);
   }
   if (MOZ_LIKELY(id == s_length_id)) {
     return -1;
   }
   if (MOZ_LIKELY(JSID_IS_ATOM(id))) {
     JSAtom* atom = JSID_TO_ATOM(id);
-    jschar s;
+    char16_t s;
     {
       JS::AutoCheckCannotGC nogc;
       if (js::AtomHasLatin1Chars(atom)) {
         s = *js::GetLatin1AtomChars(nogc, atom);
       } else {
         s = *js::GetTwoByteAtomChars(nogc, atom);
       }
     }
--- a/dom/crypto/WebCryptoTask.cpp
+++ b/dom/crypto/WebCryptoTask.cpp
@@ -2959,13 +2959,12 @@ WebCryptoTask::CreateUnwrapKeyTask(JSCon
                                       importTask);
   } else if (unwrapAlgName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
     return new UnwrapKeyTask<RsaOaepTask>(aCx, aWrappedKey,
                                       aUnwrappingKey, aUnwrapAlgorithm,
                                       importTask);
   }
 
   return new FailureTask(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/indexedDB/KeyPath.cpp
+++ b/dom/indexedDB/KeyPath.cpp
@@ -98,17 +98,17 @@ GetJSValFromKeyPathString(JSContext* aCx
   JS::Rooted<JSObject*> obj(aCx,
     aValue.isPrimitive() ? nullptr : aValue.toObjectOrNull());
 
   while (tokenizer.hasMoreTokens()) {
     const nsDependentSubstring& token = tokenizer.nextToken();
 
     NS_ASSERTION(!token.IsEmpty(), "Should be a valid keypath");
 
-    const jschar* keyPathChars = token.BeginReading();
+    const char16_t* keyPathChars = token.BeginReading();
     const size_t keyPathLen = token.Length();
 
     bool hasProp;
     if (!targetObject) {
       // We're still walking the chain of existing objects
       if (!obj) {
         return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
       }
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -487,17 +487,17 @@ void
 TabChildBase::DispatchMessageManagerMessage(const nsAString& aMessageName,
                                             const nsAString& aJSONData)
 {
     AutoSafeJSContext cx;
     JS::Rooted<JS::Value> json(cx, JSVAL_NULL);
     StructuredCloneData cloneData;
     JSAutoStructuredCloneBuffer buffer;
     if (JS_ParseJSON(cx,
-                      static_cast<const jschar*>(aJSONData.BeginReading()),
+                      static_cast<const char16_t*>(aJSONData.BeginReading()),
                       aJSONData.Length(),
                       &json)) {
         WriteStructuredClone(cx, json, buffer, cloneData.mClosure);
         cloneData.mData = buffer.data();
         cloneData.mDataLength = buffer.nbytes();
     }
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
--- a/dom/json/nsJSON.cpp
+++ b/dom/json/nsJSON.cpp
@@ -158,17 +158,17 @@ nsJSON::EncodeToStream(nsIOutputStream *
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = bufferedStream->Flush();
 
   return rv;
 }
 
 static bool
-WriteCallback(const jschar *buf, uint32_t len, void *data)
+WriteCallback(const char16_t *buf, uint32_t len, void *data)
 {
   nsJSONWriter *writer = static_cast<nsJSONWriter*>(data);
   nsresult rv =  writer->Write((const char16_t*)buf, (uint32_t)len);
   if (NS_FAILED(rv))
     return false;
 
   return true;
 }
@@ -384,17 +384,17 @@ nsJSON::DecodeFromStream(nsIInputStream 
 {
   return DecodeInternal(cx, aStream, aContentLength, true, aRetval);
 }
 
 NS_IMETHODIMP
 nsJSON::DecodeToJSVal(const nsAString &str, JSContext *cx,
                       JS::MutableHandle<JS::Value> result)
 {
-  if (!JS_ParseJSON(cx, static_cast<const jschar*>(PromiseFlatString(str).get()),
+  if (!JS_ParseJSON(cx, static_cast<const char16_t*>(PromiseFlatString(str).get()),
                     str.Length(), result)) {
     return NS_ERROR_UNEXPECTED;
   }
   return NS_OK;
 }
 
 nsresult
 nsJSON::DecodeInternal(JSContext* cx,
@@ -520,17 +520,17 @@ nsJSONListener::OnStopRequest(nsIRequest
   if (!mSniffBuffer.IsEmpty()) {
     // Just consume mSniffBuffer
     rv = ProcessBytes(nullptr, 0);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   JS::Rooted<JS::Value> reviver(mCx, JS::NullValue()), value(mCx);
 
-  JS::ConstTwoByteChars chars(reinterpret_cast<const jschar*>(mBufferedChars.Elements()),
+  JS::ConstTwoByteChars chars(reinterpret_cast<const char16_t*>(mBufferedChars.Elements()),
                               mBufferedChars.Length());
   bool ok = JS_ParseJSONWithReviver(mCx, chars.get(),
                                       uint32_t(mBufferedChars.Length()),
                                       reviver, &value);
 
   *mRootVal = value;
   mBufferedChars.TruncateLength(0);
   return ok ? NS_OK : NS_ERROR_FAILURE;
--- a/dom/plugins/test/mochitest/dialog_watcher.js
+++ b/dom/plugins/test/mochitest/dialog_watcher.js
@@ -18,18 +18,18 @@ DialogWatcher.prototype.init = function(
   this.hwnd = undefined;
   if (!this.user32) {
     this.user32 = ctypes.open("user32.dll");
   }
   if (!this.findWindow) {
     this.findWindow = user32.declare("FindWindowW",
                                      ctypes.winapi_abi,
                                      ctypes.uintptr_t,
-                                     ctypes.jschar.ptr,
-                                     ctypes.jschar.ptr);
+                                     ctypes.char16_t.ptr,
+                                     ctypes.char16_t.ptr);
   }
   if (!this.winEventProcType) {
     this.winEventProcType = ctypes.FunctionType(ctypes.stdcall_abi,
                                                 ctypes.void_t,
                                                 [ctypes.uintptr_t,
                                                 ctypes.uint32_t,
                                                 ctypes.uintptr_t,
                                                 ctypes.long,
@@ -89,33 +89,33 @@ DialogWatcher.prototype.init = function(
                                                     ctypes.uint32_t,
                                                     ctypes.uint32_t);
   }
   if (!this.getWindowTextW) {
     this.getWindowTextW = user32.declare("GetWindowTextW",
                                          ctypes.winapi_abi,
                                          ctypes.int,
                                          ctypes.uintptr_t,
-                                         ctypes.jschar.ptr,
+                                         ctypes.char16_t.ptr,
                                          ctypes.int);
   }
   if (!this.messageBox) {
     // Handy for debugging this code
     this.messageBox = user32.declare("MessageBoxW",
                                      ctypes.winapi_abi,
                                      ctypes.int,
                                      ctypes.uintptr_t,
-                                     ctypes.jschar.ptr,
-                                     ctypes.jschar.ptr,
+                                     ctypes.char16_t.ptr,
+                                     ctypes.char16_t.ptr,
                                      ctypes.uint32_t);
   }
 };
 
 DialogWatcher.prototype.getWindowText = function(hwnd) {
-  var bufType = ctypes.ArrayType(ctypes.jschar);
+  var bufType = ctypes.ArrayType(ctypes.char16_t);
   var buffer = new bufType(256);
 
   if (this.getWindowTextW(hwnd, buffer, buffer.length)) {
     return buffer.readString();
   }
 };
 
 DialogWatcher.prototype.processWindowEvents = function(timeout) {
@@ -176,9 +176,8 @@ DialogWatcher.prototype.processWindowEve
       break;
     }
   }
 
   this.unhookWinEvent(hook);
   // Returns true if the hook was successful, something was found, and we never timed out
   return this.hwnd !== undefined && waitStatus == WAIT_OBJECT_0;
 };
-
--- a/dom/plugins/test/mochitest/hangui_iface.js
+++ b/dom/plugins/test/mochitest/hangui_iface.js
@@ -28,18 +28,18 @@ function initCTypes() {
                                  ctypes.intptr_t);
   }
   if (!messageBox) {
     // Handy for debugging the test itself
     messageBox = user32.declare("MessageBoxW",
                                 ctypes.winapi_abi,
                                 ctypes.int,
                                 ctypes.uintptr_t,
-                                ctypes.jschar.ptr,
-                                ctypes.jschar.ptr,
+                                ctypes.char16_t.ptr,
+                                ctypes.char16_t.ptr,
                                 ctypes.uint32_t);
   }
   if (!watcher) {
     watcher = new DialogWatcher("Warning: Unresponsive plugin");
   }
 }
 
 function postSuccess(params) {
--- a/dom/wifi/WifiUtils.cpp
+++ b/dom/wifi/WifiUtils.cpp
@@ -158,17 +158,17 @@ convertToBytes(char* buf, uint32_t maxle
 static const uint32_t REPLACE_UTF8 = 0xFFFD;
 
 void LossyConvertUTF8toUTF16(const char* aInput, uint32_t aLength, nsAString& aOut)
 {
   JS::UTF8Chars src(aInput, aLength);
 
   char16_t dst[aLength]; // Allocating for worst case.
 
-  // First, count how many jschars need to be in the inflated string.
+  // Count how many char16_t characters are needed in the inflated string.
   // |i| is the index into |src|, and |j| is the the index into |dst|.
   size_t srclen = src.length();
   uint32_t j = 0;
   for (uint32_t i = 0; i < srclen; i++, j++) {
     uint32_t v = uint32_t(src[i]);
     if (v == uint32_t('\0') && i < srclen - 1) {
       // If the leading byte is '\0' and it's not the last byte,
       // just ignore it to prevent from being truncated. This could
@@ -209,30 +209,30 @@ void LossyConvertUTF8toUTF16(const char*
         INVALID(ReportInvalidCharacter, i, 1);
       }
 
       // Check the continuation bytes.
       for (uint32_t m = 1; m < n; m++)
         if ((src[i + m] & 0xC0) != 0x80)
           INVALID(ReportInvalidCharacter, i, m);
 
-      // Determine the code unit's length in jschars and act accordingly.
+      // Determine the code unit's length in char16_t units and act accordingly.
       v = JS::Utf8ToOneUcs4Char((uint8_t *)&src[i], n);
       if (v < 0x10000) {
-        // The n-byte UTF8 code unit will fit in a single jschar.
-        dst[j] = jschar(v);
+        // The n-byte UTF8 code unit will fit in a single char16_t.
+        dst[j] = char16_t(v);
       } else {
         v -= 0x10000;
         if (v <= 0xFFFFF) {
-          // The n-byte UTF8 code unit will fit in two jschars.
-          dst[j] = jschar((v >> 10) + 0xD800);
+          // The n-byte UTF8 code unit will fit in two char16_t units.
+          dst[j] = char16_t((v >> 10) + 0xD800);
           j++;
-          dst[j] = jschar((v & 0x3FF) + 0xDC00);
+          dst[j] = char16_t((v & 0x3FF) + 0xDC00);
         } else {
-          // The n-byte UTF8 code unit won't fit in two jschars.
+          // The n-byte UTF8 code unit won't fit in two char16_t units.
           INVALID(ReportTooBigCharacter, v, 1);
         }
       }
 
     invalidMultiByteCodeUnit:
       // Move i to the last byte of the multi-byte code unit;  the loop
       // header will do the final i++ to move to the start of the next
       // code unit.
--- a/dom/workers/ChromeWorkerScope.cpp
+++ b/dom/workers/ChromeWorkerScope.cpp
@@ -16,17 +16,17 @@
 using namespace mozilla::dom;
 USING_WORKERS_NAMESPACE
 
 namespace {
 
 #ifdef BUILD_CTYPES
 
 char*
-UnicodeToNative(JSContext* aCx, const jschar* aSource, size_t aSourceLen)
+UnicodeToNative(JSContext* aCx, const char16_t* aSource, size_t aSourceLen)
 {
   nsDependentString unicode(aSource, aSourceLen);
 
   nsAutoCString native;
   if (NS_FAILED(NS_CopyUnicodeToNative(unicode, native))) {
     JS_ReportError(aCx, "Could not convert string to native charset!");
     return nullptr;
   }
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -732,36 +732,36 @@ GetPrincipalForAsmJSCacheOp()
 
   // asmjscache::OpenEntryForX guarnatee to only access the given nsIPrincipal
   // from the main thread.
   return workerPrivate->GetPrincipalDontAssertMainThread();
 }
 
 static bool
 AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
-                           const jschar* aBegin,
-                           const jschar* aLimit,
+                           const char16_t* aBegin,
+                           const char16_t* aLimit,
                            size_t* aSize,
                            const uint8_t** aMemory,
                            intptr_t *aHandle)
 {
   nsIPrincipal* principal = GetPrincipalForAsmJSCacheOp();
   if (!principal) {
     return false;
   }
 
   return asmjscache::OpenEntryForRead(principal, aBegin, aLimit, aSize, aMemory,
                                       aHandle);
 }
 
 static bool
 AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
                             bool aInstalled,
-                            const jschar* aBegin,
-                            const jschar* aEnd,
+                            const char16_t* aBegin,
+                            const char16_t* aEnd,
                             size_t aSize,
                             uint8_t** aMemory,
                             intptr_t* aHandle)
 {
   nsIPrincipal* principal = GetPrincipalForAsmJSCacheOp();
   if (!principal) {
     return false;
   }
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -151,17 +151,17 @@ struct ScriptLoadInfo
   bool
   ReadyToExecute()
   {
     return !mChannel && NS_SUCCEEDED(mLoadResult) && !mExecutionScheduled;
   }
 
   nsString mURL;
   nsCOMPtr<nsIChannel> mChannel;
-  jschar* mScriptTextBuf;
+  char16_t* mScriptTextBuf;
   size_t mScriptTextLength;
 
   nsresult mLoadResult;
   bool mExecutionScheduled;
   bool mExecutionResult;
 };
 
 class ScriptLoaderRunnable;
--- a/dom/xbl/nsXBLProtoImpl.cpp
+++ b/dom/xbl/nsXBLProtoImpl.cpp
@@ -332,17 +332,17 @@ nsXBLProtoImpl::ResolveAllFields(JSConte
 
 void
 nsXBLProtoImpl::UndefineFields(JSContext *cx, JS::Handle<JSObject*> obj) const
 {
   JSAutoRequest ar(cx);
   for (nsXBLProtoImplField* f = mFields; f; f = f->GetNext()) {
     nsDependentString name(f->GetName());
 
-    const jschar* s = name.get();
+    const char16_t* s = name.get();
     bool hasProp;
     if (::JS_AlreadyHasOwnUCProperty(cx, obj, s, name.Length(), &hasProp) &&
         hasProp) {
       bool dummy;
       ::JS_DeleteUCProperty2(cx, obj, s, name.Length(), &dummy);
     }
   }
 }
--- a/dom/xbl/nsXBLProtoImplField.cpp
+++ b/dom/xbl/nsXBLProtoImplField.cpp
@@ -440,17 +440,17 @@ nsXBLProtoImplField::InstallField(JS::Ha
 
 
   // Now, enter the node's compartment, wrap the eval result, and define it on
   // the bound node.
   JSAutoCompartment ac2(cx, aBoundNode);
   nsDependentString name(mName);
   if (!JS_WrapValue(cx, &result) ||
       !::JS_DefineUCProperty(cx, aBoundNode,
-                             reinterpret_cast<const jschar*>(mName),
+                             reinterpret_cast<const char16_t*>(mName),
                              name.Length(), result, mJSAttributes)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   *aDidInstall = true;
   return NS_OK;
 }
 
--- a/dom/xbl/nsXBLProtoImplMethod.cpp
+++ b/dom/xbl/nsXBLProtoImplMethod.cpp
@@ -110,17 +110,17 @@ nsXBLProtoImplMethod::InstallMember(JSCo
   JS::Rooted<JSObject*> jsMethodObject(aCx, GetCompiledMethod());
   if (jsMethodObject) {
     nsDependentString name(mName);
 
     JS::Rooted<JSObject*> method(aCx, JS_CloneFunctionObject(aCx, jsMethodObject, globalObject));
     NS_ENSURE_TRUE(method, NS_ERROR_OUT_OF_MEMORY);
 
     if (!::JS_DefineUCProperty(aCx, aTargetClassObject,
-                               static_cast<const jschar*>(mName),
+                               static_cast<const char16_t*>(mName),
                                name.Length(), method,
                                JSPROP_ENUMERATE)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
   return NS_OK;
 }
 
--- a/dom/xbl/nsXBLProtoImplProperty.cpp
+++ b/dom/xbl/nsXBLProtoImplProperty.cpp
@@ -142,17 +142,17 @@ nsXBLProtoImplProperty::InstallMember(JS
 
     if (setter) {
       if (!(setter = ::JS_CloneFunctionObject(aCx, setter, globalObject)))
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     nsDependentString name(mName);
     if (!::JS_DefineUCProperty(aCx, aTargetClassObject,
-                               static_cast<const jschar*>(mName),
+                               static_cast<const char16_t*>(mName),
                                name.Length(), JS::UndefinedHandleValue, mJSAttributes,
                                JS_DATA_TO_FUNC_PTR(JSPropertyOp, getter.get()),
                                JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, setter.get())))
       return NS_ERROR_OUT_OF_MEMORY;
   }
   return NS_OK;
 }
 
--- a/js/ipc/JavaScriptShared.cpp
+++ b/js/ipc/JavaScriptShared.cpp
@@ -588,15 +588,14 @@ JavaScriptShared::Wrap(JSContext *cx, Ha
         if (!toVariant(cx, v, &var))
             return false;
 
         outCpows->AppendElement(CpowEntry(str, var));
     }
 
     return true;
 }
-
 void JavaScriptShared::fixupAfterMovingGC()
 {
     objects_.sweep();
     cpows_.sweep();
     objectIds_.sweep();
 }
--- a/js/public/Anchor.h
+++ b/js/public/Anchor.h
@@ -22,32 +22,32 @@ namespace JS {
  * behind the scenes, finding all live values and protecting them from being
  * collected. However, when JSAPI client code obtains a pointer to data the
  * scanner does not know about, owned by an object the scanner does know about,
  * Care Must Be Taken.
  *
  * The scanner recognizes only a select set of types: pointers to JSObjects and
  * similar things (JSFunctions, and so on), pointers to JSStrings, and Values.
  * So while the scanner finds all live |JSString| pointers, it does not notice
- * |jschar| pointers.
+ * |char16_t| pointers.
  *
  * So suppose we have:
  *
  *   void f(JSString *str) {
- *     const jschar *ch = JS_GetStringCharsZ(str);
+ *     const char16_t *ch = JS_GetStringCharsZ(str);
  *     ... do stuff with ch, but no uses of str ...;
  *   }
  *
  * After the call to |JS_GetStringCharsZ|, there are no further uses of
  * |str|, which means that the compiler is within its rights to not store
  * it anywhere. But because the stack scanner will not notice |ch|, there
  * is no longer any live value in this frame that would keep the string
  * alive. If |str| is the last reference to that |JSString|, and the
- * collector runs while we are using |ch|, the string's array of |jschar|s
- * may be freed out from under us.
+ * collector runs while we are using |ch|, the string's array of |char16_t|
+ * characters may be freed out from under us.
  *
  * Note that there is only an issue when 1) we extract a thing X the scanner
  * doesn't recognize from 2) a thing Y the scanner does recognize, and 3) if Y
  * gets garbage-collected, then X gets freed. If we have code like this:
  *
  *   void g(JSObject *obj) {
  *     JS::Value x;
  *     JS_GetProperty(obj, "x", &x);
@@ -62,17 +62,17 @@ namespace JS {
  * their owners, as the derived value alone won't keep them alive.
  *
  * A JS::Anchor is a kind of GC root that allows us to keep the owners of
  * derived values like |ch| alive throughout the Anchor's lifetime. We could
  * fix the above code as follows:
  *
  *   void f(JSString *str) {
  *     JS::Anchor<JSString *> a_str(str);
- *     const jschar *ch = JS_GetStringCharsZ(str);
+ *     const char16_t *ch = JS_GetStringCharsZ(str);
  *     ... do stuff with ch, but no uses of str ...;
  *   }
  *
  * This simply ensures that |str| will be live until |a_str| goes out of scope.
  * As long as we don't retain a pointer to the string's characters for longer
  * than that, we have avoided all garbage collection hazards.
  */
 template<typename T> class AnchorPermitted;
--- a/js/public/CharacterEncoding.h
+++ b/js/public/CharacterEncoding.h
@@ -113,87 +113,86 @@ class UTF8CharsZ : public mozilla::Range
 /*
  * SpiderMonkey uses a 2-byte character representation: it is a
  * 2-byte-at-a-time view of a UTF-16 byte stream. This is similar to UCS-2,
  * but unlike UCS-2, we do not strip UTF-16 extension bytes. This allows a
  * sufficiently dedicated JavaScript program to be fully unicode-aware by
  * manually interpreting UTF-16 extension characters embedded in the JS
  * string.
  */
-class TwoByteChars : public mozilla::Range<jschar>
+class TwoByteChars : public mozilla::Range<char16_t>
 {
-    typedef mozilla::Range<jschar> Base;
+    typedef mozilla::Range<char16_t> Base;
 
   public:
     TwoByteChars() : Base() {}
-    TwoByteChars(jschar *aChars, size_t aLength) : Base(aChars, aLength) {}
-    TwoByteChars(const jschar *aChars, size_t aLength) : Base(const_cast<jschar *>(aChars), aLength) {}
+    TwoByteChars(char16_t *aChars, size_t aLength) : Base(aChars, aLength) {}
+    TwoByteChars(const char16_t *aChars, size_t aLength) : Base(const_cast<char16_t *>(aChars), aLength) {}
 };
 
 /*
  * A TwoByteChars, but \0 terminated for compatibility with JSFlatString.
  */
-class TwoByteCharsZ : public mozilla::RangedPtr<jschar>
+class TwoByteCharsZ : public mozilla::RangedPtr<char16_t>
 {
-    typedef mozilla::RangedPtr<jschar> Base;
+    typedef mozilla::RangedPtr<char16_t> Base;
 
   public:
     TwoByteCharsZ() : Base(nullptr, 0) {}
 
-    TwoByteCharsZ(jschar *chars, size_t length)
+    TwoByteCharsZ(char16_t *chars, size_t length)
       : Base(chars, length)
     {
         MOZ_ASSERT(chars[length] == '\0');
     }
 
     using Base::operator=;
 };
 
-typedef mozilla::RangedPtr<const jschar> ConstCharPtr;
+typedef mozilla::RangedPtr<const char16_t> ConstCharPtr;
 
 /*
  * Like TwoByteChars, but the chars are const.
  */
-class ConstTwoByteChars : public mozilla::RangedPtr<const jschar>
+class ConstTwoByteChars : public mozilla::RangedPtr<const char16_t>
 {
   public:
     ConstTwoByteChars(const ConstTwoByteChars &s) : ConstCharPtr(s) {}
-    MOZ_IMPLICIT ConstTwoByteChars(const mozilla::RangedPtr<const jschar> &s) : ConstCharPtr(s) {}
-    ConstTwoByteChars(const jschar *s, size_t len) : ConstCharPtr(s, len) {}
-    ConstTwoByteChars(const jschar *pos, const jschar *start, size_t len)
+    MOZ_IMPLICIT ConstTwoByteChars(const mozilla::RangedPtr<const char16_t> &s) : ConstCharPtr(s) {}
+    ConstTwoByteChars(const char16_t *s, size_t len) : ConstCharPtr(s, len) {}
+    ConstTwoByteChars(const char16_t *pos, const char16_t *start, size_t len)
       : ConstCharPtr(pos, start, len)
     {}
 
     using ConstCharPtr::operator=;
 };
 
-
 /*
  * Convert a 2-byte character sequence to "ISO-Latin-1". This works by
  * truncating each 2-byte pair in the sequence to a 1-byte pair. If the source
  * contains any UTF-16 extension characters, then this may give invalid Latin1
  * output. The returned string is zero terminated. The returned string or the
  * returned string's |start()| must be freed with JS_free or js_free,
  * respectively. If allocation fails, an OOM error will be set and the method
  * will return a nullptr chars (which can be tested for with the ! operator).
  * This method cannot trigger GC.
  */
 extern Latin1CharsZ
 LossyTwoByteCharsToNewLatin1CharsZ(js::ThreadSafeContext *cx,
-                                   const mozilla::Range<const jschar> tbchars);
+                                   const mozilla::Range<const char16_t> tbchars);
 
 template <typename CharT>
 extern UTF8CharsZ
 CharsToNewUTF8CharsZ(js::ThreadSafeContext *cx, const mozilla::Range<const CharT> chars);
 
 uint32_t
 Utf8ToOneUcs4Char(const uint8_t *utf8Buffer, int utf8Length);
 
 /*
- * Inflate bytes in UTF-8 encoding to jschars.
+ * Inflate bytes in UTF-8 encoding to char16_t.
  * - On error, returns an empty TwoByteCharsZ.
  * - On success, returns a malloc'd TwoByteCharsZ, and updates |outlen| to hold
  *   its length;  the length value excludes the trailing null.
  */
 extern TwoByteCharsZ
 UTF8CharsToNewTwoByteCharsZ(JSContext *cx, const UTF8Chars utf8, size_t *outlen);
 
 /*
--- a/js/public/Class.h
+++ b/js/public/Class.h
@@ -147,17 +147,17 @@ typedef bool
 // Finalize obj, which the garbage collector has determined to be unreachable
 // from other live objects or from GC roots.  Obviously, finalizers must never
 // store a reference to obj.
 typedef void
 (* JSFinalizeOp)(JSFreeOp *fop, JSObject *obj);
 
 // Finalizes external strings created by JS_NewExternalString.
 struct JSStringFinalizer {
-    void (*finalize)(const JSStringFinalizer *fin, jschar *chars);
+    void (*finalize)(const JSStringFinalizer *fin, char16_t *chars);
 };
 
 // Check whether v is an instance of obj.  Return false on error or exception,
 // true on success with true in *bp if v is an instance of obj, false in
 // *bp otherwise.
 typedef bool
 (* JSHasInstanceOp)(JSContext *cx, JS::HandleObject obj, JS::MutableHandleValue vp,
                     bool *bp);
--- a/js/public/GCAPI.h
+++ b/js/public/GCAPI.h
@@ -245,18 +245,18 @@ enum GCProgress {
 };
 
 struct JS_FRIEND_API(GCDescription) {
     bool isCompartment_;
 
     explicit GCDescription(bool isCompartment)
       : isCompartment_(isCompartment) {}
 
-    jschar *formatMessage(JSRuntime *rt) const;
-    jschar *formatJSON(JSRuntime *rt, uint64_t timestamp) const;
+    char16_t *formatMessage(JSRuntime *rt) const;
+    char16_t *formatJSON(JSRuntime *rt, uint64_t timestamp) const;
 };
 
 typedef void
 (* GCSliceCallback)(JSRuntime *rt, GCProgress progress, const GCDescription &desc);
 
 /*
  * The GC slice callback is called at the beginning and end of each slice. This
  * callback may be used for GC notifications as well as to perform additional
--- a/js/public/OldDebugAPI.h
+++ b/js/public/OldDebugAPI.h
@@ -70,17 +70,17 @@ extern JS_PUBLIC_API(JSScript *)
 JS_GetFunctionScript(JSContext *cx, JS::HandleFunction fun);
 
 
 /************************************************************************/
 
 extern JS_PUBLIC_API(const char *)
 JS_GetScriptFilename(JSScript *script);
 
-extern JS_PUBLIC_API(const jschar *)
+extern JS_PUBLIC_API(const char16_t *)
 JS_GetScriptSourceMap(JSContext *cx, JSScript *script);
 
 extern JS_PUBLIC_API(unsigned)
 JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script);
 
 extern JS_PUBLIC_API(unsigned)
 JS_GetScriptLineExtent(JSContext *cx, JSScript *script);
 
--- a/js/public/TypeDecls.h
+++ b/js/public/TypeDecls.h
@@ -26,18 +26,16 @@ struct JSContext;
 class JSFunction;
 class JSObject;
 class JSScript;
 class JSString;
 class JSAddonId;
 
 struct jsid;
 
-typedef char16_t jschar;
-
 namespace JS {
 
 typedef unsigned char Latin1Char;
 
 class Symbol;
 class Value;
 template <typename T> class Handle;
 template <typename T> class MutableHandle;
--- a/js/public/UbiNode.h
+++ b/js/public/UbiNode.h
@@ -183,17 +183,17 @@ class Base {
     }
     bool operator!=(const Base &rhs) const { return !(*this == rhs); }
 
     // Return a human-readable name for the referent's type. The result should
     // be statically allocated. (You can use MOZ_UTF16("strings") for this.)
     //
     // This must always return Concrete<T>::concreteTypeName; we use that
     // pointer as a tag for this particular referent type.
-    virtual const jschar *typeName() const = 0;
+    virtual const char16_t *typeName() const = 0;
 
     // Return the size of this node, in bytes. Include any structures that this
     // node owns exclusively that are not exposed as their own ubi::Nodes.
     virtual size_t size() const = 0;
 
     // Return an EdgeRange that initially contains all the referent's outgoing
     // edges. The EdgeRange should be freed with 'js_delete'. (You could use
     // ScopedDJSeletePtr<EdgeRange> to manage it.) On OOM, report an exception
@@ -219,18 +219,18 @@ class Base {
 };
 
 // A traits template with a specialization for each referent type that
 // ubi::Node supports. The specialization must be the concrete subclass of
 // Base that represents a pointer to the referent type. It must also
 // include the members described here.
 template<typename Referent>
 struct Concrete {
-    // The specific jschar array returned by Concrete<T>::typeName.
-    static const jschar concreteTypeName[];
+    // The specific char16_t array returned by Concrete<T>::typeName.
+    static const char16_t concreteTypeName[];
 
     // Construct an instance of this concrete class in |storage| referring
     // to |referent|. Implementations typically use a placement 'new'.
     //
     // In some cases, |referent| will contain dynamic type information that
     // identifies it a some more specific subclass of |Referent|. For example,
     // when |Referent| is |JSObject|, then |referent->getClass()| could tell us
     // that it's actually a JSFunction. Similarly, if |Referent| is
@@ -329,17 +329,17 @@ class Node {
     }
 
     // If this node refers to something that can be represented as a JavaScript
     // value that is safe to expose to JavaScript code, return that value.
     // Otherwise return UndefinedValue(). JSStrings, JS::Symbols, and some (but
     // not all!) JSObjects can be exposed.
     JS::Value exposeToJS() const;
 
-    const jschar *typeName()        const { return base()->typeName(); }
+    const char16_t *typeName()      const { return base()->typeName(); }
     size_t size()                   const { return base()->size(); }
     JS::Zone *zone()                const { return base()->zone(); }
     JSCompartment *compartment()    const { return base()->compartment(); }
     EdgeRange *edges(JSContext *cx, bool wantNames = true) const {
         return base()->edges(cx, wantNames);
     }
 
     // A hash policy for ubi::Nodes.
@@ -374,17 +374,17 @@ class Edge {
     // false as the wantNames parameter.
     //
     // The storage is owned by this Edge, and will be freed when this Edge is
     // destructed.
     //
     // (In real life we'll want a better representation for names, to avoid
     // creating tons of strings when the names follow a pattern; and we'll need
     // to think about lifetimes carefully to ensure traversal stays cheap.)
-    const jschar *name;
+    const char16_t *name;
 
     // This edge's referent.
     Node referent;
 
   private:
     Edge(const Edge &) MOZ_DELETE;
     Edge &operator=(const Edge &) MOZ_DELETE;
 };
@@ -427,28 +427,28 @@ class EdgeRange {
 
 
 // Concrete classes for ubi::Node referent types.
 
 // A reusable ubi::Concrete specialization base class for types supported by
 // JS_TraceChildren.
 template<typename Referent>
 class TracerConcrete : public Base {
-    const jschar *typeName() const MOZ_OVERRIDE { return concreteTypeName; }
+    const char16_t *typeName() const MOZ_OVERRIDE { return concreteTypeName; }
     size_t size() const MOZ_OVERRIDE { return 0; } // not implemented yet; bug 1011300
     EdgeRange *edges(JSContext *, bool wantNames) const MOZ_OVERRIDE;
     JS::Zone *zone() const MOZ_OVERRIDE { return get().zone(); }
     JSCompartment *compartment() const MOZ_OVERRIDE { return nullptr; }
 
   protected:
     explicit TracerConcrete(Referent *ptr) : Base(ptr) { }
     Referent &get() const { return *static_cast<Referent *>(ptr); }
 
   public:
-    static const jschar concreteTypeName[];
+    static const char16_t concreteTypeName[];
     static void construct(void *storage, Referent *ptr) { new (storage) TracerConcrete(ptr); }
 };
 
 // For JS_TraceChildren-based types that have a 'compartment' method.
 template<typename Referent>
 class TracerConcreteWithCompartment : public TracerConcrete<Referent> {
     typedef TracerConcrete<Referent> TracerBase;
     JSCompartment *compartment() const MOZ_OVERRIDE {
@@ -471,27 +471,27 @@ template<> struct Concrete<js::LazyScrip
 template<> struct Concrete<js::jit::JitCode> : TracerConcrete<js::jit::JitCode> { };
 template<> struct Concrete<js::Shape> : TracerConcreteWithCompartment<js::Shape> { };
 template<> struct Concrete<js::BaseShape> : TracerConcreteWithCompartment<js::BaseShape> { };
 template<> struct Concrete<js::types::TypeObject> : TracerConcrete<js::types::TypeObject> { };
 
 // The ubi::Node null pointer. Any attempt to operate on a null ubi::Node asserts.
 template<>
 class Concrete<void> : public Base {
-    const jschar *typeName() const MOZ_OVERRIDE;
+    const char16_t *typeName() const MOZ_OVERRIDE;
     size_t size() const MOZ_OVERRIDE;
     EdgeRange *edges(JSContext *cx, bool wantNames) const MOZ_OVERRIDE;
     JS::Zone *zone() const MOZ_OVERRIDE;
     JSCompartment *compartment() const MOZ_OVERRIDE;
 
     explicit Concrete(void *ptr) : Base(ptr) { }
 
   public:
     static void construct(void *storage, void *ptr) { new (storage) Concrete(ptr); }
-    static const jschar concreteTypeName[];
+    static const char16_t concreteTypeName[];
 };
 
 
 } // namespace ubi
 } // namespace JS
 
 namespace js {
 
--- a/js/src/asmjs/AsmJSLink.cpp
+++ b/js/src/asmjs/AsmJSLink.cpp
@@ -750,17 +750,17 @@ HandleDynamicLinkFailure(JSContext *cx, 
     // also inherited it somehow.
     if (module.strict())
         options.strictOption = true;
 
     AutoStableStringChars stableChars(cx);
     if (!stableChars.initTwoByte(cx, src))
         return false;
 
-    const jschar *chars = stableChars.twoByteRange().start().get();
+    const char16_t *chars = stableChars.twoByteRange().start().get();
     SourceBufferHolder::Ownership ownership = stableChars.maybeGiveOwnershipToCaller()
                                               ? SourceBufferHolder::GiveOwnership
                                               : SourceBufferHolder::NoOwnership;
     SourceBufferHolder srcBuf(chars, end - begin, ownership);
     if (!frontend::CompileFunctionBody(cx, &fun, options, formals, srcBuf))
         return false;
 
     // Call the function we just recompiled.
--- a/js/src/asmjs/AsmJSModule.cpp
+++ b/js/src/asmjs/AsmJSModule.cpp
@@ -908,17 +908,17 @@ ReadScalar(const uint8_t *src, T *dst)
     return src + sizeof(*dst);
 }
 
 static size_t
 SerializedNameSize(PropertyName *name)
 {
     size_t s = sizeof(uint32_t);
     if (name)
-        s += name->length() * (name->hasLatin1Chars() ? sizeof(Latin1Char) : sizeof(jschar));
+        s += name->length() * (name->hasLatin1Chars() ? sizeof(Latin1Char) : sizeof(char16_t));
     return s;
 }
 
 size_t
 AsmJSModule::Name::serializedSize() const
 {
     return SerializedNameSize(name_);
 }
@@ -931,17 +931,17 @@ SerializeName(uint8_t *cursor, PropertyN
         static_assert(JSString::MAX_LENGTH <= INT32_MAX, "String length must fit in 31 bits");
         uint32_t length = name->length();
         uint32_t lengthAndEncoding = (length << 1) | uint32_t(name->hasLatin1Chars());
         cursor = WriteScalar<uint32_t>(cursor, lengthAndEncoding);
         JS::AutoCheckCannotGC nogc;
         if (name->hasLatin1Chars())
             cursor = WriteBytes(cursor, name->latin1Chars(nogc), length * sizeof(Latin1Char));
         else
-            cursor = WriteBytes(cursor, name->twoByteChars(nogc), length * sizeof(jschar));
+            cursor = WriteBytes(cursor, name->twoByteChars(nogc), length * sizeof(char16_t));
     } else {
         cursor = WriteScalar<uint32_t>(cursor, 0);
     }
     return cursor;
 }
 
 uint8_t *
 AsmJSModule::Name::serialize(uint8_t *cursor) const
@@ -983,17 +983,17 @@ DeserializeName(ExclusiveContext *cx, co
     if (length == 0) {
         *name = nullptr;
         return cursor;
     }
 
     bool latin1 = lengthAndEncoding & 0x1;
     return latin1
            ? DeserializeChars<Latin1Char>(cx, cursor, length, name)
-           : DeserializeChars<jschar>(cx, cursor, length, name);
+           : DeserializeChars<char16_t>(cx, cursor, length, name);
 }
 
 const uint8_t *
 AsmJSModule::Name::deserialize(ExclusiveContext *cx, const uint8_t *cursor)
 {
     return DeserializeName(cx, cursor, &name_);
 }
 
@@ -1905,25 +1905,25 @@ class ModuleCharsForStore : ModuleChars
     uint32_t uncompressedSize_;
     uint32_t compressedSize_;
     Vector<char, 0, SystemAllocPolicy> compressedBuffer_;
 
   public:
     bool init(AsmJSParser &parser) {
         JS_ASSERT(beginOffset(parser) < endOffset(parser));
 
-        uncompressedSize_ = (endOffset(parser) - beginOffset(parser)) * sizeof(jschar);
+        uncompressedSize_ = (endOffset(parser) - beginOffset(parser)) * sizeof(char16_t);
         size_t maxCompressedSize = LZ4::maxCompressedSize(uncompressedSize_);
         if (maxCompressedSize < uncompressedSize_)
             return false;
 
         if (!compressedBuffer_.resize(maxCompressedSize))
             return false;
 
-        const jschar *chars = parser.tokenStream.rawBase() + beginOffset(parser);
+        const char16_t *chars = parser.tokenStream.rawBase() + beginOffset(parser);
         const char *source = reinterpret_cast<const char*>(chars);
         size_t compressedSize = LZ4::compress(source, uncompressedSize_, compressedBuffer_.begin());
         if (!compressedSize || compressedSize > UINT32_MAX)
             return false;
 
         compressedSize_ = compressedSize;
 
         // For a function statement or named function expression:
@@ -1967,27 +1967,27 @@ class ModuleCharsForStore : ModuleChars
         if (isFunCtor_)
             cursor = SerializeVector(cursor, funCtorArgs_);
         return cursor;
     }
 };
 
 class ModuleCharsForLookup : ModuleChars
 {
-    Vector<jschar, 0, SystemAllocPolicy> chars_;
+    Vector<char16_t, 0, SystemAllocPolicy> chars_;
 
   public:
     const uint8_t *deserialize(ExclusiveContext *cx, const uint8_t *cursor) {
         uint32_t uncompressedSize;
         cursor = ReadScalar<uint32_t>(cursor, &uncompressedSize);
 
         uint32_t compressedSize;
         cursor = ReadScalar<uint32_t>(cursor, &compressedSize);
 
-        if (!chars_.resize(uncompressedSize / sizeof(jschar)))
+        if (!chars_.resize(uncompressedSize / sizeof(char16_t)))
             return nullptr;
 
         const char *source = reinterpret_cast<const char*>(cursor);
         char *dest = reinterpret_cast<char*>(chars_.begin());
         if (!LZ4::decompress(source, dest, uncompressedSize))
             return nullptr;
 
         cursor += compressedSize;
@@ -1995,18 +1995,18 @@ class ModuleCharsForLookup : ModuleChars
         cursor = ReadScalar<uint32_t>(cursor, &isFunCtor_);
         if (isFunCtor_)
             cursor = DeserializeVector(cx, cursor, &funCtorArgs_);
 
         return cursor;
     }
 
     bool match(AsmJSParser &parser) const {
-        const jschar *parseBegin = parser.tokenStream.rawBase() + beginOffset(parser);
-        const jschar *parseLimit = parser.tokenStream.rawLimit();
+        const char16_t *parseBegin = parser.tokenStream.rawBase() + beginOffset(parser);
+        const char16_t *parseLimit = parser.tokenStream.rawLimit();
         JS_ASSERT(parseLimit >= parseBegin);
         if (uint32_t(parseLimit - parseBegin) < chars_.length())
             return false;
         if (!PodEqual(chars_.begin(), parseBegin, chars_.length()))
             return false;
         if (isFunCtor_ != parser.pc->isFunctionConstructorBody())
             return false;
         if (isFunCtor_) {
@@ -2072,18 +2072,18 @@ js::StoreAsmJSModuleInCache(AsmJSParser 
     size_t serializedSize = machineId.serializedSize() +
                             moduleChars.serializedSize() +
                             module.serializedSize();
 
     JS::OpenAsmJSCacheEntryForWriteOp open = cx->asmJSCacheOps().openEntryForWrite;
     if (!open)
         return false;
 
-    const jschar *begin = parser.tokenStream.rawBase() + ModuleChars::beginOffset(parser);
-    const jschar *end = parser.tokenStream.rawBase() + ModuleChars::endOffset(parser);
+    const char16_t *begin = parser.tokenStream.rawBase() + ModuleChars::beginOffset(parser);
+    const char16_t *end = parser.tokenStream.rawBase() + ModuleChars::endOffset(parser);
     bool installed = parser.options().installedFile;
 
     ScopedCacheEntryOpenedForWrite entry(cx, serializedSize);
     if (!open(cx->global(), installed, begin, end, entry.serializedSize,
               &entry.memory, &entry.handle)) {
         return false;
     }
 
@@ -2124,18 +2124,18 @@ js::LookupAsmJSModuleInCache(ExclusiveCo
     MachineId machineId;
     if (!machineId.extractCurrentState(cx))
         return true;
 
     JS::OpenAsmJSCacheEntryForReadOp open = cx->asmJSCacheOps().openEntryForRead;
     if (!open)
         return true;
 
-    const jschar *begin = parser.tokenStream.rawBase() + ModuleChars::beginOffset(parser);
-    const jschar *limit = parser.tokenStream.rawLimit();
+    const char16_t *begin = parser.tokenStream.rawBase() + ModuleChars::beginOffset(parser);
+    const char16_t *limit = parser.tokenStream.rawLimit();
 
     ScopedCacheEntryOpenedForRead entry(cx);
     if (!open(cx->global(), begin, limit, &entry.serializedSize, &entry.memory, &entry.handle))
         return true;
 
     const uint8_t *cursor = entry.memory;
 
     MachineId cachedMachineId;
--- a/js/src/builtin/Eval.cpp
+++ b/js/src/builtin/Eval.cpp
@@ -165,17 +165,17 @@ EvalStringMightBeJSON(const mozilla::Ran
         // Rather than force the JSON parser to handle this quirk when used by
         // eval, we simply don't use the JSON parser when either character
         // appears in the provided string.  See bug 657367.
         if (sizeof(CharT) > 1) {
             for (RangedPtr<const CharT> cp = chars.start() + 1, end = chars.end() - 1;
                  cp < end;
                  cp++)
             {
-                jschar c = *cp;
+                char16_t c = *cp;
                 if (c == 0x2028 || c == 0x2029)
                     return false;
             }
         }
 
         return true;
     }
     return false;
@@ -331,17 +331,17 @@ EvalKernel(JSContext *cx, const CallArgs
                .setNoScriptRval(false)
                .setOriginPrincipals(originPrincipals)
                .setIntroductionInfo(introducerFilename, "eval", lineno, maybeScript, pcOffset);
 
         AutoStableStringChars flatChars(cx);
         if (!flatChars.initTwoByte(cx, flatStr))
             return false;
 
-        const jschar *chars = flatChars.twoByteRange().start().get();
+        const char16_t *chars = flatChars.twoByteRange().start().get();
         SourceBufferHolder::Ownership ownership = flatChars.maybeGiveOwnershipToCaller()
                                                   ? SourceBufferHolder::GiveOwnership
                                                   : SourceBufferHolder::NoOwnership;
         SourceBufferHolder srcBuf(chars, flatStr->length(), ownership);
         JSScript *compiled = frontend::CompileScript(cx, &cx->tempLifoAlloc(),
                                                      scopeobj, callerScript, options,
                                                      srcBuf, flatStr, staticLevel);
         if (!compiled)
@@ -404,17 +404,17 @@ js::DirectEvalStringFromIon(JSContext *c
                .setNoScriptRval(false)
                .setOriginPrincipals(originPrincipals)
                .setIntroductionInfo(introducerFilename, "eval", lineno, maybeScript, pcOffset);
 
         AutoStableStringChars flatChars(cx);
         if (!flatChars.initTwoByte(cx, flatStr))
             return false;
 
-        const jschar *chars = flatChars.twoByteRange().start().get();
+        const char16_t *chars = flatChars.twoByteRange().start().get();
         SourceBufferHolder::Ownership ownership = flatChars.maybeGiveOwnershipToCaller()
                                                   ? SourceBufferHolder::GiveOwnership
                                                   : SourceBufferHolder::NoOwnership;
         SourceBufferHolder srcBuf(chars, flatStr->length(), ownership);
         JSScript *compiled = frontend::CompileScript(cx, &cx->tempLifoAlloc(),
                                                      scopeobj, callerScript, options,
                                                      srcBuf, flatStr, staticLevel);
         if (!compiled)
--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -541,17 +541,17 @@ class ScopedICUObject
     // to transfer the object just before returning.
     T *forget() {
         T *tmp = ptr_;
         ptr_ = nullptr;
         return tmp;
     }
 };
 
-// The inline capacity we use for the jschar Vectors.
+// The inline capacity we use for the char16_t Vectors.
 static const size_t INITIAL_CHAR_BUFFER_SIZE = 32;
 
 /******************** Collator ********************/
 
 static void collator_finalize(FreeOp *fop, JSObject *obj);
 
 static const uint32_t UCOLLATOR_SLOT = 0;
 static const uint32_t COLLATOR_SLOTS_COUNT = 1;
@@ -968,22 +968,22 @@ intl_CompareStrings(JSContext *cx, UColl
     AutoStableStringChars stableChars1(cx);
     if (!stableChars1.initTwoByte(cx, str1))
         return false;
 
     AutoStableStringChars stableChars2(cx);
     if (!stableChars2.initTwoByte(cx, str2))
         return false;
 
-    mozilla::Range<const jschar> chars1 = stableChars1.twoByteRange();
-    mozilla::Range<const jschar> chars2 = stableChars2.twoByteRange();
+    mozilla::Range<const char16_t> chars1 = stableChars1.twoByteRange();
+    mozilla::Range<const char16_t> chars2 = stableChars2.twoByteRange();
 
     UCollationResult uresult = ucol_strcoll(coll,
-                                            JSCharToUChar(chars1.start().get()), chars1.length(),
-                                            JSCharToUChar(chars2.start().get()), chars2.length());
+                                            Char16ToUChar(chars1.start().get()), chars1.length(),
+                                            Char16ToUChar(chars2.start().get()), chars2.length());
     int32_t res;
     switch (uresult) {
         case UCOL_LESS: res = -1; break;
         case UCOL_EQUAL: res = 0; break;
         case UCOL_GREATER: res = 1; break;
         default: MOZ_CRASH("ucol_strcoll returned bad UCollationResult");
     }
     result.setInt32(res);
@@ -1318,17 +1318,17 @@ NewUNumberFormat(JSContext *cx, HandleOb
     if (equal(style, "currency")) {
         if (!JSObject::getProperty(cx, internals, internals, cx->names().currency, &value))
             return nullptr;
         currency = value.toString();
         MOZ_ASSERT(currency->length() == 3, "IsWellFormedCurrencyCode permits only length-3 strings");
         if (!currency->ensureFlat(cx) || !stableChars.initTwoByte(cx, currency))
             return nullptr;
         // uCurrency remains owned by stableChars.
-        uCurrency = JSCharToUChar(stableChars.twoByteRange().start().get());
+        uCurrency = Char16ToUChar(stableChars.twoByteRange().start().get());
         if (!uCurrency)
             return nullptr;
 
         if (!JSObject::getProperty(cx, internals, internals, cx->names().currencyDisplay, &value))
             return nullptr;
         JSAutoByteString currencyDisplay(cx, value.toString());
         if (!currencyDisplay)
             return nullptr;
@@ -1421,27 +1421,27 @@ NewUNumberFormat(JSContext *cx, HandleOb
 
 static bool
 intl_FormatNumber(JSContext *cx, UNumberFormat *nf, double x, MutableHandleValue result)
 {
     // FormatNumber doesn't consider -0.0 to be negative.
     if (IsNegativeZero(x))
         x = 0.0;
 
-    Vector<jschar, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
+    Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
     if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
         return false;
     UErrorCode status = U_ZERO_ERROR;
-    int size = unum_formatDouble(nf, x, JSCharToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE,
+    int size = unum_formatDouble(nf, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE,
                                  nullptr, &status);
     if (status == U_BUFFER_OVERFLOW_ERROR) {
         if (!chars.resize(size))
             return false;
         status = U_ZERO_ERROR;
-        unum_formatDouble(nf, x, JSCharToUChar(chars.begin()), size, nullptr, &status);
+        unum_formatDouble(nf, x, Char16ToUChar(chars.begin()), size, nullptr, &status);
     }
     if (U_FAILURE(status)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
         return false;
     }
 
     JSString *str = NewStringCopyN<CanGC>(cx, chars.begin(), size);
     if (!str)
@@ -1794,46 +1794,46 @@ js::intl_patternForSkeleton(JSContext *c
     JSFlatString *skeletonFlat = args[1].toString()->ensureFlat(cx);
     if (!skeletonFlat)
         return false;
 
     AutoStableStringChars stableChars(cx);
     if (!stableChars.initTwoByte(cx, skeletonFlat))
         return false;
 
-    mozilla::Range<const jschar> skeletonChars = stableChars.twoByteRange();
-    uint32_t skeletonLen = u_strlen(JSCharToUChar(skeletonChars.start().get()));
+    mozilla::Range<const char16_t> skeletonChars = stableChars.twoByteRange();
+    uint32_t skeletonLen = u_strlen(Char16ToUChar(skeletonChars.start().get()));
 
     UErrorCode status = U_ZERO_ERROR;
     UDateTimePatternGenerator *gen = udatpg_open(icuLocale(locale.ptr()), &status);
     if (U_FAILURE(status)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
         return false;
     }
     ScopedICUObject<UDateTimePatternGenerator> toClose(gen, udatpg_close);
 
-    int32_t size = udatpg_getBestPattern(gen, JSCharToUChar(skeletonChars.start().get()),
+    int32_t size = udatpg_getBestPattern(gen, Char16ToUChar(skeletonChars.start().get()),
                                          skeletonLen, nullptr, 0, &status);
     if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
         return false;
     }
     ScopedJSFreePtr<UChar> pattern(cx->pod_malloc<UChar>(size + 1));
     if (!pattern)
         return false;
     pattern[size] = '\0';
     status = U_ZERO_ERROR;
-    udatpg_getBestPattern(gen, JSCharToUChar(skeletonChars.start().get()),
+    udatpg_getBestPattern(gen, Char16ToUChar(skeletonChars.start().get()),
                           skeletonLen, pattern, size, &status);
     if (U_FAILURE(status)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
         return false;
     }
 
-    RootedString str(cx, JS_NewUCStringCopyZ(cx, reinterpret_cast<jschar*>(pattern.get())));
+    RootedString str(cx, JS_NewUCStringCopyZ(cx, reinterpret_cast<char16_t*>(pattern.get())));
     if (!str)
         return false;
     args.rval().setString(str);
     return true;
 }
 
 /**
  * Returns a new UDateFormat with the locale and date-time formatting options
@@ -1873,31 +1873,31 @@ NewUDateFormat(JSContext *cx, HandleObje
     AutoStableStringChars timeZoneChars(cx);
     if (hasP) {
         if (!JSObject::getProperty(cx, internals, internals, cx->names().timeZone, &value))
             return nullptr;
         if (!value.isUndefined()) {
             JSFlatString *flat = value.toString()->ensureFlat(cx);
             if (!flat || !timeZoneChars.initTwoByte(cx, flat))
                 return nullptr;
-            uTimeZone = JSCharToUChar(timeZoneChars.twoByteRange().start().get());
+            uTimeZone = Char16ToUChar(timeZoneChars.twoByteRange().start().get());
             if (!uTimeZone)
                 return nullptr;
             uTimeZoneLength = u_strlen(uTimeZone);
         }
     }
     if (!JSObject::getProperty(cx, internals, internals, cx->names().pattern, &value))
         return nullptr;
 
     AutoStableStringChars patternChars(cx);
     JSFlatString *flat = value.toString()->ensureFlat(cx);
     if (!flat || !patternChars.initTwoByte(cx, flat))
         return nullptr;
 
-    uPattern = JSCharToUChar(patternChars.twoByteRange().start().get());
+    uPattern = Char16ToUChar(patternChars.twoByteRange().start().get());
     if (!uPattern)
         return nullptr;
     uPatternLength = u_strlen(uPattern);
 
     UErrorCode status = U_ZERO_ERROR;
 
     // If building with ICU headers before 50.1, use UDAT_IGNORE instead of
     // UDAT_PATTERN.
@@ -1922,27 +1922,27 @@ NewUDateFormat(JSContext *cx, HandleObje
 static bool
 intl_FormatDateTime(JSContext *cx, UDateFormat *df, double x, MutableHandleValue result)
 {
     if (!IsFinite(x)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DATE_NOT_FINITE);
         return false;
     }
 
-    Vector<jschar, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
+    Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
     if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
         return false;
     UErrorCode status = U_ZERO_ERROR;
-    int size = udat_format(df, x, JSCharToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE,
+    int size = udat_format(df, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE,
                            nullptr, &status);
     if (status == U_BUFFER_OVERFLOW_ERROR) {
         if (!chars.resize(size))
             return false;
         status = U_ZERO_ERROR;
-        udat_format(df, x, JSCharToUChar(chars.begin()), size, nullptr, &status);
+        udat_format(df, x, Char16ToUChar(chars.begin()), size, nullptr, &status);
     }
     if (U_FAILURE(status)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
         return false;
     }
 
     JSString *str = NewStringCopyN<CanGC>(cx, chars.begin(), size);
     if (!str)
--- a/js/src/builtin/Intl.h
+++ b/js/src/builtin/Intl.h
@@ -175,25 +175,25 @@ intl_patternForSkeleton(JSContext *cx, u
  * Spec: ECMAScript Internationalization API Specification, 12.3.2.
  *
  * Usage: formatted = intl_FormatDateTime(dateTimeFormat, x)
  */
 extern bool
 intl_FormatDateTime(JSContext *cx, unsigned argc, Value *vp);
 
 /**
- * Cast jschar* strings to UChar* strings used by ICU.
+ * Cast char16_t* strings to UChar* strings used by ICU.
  */
 inline const UChar *
-JSCharToUChar(const jschar *chars)
+Char16ToUChar(const char16_t *chars)
 {
   return reinterpret_cast<const UChar *>(chars);
 }
 
 inline UChar *
-JSCharToUChar(jschar *chars)
+Char16ToUChar(char16_t *chars)
 {
   return reinterpret_cast<UChar *>(chars);
 }
 
 } // namespace js
 
 #endif /* builtin_Intl_h */
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -224,17 +224,17 @@ js::ObjectToSource(JSContext *cx, Handle
             /*
              * If id is a string that's not an identifier, or if it's a negative
              * integer, then it must be quoted.
              */
             if (JSID_IS_ATOM(id)
                 ? !IsIdentifier(JSID_TO_ATOM(id))
                 : JSID_TO_INT(id) < 0)
             {
-                idstr = js_QuoteString(cx, idstr, jschar('\''));
+                idstr = js_QuoteString(cx, idstr, char16_t('\''));
                 if (!idstr)
                     return nullptr;
             }
         }
 
         for (int j = 0; j < valcnt; j++) {
             /*
              * Censor an accessor descriptor getter or setter part if it's
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -139,17 +139,17 @@ template <typename CharT>
 static bool
 EscapeNakedForwardSlashes(StringBuffer &sb, const CharT *oldChars, size_t oldLen)
 {
     for (const CharT *it = oldChars; it < oldChars + oldLen; ++it) {
         if (*it == '/' && (it == oldChars || it[-1] != '\\')) {
             /* There's a forward slash that needs escaping. */
             if (sb.empty()) {
                 /* This is the first one we've seen, copy everything up to this point. */
-                if (mozilla::IsSame<CharT, jschar>::value && !sb.ensureTwoByteChars())
+                if (mozilla::IsSame<CharT, char16_t>::value && !sb.ensureTwoByteChars())
                     return false;
 
                 if (!sb.reserve(oldLen + 1))
                     return false;
 
                 sb.infallibleAppend(oldChars, size_t(it - oldChars));
             }
             if (!sb.append('\\'))
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -1722,17 +1722,17 @@ ReportLargeAllocationFailure(JSContext *
     void *buf = cx->runtime()->onOutOfMemoryCanGC(NULL, JSRuntime::LARGE_ALLOCATION);
     js_free(buf);
     args.rval().setUndefined();
     return true;
 }
 
 namespace heaptools {
 
-typedef UniquePtr<jschar[], JS::FreePolicy> EdgeName;
+typedef UniquePtr<char16_t[], JS::FreePolicy> EdgeName;
 
 // An edge to a node from its predecessor in a path through the graph.
 class BackEdge {
     // The node from which this edge starts.
     JS::ubi::Node predecessor_;
 
     // The name of this edge.
     EdgeName name_;
@@ -1946,19 +1946,19 @@ EvalReturningScope(JSContext *cx, unsign
     RootedString str(cx);
     if (!JS_ConvertArguments(cx, args, "S", str.address()))
         return false;
 
     AutoStableStringChars strChars(cx);
     if (!strChars.initTwoByte(cx, str))
         return false;
 
-    mozilla::Range<const jschar> chars = strChars.twoByteRange();
+    mozilla::Range<const char16_t> chars = strChars.twoByteRange();
     size_t srclen = chars.length();
-    const jschar *src = chars.start().get();
+    const char16_t *src = chars.start().get();
 
     JS::AutoFilename filename;
     unsigned lineno;
 
     DescribeScriptedCaller(cx, &filename, &lineno);
 
     JS::CompileOptions options(cx);
     options.setFileAndLine(filename.get(), lineno);
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -95,17 +95,17 @@ GetDeflatedUTF8StringLength(JSContext *m
     return (size_t) -1;
 }
 
 template size_t
 GetDeflatedUTF8StringLength(JSContext *maybecx, const Latin1Char *chars,
                             size_t nchars);
 
 template size_t
-GetDeflatedUTF8StringLength(JSContext *maybecx, const jschar *chars,
+GetDeflatedUTF8StringLength(JSContext *maybecx, const char16_t *chars,
                             size_t nchars);
 
 static size_t
 GetDeflatedUTF8StringLength(JSContext *maybecx, JSLinearString *str)
 {
     size_t length = str->length();
 
     JS::AutoCheckCannotGC nogc;
@@ -115,17 +115,17 @@ GetDeflatedUTF8StringLength(JSContext *m
 }
 
 template <typename CharT>
 bool
 DeflateStringToUTF8Buffer(JSContext *maybecx, const CharT *src, size_t srclen,
                           char *dst, size_t *dstlenp)
 {
     size_t i, utf8Len;
-    jschar c, c2;
+    char16_t c, c2;
     uint32_t v;
     uint8_t utf8buf[6];
 
     size_t dstlen = *dstlenp;
     size_t origDstlen = dstlen;
 
     while (srclen) {
         c = *src++;
@@ -179,17 +179,17 @@ bufferTooSmall:
     return false;
 }
 
 template bool
 DeflateStringToUTF8Buffer(JSContext *maybecx, const Latin1Char *src, size_t srclen,
                           char *dst, size_t *dstlenp);
 
 template bool
-DeflateStringToUTF8Buffer(JSContext *maybecx, const jschar *src, size_t srclen,
+DeflateStringToUTF8Buffer(JSContext *maybecx, const char16_t *src, size_t srclen,
                           char *dst, size_t *dstlenp);
 
 static bool
 DeflateStringToUTF8Buffer(JSContext *maybecx, JSLinearString *str, char *dst,
                           size_t *dstlenp)
 {
     size_t length = str->length();
 
@@ -1682,17 +1682,17 @@ jsvalToInteger(JSContext* cx, jsval val,
       case TYPE_bool:
       case TYPE_float:
       case TYPE_double:
       case TYPE_float32_t:
       case TYPE_float64_t:
       case TYPE_char:
       case TYPE_signed_char:
       case TYPE_unsigned_char:
-      case TYPE_jschar:
+      case TYPE_char16_t:
       case TYPE_pointer:
       case TYPE_function:
       case TYPE_array:
       case TYPE_struct:
         // Not a compatible number type.
         return false;
       }
     }
@@ -1768,17 +1768,17 @@ jsvalToFloat(JSContext *cx, jsval val, F
 #define DEFINE_INT_TYPE(x, y, z) DEFINE_FLOAT_TYPE(x, y, z)
 #define DEFINE_WRAPPED_INT_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
 #include "ctypes/typedefs.h"
       case TYPE_void_t:
       case TYPE_bool:
       case TYPE_char:
       case TYPE_signed_char:
       case TYPE_unsigned_char:
-      case TYPE_jschar:
+      case TYPE_char16_t:
       case TYPE_pointer:
       case TYPE_function:
       case TYPE_array:
       case TYPE_struct:
         // Not a compatible number type.
         return false;
       }
     }
@@ -1813,17 +1813,17 @@ StringToInteger(JSContext* cx, CharT* cp
     cp += 2;
     base = 16;
   }
 
   // Scan the string left to right and build the number,
   // checking for valid characters 0 - 9, a - f, A - F and overflow.
   IntegerType i = 0;
   while (cp != end) {
-    jschar c = *cp++;
+    char16_t c = *cp++;
     if (c >= '0' && c <= '9')
       c -= '0';
     else if (base == 16 && c >= 'a' && c <= 'f')
       c = c - 'a' + 10;
     else if (base == 16 && c >= 'A' && c <= 'F')
       c = c - 'A' + 10;
     else
       return false;
@@ -2177,19 +2177,19 @@ ConvertToJS(JSContext* cx,
   }
 #define DEFINE_CHAR_TYPE(name, type, ffiType)                                  \
   case TYPE_##name:                                                            \
     /* Convert to an integer. We have no idea what character encoding to */    \
     /* use, if any. */                                                         \
     *result = INT_TO_JSVAL(*static_cast<type*>(data));                         \
     break;
 #include "ctypes/typedefs.h"
-  case TYPE_jschar: {
-    // Convert the jschar to a 1-character string.
-    JSString* str = JS_NewUCStringCopyN(cx, static_cast<jschar*>(data), 1);
+  case TYPE_char16_t: {
+    // Convert the char16_t to a 1-character string.
+    JSString* str = JS_NewUCStringCopyN(cx, static_cast<char16_t*>(data), 1);
     if (!str)
       return false;
 
     *result = STRING_TO_JSVAL(str);
     break;
   }
   case TYPE_pointer:
   case TYPE_array:
@@ -2343,23 +2343,23 @@ ImplicitConvert(JSContext* cx,
   case TYPE_##name: {                                                          \
     type result;                                                               \
     if (!jsvalToFloat(cx, val, &result))                                       \
       return TypeError(cx, #name, val);                                        \
     *static_cast<type*>(buffer) = result;                                      \
     break;                                                                     \
   }
 #define DEFINE_CHAR_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
-#define DEFINE_JSCHAR_TYPE(name, type, ffiType)                                \
+#define DEFINE_CHAR16_TYPE(name, type, ffiType)                                \
   case TYPE_##name: {                                                          \
     /* Convert from a 1-character string, regardless of encoding, */           \
     /* or from an integer, provided the result fits in 'type'. */              \
     type result;                                                               \
-    if (val.isString()) {                                                \
-      JSString* str = val.toString();                                    \
+    if (val.isString()) {                                                      \
+      JSString* str = val.toString();                                          \
       if (str->length() != 1)                                                  \
         return TypeError(cx, #name, val);                                      \
       JSLinearString *linear = str->ensureLinear(cx);                          \
       if (!linear)                                                             \
         return false;                                                          \
       result = linear->latin1OrTwoByteChar(0);                                 \
     } else if (!jsvalToInteger(cx, val, &result)) {                            \
       return TypeError(cx, #name, val);                                        \
@@ -2423,36 +2423,36 @@ ImplicitConvert(JSContext* cx,
           return false;
         }
 
         ASSERT_OK(DeflateStringToUTF8Buffer(cx, sourceLinear, *charBuffer, &nbytes));
         (*charBuffer)[nbytes] = 0;
         *freePointer = true;
         break;
       }
-      case TYPE_jschar: {
-        // Copy the jschar string data. (We could provide direct access to the
+      case TYPE_char16_t: {
+        // Copy the char16_t string data. (We could provide direct access to the
         // JSString's buffer, but this approach is safer if the caller happens
         // to modify the string.)
-        jschar** jscharBuffer = static_cast<jschar**>(buffer);
-        *jscharBuffer = cx->pod_malloc<jschar>(sourceLength + 1);
-        if (!*jscharBuffer) {
+        char16_t** char16Buffer = static_cast<char16_t**>(buffer);
+        *char16Buffer = cx->pod_malloc<char16_t>(sourceLength + 1);
+        if (!*char16Buffer) {
           JS_ReportAllocationOverflow(cx);
           return false;
         }
 
         *freePointer = true;
         if (sourceLinear->hasLatin1Chars()) {
             AutoCheckCannotGC nogc;
-            CopyAndInflateChars(*jscharBuffer, sourceLinear->latin1Chars(nogc), sourceLength);
+            CopyAndInflateChars(*char16Buffer, sourceLinear->latin1Chars(nogc), sourceLength);
         } else {
             AutoCheckCannotGC nogc;
-            mozilla::PodCopy(*jscharBuffer, sourceLinear->twoByteChars(nogc), sourceLength);
+            mozilla::PodCopy(*char16Buffer, sourceLinear->twoByteChars(nogc), sourceLength);
         }
-        (*jscharBuffer)[sourceLength] = 0;
+        (*char16Buffer)[sourceLength] = 0;
         break;
       }
       default:
         return TypeError(cx, "string pointer", val);
       }
       break;
     } else if (val.isObject() && JS_IsArrayBufferObject(valObj)) {
       // Convert ArrayBuffer to pointer without any copy.
@@ -2506,25 +2506,25 @@ ImplicitConvert(JSContext* cx,
         ASSERT_OK(DeflateStringToUTF8Buffer(cx, sourceLinear, charBuffer,
                                             &nbytes));
 
         if (targetLength > nbytes)
           charBuffer[nbytes] = 0;
 
         break;
       }
-      case TYPE_jschar: {
-        // Copy the string data, jschar for jschar, including the terminator
+      case TYPE_char16_t: {
+        // Copy the string data, char16_t for char16_t, including the terminator
         // if there's space.
         if (targetLength < sourceLength) {
           JS_ReportError(cx, "ArrayType has insufficient length");
           return false;
         }
 
-        jschar *dest = static_cast<jschar*>(buffer);
+        char16_t *dest = static_cast<char16_t*>(buffer);
         if (sourceLinear->hasLatin1Chars()) {
             AutoCheckCannotGC nogc;
             CopyAndInflateChars(dest, sourceLinear->latin1Chars(nogc), sourceLength);
         } else {
             AutoCheckCannotGC nogc;
             mozilla::PodCopy(dest, sourceLinear->twoByteChars(nogc), sourceLength);
         }
 
@@ -2697,25 +2697,25 @@ ExplicitConvert(JSContext* cx, HandleVal
     break;
   }
 #define DEFINE_INT_TYPE(name, type, ffiType)                                   \
   case TYPE_##name: {                                                          \
     /* Convert numeric values with a C-style cast, and */                      \
     /* allow conversion from a base-10 or base-16 string. */                   \
     type result;                                                               \
     if (!jsvalToIntegerExplicit(val, &result) &&                               \
-        (!val.isString() ||                                              \
-         !StringToInteger(cx, val.toString(), &result)))                 \
+        (!val.isString() ||                                                    \
+         !StringToInteger(cx, val.toString(), &result)))                       \
       return TypeError(cx, #name, val);                                        \
     *static_cast<type*>(buffer) = result;                                      \
     break;                                                                     \
   }
 #define DEFINE_WRAPPED_INT_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
 #define DEFINE_CHAR_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
-#define DEFINE_JSCHAR_TYPE(x, y, z) DEFINE_CHAR_TYPE(x, y, z)
+#define DEFINE_CHAR16_TYPE(x, y, z) DEFINE_CHAR_TYPE(x, y, z)
 #include "ctypes/typedefs.h"
   case TYPE_pointer: {
     // Convert a number, Int64 object, or UInt64 object to a pointer.
     uintptr_t result;
     if (!jsvalToPtrExplicit(cx, val, &result))
       return TypeError(cx, "pointer", val);
     *static_cast<uintptr_t*>(buffer) = result;
     break;
@@ -3046,19 +3046,19 @@ BuildDataSource(JSContext* cx,
     break;                                                                     \
   }
 #define DEFINE_CHAR_TYPE(name, type, ffiType)                                  \
   case TYPE_##name:                                                            \
     /* Serialize as an integer. */                                             \
     IntegerToString(*static_cast<type*>(data), 10, result);                    \
     break;
 #include "ctypes/typedefs.h"
-  case TYPE_jschar: {
+  case TYPE_char16_t: {
     // Serialize as a 1-character JS string.
-    JSString* str = JS_NewUCStringCopyN(cx, static_cast<jschar*>(data), 1);
+    JSString* str = JS_NewUCStringCopyN(cx, static_cast<char16_t*>(data), 1);
     if (!str)
       return false;
 
     // Escape characters, and quote as necessary.
     RootedValue valStr(cx, StringValue(str));
     JSString* src = JS_ValueToSource(cx, valStr);
     if (!src)
       return false;
@@ -4370,17 +4370,17 @@ ArrayType::ConstructData(JSContext* cx,
         // Determine the UTF-8 length.
         length = GetDeflatedUTF8StringLength(cx, sourceLinear);
         if (length == (size_t) -1)
           return false;
 
         ++length;
         break;
       }
-      case TYPE_jschar:
+      case TYPE_char16_t:
         length = sourceLength + 1;
         break;
       default:
         return TypeError(cx, "array", args[0]);
       }
 
     } else {
       JS_ReportError(cx, "argument must be an array object or length");
@@ -5467,17 +5467,17 @@ IsEllipsis(JSContext* cx, jsval v, bool*
   if (!v.isString())
     return true;
   JSString* str = v.toString();
   if (str->length() != 3)
     return true;
   JSLinearString *linear = str->ensureLinear(cx);
   if (!linear)
     return false;
-  jschar dot = '.';
+  char16_t dot = '.';
   *isEllipsis = (linear->latin1OrTwoByteChar(0) == dot &&
                  linear->latin1OrTwoByteChar(1) == dot &&
                  linear->latin1OrTwoByteChar(2) == dot);
   return true;
 }
 
 static bool
 PrepareCIF(JSContext* cx,
@@ -5943,17 +5943,17 @@ FunctionType::Call(JSContext* cx,
     if (sizeof(type) < sizeof(ffi_arg)) {                                      \
       ffi_arg data = *static_cast<ffi_arg*>(returnValue.mData);                \
       *static_cast<type*>(returnValue.mData) = static_cast<type>(data);        \
     }                                                                          \
     break;
 #define DEFINE_WRAPPED_INT_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
 #define DEFINE_BOOL_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
 #define DEFINE_CHAR_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
-#define DEFINE_JSCHAR_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
+#define DEFINE_CHAR16_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
 #include "ctypes/typedefs.h"
   default:
     break;
   }
 
   // prepare a JS object from the result
   RootedObject returnType(cx, fninfo->mReturnType);
   return ConvertToJS(cx, returnType, NullPtr(), returnValue.mData, false, true, vp);
@@ -6210,17 +6210,17 @@ CClosure::ClosureStub(ffi_cif* cif, void
   if (cif->rtype != &ffi_type_void) {
     rvSize = cif->rtype->size;
     switch (typeCode) {
 #define DEFINE_INT_TYPE(name, type, ffiType)                                   \
     case TYPE_##name:
 #define DEFINE_WRAPPED_INT_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
 #define DEFINE_BOOL_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
 #define DEFINE_CHAR_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
-#define DEFINE_JSCHAR_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
+#define DEFINE_CHAR16_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
 #include "ctypes/typedefs.h"
       rvSize = Align(rvSize, sizeof(ffi_arg));
       break;
     default:
       break;
     }
     memset(result, 0, rvSize);
   }
@@ -6296,17 +6296,17 @@ CClosure::ClosureStub(ffi_cif* cif, void
     if (sizeof(type) < sizeof(ffi_arg)) {                                      \
       ffi_arg data = *static_cast<type*>(result);                              \
       *static_cast<ffi_arg*>(result) = data;                                   \
     }                                                                          \
     break;
 #define DEFINE_WRAPPED_INT_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
 #define DEFINE_BOOL_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
 #define DEFINE_CHAR_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
-#define DEFINE_JSCHAR_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
+#define DEFINE_CHAR16_TYPE(x, y, z) DEFINE_INT_TYPE(x, y, z)
 #include "ctypes/typedefs.h"
   default:
     break;
   }
 }
 
 /*******************************************************************************
 ** CData implementation
@@ -6641,29 +6641,29 @@ ReadStringCommon(JSContext* cx, InflateU
   case TYPE_uint8_t:
   case TYPE_char:
   case TYPE_signed_char:
   case TYPE_unsigned_char: {
     char* bytes = static_cast<char*>(data);
     size_t length = strnlen(bytes, maxLength);
 
     // Determine the length.
-    jschar *dst = inflateUTF8(cx, JS::UTF8Chars(bytes, length), &length).get();
+    char16_t *dst = inflateUTF8(cx, JS::UTF8Chars(bytes, length), &length).get();
     if (!dst)
       return false;
 
     result = JS_NewUCString(cx, dst, length);
     break;
   }
   case TYPE_int16_t:
   case TYPE_uint16_t:
   case TYPE_short:
   case TYPE_unsigned_short:
-  case TYPE_jschar: {
-    jschar* chars = static_cast<jschar*>(data);
+  case TYPE_char16_t: {
+    char16_t* chars = static_cast<char16_t*>(data);
     size_t length = strnlen(chars, maxLength);
     result = JS_NewUCStringCopyN(cx, chars, length);
     break;
   }
   default:
     JS_ReportError(cx,
       "base type is not an 8-bit or 16-bit integer or character type");
     return false;
--- a/js/src/ctypes/CTypes.h
+++ b/js/src/ctypes/CTypes.h
@@ -58,20 +58,20 @@ private:
 template<class T, size_t N = 0>
 class Array : public Vector<T, N, SystemAllocPolicy>
 {
   static_assert(!mozilla::IsSame<T, JS::Value>::value,
                 "use JS::AutoValueVector instead");
 };
 
 // String and AutoString classes, based on Vector.
-typedef Vector<jschar,  0, SystemAllocPolicy> String;
-typedef Vector<jschar, 64, SystemAllocPolicy> AutoString;
-typedef Vector<char,    0, SystemAllocPolicy> CString;
-typedef Vector<char,   64, SystemAllocPolicy> AutoCString;
+typedef Vector<char16_t,  0, SystemAllocPolicy> String;
+typedef Vector<char16_t, 64, SystemAllocPolicy> AutoString;
+typedef Vector<char,      0, SystemAllocPolicy> CString;
+typedef Vector<char,     64, SystemAllocPolicy> AutoCString;
 
 // Convenience functions to append, insert, and compare Strings.
 template <class T, size_t N, class AP, size_t ArrayLength>
 void
 AppendString(Vector<T, N, AP> &v, const char (&array)[ArrayLength])
 {
   // Don't include the trailing '\0'.
   size_t alen = ArrayLength - 1;
@@ -87,17 +87,17 @@ template <class T, size_t N, size_t M, c
 void
 AppendString(Vector<T, N, AP> &v, Vector<T, M, AP> &w)
 {
   v.append(w.begin(), w.length());
 }
 
 template <size_t N, class AP>
 void
-AppendString(Vector<jschar, N, AP> &v, JSString* str)
+AppendString(Vector<char16_t, N, AP> &v, JSString* str)
 {
   JS_ASSERT(str);
   JSLinearString *linear = str->ensureLinear(nullptr);
   if (!linear)
     return;
   JS::AutoCheckCannotGC nogc;
   if (linear->hasLatin1Chars())
     v.append(linear->latin1Chars(nogc), linear->length());
@@ -120,17 +120,17 @@ AppendString(Vector<char, N, AP> &v, JSS
     return;
 
   JS::AutoCheckCannotGC nogc;
   if (linear->hasLatin1Chars()) {
     const Latin1Char *chars = linear->latin1Chars(nogc);
     for (size_t i = 0; i < alen; ++i)
       v[i + vlen] = char(chars[i]);
   } else {
-    const jschar *chars = linear->twoByteChars(nogc);
+    const char16_t *chars = linear->twoByteChars(nogc);
     for (size_t i = 0; i < alen; ++i)
       v[i + vlen] = char(chars[i]);
   }
 }
 
 template <class T, size_t N, class AP, size_t ArrayLength>
 void
 PrependString(Vector<T, N, AP> &v, const char (&array)[ArrayLength])
@@ -146,39 +146,39 @@ PrependString(Vector<T, N, AP> &v, const
 
   // Copy data to insert.
   for (size_t i = 0; i < alen; ++i)
     v[i] = array[i];
 }
 
 template <size_t N, class AP>
 void
-PrependString(Vector<jschar, N, AP> &v, JSString* str)
+PrependString(Vector<char16_t, N, AP> &v, JSString* str)
 {
   JS_ASSERT(str);
   size_t vlen = v.length();
   size_t alen = str->length();
   if (!v.resize(vlen + alen))
     return;
 
   JSLinearString* linear = str->ensureLinear(nullptr);
   if (!linear)
     return;
 
   // Move vector data forward. This is safe since we've already resized.
-  memmove(v.begin() + alen, v.begin(), vlen * sizeof(jschar));
+  memmove(v.begin() + alen, v.begin(), vlen * sizeof(char16_t));
 
   // Copy data to insert.
   JS::AutoCheckCannotGC nogc;
   if (linear->hasLatin1Chars()) {
     const Latin1Char *chars = linear->latin1Chars(nogc);
     for (size_t i = 0; i < alen; i++)
       v[i] = chars[i];
   } else {
-    memcpy(v.begin(), linear->twoByteChars(nogc), alen * sizeof(jschar));
+    memcpy(v.begin(), linear->twoByteChars(nogc), alen * sizeof(char16_t));
   }
 }
 
 template <typename CharT>
 extern size_t
 GetDeflatedUTF8StringLength(JSContext *maybecx, const CharT *chars,
                             size_t charsLength);
 
--- a/js/src/ctypes/typedefs.h
+++ b/js/src/ctypes/typedefs.h
@@ -19,30 +19,30 @@
  * This header lacks a #ifndef wrapper because it is deliberately #included
  * multiple times in ctypes/CTypes.h.
  */
 
 // If we're not breaking the types out, combine them together under one
 // DEFINE_TYPE macro. Otherwise, turn off whichever ones we're not using.
 #if defined(DEFINE_TYPE)
 #  define DEFINE_CHAR_TYPE(x, y, z)         DEFINE_TYPE(x, y, z)
-#  define DEFINE_JSCHAR_TYPE(x, y, z)       DEFINE_TYPE(x, y, z)
+#  define DEFINE_CHAR16_TYPE(x, y, z)       DEFINE_TYPE(x, y, z)
 #  define DEFINE_BOOL_TYPE(x, y, z)         DEFINE_TYPE(x, y, z)
 #  define DEFINE_INT_TYPE(x, y, z)          DEFINE_TYPE(x, y, z)
 #  define DEFINE_WRAPPED_INT_TYPE(x, y, z)  DEFINE_TYPE(x, y, z)
 #  define DEFINE_FLOAT_TYPE(x, y, z)        DEFINE_TYPE(x, y, z)
 #else
 #  ifndef DEFINE_BOOL_TYPE
 #    define DEFINE_BOOL_TYPE(x, y, z)
 #  endif
 #  ifndef DEFINE_CHAR_TYPE
 #    define DEFINE_CHAR_TYPE(x, y, z)
 #  endif
-#  ifndef DEFINE_JSCHAR_TYPE
-#    define DEFINE_JSCHAR_TYPE(x, y, z)
+#  ifndef DEFINE_CHAR16_TYPE
+#    define DEFINE_CHAR16_TYPE(x, y, z)
 #  endif
 #  ifndef DEFINE_INT_TYPE
 #    define DEFINE_INT_TYPE(x, y, z)
 #  endif
 #  ifndef DEFINE_WRAPPED_INT_TYPE
 #    define DEFINE_WRAPPED_INT_TYPE(x, y, z)
 #  endif
 #  ifndef DEFINE_FLOAT_TYPE
@@ -96,27 +96,27 @@ DEFINE_WRAPPED_INT_TYPE(intptr_t,       
 DEFINE_WRAPPED_INT_TYPE(uintptr_t,          uintptr_t,          CTYPES_FFI_UINTPTR_T)
 DEFINE_FLOAT_TYPE      (float32_t,          float,              ffi_type_float)
 DEFINE_FLOAT_TYPE      (float64_t,          double,             ffi_type_double)
 DEFINE_FLOAT_TYPE      (float,              float,              ffi_type_float)
 DEFINE_FLOAT_TYPE      (double,             double,             ffi_type_double)
 DEFINE_CHAR_TYPE       (char,               char,               ffi_type_uint8)
 DEFINE_CHAR_TYPE       (signed_char,        signed char,        ffi_type_sint8)
 DEFINE_CHAR_TYPE       (unsigned_char,      unsigned char,      ffi_type_uint8)
-DEFINE_JSCHAR_TYPE     (jschar,             jschar,             ffi_type_uint16)
+DEFINE_CHAR16_TYPE     (char16_t,           char16_t,           ffi_type_uint16)
 
 #undef CTYPES_SSIZE_T
 #undef CTYPES_FFI_BOOL
 #undef CTYPES_FFI_LONG
 #undef CTYPES_FFI_ULONG
 #undef CTYPES_FFI_SIZE_T
 #undef CTYPES_FFI_SSIZE_T
 #undef CTYPES_FFI_INTPTR_T
 #undef CTYPES_FFI_UINTPTR_T
 
 #undef DEFINE_TYPE
 #undef DEFINE_CHAR_TYPE
-#undef DEFINE_JSCHAR_TYPE
+#undef DEFINE_CHAR16_TYPE
 #undef DEFINE_BOOL_TYPE
 #undef DEFINE_INT_TYPE
 #undef DEFINE_WRAPPED_INT_TYPE
 #undef DEFINE_FLOAT_TYPE
 
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -453,17 +453,17 @@ frontend::CompileScript(ExclusiveContext
 
     if (sct && !extraSct && !sct->complete())
         return nullptr;
 
     return script;
 }
 
 bool
-frontend::CompileLazyFunction(JSContext *cx, Handle<LazyScript*> lazy, const jschar *chars, size_t length)
+frontend::CompileLazyFunction(JSContext *cx, Handle<LazyScript*> lazy, const char16_t *chars, size_t length)
 {
     JS_ASSERT(cx->compartment() == lazy->functionNonDelazifying()->compartment());
 
     CompileOptions options(cx, lazy->version());
     options.setOriginPrincipals(lazy->originPrincipals())
            .setFileAndLine(lazy->source()->filename(), lazy->lineno())
            .setColumn(lazy->column())
            .setCompileAndGo(true)
--- a/js/src/frontend/BytecodeCompiler.h
+++ b/js/src/frontend/BytecodeCompiler.h
@@ -24,17 +24,17 @@ namespace frontend {
 JSScript *
 CompileScript(ExclusiveContext *cx, LifoAlloc *alloc,
               HandleObject scopeChain, HandleScript evalCaller,
               const ReadOnlyCompileOptions &options, SourceBufferHolder &srcBuf,
               JSString *source_ = nullptr, unsigned staticLevel = 0,
               SourceCompressionTask *extraSct = nullptr);
 
 bool
-CompileLazyFunction(JSContext *cx, Handle<LazyScript*> lazy, const jschar *chars, size_t length);
+CompileLazyFunction(JSContext *cx, Handle<LazyScript*> lazy, const char16_t *chars, size_t length);
 
 bool
 CompileFunctionBody(JSContext *cx, MutableHandleFunction fun,
                     const ReadOnlyCompileOptions &options,
                     const AutoNameVector &formals, JS::SourceBufferHolder &srcBuf);
 bool
 CompileStarGeneratorBody(JSContext *cx, MutableHandleFunction fun,
                          const ReadOnlyCompileOptions &options,
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -695,17 +695,17 @@ ListNode::dump(int indent)
 template <typename CharT>
 static void
 DumpName(const CharT *s, size_t len)
 {
     if (len == 0)
         fprintf(stderr, "#<zero-length name>");
 
     for (size_t i = 0; i < len; i++) {
-        jschar c = s[i];
+        char16_t c = s[i];
         if (c > 32 && c < 127)
             fputc(c, stderr);
         else if (c <= 255)
             fprintf(stderr, "\\x%02x", unsigned(c));
         else
             fprintf(stderr, "\\u%04x", unsigned(c));
     }
 }
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -410,17 +410,17 @@ Parser<SyntaxParseHandler>::abortIfSynta
 {
     abortedSyntaxParse = true;
     return false;
 }
 
 template <typename ParseHandler>
 Parser<ParseHandler>::Parser(ExclusiveContext *cx, LifoAlloc *alloc,
                              const ReadOnlyCompileOptions &options,
-                             const jschar *chars, size_t length, bool foldConstants,
+                             const char16_t *chars, size_t length, bool foldConstants,
                              Parser<SyntaxParseHandler> *syntaxParser,
                              LazyScript *lazyOuterFunction)
   : AutoGCRooter(cx, PARSER),
     context(cx),
     alloc(*alloc),
     tokenStream(cx, options, chars, length, thisForCtor()),
     traceListHead(nullptr),
     pc(nullptr),
@@ -6965,17 +6965,17 @@ JSAtom * Parser<ParseHandler>::stopStrin
     return atom;
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::newRegExp()
 {
     // Create the regexp even when doing a syntax parse, to check the regexp's syntax.
-    const jschar *chars = tokenStream.getTokenbuf().begin();
+    const char16_t *chars = tokenStream.getTokenbuf().begin();
     size_t length = tokenStream.getTokenbuf().length();
     RegExpFlag flags = tokenStream.currentToken().regExpFlags();
 
     Rooted<RegExpObject*> reobj(context);
     RegExpStatics *res = context->global()->getRegExpStatics(context);
     if (!res)
         return null();
 
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -368,17 +368,17 @@ class Parser : private JS::AutoGCRooter,
                       unsigned errorNumber, va_list args);
   public:
     bool report(ParseReportKind kind, bool strict, Node pn, unsigned errorNumber, ...);
     bool reportNoOffset(ParseReportKind kind, bool strict, unsigned errorNumber, ...);
     bool reportWithOffset(ParseReportKind kind, bool strict, uint32_t offset, unsigned errorNumber,
                           ...);
 
     Parser(ExclusiveContext *cx, LifoAlloc *alloc, const ReadOnlyCompileOptions &options,
-           const jschar *chars, size_t length, bool foldConstants,
+           const char16_t *chars, size_t length, bool foldConstants,
            Parser<SyntaxParseHandler> *syntaxParser,
            LazyScript *lazyOuterFunction);
     ~Parser();
 
     // A Parser::Mark is the extension of the LifoAlloc::Mark to the entire
     // Parser's state. Note: clients must still take care that any ParseContext
     // that points into released ParseNodes is destroyed.
     class Mark
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -280,17 +280,17 @@ TokenStream::SourceCoords::lineNumAndCol
 
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable:4351)
 #endif
 
 // Initialize members that aren't initialized in |init|.
 TokenStream::TokenStream(ExclusiveContext *cx, const ReadOnlyCompileOptions &options,
-                         const jschar *base, size_t length, StrictModeGetter *smg)
+                         const char16_t *base, size_t length, StrictModeGetter *smg)
   : srcCoords(cx, options.lineno),
     options_(options),
     tokens(),
     cursor(),
     lookahead(),
     lineno(options.lineno),
     flags(),
     linebase(base - options.column),
@@ -384,17 +384,17 @@ TokenStream::updateFlagsForEOL()
 // This gets the next char, normalizing all EOL sequences to '\n' as it goes.
 int32_t
 TokenStream::getChar()
 {
     int32_t c;
     if (MOZ_LIKELY(userbuf.hasRawChars())) {
         c = userbuf.getRawChar();
 
-        // Normalize the jschar if it was a newline.  We need to detect any of
+        // Normalize the char16_t if it was a newline.  We need to detect any of
         // these four characters:  '\n' (0x000a), '\r' (0x000d),
         // LINE_SEPARATOR (0x2028), PARA_SEPARATOR (0x2029).  Testing for each
         // one in turn is slow, so we use a single probabilistic check, and if
         // that succeeds, test for them individually.
         //
         // We use the bottom 8 bits to index into a lookup table, succeeding
         // when d&0xff is 0xa, 0xd, 0x28 or 0x29.  Among ASCII chars (which
         // are by the far the most common) this gives false positives for '('
@@ -475,38 +475,38 @@ TokenStream::ungetCharIgnoreEOL(int32_t 
     userbuf.ungetRawChar();
 }
 
 // Return true iff |n| raw characters can be read from this without reading past
 // EOF or a newline, and copy those characters into |cp| if so.  The characters
 // are not consumed: use skipChars(n) to do so after checking that the consumed
 // characters had appropriate values.
 bool
-TokenStream::peekChars(int n, jschar *cp)
+TokenStream::peekChars(int n, char16_t *cp)
 {
     int i, j;
     int32_t c;
 
     for (i = 0; i < n; i++) {
         c = getCharIgnoreEOL();
         if (c == EOF)
             break;
         if (c == '\n') {
             ungetCharIgnoreEOL(c);
             break;
         }
-        cp[i] = jschar(c);
+        cp[i] = char16_t(c);
     }
     for (j = i - 1; j >= 0; j--)
         ungetCharIgnoreEOL(cp[j]);
     return i == n;
 }
 
-const jschar *
-TokenStream::TokenBuf::findEOLMax(const jschar *p, size_t max)
+const char16_t *
+TokenStream::TokenBuf::findEOLMax(const char16_t *p, size_t max)
 {
     JS_ASSERT(base_ <= p && p <= limit_);
 
     size_t n = 0;
     while (true) {
         if (p >= limit_)
             break;
         if (n >= max)
@@ -516,17 +516,17 @@ TokenStream::TokenBuf::findEOLMax(const 
         n++;
     }
     return p;
 }
 
 void
 TokenStream::advance(size_t position)
 {
-    const jschar *end = userbuf.base() + position;
+    const char16_t *end = userbuf.base() + position;
     while (userbuf.addressOfNextRawChar() < end)
         getChar();
 
     Token *cur = &tokens[cursor];
     cur->pos.begin = userbuf.addressOfNextRawChar() - userbuf.base();
     cur->type = TOK_ERROR;
     lookahead = 0;
 }
@@ -676,48 +676,48 @@ TokenStream::reportCompileErrorNumberVA(
     // lineno doesn't match TokenStream's lineno, that means we've scanned past
     // the line that T starts on, which makes it hard to print some or all of
     // T's (starting) line for context.
     //
     // So we don't even try, leaving report.linebuf and friends zeroed.  This
     // means that any error involving a multi-line token (e.g. an unterminated
     // multi-line string literal) won't have a context printed.
     if (offset != NoOffset && err.report.lineno == lineno && !callerFilename) {
-        const jschar *tokenStart = userbuf.base() + offset;
+        const char16_t *tokenStart = userbuf.base() + offset;
 
         // We show only a portion (a "window") of the line around the erroneous
         // token -- the first char in the token, plus |windowRadius| chars
         // before it and |windowRadius - 1| chars after it.  This is because
         // lines can be very long and printing the whole line is (a) not that
         // helpful, and (b) can waste a lot of memory.  See bug 634444.
         static const size_t windowRadius = 60;
 
         // Truncate at the front if necessary.
-        const jschar *windowBase = (linebase + windowRadius < tokenStart)
+        const char16_t *windowBase = (linebase + windowRadius < tokenStart)
                                  ? tokenStart - windowRadius
                                  : linebase;
         uint32_t windowOffset = tokenStart - windowBase;
 
         // Find EOL, or truncate at the back if necessary.
-        const jschar *windowLimit = userbuf.findEOLMax(tokenStart, windowRadius);
+        const char16_t *windowLimit = userbuf.findEOLMax(tokenStart, windowRadius);
         size_t windowLength = windowLimit - windowBase;
         JS_ASSERT(windowLength <= windowRadius * 2);
 
         // Create the windowed strings.
         StringBuffer windowBuf(cx);
-        if (!windowBuf.append(windowBase, windowLength) || !windowBuf.append((jschar)0))
+        if (!windowBuf.append(windowBase, windowLength) || !windowBuf.append((char16_t)0))
             return false;
 
         // Unicode and char versions of the window into the offending source
         // line, without final \n.
         err.report.uclinebuf = windowBuf.stealChars();
         if (!err.report.uclinebuf)
             return false;
 
-        mozilla::Range<const jschar> tbchars(err.report.uclinebuf, windowLength);
+        mozilla::Range<const char16_t> tbchars(err.report.uclinebuf, windowLength);
         err.report.linebuf = JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars).c_str();
         if (!err.report.linebuf)
             return false;
 
         err.report.tokenptr = err.report.linebuf + windowOffset;
         err.report.uctokenptr = err.report.uclinebuf + windowOffset;
     }
 
@@ -780,17 +780,17 @@ TokenStream::reportAsmJSError(uint32_t o
 
 // We have encountered a '\': check for a Unicode escape sequence after it.
 // Return 'true' and the character code value (by value) if we found a
 // Unicode escape sequence.  Otherwise, return 'false'.  In both cases, do not
 // advance along the buffer.
 bool
 TokenStream::peekUnicodeEscape(int *result)
 {
-    jschar cp[5];
+    char16_t cp[5];
 
     if (peekChars(5, cp) && cp[0] == 'u' &&
         JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]) &&
         JS7_ISHEX(cp[3]) && JS7_ISHEX(cp[4]))
     {
         *result = (((((JS7_UNHEX(cp[1]) << 4)
                 + JS7_UNHEX(cp[2])) << 4)
               + JS7_UNHEX(cp[3])) << 4)
@@ -818,17 +818,17 @@ TokenStream::matchUnicodeEscapeIdent(int
         return true;
     }
     return false;
 }
 
 // Helper function which returns true if the first length(q) characters in p are
 // the same as the characters in q.
 static bool
-CharsMatch(const jschar *p, const char *q) {
+CharsMatch(const char16_t *p, const char *q) {
     while (*q) {
         if (*p++ != *q++)
             return false;
     }
     return true;
 }
 
 bool
@@ -849,20 +849,20 @@ TokenStream::getDirectives(bool isMultil
 
     return true;
 }
 
 bool
 TokenStream::getDirective(bool isMultiline, bool shouldWarnDeprecated,
                           const char *directive, int directiveLength,
                           const char *errorMsgPragma,
-                          UniquePtr<jschar[], JS::FreePolicy> *destination)
+                          UniquePtr<char16_t[], JS::FreePolicy> *destination)
 {
     JS_ASSERT(directiveLength <= 18);
-    jschar peeked[18];
+    char16_t peeked[18];
     int32_t c;
 
     if (peekChars(directiveLength, peeked) && CharsMatch(peeked, directive)) {
         if (shouldWarnDeprecated &&
             !reportWarning(JSMSG_DEPRECATED_PRAGMA, errorMsgPragma))
             return false;
 
         skipChars(directiveLength);
@@ -882,17 +882,17 @@ TokenStream::getDirective(bool isMultili
 
         if (tokenbuf.empty())
             // The directive's URL was missing, but this is not quite an
             // exception that we should stop and drop everything for.
             return true;
 
         size_t length = tokenbuf.length();
 
-        *destination = cx->make_pod_array<jschar>(length + 1);
+        *destination = cx->make_pod_array<char16_t>(length + 1);
         if (!*destination)
             return false;
 
         PodCopy(destination->get(), tokenbuf.begin(), length);
         (*destination)[length] = '\0';
     }
 
     return true;
@@ -954,20 +954,20 @@ IsTokenSane(Token *tp)
     if (tp->pos.end < tp->pos.begin)
         return false;
 
     return true;
 }
 #endif
 
 bool
-TokenStream::putIdentInTokenbuf(const jschar *identStart)
+TokenStream::putIdentInTokenbuf(const char16_t *identStart)
 {
     int32_t c, qc;
-    const jschar *tmp = userbuf.addressOfNextRawChar();
+    const char16_t *tmp = userbuf.addressOfNextRawChar();
     userbuf.setAddressOfNextRawChar(identStart);
 
     tokenbuf.clear();
     for (;;) {
         c = getCharIgnoreEOL();
         if (!IsIdentifierPart(c)) {
             if (c != '\\' || !matchUnicodeEscapeIdent(&qc))
                 break;
@@ -1005,17 +1005,17 @@ TokenStream::checkForKeyword(const Keywo
             return true;
     }
 
     // Strict reserved word.
     return reportStrictModeError(JSMSG_RESERVED_ID, kw->chars);
 }
 
 bool
-TokenStream::checkForKeyword(const jschar *s, size_t length, TokenKind *ttp)
+TokenStream::checkForKeyword(const char16_t *s, size_t length, TokenKind *ttp)
 {
     const KeywordInfo *kw = FindKeyword(s, length);
     if (!kw)
         return true;
 
     return checkForKeyword(kw, ttp);
 }
 
@@ -1025,27 +1025,27 @@ TokenStream::checkForKeyword(JSAtom *ato
     const KeywordInfo *kw = FindKeyword(atom);
     if (!kw)
         return true;
 
     return checkForKeyword(kw, ttp);
 }
 
 enum FirstCharKind {
-    // A jschar has the 'OneChar' kind if it, by itself, constitutes a valid
+    // A char16_t has the 'OneChar' kind if it, by itself, constitutes a valid
     // token that cannot also be a prefix of a longer token.  E.g. ';' has the
     // OneChar kind, but '+' does not, because '++' and '+=' are valid longer tokens
     // that begin with '+'.
     //
     // The few token kinds satisfying these properties cover roughly 35--45%
     // of the tokens seen in practice.
     //
     // We represent the 'OneChar' kind with any positive value less than
     // TOK_LIMIT.  This representation lets us associate each one-char token
-    // jschar with a TokenKind and thus avoid a subsequent jschar-to-TokenKind
+    // char16_t with a TokenKind and thus avoid a subsequent char16_t-to-TokenKind
     // conversion.
     OneChar_Min = 0,
     OneChar_Max = TOK_LIMIT - 1,
 
     Space = TOK_LIMIT,
     Ident,
     Dec,
     String,
@@ -1099,20 +1099,20 @@ static_assert(LastCharKind < (1 << (size
               "Elements of firstCharKinds[] are too small");
 
 TokenKind
 TokenStream::getTokenInternal(Modifier modifier)
 {
     int c, qc;
     Token *tp;
     FirstCharKind c1kind;
-    const jschar *numStart;
+    const char16_t *numStart;
     bool hasExp;
     DecimalPoint decimalPoint;
-    const jschar *identStart;
+    const char16_t *identStart;
     bool hadUnicodeEscape;
 
     // Check if in the middle of a template string. Have to get this out of
     // the way first.
     if (MOZ_UNLIKELY(modifier == TemplateTail)) {
         if (!getStringOrTemplateToken('`', &tp))
             goto error;
         goto out;
@@ -1207,17 +1207,17 @@ TokenStream::getTokenInternal(Modifier m
                 hadUnicodeEscape = true;
             }
         }
         ungetCharIgnoreEOL(c);
 
         // Identifiers containing no Unicode escapes can be processed directly
         // from userbuf.  The rest must use the escapes converted via tokenbuf
         // before atomizing.
-        const jschar *chars;
+        const char16_t *chars;
         size_t length;
         if (hadUnicodeEscape) {
             if (!putIdentInTokenbuf(identStart))
                 goto error;
 
             chars = tokenbuf.begin();
             length = tokenbuf.length();
         } else {
@@ -1279,23 +1279,23 @@ TokenStream::getTokenInternal(Modifier m
 
         if (c != EOF && IsIdentifierStart(c)) {
             reportError(JSMSG_IDSTART_AFTER_NUMBER);
             goto error;
         }
 
         // Unlike identifiers and strings, numbers cannot contain escaped
         // chars, so we don't need to use tokenbuf.  Instead we can just
-        // convert the jschars in userbuf directly to the numeric value.
+        // convert the char16_t characters in userbuf to the numeric value.
         double dval;
         if (!((decimalPoint == HasDecimal) || hasExp)) {
             if (!GetDecimalInteger(cx, numStart, userbuf.addressOfNextRawChar(), &dval))
                 goto error;
         } else {
-            const jschar *dummy;
+            const char16_t *dummy;
             if (!js_strtod(cx, numStart, userbuf.addressOfNextRawChar(), &dummy, &dval))
                 goto error;
         }
         tp->type = TOK_NUMBER;
         tp->setNumber(dval, decimalPoint);
         goto out;
     }
 
@@ -1385,17 +1385,17 @@ TokenStream::getTokenInternal(Modifier m
         ungetCharIgnoreEOL(c);
 
         if (c != EOF && IsIdentifierStart(c)) {
             reportError(JSMSG_IDSTART_AFTER_NUMBER);
             goto error;
         }
 
         double dval;
-        const jschar *dummy;
+        const char16_t *dummy;
         if (!GetPrefixInteger(cx, numStart, userbuf.addressOfNextRawChar(), radix, &dummy, &dval))
             goto error;
         tp->type = TOK_NUMBER;
         tp->setNumber(dval, NoDecimal);
         goto out;
     }
 
     // This handles everything else.
@@ -1690,33 +1690,33 @@ bool TokenStream::getStringOrTemplateTok
                                 val = 8 * val + JS7_UNDEC(c);
                                 if (val <= 0377)
                                     getChar();
                                 else
                                     val = save;
                             }
                         }
 
-                        c = jschar(val);
+                        c = char16_t(val);
                     } else if (c == 'u') {
-                        jschar cp[4];
+                        char16_t cp[4];
                         if (peekChars(4, cp) &&
                             JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1]) &&
                             JS7_ISHEX(cp[2]) && JS7_ISHEX(cp[3])) {
                             c = (((((JS7_UNHEX(cp[0]) << 4)
                                     + JS7_UNHEX(cp[1])) << 4)
                                   + JS7_UNHEX(cp[2])) << 4)
                                 + JS7_UNHEX(cp[3]);
                             skipChars(4);
                         } else {
                             reportError(JSMSG_MALFORMED_ESCAPE, "Unicode");
                             return false;
                         }
                     } else if (c == 'x') {
-                        jschar cp[2];
+                        char16_t cp[2];
                         if (peekChars(2, cp) &&
                                 JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1])) {
                             c = (JS7_UNHEX(cp[0]) << 4) + JS7_UNHEX(cp[1]);
                             skipChars(2);
                         } else {
                             reportError(JSMSG_MALFORMED_ESCAPE, "hexadecimal");
                             return false;
                         }
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -197,17 +197,17 @@ struct CompileError {
 //
 class StrictModeGetter {
   public:
     virtual bool strictMode() = 0;
 };
 
 // TokenStream is the lexical scanner for Javascript source text.
 //
-// It takes a buffer of jschars and linearly scans it into |Token|s.
+// It takes a buffer of char16_t characters and linearly scans it into |Token|s.
 // Internally the class uses a four element circular buffer |tokens| of
 // |Token|s. As an index for |tokens|, the member |cursor| points to the
 // current token.
 // Calls to getToken() increase |cursor| by one and return the new current
 // token. If a TokenStream was just created, the current token is initialized
 // with random data (i.e. not initialized). It is therefore important that
 // one of the first four member functions listed below is called first.
 // The circular buffer lets us go back up to two tokens from the last
@@ -249,20 +249,20 @@ class MOZ_STACK_CLASS TokenStream
     };
 
     static const size_t ntokens = 4;                // 1 current + 2 lookahead, rounded
                                                     // to power of 2 to avoid divmod by 3
     static const unsigned maxLookahead = 2;
     static const unsigned ntokensMask = ntokens - 1;
 
   public:
-    typedef Vector<jschar, 32> CharBuffer;
+    typedef Vector<char16_t, 32> CharBuffer;
 
     TokenStream(ExclusiveContext *cx, const ReadOnlyCompileOptions &options,
-                const jschar *base, size_t length, StrictModeGetter *smg);
+                const char16_t *base, size_t length, StrictModeGetter *smg);
 
     ~TokenStream();
 
     // Accessors.
     const Token &currentToken() const { return tokens[cursor]; }
     bool isCurrentTokenType(TokenKind type) const {
         return currentToken().type == type;
     }
@@ -307,18 +307,18 @@ class MOZ_STACK_CLASS TokenStream
                                           va_list args);
 
     // asm.js reporter
     void reportAsmJSError(uint32_t offset, unsigned errorNumber, ...);
 
     JSAtom *getRawTemplateStringAtom() {
         JS_ASSERT(currentToken().type == TOK_TEMPLATE_HEAD ||
                   currentToken().type == TOK_NO_SUBS_TEMPLATE);
-        const jschar *cur = userbuf.base() + currentToken().pos.begin + 1;
-        const jschar *end;
+        const char16_t *cur = userbuf.base() + currentToken().pos.begin + 1;
+        const char16_t *end;
         if (currentToken().type == TOK_TEMPLATE_HEAD) {
             // Of the form    |`...${|   or   |}...${|
             end = userbuf.base() + currentToken().pos.end - 2;
         } else {
             // NO_SUBS_TEMPLATE is of the form   |`...`|   or   |}...`|
             end = userbuf.base() + currentToken().pos.end - 1;
         }
 
@@ -340,17 +340,17 @@ class MOZ_STACK_CLASS TokenStream
   private:
     // These are private because they should only be called by the tokenizer
     // while tokenizing not by, for example, BytecodeEmitter.
     bool reportStrictModeError(unsigned errorNumber, ...);
     bool strictMode() const { return strictModeGetter && strictModeGetter->strictMode(); }
 
     void onError();
     static JSAtom *atomize(ExclusiveContext *cx, CharBuffer &cb);
-    bool putIdentInTokenbuf(const jschar *identStart);
+    bool putIdentInTokenbuf(const char16_t *identStart);
 
     struct Flags
     {
         bool isEOF:1;           // Hit end of file.
         bool isDirtyLine:1;     // Non-whitespace since start of line.
         bool sawOctalEscape:1;  // Saw an octal character escape.
         bool hadError:1;        // Returned TOK_ERROR from getToken.
 
@@ -473,71 +473,71 @@ class MOZ_STACK_CLASS TokenStream
         // reference in the constructor.
         //
         // This class is explicity ignored by the analysis, so don't add any
         // more pointers to GC things here!
         explicit Position(AutoKeepAtoms&) { }
       private:
         Position(const Position&) MOZ_DELETE;
         friend class TokenStream;
-        const jschar *buf;
+        const char16_t *buf;
         Flags flags;
         unsigned lineno;
-        const jschar *linebase;
-        const jschar *prevLinebase;
+        const char16_t *linebase;
+        const char16_t *prevLinebase;
         Token currentToken;
         unsigned lookahead;
         Token lookaheadTokens[maxLookahead];
     };
 
     void advance(size_t position);
     void tell(Position *);
     void seek(const Position &pos);
     bool seek(const Position &pos, const TokenStream &other);
 
     size_t positionToOffset(const Position &pos) const {
         return pos.buf - userbuf.base();
     }
 
-    const jschar *rawBase() const {
+    const char16_t *rawBase() const {
         return userbuf.base();
     }
 
-    const jschar *rawLimit() const {
+    const char16_t *rawLimit() const {
         return userbuf.limit();
     }
 
     bool hasDisplayURL() const {
         return displayURL_ != nullptr;
     }
 
-    jschar *displayURL() {
+    char16_t *displayURL() {
         return displayURL_.get();
     }
 
     bool hasSourceMapURL() const {
         return sourceMapURL_ != nullptr;
     }
 
-    jschar *sourceMapURL() {
+    char16_t *sourceMapURL() {
         return sourceMapURL_.get();
     }
 
     // If the name at s[0:length] is not a keyword in this version, return
     // true with *ttp unchanged.
     //
     // If it is a reserved word in this version and strictness mode, and thus
     // can't be present in correct code, report a SyntaxError and return false.
     //
     // If it is a keyword, like "if", the behavior depends on ttp. If ttp is
     // null, report a SyntaxError ("if is a reserved identifier") and return
     // false. If ttp is non-null, return true with the keyword's TokenKind in
     // *ttp.
     bool checkForKeyword(const KeywordInfo *kw, TokenKind *ttp);
-    bool checkForKeyword(const jschar *s, size_t length, TokenKind *ttp);
+    bool checkForKeyword(const char16_t *s, size_t length, TokenKind *ttp);
     bool checkForKeyword(JSAtom *atom, TokenKind *ttp);
 
     // This class maps a userbuf offset (which is 0-indexed) to a line number
     // (which is 1-indexed) and a column index (which is 0-indexed).
     class SourceCoords
     {
         // For a given buffer holding source code, |lineStartOffsets_| has one
         // element per line of source code, plus one sentinel element.  Each
@@ -620,117 +620,117 @@ class MOZ_STACK_CLASS TokenStream
   private:
     // This is the low-level interface to the JS source code buffer.  It just
     // gets raw chars, basically.  TokenStreams functions are layered on top
     // and do some extra stuff like converting all EOL sequences to '\n',
     // tracking the line number, and setting |flags.isEOF|.  (The "raw" in "raw
     // chars" refers to the lack of EOL sequence normalization.)
     class TokenBuf {
       public:
-        TokenBuf(ExclusiveContext *cx, const jschar *buf, size_t length)
+        TokenBuf(ExclusiveContext *cx, const char16_t *buf, size_t length)
           : base_(buf), limit_(buf + length), ptr(buf)
         { }
 
         bool hasRawChars() const {
             return ptr < limit_;
         }
 
         bool atStart() const {
             return ptr == base_;
         }
 
-        const jschar *base() const {
+        const char16_t *base() const {
             return base_;
         }
 
-        const jschar *limit() const {
+        const char16_t *limit() const {
             return limit_;
         }
 
-        jschar getRawChar() {
+        char16_t getRawChar() {
             return *ptr++;      // this will nullptr-crash if poisoned
         }
 
-        jschar peekRawChar() const {
+        char16_t peekRawChar() const {
             return *ptr;        // this will nullptr-crash if poisoned
         }
 
-        bool matchRawChar(jschar c) {
+        bool matchRawChar(char16_t c) {
             if (*ptr == c) {    // this will nullptr-crash if poisoned
                 ptr++;
                 return true;
             }
             return false;
         }
 
-        bool matchRawCharBackwards(jschar c) {
+        bool matchRawCharBackwards(char16_t c) {
             JS_ASSERT(ptr);     // make sure it hasn't been poisoned
             if (*(ptr - 1) == c) {
                 ptr--;
                 return true;
             }
             return false;
         }
 
         void ungetRawChar() {
             JS_ASSERT(ptr);     // make sure it hasn't been poisoned
             ptr--;
         }
 
-        const jschar *addressOfNextRawChar(bool allowPoisoned = false) const {
+        const char16_t *addressOfNextRawChar(bool allowPoisoned = false) const {
             JS_ASSERT_IF(!allowPoisoned, ptr);     // make sure it hasn't been poisoned
             return ptr;
         }
 
         // Use this with caution!
-        void setAddressOfNextRawChar(const jschar *a, bool allowPoisoned = false) {
+        void setAddressOfNextRawChar(const char16_t *a, bool allowPoisoned = false) {
             JS_ASSERT_IF(!allowPoisoned, a);
             ptr = a;
         }
 
 #ifdef DEBUG
         // Poison the TokenBuf so it cannot be accessed again.
         void poison() {
             ptr = nullptr;
         }
 #endif
 
         static bool isRawEOLChar(int32_t c) {
             return c == '\n' || c == '\r' || c == LINE_SEPARATOR || c == PARA_SEPARATOR;
         }
 
-        // Finds the next EOL, but stops once 'max' jschars have been scanned
-        // (*including* the starting jschar).
-        const jschar *findEOLMax(const jschar *p, size_t max);
+        // Finds the next EOL, but stops once 'max' characters have been scanned
+        // (*including* the starting char16_t).
+        const char16_t *findEOLMax(const char16_t *p, size_t max);
 
       private:
-        const jschar *base_;            // base of buffer
-        const jschar *limit_;           // limit for quick bounds check
-        const jschar *ptr;              // next char to get
+        const char16_t *base_;          // base of buffer
+        const char16_t *limit_;         // limit for quick bounds check
+        const char16_t *ptr;            // next char to get
     };
 
     TokenKind getTokenInternal(Modifier modifier);
 
     bool getStringOrTemplateToken(int qc, Token **tp);
 
     int32_t getChar();
     int32_t getCharIgnoreEOL();
     void ungetChar(int32_t c);
     void ungetCharIgnoreEOL(int32_t c);
     Token *newToken(ptrdiff_t adjust);
     bool peekUnicodeEscape(int32_t *c);
     bool matchUnicodeEscapeIdStart(int32_t *c);
     bool matchUnicodeEscapeIdent(int32_t *c);
-    bool peekChars(int n, jschar *cp);
+    bool peekChars(int n, char16_t *cp);
 
     bool getDirectives(bool isMultiline, bool shouldWarnDeprecated);
     bool getDirective(bool isMultiline, bool shouldWarnDeprecated,
                       const char *directive, int directiveLength,
                       const char *errorMsgPragma,
-                      mozilla::UniquePtr<jschar[], JS::FreePolicy> *destination);
+                      mozilla::UniquePtr<char16_t[], JS::FreePolicy> *destination);
     bool getDisplayURL(bool isMultiline, bool shouldWarnDeprecated);
     bool getSourceMappingURL(bool isMultiline, bool shouldWarnDeprecated);
 
     // |expect| cannot be an EOL char.
     bool matchChar(int32_t expect) {
         MOZ_ASSERT(!TokenBuf::isRawEOLChar(expect));
         return MOZ_LIKELY(userbuf.hasRawChars()) &&
                userbuf.matchRawChar(expect);
@@ -758,33 +758,33 @@ class MOZ_STACK_CLASS TokenStream
     // Options used for parsing/tokenizing.
     const ReadOnlyCompileOptions &options_;
 
     Token               tokens[ntokens];    // circular token buffer
     unsigned            cursor;             // index of last parsed token
     unsigned            lookahead;          // count of lookahead tokens
     unsigned            lineno;             // current line number
     Flags               flags;              // flags -- see above
-    const jschar        *linebase;          // start of current line;  points into userbuf
-    const jschar        *prevLinebase;      // start of previous line;  nullptr if on the first line
+    const char16_t      *linebase;          // start of current line;  points into userbuf
+    const char16_t      *prevLinebase;      // start of previous line;  nullptr if on the first line
     TokenBuf            userbuf;            // user input buffer
     const char          *filename;          // input filename or null
-    mozilla::UniquePtr<jschar[], JS::FreePolicy> displayURL_; // the user's requested source URL or null
-    mozilla::UniquePtr<jschar[], JS::FreePolicy> sourceMapURL_; // source map's filename or null
+    mozilla::UniquePtr<char16_t[], JS::FreePolicy> displayURL_; // the user's requested source URL or null
+    mozilla::UniquePtr<char16_t[], JS::FreePolicy> sourceMapURL_; // source map's filename or null
     CharBuffer          tokenbuf;           // current token string buffer
     bool                maybeEOL[256];      // probabilistic EOL lookup table
     bool                maybeStrSpecial[256];   // speeds up string scanning
     uint8_t             isExprEnding[TOK_LIMIT];// which tokens definitely terminate exprs?
     ExclusiveContext    *const cx;
     JSPrincipals        *const originPrincipals;
     StrictModeGetter    *strictModeGetter;  // used to test for strict mode
 };
 
 // Steal one JSREPORT_* bit (see jsapi.h) to tell that arguments to the error
-// message have const jschar* type, not const char*.
+// message have const char16_t* type, not const char*.
 #define JSREPORT_UC 0x100
 
 } // namespace frontend
 } // namespace js
 
 extern JS_FRIEND_API(int)
 js_fgets(char *buf, int size, FILE *file);
 
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -119,23 +119,23 @@ class gcstats::StatisticsSerializer
     }
 
     void endArray() {
         needComma_ = false;
         pJSON("]");
         needComma_ = true;
     }
 
-    jschar *finishJSString() {
+    char16_t *finishJSString() {
         char *buf = finishCString();
         if (!buf)
             return nullptr;
 
         size_t nchars = strlen(buf);
-        jschar *out = js_pod_malloc<jschar>(nchars + 1);
+        char16_t *out = js_pod_malloc<char16_t>(nchars + 1);
         if (!out) {
             oom_ = true;
             js_free(buf);
             return nullptr;
         }
 
         CopyAndInflateChars(out, buf, nchars);
         js_free(buf);
@@ -419,25 +419,25 @@ Statistics::formatData(StatisticsSeriali
     }
     ss.extra("    Totals: ");
     FormatPhaseTimes(ss, "Totals", phaseTimes);
     ss.endObject();
 
     return !ss.isOOM();
 }
 
-jschar *
+char16_t *
 Statistics::formatMessage()
 {
     StatisticsSerializer ss(StatisticsSerializer::AsText);
     formatData(ss, 0);
     return ss.finishJSString();
 }
 
-jschar *
+char16_t *
 Statistics::formatJSON(uint64_t timestamp)
 {
     StatisticsSerializer ss(StatisticsSerializer::AsJSON);
     formatData(ss, timestamp);
     return ss.finishJSString();
 }
 
 Statistics::Statistics(JSRuntime *rt)
--- a/js/src/gc/Statistics.h
+++ b/js/src/gc/Statistics.h
@@ -112,18 +112,18 @@ struct Statistics
     void count(Stat s) {
         JS_ASSERT(s < STAT_LIMIT);
         counts[s]++;
     }
 
     int64_t beginSCC();
     void endSCC(unsigned scc, int64_t start);
 
-    jschar *formatMessage();
-    jschar *formatJSON(uint64_t timestamp);
+    char16_t *formatMessage();
+    char16_t *formatJSON(uint64_t timestamp);
 
     JS::GCSliceCallback setSliceCallback(JS::GCSliceCallback callback);
 
   private:
     JSRuntime *runtime;
 
     int64_t startupTime;
 
--- a/js/src/gdb/README
+++ b/js/src/gdb/README
@@ -109,31 +109,31 @@ module search path. Our autoload code tr
 after importing our other SpiderMonkey support modules. For example:
 
     $ echo $PYTHONPATH
     /home/jimb/python
     $ cat ~/python/my_mozilla_printers.py
     import gdb
     from mozilla.prettyprinters import ptr_pretty_printer
 
-    # Simple jschar * printer. Doesn't show address; chases null pointers.
-    @ptr_pretty_printer('jschar')
-    class jscharPtr(object):
+    # Simple char16_t * printer. Doesn't show address; chases null pointers.
+    @ptr_pretty_printer('char16_t')
+    class char16Ptr(object):
         def __init__(self, value, cache): self.value = value
         def display_hint(self): return 'string'
         def to_string(self):
             c = u''
             for i in xrange(50):
                 if self.value[i] == 0: break
                 c += unichr(self.value[i])
             return c
     $
     ...
     (gdb) whatis sample
-    type = jschar [4]
+    type = char16_t [4]
     (gdb) print &sample[0]
     $1 = "Hi!"
 
 Running the unit tests
 ----------------------
 
 These extensions have unit tests, invoked as follows:
 
--- a/js/src/gdb/TODO
+++ b/js/src/gdb/TODO
@@ -1,10 +1,10 @@
 * Ideas:
-- jschar *
+- char16_t *
 - js::Shape, js::Baseshape
 - printers for structures with horrible unions (JSString, JSParseNode)
 - bring back parse_node.py
 - New 'js show' command for showing full trees, property lists, hash table
   contents, and so on --- JSParseNode * should not show the whole tree.
   Possibly clean up some "pointer-only" stuff in parse_node.py.
   - 'js show <defn>' lists a JSDefinition's uses
   - 'js show <parsenode>' shows entire tree
--- a/js/src/gdb/mozilla/JSString.py
+++ b/js/src/gdb/mozilla/JSString.py
@@ -29,25 +29,25 @@ class Common(mozilla.prettyprinters.Poin
             cache.mod_JSString = JSStringTypeCache(cache)
         self.stc = cache.mod_JSString
 
 @ptr_pretty_printer("JSString")
 class JSStringPtr(Common):
     def display_hint(self):
         return "string"
 
-    def jschars(self):
+    def chars(self):
         d = self.value['d']
         length = d['u1']['length']
         flags = d['u1']['flags']
         is_rope = ((flags & self.stc.TYPE_FLAGS_MASK) == self.stc.ROPE_FLAGS)
         if is_rope:
-            for c in JSStringPtr(d['s']['u2']['left'], self.cache).jschars():
+            for c in JSStringPtr(d['s']['u2']['left'], self.cache).chars():
                 yield c
-            for c in JSStringPtr(d['s']['u3']['right'], self.cache).jschars():
+            for c in JSStringPtr(d['s']['u3']['right'], self.cache).chars():
                 yield c
         else:
             is_inline = (flags & self.stc.INLINE_CHARS_BIT) != 0
             is_latin1 = (flags & self.stc.LATIN1_CHARS_BIT) != 0
             if is_inline:
                 if is_latin1:
                     chars = d['inlineStorageLatin1']
                 else:
@@ -57,16 +57,16 @@ class JSStringPtr(Common):
                     chars = d['s']['u2']['nonInlineCharsLatin1']
                 else:
                     chars = d['s']['u2']['nonInlineCharsTwoByte']
             for i in range(length):
                 yield chars[i]
 
     def to_string(self):
         s = u''
-        for c in self.jschars():
+        for c in self.chars():
             s += chr(c)
         return s
 
 @ptr_pretty_printer("JSAtom")
 class JSAtomPtr(Common):
     def to_string(self):
         return self.value.cast(self.cache.JSString_ptr_t)
--- a/js/src/irregexp/NativeRegExpMacroAssembler.cpp
+++ b/js/src/irregexp/NativeRegExpMacroAssembler.cpp
@@ -294,17 +294,17 @@ NativeRegExpMacroAssembler::GenerateCode
                     // Keep capture start in current_character for the zero-length check later.
                     masm.movePtr(temp0, current_character);
                 }
 
                 // Convert to index from start of string, not end.
                 masm.addPtr(inputByteLength, temp0);
 
                 // Convert byte index to character index.
-                if (mode_ == JSCHAR)
+                if (mode_ == CHAR16)
                     masm.rshiftPtrArithmetic(Imm32(1), temp0);
 
                 masm.store32(temp0, Address(outputRegisters, i * sizeof(int32_t)));
             }
         }
 
         // Restart matching if the regular expression is flagged as global.
         if (global()) {
@@ -599,25 +599,25 @@ NativeRegExpMacroAssembler::CheckNotChar
     } else {
         masm.move32(Imm32(and_with), temp0);
         masm.and32(current_character, temp0);
         masm.branch32(Assembler::NotEqual, temp0, Imm32(c), BranchOrBacktrack(on_not_equal));
     }
 }
 
 void
-NativeRegExpMacroAssembler::CheckCharacterGT(jschar c, Label* on_greater)
+NativeRegExpMacroAssembler::CheckCharacterGT(char16_t c, Label* on_greater)
 {
     JitSpew(SPEW_PREFIX "CheckCharacterGT(%d)", (int) c);
     masm.branch32(Assembler::GreaterThan, current_character, Imm32(c),
                   BranchOrBacktrack(on_greater));
 }
 
 void
-NativeRegExpMacroAssembler::CheckCharacterLT(jschar c, Label* on_less)
+NativeRegExpMacroAssembler::CheckCharacterLT(char16_t c, Label* on_less)
 {
     JitSpew(SPEW_PREFIX "CheckCharacterLT(%d)", (int) c);
     masm.branch32(Assembler::LessThan, current_character, Imm32(c), BranchOrBacktrack(on_less));
 }
 
 void
 NativeRegExpMacroAssembler::CheckGreedyLoop(Label* on_tos_equals_current_position)
 {
@@ -666,17 +666,17 @@ NativeRegExpMacroAssembler::CheckNotBack
     masm.computeEffectiveAddress(BaseIndex(temp0, temp1, TimesOne), backtrack_stack_pointer); // End of match.
 
     Label loop;
     masm.bind(&loop);
     if (mode_ == ASCII) {
         masm.load8ZeroExtend(Address(current_character, 0), temp0);
         masm.load8ZeroExtend(Address(temp1, 0), temp2);
     } else {
-        JS_ASSERT(mode_ == JSCHAR);
+        JS_ASSERT(mode_ == CHAR16);
         masm.load16ZeroExtend(Address(current_character, 0), temp0);
         masm.load16ZeroExtend(Address(temp1, 0), temp2);
     }
     masm.branch32(Assembler::NotEqual, temp0, temp2, &fail);
 
     // Increment pointers into capture and match string.
     masm.addPtr(Imm32(char_size()), current_character);
     masm.addPtr(Imm32(char_size()), temp1);
@@ -788,17 +788,17 @@ NativeRegExpMacroAssembler::CheckNotBack
         masm.bind(&success);
 
         // Drop original character position value.
         masm.addPtr(Imm32(sizeof(uintptr_t)), StackPointer);
 
         // Compute new value of character position after the matched part.
         masm.subPtr(input_end_pointer, current_position);
     } else {
-        JS_ASSERT(mode_ == JSCHAR);
+        JS_ASSERT(mode_ == CHAR16);
 
         // Note: temp1 needs to be saved/restored if it is volatile, as it is used after the call.
         GeneralRegisterSet volatileRegs = GeneralRegisterSet::Volatile();
         volatileRegs.takeUnchecked(temp0);
         volatileRegs.takeUnchecked(temp2);
         masm.PushRegsInMask(volatileRegs);
 
         // Set byte_offset1.
@@ -813,61 +813,61 @@ NativeRegExpMacroAssembler::CheckNotBack
         // Parameters are
         //   Address byte_offset1 - Address captured substring's start.
         //   Address byte_offset2 - Address of current character position.
         //   size_t byte_length - length of capture in bytes(!)
         masm.setupUnalignedABICall(3, temp0);
         masm.passABIArg(current_character);
         masm.passABIArg(current_position);
         masm.passABIArg(temp1);
-        int (*fun)(const jschar*, const jschar*, size_t) = CaseInsensitiveCompareStrings;
+        int (*fun)(const char16_t*, const char16_t*, size_t) = CaseInsensitiveCompareStrings;
         masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, fun));
         masm.storeCallResult(temp0);
 
         masm.PopRegsInMask(volatileRegs);
 
         // Check if function returned non-zero for success or zero for failure.
         masm.branchTest32(Assembler::Zero, temp0, temp0, BranchOrBacktrack(on_no_match));
 
         // On success, increment position by length of capture.
         masm.addPtr(temp1, current_position);
     }
 
     masm.bind(&fallthrough);
 }
 
 void
-NativeRegExpMacroAssembler::CheckNotCharacterAfterMinusAnd(jschar c, jschar minus, jschar and_with,
+NativeRegExpMacroAssembler::CheckNotCharacterAfterMinusAnd(char16_t c, char16_t minus, char16_t and_with,
                                                            Label* on_not_equal)
 {
     JitSpew(SPEW_PREFIX "CheckNotCharacterAfterMinusAnd(%d, %d, %d)", (int) c,
             (int) minus, (int) and_with);
 
     masm.computeEffectiveAddress(Address(current_character, -minus), temp0);
     if (c == 0) {
         masm.branchTest32(Assembler::NonZero, temp0, Imm32(and_with),
                           BranchOrBacktrack(on_not_equal));
     } else {
         masm.and32(Imm32(and_with), temp0);
         masm.branch32(Assembler::NotEqual, temp0, Imm32(c), BranchOrBacktrack(on_not_equal));
     }
 }
 
 void
-NativeRegExpMacroAssembler::CheckCharacterInRange(jschar from, jschar to,
+NativeRegExpMacroAssembler::CheckCharacterInRange(char16_t from, char16_t to,
                                                   Label* on_in_range)
 {
     JitSpew(SPEW_PREFIX "CheckCharacterInRange(%d, %d)", (int) from, (int) to);
 
     masm.computeEffectiveAddress(Address(current_character, -from), temp0);
     masm.branch32(Assembler::BelowOrEqual, temp0, Imm32(to - from), BranchOrBacktrack(on_in_range));
 }
 
 void
-NativeRegExpMacroAssembler::CheckCharacterNotInRange(jschar from, jschar to,
+NativeRegExpMacroAssembler::CheckCharacterNotInRange(char16_t from, char16_t to,
                                                      Label* on_not_in_range)
 {
     JitSpew(SPEW_PREFIX "CheckCharacterNotInRange(%d, %d)", (int) from, (int) to);
 
     masm.computeEffectiveAddress(Address(current_character, -from), temp0);
     masm.branch32(Assembler::Above, temp0, Imm32(to - from), BranchOrBacktrack(on_not_in_range));
 }
 
@@ -947,19 +947,19 @@ NativeRegExpMacroAssembler::LoadCurrentC
             masm.load32(address, current_character);
         } else if (characters == 2) {
             masm.load16ZeroExtend(address, current_character);
         } else {
             JS_ASSERT(characters = 1);
             masm.load8ZeroExtend(address, current_character);
         }
     } else {
-        JS_ASSERT(mode_ == JSCHAR);
+        JS_ASSERT(mode_ == CHAR16);
         JS_ASSERT(characters <= 2);
-        BaseIndex address(input_end_pointer, current_position, TimesOne, cp_offset * sizeof(jschar));
+        BaseIndex address(input_end_pointer, current_position, TimesOne, cp_offset * sizeof(char16_t));
         if (characters == 2)
             masm.load32(address, current_character);
         else
             masm.load16ZeroExtend(address, current_character);
     }
 }
 
 void
@@ -1194,17 +1194,17 @@ NativeRegExpMacroAssembler::JumpOrBacktr
 
     if (to)
         masm.jump(to);
     else
         Backtrack();
 }
 
 bool
-NativeRegExpMacroAssembler::CheckSpecialCharacterClass(jschar type, Label* on_no_match)
+NativeRegExpMacroAssembler::CheckSpecialCharacterClass(char16_t type, Label* on_no_match)
 {
     JitSpew(SPEW_PREFIX "CheckSpecialCharacterClass(%d)", (int) type);
 
     Label *branch = BranchOrBacktrack(on_no_match);
 
     // Range checks (c in min..max) are generally implemented by an unsigned
     // (c - min) <= (max - min) check
     switch (type) {
@@ -1242,17 +1242,17 @@ NativeRegExpMacroAssembler::CheckSpecial
       case '.': {
         // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029)
         masm.move32(current_character, temp0);
         masm.xor32(Imm32(0x01), temp0);
 
         // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c
         masm.sub32(Imm32(0x0b), temp0);
         masm.branch32(Assembler::BelowOrEqual, temp0, Imm32(0x0c - 0x0b), branch);
-        if (mode_ == JSCHAR) {
+        if (mode_ == CHAR16) {
             // Compare original value to 0x2028 and 0x2029, using the already
             // computed (current_char ^ 0x01 - 0x0b). I.e., check for
             // 0x201d (0x2028 - 0x0b) or 0x201e.
             masm.sub32(Imm32(0x2028 - 0x0b), temp0);
             masm.branch32(Assembler::BelowOrEqual, temp0, Imm32(0x2029 - 0x2028), branch);
         }
         return true;
       }
@@ -1294,17 +1294,17 @@ NativeRegExpMacroAssembler::CheckSpecial
         // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c
         masm.sub32(Imm32(0x0b), temp0);
 
         if (mode_ == ASCII) {
             masm.branch32(Assembler::Above, temp0, Imm32(0x0c - 0x0b), branch);
         } else {
             Label done;
             masm.branch32(Assembler::BelowOrEqual, temp0, Imm32(0x0c - 0x0b), &done);
-            JS_ASSERT(JSCHAR == mode_);
+            JS_ASSERT(CHAR16 == mode_);
 
             // Compare original value to 0x2028 and 0x2029, using the already
             // computed (current_char ^ 0x01 - 0x0b). I.e., check for
             // 0x201d (0x2028 - 0x0b) or 0x201e.
             masm.sub32(Imm32(0x2028 - 0x0b), temp0);
             masm.branch32(Assembler::Above, temp0, Imm32(1), branch);
 
             masm.bind(&done);
--- a/js/src/irregexp/NativeRegExpMacroAssembler.h
+++ b/js/src/irregexp/NativeRegExpMacroAssembler.h
@@ -59,69 +59,69 @@ struct InputOutputData
         matches(matches),
         result(0)
     {}
 };
 
 struct FrameData
 {
     // Copy of the input/output data's data.
-    jschar *inputStart;
+    char16_t *inputStart;
     size_t startIndex;
 
     // Pointer to the character before the input start.
-    jschar *inputStartMinusOne;
+    char16_t *inputStartMinusOne;
 
     // Copy of the input MatchPairs registers, may be modified by JIT code.
     int32_t *outputRegisters;
     int32_t numOutputRegisters;
 
     int32_t successfulCaptures;
 
     void *backtrackStackBase;
 };
 
 class MOZ_STACK_CLASS NativeRegExpMacroAssembler : public RegExpMacroAssembler
 {
   public:
     // Type of input string to generate code for.
-    enum Mode { ASCII = 1, JSCHAR = 2 };
+    enum Mode { ASCII = 1, CHAR16 = 2 };
 
     NativeRegExpMacroAssembler(LifoAlloc *alloc, RegExpShared *shared,
                                JSRuntime *rt, Mode mode, int registers_to_save);
 
     // Inherited virtual methods.
     RegExpCode GenerateCode(JSContext *cx);
     int stack_limit_slack();
     bool CanReadUnaligned();
     void AdvanceCurrentPosition(int by);
     void AdvanceRegister(int reg, int by);
     void Backtrack();
     void Bind(jit::Label* label);
     void CheckAtStart(jit::Label* on_at_start);
     void CheckCharacter(unsigned c, jit::Label* on_equal);
     void CheckCharacterAfterAnd(unsigned c, unsigned and_with, jit::Label* on_equal);
-    void CheckCharacterGT(jschar limit, jit::Label* on_greater);
-    void CheckCharacterLT(jschar limit, jit::Label* on_less);
+    void CheckCharacterGT(char16_t limit, jit::Label* on_greater);
+    void CheckCharacterLT(char16_t limit, jit::Label* on_less);
     void CheckGreedyLoop(jit::Label* on_tos_equals_current_position);
     void CheckNotAtStart(jit::Label* on_not_at_start);
     void CheckNotBackReference(int start_reg, jit::Label* on_no_match);
     void CheckNotBackReferenceIgnoreCase(int start_reg, jit::Label* on_no_match);
     void CheckNotCharacter(unsigned c, jit::Label* on_not_equal);
     void CheckNotCharacterAfterAnd(unsigned c, unsigned and_with, jit::Label* on_not_equal);
-    void CheckNotCharacterAfterMinusAnd(jschar c, jschar minus, jschar and_with,
+    void CheckNotCharacterAfterMinusAnd(char16_t c, char16_t minus, char16_t and_with,
                                         jit::Label* on_not_equal);
-    void CheckCharacterInRange(jschar from, jschar to,
+    void CheckCharacterInRange(char16_t from, char16_t to,
                                jit::Label* on_in_range);
-    void CheckCharacterNotInRange(jschar from, jschar to,
+    void CheckCharacterNotInRange(char16_t from, char16_t to,
                                   jit::Label* on_not_in_range);
     void CheckBitInTable(uint8_t *table, jit::Label* on_bit_set);
     void CheckPosition(int cp_offset, jit::Label* on_outside_input);
     void JumpOrBacktrack(jit::Label *to);
-    bool CheckSpecialCharacterClass(jschar type, jit::Label* on_no_match);
+    bool CheckSpecialCharacterClass(char16_t type, jit::Label* on_no_match);
     void Fail();
     void IfRegisterGE(int reg, int comparand, jit::Label* if_ge);
     void IfRegisterLT(int reg, int comparand, jit::Label* if_lt);
     void IfRegisterEqPos(int reg, jit::Label* if_eq);
     void LoadCurrentCharacter(int cp_offset, jit::Label* on_end_of_input,
                               bool check_bounds = true, int characters = 1);
     void PopCurrentPosition();
     void PopRegister(int register_index);
@@ -146,17 +146,17 @@ class MOZ_STACK_CLASS NativeRegExpMacroA
 
     // Byte map of one byte characters with a 0xff if the character is a word
     // character (digit, letter or underscore) and 0x00 otherwise.
     // Used by generated RegExp code.
     static const uint8_t word_character_map[256];
 
     // Byte size of chars in the string to match (decided by the Mode argument)
     inline int char_size() { return static_cast<int>(mode_); }
-    inline jit::Scale factor() { return mode_ == JSCHAR ? jit::TimesTwo : jit::TimesOne; }
+    inline jit::Scale factor() { return mode_ == CHAR16 ? jit::TimesTwo : jit::TimesOne; }
 
     jit::Label *BranchOrBacktrack(jit::Label *branch);
 
     // Pushes a register or constant on the backtrack stack. Decrements the
     // stack pointer by a word size and stores the register's value there.
     void PushBacktrack(jit::Register value);
     void PushBacktrack(int32_t value);
 
--- a/js/src/irregexp/RegExpAST.h
+++ b/js/src/irregexp/RegExpAST.h
@@ -145,50 +145,50 @@ class RegExpAssertion : public RegExpTre
   AssertionType assertion_type() { return assertion_type_; }
  private:
   AssertionType assertion_type_;
 };
 
 class CharacterSet
 {
   public:
-    explicit CharacterSet(jschar standard_set_type)
+    explicit CharacterSet(char16_t standard_set_type)
       : ranges_(nullptr),
         standard_set_type_(standard_set_type)
     {}
     explicit CharacterSet(CharacterRangeVector *ranges)
       : ranges_(ranges),
         standard_set_type_(0)
     {}
 
     CharacterRangeVector &ranges(LifoAlloc *alloc);
-    jschar standard_set_type() { return standard_set_type_; }
-    void set_standard_set_type(jschar special_set_type) {
+    char16_t standard_set_type() { return standard_set_type_; }
+    void set_standard_set_type(char16_t special_set_type) {
         standard_set_type_ = special_set_type;
     }
     bool is_standard() { return standard_set_type_ != 0; }
     void Canonicalize();
 
   private:
     CharacterRangeVector *ranges_;
 
     // If non-zero, the value represents a standard set (e.g., all whitespace
     // characters) without having to expand the ranges.
-    jschar standard_set_type_;
+    char16_t standard_set_type_;
 };
 
 class RegExpCharacterClass : public RegExpTree
 {
   public:
     RegExpCharacterClass(CharacterRangeVector *ranges, bool is_negated)
       : set_(ranges),
         is_negated_(is_negated)
     {}
 
-    explicit RegExpCharacterClass(jschar type)
+    explicit RegExpCharacterClass(char16_t type)
       : set_(type),
         is_negated_(false)
     {}
 
     virtual void* Accept(RegExpVisitor* visitor, void* data);
     virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                                RegExpNode* on_success);
     virtual RegExpCharacterClass* AsCharacterClass();
@@ -210,27 +210,27 @@ class RegExpCharacterClass : public RegE
     // s : unicode whitespace
     // S : unicode non-whitespace
     // w : ASCII word character (digit, letter, underscore)
     // W : non-ASCII word character
     // d : ASCII digit
     // D : non-ASCII digit
     // . : non-unicode non-newline
     // * : All characters
-    jschar standard_type() { return set_.standard_set_type(); }
+    char16_t standard_type() { return set_.standard_set_type(); }
 
     CharacterRangeVector &ranges(LifoAlloc *alloc) { return set_.ranges(alloc); }
     bool is_negated() { return is_negated_; }
 
   private:
     CharacterSet set_;
     bool is_negated_;
 };
 
-typedef Vector<jschar, 10, LifoAllocPolicy<Infallible> > CharacterVector;
+typedef Vector<char16_t, 10, LifoAllocPolicy<Infallible> > CharacterVector;
 
 class RegExpAtom : public RegExpTree
 {
   public:
     explicit RegExpAtom(CharacterVector *data)
       : data_(data)
     {}
 
--- a/js/src/irregexp/RegExpEngine.cpp
+++ b/js/src/irregexp/RegExpEngine.cpp
@@ -80,17 +80,17 @@ static const int kDigitRangeCount = Arra
 static const int kSurrogateRanges[] = { 0xd800, 0xe000, 0x10000 };
 static const int kSurrogateRangeCount = ArrayLength(kSurrogateRanges);
 static const int kLineTerminatorRanges[] = { 0x000A, 0x000B, 0x000D, 0x000E,
     0x2028, 0x202A, 0x10000 };
 static const int kLineTerminatorRangeCount = ArrayLength(kLineTerminatorRanges);
 static const unsigned kMaxOneByteCharCode = 0xff;
 static const int kMaxUtf16CodeUnit = 0xffff;
 
-static jschar
+static char16_t
 MaximumCharacter(bool ascii)
 {
     return ascii ? kMaxOneByteCharCode : kMaxUtf16CodeUnit;
 }
 
 static void
 AddClass(const int* elmv, int elmc,
          CharacterRangeVector *ranges)
@@ -107,28 +107,28 @@ static void
 AddClassNegated(const int *elmv,
                 int elmc,
                 CharacterRangeVector *ranges)
 {
     elmc--;
     JS_ASSERT(elmv[elmc] == 0x10000);
     JS_ASSERT(elmv[0] != 0x0000);
     JS_ASSERT(elmv[elmc-1] != kMaxUtf16CodeUnit);
-    jschar last = 0x0000;
+    char16_t last = 0x0000;
     for (int i = 0; i < elmc; i += 2) {
         JS_ASSERT(last <= elmv[i] - 1);
         JS_ASSERT(elmv[i] < elmv[i + 1]);
         ranges->append(CharacterRange(last, elmv[i] - 1));
         last = elmv[i + 1];
     }
     ranges->append(CharacterRange(last, kMaxUtf16CodeUnit));
 }
 
 void
-CharacterRange::AddClassEscape(LifoAlloc *alloc, jschar type,
+CharacterRange::AddClassEscape(LifoAlloc *alloc, char16_t type,
 			       CharacterRangeVector *ranges)
 {
     switch (type) {
       case 's':
         AddClass(kSpaceRanges, kSpaceRangeCount, ranges);
         break;
       case 'S':
         AddClassNegated(kSpaceRanges, kSpaceRangeCount, ranges);
@@ -183,29 +183,29 @@ RangesContainLatin1Equivalents(const Cha
     return false;
 }
 
 static const size_t kEcma262UnCanonicalizeMaxWidth = 4;
 
 // Returns the number of characters in the equivalence class, omitting those
 // that cannot occur in the source string if it is a one byte string.
 static int
-GetCaseIndependentLetters(jschar character,
+GetCaseIndependentLetters(char16_t character,
                           bool ascii_subject,
-                          jschar *letters)
+                          char16_t *letters)
 {
-    jschar choices[] = {
+    const char16_t choices[] = {
         character,
         unicode::ToLowerCase(character),
         unicode::ToUpperCase(character)
     };
 
     size_t count = 0;
     for (size_t i = 0; i < ArrayLength(choices); i++) {
-        jschar c = choices[i];
+        char16_t c = choices[i];
 
         // The standard requires that non-ASCII characters cannot have ASCII
         // character codes in their equivalence class, even though this
         // situation occurs multiple times in the unicode tables.
         static const unsigned kMaxAsciiCharCode = 127;
         if (character > kMaxAsciiCharCode && c <= kMaxAsciiCharCode)
             continue;
 
@@ -225,18 +225,18 @@ GetCaseIndependentLetters(jschar charact
             continue;
 
         letters[count++] = c;
     }
 
     return count;
 }
 
-static jschar
-ConvertNonLatin1ToLatin1(jschar c)
+static char16_t
+ConvertNonLatin1ToLatin1(char16_t c)
 {
     JS_ASSERT(c > kMaxOneByteCharCode);
     switch (c) {
       // This are equivalent characters in unicode.
       case 0x39c:
       case 0x3bc:
         return 0xb5;
       // This is an uppercase of a Latin-1 character
@@ -245,32 +245,32 @@ ConvertNonLatin1ToLatin1(jschar c)
         return 0xff;
     }
     return 0;
 }
 
 void
 CharacterRange::AddCaseEquivalents(bool is_ascii, CharacterRangeVector *ranges)
 {
-    jschar bottom = from();
-    jschar top = to();
+    char16_t bottom = from();
+    char16_t top = to();
 
     if (is_ascii && !RangeContainsLatin1Equivalents(*this)) {
         if (bottom > kMaxOneByteCharCode)
             return;
         if (top > kMaxOneByteCharCode)
             top = kMaxOneByteCharCode;
     }
 
-    for (jschar c = bottom;; c++) {
-        jschar chars[kEcma262UnCanonicalizeMaxWidth];
+    for (char16_t c = bottom;; c++) {
+        char16_t chars[kEcma262UnCanonicalizeMaxWidth];
         size_t length = GetCaseIndependentLetters(c, is_ascii, chars);
 
         for (size_t i = 0; i < length; i++) {
-            jschar other = chars[i];
+            char16_t other = chars[i];
             if (other == c)
                 continue;
 
             // Try to combine with an existing range.
             bool found = false;
             for (size_t i = 0; i < ranges->length(); i++) {
                 CharacterRange &range = (*ranges)[i];
                 if (range.Contains(other)) {
@@ -413,18 +413,18 @@ InsertRangeInCanonicalList(CharacterRang
                            int count,
                            CharacterRange insert)
 {
     // Inserts a range into list[0..count[, which must be sorted
     // by from value and non-overlapping and non-adjacent, using at most
     // list[0..count] for the result. Returns the number of resulting
     // canonicalized ranges. Inserting a range may collapse existing ranges into
     // fewer ranges, so the return value can be anything in the range 1..count+1.
-    jschar from = insert.from();
-    jschar to = insert.to();
+    char16_t from = insert.from();
+    char16_t to = insert.to();
     int start_pos = 0;
     int end_pos = count;
     for (int i = count - 1; i >= 0; i--) {
         CharacterRange current = list[i];
         if (current.from() > to + 1) {
             end_pos = i;
         } else if (current.to() + 1 < from) {
             start_pos = i + 1;
@@ -720,17 +720,17 @@ TextNode::FilterASCII(int depth, bool ig
                 uint16_t c = quarks[j];
                 if (c <= kMaxOneByteCharCode)
                     continue;
                 if (!ignore_case)
                     return set_replacement(nullptr);
 
                 // Here, we need to check for characters whose upper and lower cases
                 // are outside the Latin-1 range.
-                jschar converted = ConvertNonLatin1ToLatin1(c);
+                char16_t converted = ConvertNonLatin1ToLatin1(c);
                 if (converted == 0) {
                     // Character is outside Latin-1 completely
                     return set_replacement(nullptr);
                 }
 
                 // Convert quark to Latin-1 in place.
                 quarks[j] = converted;
             }
@@ -1721,17 +1721,17 @@ irregexp::CompilePattern(JSContext *cx, 
     Maybe<jit::IonContext> ctx;
     Maybe<NativeRegExpMacroAssembler> native_assembler;
     Maybe<InterpretedRegExpMacroAssembler> interpreted_assembler;
 
     RegExpMacroAssembler *assembler;
     if (IsNativeRegExpEnabled(cx)) {
         NativeRegExpMacroAssembler::Mode mode =
             is_ascii ? NativeRegExpMacroAssembler::ASCII
-                     : NativeRegExpMacroAssembler::JSCHAR;
+                     : NativeRegExpMacroAssembler::CHAR16;
 
         ctx.emplace(cx, (jit::TempAllocator *) nullptr);
         native_assembler.emplace(&alloc, shared, cx->runtime(), mode, (data->capture_count + 1) * 2);
         assembler = native_assembler.ptr();
     } else {
         interpreted_assembler.emplace(&alloc, shared, (data->capture_count + 1) * 2);
         assembler = interpreted_assembler.ptr();
     }
@@ -1773,17 +1773,17 @@ irregexp::ExecuteCode(JSContext *cx, jit
     return (RegExpRunStatus) data.result;
 }
 
 template RegExpRunStatus
 irregexp::ExecuteCode(JSContext *cx, jit::JitCode *codeBlock, const Latin1Char *chars, size_t start,
                       size_t length, MatchPairs *matches);
 
 template RegExpRunStatus
-irregexp::ExecuteCode(JSContext *cx, jit::JitCode *codeBlock, const jschar *chars, size_t start,
+irregexp::ExecuteCode(JSContext *cx, jit::JitCode *codeBlock, const char16_t *chars, size_t start,
                       size_t length, MatchPairs *matches);
 
 // -------------------------------------------------------------------
 // Tree to graph conversion
 
 RegExpNode *
 RegExpAtom::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
 {
@@ -3212,18 +3212,18 @@ SplitSearchSpace(RangeBoundaryVector &ra
 // know that the character is in the range of min_char to max_char inclusive.
 // Either label can be nullptr indicating backtracking.  Either label can also be
 // equal to the fall_through label.
 static void
 GenerateBranches(RegExpMacroAssembler* masm,
                  RangeBoundaryVector &ranges,
                  int start_index,
                  int end_index,
-                 jschar min_char,
-                 jschar max_char,
+                 char16_t min_char,
+                 char16_t max_char,
                  jit::Label* fall_through,
                  jit::Label* even_label,
                  jit::Label* odd_label)
 {
     int first = ranges[start_index];
     int last = ranges[end_index] - 1;
 
     JS_ASSERT(min_char < first);
@@ -3467,25 +3467,25 @@ EmitCharClass(LifoAlloc *alloc,
                      max_char,
                      &fall_through,
                      zeroth_entry_is_failure ? &fall_through : on_failure,
                      zeroth_entry_is_failure ? on_failure : &fall_through);
     macro_assembler->Bind(&fall_through);
 }
 
 typedef bool EmitCharacterFunction(RegExpCompiler* compiler,
-                                   jschar c,
+                                   char16_t c,
                                    jit::Label* on_failure,
                                    int cp_offset,
                                    bool check,
                                    bool preloaded);
 
 static inline bool
 EmitSimpleCharacter(RegExpCompiler* compiler,
-                    jschar c,
+                    char16_t c,
                     jit::Label* on_failure,
                     int cp_offset,
                     bool check,
                     bool preloaded)
 {
     RegExpMacroAssembler* assembler = compiler->macro_assembler();
     bool bound_checked = false;
     if (!preloaded) {
@@ -3495,25 +3495,25 @@ EmitSimpleCharacter(RegExpCompiler* comp
     assembler->CheckNotCharacter(c, on_failure);
     return bound_checked;
 }
 
 // Only emits non-letters (things that don't have case).  Only used for case
 // independent matches.
 static inline bool
 EmitAtomNonLetter(RegExpCompiler* compiler,
-                  jschar c,
+                  char16_t c,
                   jit::Label* on_failure,
                   int cp_offset,
                   bool check,
                   bool preloaded)
 {
     RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
     bool ascii = compiler->ascii();
-    jschar chars[kEcma262UnCanonicalizeMaxWidth];
+    char16_t chars[kEcma262UnCanonicalizeMaxWidth];
     int length = GetCaseIndependentLetters(c, ascii, chars);
     if (length < 1) {
         // This can't match.  Must be an ASCII subject and a non-ASCII character.
         // We do not need to do anything since the ASCII pass already handled this.
         return false;  // Bounds not checked.
     }
     bool checked = false;
     // We handle the length > 1 case in a later pass.
@@ -3529,67 +3529,67 @@ EmitAtomNonLetter(RegExpCompiler* compil
         macro_assembler->CheckNotCharacter(c, on_failure);
     }
     return checked;
 }
 
 static bool
 ShortCutEmitCharacterPair(RegExpMacroAssembler* macro_assembler,
                           bool ascii,
-                          jschar c1,
-                          jschar c2,
+                          char16_t c1,
+                          char16_t c2,
                           jit::Label* on_failure)
 {
-    jschar char_mask = MaximumCharacter(ascii);
+    char16_t char_mask = MaximumCharacter(ascii);
 
     JS_ASSERT(c1 != c2);
     if (c1 > c2) {
-        jschar tmp = c1;
+        char16_t tmp = c1;
         c1 = c2;
         c2 = tmp;
     }
 
-    jschar exor = c1 ^ c2;
+    char16_t exor = c1 ^ c2;
     // Check whether exor has only one bit set.
     if (((exor - 1) & exor) == 0) {
         // If c1 and c2 differ only by one bit.
-        jschar mask = char_mask ^ exor;
+        char16_t mask = char_mask ^ exor;
         macro_assembler->CheckNotCharacterAfterAnd(c1, mask, on_failure);
         return true;
     }
 
-    jschar diff = c2 - c1;
+    char16_t diff = c2 - c1;
     if (((diff - 1) & diff) == 0 && c1 >= diff) {
         // If the characters differ by 2^n but don't differ by one bit then
         // subtract the difference from the found character, then do the or
         // trick.  We avoid the theoretical case where negative numbers are
         // involved in order to simplify code generation.
-        jschar mask = char_mask ^ diff;
+        char16_t mask = char_mask ^ diff;
         macro_assembler->CheckNotCharacterAfterMinusAnd(c1 - diff,
                                                         diff,
                                                         mask,
                                                         on_failure);
         return true;
     }
     return false;
 }
 
 // Only emits letters (things that have case).  Only used for case independent
 // matches.
 static inline bool
 EmitAtomLetter(RegExpCompiler* compiler,
-               jschar c,
+               char16_t c,
                jit::Label* on_failure,
                int cp_offset,
                bool check,
                bool preloaded)
 {
     RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
     bool ascii = compiler->ascii();
-    jschar chars[kEcma262UnCanonicalizeMaxWidth];
+    char16_t chars[kEcma262UnCanonicalizeMaxWidth];
     int length = GetCaseIndependentLetters(c, ascii, chars);
     if (length <= 1) return false;
     // We may not need to check against the end of the input string
     // if this character lies before a character that matched.
     if (!preloaded)
         macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check);
     jit::Label ok;
     JS_ASSERT(kEcma262UnCanonicalizeMaxWidth == 4);
@@ -4586,19 +4586,19 @@ TextNode::FillInBMInfo(int initial_offse
         if (text.text_type() == TextElement::ATOM) {
             RegExpAtom* atom = text.atom();
             for (int j = 0; j < atom->length(); j++, offset++) {
                 if (offset >= bm->length()) {
                     if (initial_offset == 0)
                         set_bm_info(not_at_start, bm);
                     return true;
                 }
-                jschar character = atom->data()[j];
+                char16_t character = atom->data()[j];
                 if (bm->compiler()->ignore_case()) {
-                    jschar chars[kEcma262UnCanonicalizeMaxWidth];
+                    char16_t chars[kEcma262UnCanonicalizeMaxWidth];
                     int length = GetCaseIndependentLetters(character,
                                                            bm->max_char() == kMaxOneByteCharCode,
                                                            chars);
                     for (int j = 0; j < length; j++)
                         bm->Set(offset, chars[j]);
                 } else {
                     if (character <= max_char) bm->Set(offset, character);
                 }
@@ -4670,28 +4670,28 @@ TextNode::GetQuickCheckDetails(QuickChec
 
     for (size_t k = 0; k < elements().length(); k++) {
         TextElement elm = elements()[k];
         if (elm.text_type() == TextElement::ATOM) {
             const CharacterVector &quarks = elm.atom()->data();
             for (size_t i = 0; i < (size_t) characters && i < quarks.length(); i++) {
                 QuickCheckDetails::Position* pos =
                     details->positions(characters_filled_in);
-                jschar c = quarks[i];
+                char16_t c = quarks[i];
                 if (c > char_mask) {
                     // If we expect a non-ASCII character from an ASCII string,
                     // there is no way we can match. Not even case independent
                     // matching can turn an ASCII character into non-ASCII or
                     // vice versa.
                     details->set_cannot_match();
                     pos->determines_perfectly = false;
                     return;
                 }
                 if (compiler->ignore_case()) {
-                    jschar chars[kEcma262UnCanonicalizeMaxWidth];
+                    char16_t chars[kEcma262UnCanonicalizeMaxWidth];
                     size_t length = GetCaseIndependentLetters(c, compiler->ascii(), chars);
                     JS_ASSERT(length != 0);  // Can only happen if c > char_mask (see above).
                     if (length == 1) {
                         // This letter has no case equivalents, so it's nice and simple
                         // and the mask-compare will determine definitely whether we have
                         // a match at this character position.
                         pos->mask = char_mask;
                         pos->value = c;
@@ -4747,34 +4747,34 @@ TextNode::GetQuickCheckDetails(QuickChec
                     first_range++;
                     if (first_range == ranges.length()) {
                         details->set_cannot_match();
                         pos->determines_perfectly = false;
                         return;
                     }
                 }
                 CharacterRange range = ranges[first_range];
-                jschar from = range.from();
-                jschar to = range.to();
+                char16_t from = range.from();
+                char16_t to = range.to();
                 if (to > char_mask) {
                     to = char_mask;
                 }
                 uint32_t differing_bits = (from ^ to);
                 // A mask and compare is only perfect if the differing bits form a
                 // number like 00011111 with one single block of trailing 1s.
                 if ((differing_bits & (differing_bits + 1)) == 0 &&
                     from + differing_bits == to) {
                     pos->determines_perfectly = true;
                 }
                 uint32_t common_bits = ~SmearBitsRight(differing_bits);
                 uint32_t bits = (from & common_bits);
                 for (size_t i = first_range + 1; i < ranges.length(); i++) {
                     CharacterRange range = ranges[i];
-                    jschar from = range.from();
-                    jschar to = range.to();
+                    char16_t from = range.from();
+                    char16_t to = range.to();
                     if (from > char_mask) continue;
                     if (to > char_mask) to = char_mask;
                     // Here we are combining more ranges into the mask and compare
                     // value.  With each new range the mask becomes more sparse and
                     // so the chances of a false positive rise.  A character class
                     // with multiple ranges is assumed never to be equivalent to a
                     // mask and compare operation.
                     pos->determines_perfectly = false;
@@ -4875,13 +4875,13 @@ void QuickCheckDetails::Merge(QuickCheck
             !other_pos->determines_perfectly) {
             // Our mask-compare operation will be approximate unless we have the
             // exact same operation on both sides of the alternation.
             pos->determines_perfectly = false;
         }
         pos->mask &= other_pos->mask;
         pos->value &= pos->mask;
         other_pos->value &= pos->mask;
-        jschar differing_bits = (pos->value ^ other_pos->value);
+        char16_t differing_bits = (pos->value ^ other_pos->value);
         pos->mask &= ~differing_bits;
         pos->value &= pos->mask;
     }
 }
--- a/js/src/irregexp/RegExpEngine.h
+++ b/js/src/irregexp/RegExpEngine.h
@@ -134,39 +134,39 @@ typedef Vector<CharacterRange, 1, LifoAl
 // inclusive.
 class CharacterRange
 {
   public:
     CharacterRange()
       : from_(0), to_(0)
     {}
 
-    CharacterRange(jschar from, jschar to)
+    CharacterRange(char16_t from, char16_t to)
       : from_(from), to_(to)
     {}
 
-    static void AddClassEscape(LifoAlloc *alloc, jschar type, CharacterRangeVector *ranges);
+    static void AddClassEscape(LifoAlloc *alloc, char16_t type, CharacterRangeVector *ranges);
 
-    static inline CharacterRange Singleton(jschar value) {
+    static inline CharacterRange Singleton(char16_t value) {
         return CharacterRange(value, value);
     }
-    static inline CharacterRange Range(jschar from, jschar to) {
+    static inline CharacterRange Range(char16_t from, char16_t to) {
         JS_ASSERT(from <= to);
         return CharacterRange(from, to);
     }
     static inline CharacterRange Everything() {
         return CharacterRange(0, 0xFFFF);
     }
-    bool Contains(jschar i) { return from_ <= i && i <= to_; }
-    jschar from() const { return from_; }
-    void set_from(jschar value) { from_ = value; }
-    jschar to() const { return to_; }
-    void set_to(jschar value) { to_ = value; }
+    bool Contains(char16_t i) { return from_ <= i && i <= to_; }
+    char16_t from() const { return from_; }
+    void set_from(char16_t value) { from_ = value; }
+    char16_t to() const { return to_; }
+    void set_to(char16_t value) { to_ = value; }
     bool is_valid() { return from_ <= to_; }
-    bool IsEverything(jschar max) { return from_ == 0 && to_ >= max; }
+    bool IsEverything(char16_t max) { return from_ == 0 && to_ >= max; }
     bool IsSingleton() { return (from_ == to_); }
     void AddCaseEquivalents(bool is_ascii, CharacterRangeVector *ranges);
 
     static void Split(const LifoAlloc *alloc,
                       CharacterRangeVector base,
                       const Vector<int> &overlay,
                       CharacterRangeVector* included,
                       CharacterRangeVector* excluded);
@@ -185,18 +185,18 @@ class CharacterRange
     static void Negate(const LifoAlloc *alloc,
                        CharacterRangeVector src,
                        CharacterRangeVector *dst);
 
     static const int kStartMarker = (1 << 24);
     static const int kPayloadMask = (1 << 24) - 1;
 
   private:
-    jschar from_;
-    jschar to_;
+    char16_t from_;
+    char16_t to_;
 };
 
 // A set of unsigned integers that behaves especially well on small
 // integers (< 32).
 class OutSet
 {
   public:
     OutSet()
@@ -242,35 +242,35 @@ class DispatchTable
     {}
 
     class Entry {
       public:
         Entry()
           : from_(0), to_(0), out_set_(nullptr)
         {}
 
-        Entry(jschar from, jschar to, OutSet* out_set)
+        Entry(char16_t from, char16_t to, OutSet* out_set)
           : from_(from), to_(to), out_set_(out_set)
         {}
 
-        jschar from() { return from_; }
-        jschar to() { return to_; }
-        void set_to(jschar value) { to_ = value; }
+        char16_t from() { return from_; }
+        char16_t to() { return to_; }
+        void set_to(char16_t value) { to_ = value; }
         void AddValue(LifoAlloc *alloc, int value) {
             out_set_ = out_set_->Extend(alloc, value);
         }
         OutSet* out_set() { return out_set_; }
       private:
-        jschar from_;
-        jschar to_;
+        char16_t from_;
+        char16_t to_;
         OutSet* out_set_;
     };
 
     void AddRange(LifoAlloc *alloc, CharacterRange range, int value);
-    OutSet* Get(jschar value);
+    OutSet* Get(char16_t value);
     void Dump();
 
   private:
     // There can't be a static empty set since it allocates its
     // successors in a LifoAlloc and caches them.
     OutSet* empty() { return &empty_; }
     OutSet empty_;
 };
@@ -417,18 +417,18 @@ class QuickCheckDetails
     bool cannot_match() { return cannot_match_; }
     void set_cannot_match() { cannot_match_ = true; }
 
     int characters() { return characters_; }
     void set_characters(int characters) { characters_ = characters; }
 
     struct Position {
         Position() : mask(0), value(0), determines_perfectly(false) { }
-        jschar mask;
-        jschar value;
+        char16_t mask;
+        char16_t value;
         bool determines_perfectly;
     };
 
     Position* positions(int index) {
         JS_ASSERT(index >= 0);
         JS_ASSERT(index < characters_);
         return positions_ + index;
     }
--- a/js/src/irregexp/RegExpInterpreter.cpp
+++ b/js/src/irregexp/RegExpInterpreter.cpp
@@ -229,18 +229,18 @@ irregexp::InterpretCode(JSContext *cx, c
                 CharT next = chars[pos + 1];
                 current_char = (chars[pos] | (next << (kBitsPerByte * sizeof(CharT))));
                 pc += BC_LOAD_2_CURRENT_CHARS_LENGTH;
             }
             break;
           }
           BYTECODE(LOAD_2_CURRENT_CHARS_UNCHECKED) {
             int pos = current + (insn >> BYTECODE_SHIFT);
-            jschar next = chars[pos + 1];
-            current_char = (chars[pos] | (next << (kBitsPerByte * sizeof(jschar))));
+            char16_t next = chars[pos + 1];
+            current_char = (chars[pos] | (next << (kBitsPerByte * sizeof(char16_t))));
             pc += BC_LOAD_2_CURRENT_CHARS_UNCHECKED_LENGTH;
             break;
           }
           BYTECODE(LOAD_4_CURRENT_CHARS)
             MOZ_CRASH("ASCII handling implemented");
           BYTECODE(LOAD_4_CURRENT_CHARS_UNCHECKED)
             MOZ_CRASH("ASCII handling implemented");
           BYTECODE(CHECK_4_CHARS) {
@@ -455,10 +455,10 @@ irregexp::InterpretCode(JSContext *cx, c
     }
 }
 
 template RegExpRunStatus
 irregexp::InterpretCode(JSContext *cx, const uint8_t *byteCode, const Latin1Char *chars, size_t current,
                         size_t length, MatchPairs *matches);
 
 template RegExpRunStatus
-irregexp::InterpretCode(JSContext *cx, const uint8_t *byteCode, const jschar *chars, size_t current,
+irregexp::InterpretCode(JSContext *cx, const uint8_t *byteCode, const char16_t *chars, size_t current,
                         size_t length, MatchPairs *matches);
--- a/js/src/irregexp/RegExpMacroAssembler.cpp
+++ b/js/src/irregexp/RegExpMacroAssembler.cpp
@@ -39,35 +39,35 @@ template <typename CharT>
 int
 irregexp::CaseInsensitiveCompareStrings(const CharT *substring1, const CharT *substring2,
 					size_t byteLength)
 {
     JS_ASSERT(byteLength % sizeof(CharT) == 0);
     size_t length = byteLength / sizeof(CharT);
 
     for (size_t i = 0; i < length; i++) {
-        jschar c1 = substring1[i];
-        jschar c2 = substring2[i];
+        char16_t c1 = substring1[i];
+        char16_t c2 = substring2[i];
         if (c1 != c2) {
             c1 = unicode::ToLowerCase(c1);
             c2 = unicode::ToLowerCase(c2);
             if (c1 != c2)
                 return 0;
         }
     }
 
     return 1;
 }
 
 template int
 irregexp::CaseInsensitiveCompareStrings(const Latin1Char *substring1, const Latin1Char *substring2,
 					size_t byteLength);
 
 template int
-irregexp::CaseInsensitiveCompareStrings(const jschar *substring1, const jschar *substring2,
+irregexp::CaseInsensitiveCompareStrings(const char16_t *substring1, const char16_t *substring2,
 					size_t byteLength);
 
 InterpretedRegExpMacroAssembler::InterpretedRegExpMacroAssembler(LifoAlloc *alloc, RegExpShared *shared,
                                                                  size_t numSavedRegisters)
   : RegExpMacroAssembler(*alloc, shared, numSavedRegisters),
     pc_(0),
     advance_current_start_(0),
     advance_current_offset_(0),
@@ -168,24 +168,24 @@ InterpretedRegExpMacroAssembler::CheckCh
     } else {
         Emit(BC_AND_CHECK_CHAR, c);
     }
     Emit32(and_with);
     EmitOrLink(on_equal);
 }
 
 void
-InterpretedRegExpMacroAssembler::CheckCharacterGT(jschar limit, jit::Label* on_greater)
+InterpretedRegExpMacroAssembler::CheckCharacterGT(char16_t limit, jit::Label* on_greater)
 {
     Emit(BC_CHECK_GT, limit);
     EmitOrLink(on_greater);
 }
 
 void
-InterpretedRegExpMacroAssembler::CheckCharacterLT(jschar limit, jit::Label* on_less)
+InterpretedRegExpMacroAssembler::CheckCharacterLT(char16_t limit, jit::Label* on_less)
 {
     Emit(BC_CHECK_LT, limit);
     EmitOrLink(on_less);
 }
 
 void
 InterpretedRegExpMacroAssembler::CheckGreedyLoop(jit::Label* on_tos_equals_current_position)
 {
@@ -240,37 +240,37 @@ InterpretedRegExpMacroAssembler::CheckNo
     } else {
         Emit(BC_AND_CHECK_NOT_CHAR, c);
     }
     Emit32(and_with);
     EmitOrLink(on_not_equal);
 }
 
 void
-InterpretedRegExpMacroAssembler::CheckNotCharacterAfterMinusAnd(jschar c, jschar minus, jschar and_with,
+InterpretedRegExpMacroAssembler::CheckNotCharacterAfterMinusAnd(char16_t c, char16_t minus, char16_t and_with,
                                                                 jit::Label* on_not_equal)
 {
     Emit(BC_MINUS_AND_CHECK_NOT_CHAR, c);
     Emit16(minus);
     Emit16(and_with);
     EmitOrLink(on_not_equal);
 }
 
 void
-InterpretedRegExpMacroAssembler::CheckCharacterInRange(jschar from, jschar to,
+InterpretedRegExpMacroAssembler::CheckCharacterInRange(char16_t from, char16_t to,
                                                        jit::Label* on_in_range)
 {
     Emit(BC_CHECK_CHAR_IN_RANGE, 0);
     Emit16(from);
     Emit16(to);
     EmitOrLink(on_in_range);
 }
 
 void
-InterpretedRegExpMacroAssembler::CheckCharacterNotInRange(jschar from, jschar to,
+InterpretedRegExpMacroAssembler::CheckCharacterNotInRange(char16_t from, char16_t to,
                                                           jit::Label* on_not_in_range)
 {
     Emit(BC_CHECK_CHAR_NOT_IN_RANGE, 0);
     Emit16(from);
     Emit16(to);
     EmitOrLink(on_not_in_range);
 }
 
--- a/js/src/irregexp/RegExpMacroAssembler.h
+++ b/js/src/irregexp/RegExpMacroAssembler.h
@@ -102,41 +102,41 @@ class MOZ_STACK_CLASS RegExpMacroAssembl
     // Dispatch after looking the current character up in a 2-bits-per-entry
     // map.  The destinations vector has up to 4 labels.
     virtual void CheckCharacter(unsigned c, jit::Label* on_equal) = 0;
 
     // Bitwise and the current character with the given constant and then
     // check for a match with c.
     virtual void CheckCharacterAfterAnd(unsigned c, unsigned and_with, jit::Label* on_equal) = 0;
 
-    virtual void CheckCharacterGT(jschar limit, jit::Label* on_greater) = 0;
-    virtual void CheckCharacterLT(jschar limit, jit::Label* on_less) = 0;
+    virtual void CheckCharacterGT(char16_t limit, jit::Label* on_greater) = 0;
+    virtual void CheckCharacterLT(char16_t limit, jit::Label* on_less) = 0;
     virtual void CheckGreedyLoop(jit::Label* on_tos_equals_current_position) = 0;
     virtual void CheckNotAtStart(jit::Label* on_not_at_start) = 0;
     virtual void CheckNotBackReference(int start_reg, jit::Label* on_no_match) = 0;
     virtual void CheckNotBackReferenceIgnoreCase(int start_reg, jit::Label* on_no_match) = 0;
 
     // Check the current character for a match with a literal character.  If we
     // fail to match then goto the on_failure label.  End of input always
     // matches.  If the label is nullptr then we should pop a backtrack address off
     // the stack and go to that.
     virtual void CheckNotCharacter(unsigned c, jit::Label* on_not_equal) = 0;
     virtual void CheckNotCharacterAfterAnd(unsigned c, unsigned and_with, jit::Label* on_not_equal) = 0;
 
     // Subtract a constant from the current character, then and with the given
     // constant and then check for a match with c.
-    virtual void CheckNotCharacterAfterMinusAnd(jschar c,
-                                        jschar minus,
-                                        jschar and_with,
+    virtual void CheckNotCharacterAfterMinusAnd(char16_t c,
+                                        char16_t minus,
+                                        char16_t and_with,
                                         jit::Label* on_not_equal) = 0;
 
-    virtual void CheckCharacterInRange(jschar from, jschar to,  // Both inclusive.
+    virtual void CheckCharacterInRange(char16_t from, char16_t to,  // Both inclusive.
                                jit::Label* on_in_range) = 0;
 
-    virtual void CheckCharacterNotInRange(jschar from, jschar to,  // Both inclusive.
+    virtual void CheckCharacterNotInRange(char16_t from, char16_t to,  // Both inclusive.
                                   jit::Label* on_not_in_range) = 0;
 
     // The current character (modulus the kTableSize) is looked up in the byte
     // array, and if the found byte is non-zero, we jump to the on_bit_set label.
     virtual void CheckBitInTable(uint8_t *table, jit::Label* on_bit_set) = 0;
 
     // Checks whether the given offset from the current position is before
     // the end of the string. May overwrite the current character.
@@ -146,17 +146,17 @@ class MOZ_STACK_CLASS RegExpMacroAssembl
 
     // Jump to either the target label or the top of the backtrack stack.
     virtual void JumpOrBacktrack(jit::Label *to) = 0;
 
     // Check whether a standard/default character class matches the current
     // character. Returns false if the type of special character class does
     // not have custom support.
     // May clobber the current loaded character.
-    virtual bool CheckSpecialCharacterClass(jschar type, jit::Label* on_no_match) {
+    virtual bool CheckSpecialCharacterClass(char16_t type, jit::Label* on_no_match) {
         return false;
     }
 
     virtual void Fail() = 0;
 
     // Check whether a register is >= a given constant and go to a label if it
     // is.  Backtracks instead if the label is nullptr.
     virtual void IfRegisterGE(int reg, int comparand, jit::Label *if_ge) = 0;
@@ -231,29 +231,29 @@ class MOZ_STACK_CLASS InterpretedRegExpM
     RegExpCode GenerateCode(JSContext *cx);
     void AdvanceCurrentPosition(int by);
     void AdvanceRegister(int reg, int by);
     void Backtrack();
     void Bind(jit::Label* label);
     void CheckAtStart(jit::Label* on_at_start);
     void CheckCharacter(unsigned c, jit::Label* on_equal);
     void CheckCharacterAfterAnd(unsigned c, unsigned and_with, jit::Label* on_equal);
-    void CheckCharacterGT(jschar limit, jit::Label* on_greater);
-    void CheckCharacterLT(jschar limit, jit::Label* on_less);
+    void CheckCharacterGT(char16_t limit, jit::Label* on_greater);
+    void CheckCharacterLT(char16_t limit, jit::Label* on_less);
     void CheckGreedyLoop(jit::Label* on_tos_equals_current_position);
     void CheckNotAtStart(jit::Label* on_not_at_start);
     void CheckNotBackReference(int start_reg, jit::Label* on_no_match);
     void CheckNotBackReferenceIgnoreCase(int start_reg, jit::Label* on_no_match);
     void CheckNotCharacter(unsigned c, jit::Label* on_not_equal);
     void CheckNotCharacterAfterAnd(unsigned c, unsigned and_with, jit::Label* on_not_equal);
-    void CheckNotCharacterAfterMinusAnd(jschar c, jschar minus, jschar and_with,
+    void CheckNotCharacterAfterMinusAnd(char16_t c, char16_t minus, char16_t and_with,
                                         jit::Label* on_not_equal);
-    void CheckCharacterInRange(jschar from, jschar to,
+    void CheckCharacterInRange(char16_t from, char16_t to,
                                jit::Label* on_in_range);
-    void CheckCharacterNotInRange(jschar from, jschar to,
+    void CheckCharacterNotInRange(char16_t from, char16_t to,
                                   jit::Label* on_not_in_range);
     void CheckBitInTable(uint8_t *table, jit::Label* on_bit_set);
     void JumpOrBacktrack(jit::Label *to);
     void Fail();
     void IfRegisterGE(int reg, int comparand, jit::Label* if_ge);
     void IfRegisterLT(int reg, int comparand, jit::Label* if_lt);
     void IfRegisterEqPos(int reg, jit::Label* if_eq);
     void LoadCurrentCharacter(int cp_offset, jit::Label* on_end_of_input,
--- a/js/src/irregexp/RegExpParser.cpp
+++ b/js/src/irregexp/RegExpParser.cpp
@@ -71,17 +71,17 @@ RegExpBuilder::FlushText()
         for (int i = 0; i < num_text; i++)
             text_.Get(i)->AppendToText(text);
         terms_.Add(alloc, text);
     }
     text_.Clear();
 }
 
 void
-RegExpBuilder::AddCharacter(jschar c)
+RegExpBuilder::AddCharacter(char16_t c)
 {
     pending_empty_ = false;
     if (characters_ == nullptr)
         characters_ = alloc->newInfallible<CharacterVector>(*alloc);
     characters_->append(c);
     last_added_ = ADD_CHAR;
 }
 
@@ -392,25 +392,25 @@ RegExpParser<CharT>::ParseClassCharacter
         widechar result = current();
         Advance();
         return result;
       }
     }
     return 0;
 }
 
-static const jschar kNoCharClass = 0;
+static const char16_t kNoCharClass = 0;
 
 // Adds range or pre-defined character class to character ranges.
 // If char_class is not kInvalidClass, it's interpreted as a class
 // escape (i.e., 's' means whitespace, from '\s').
 static inline void
 AddRangeOrEscape(LifoAlloc *alloc,
                  CharacterRangeVector *ranges,
-                 jschar char_class,
+                 char16_t char_class,
                  CharacterRange range)
 {
     if (char_class != kNoCharClass)
         CharacterRange::AddClassEscape(alloc, char_class, ranges);
     else
         ranges->append(range);
 }
 
@@ -422,32 +422,32 @@ RegExpParser<CharT>::ParseCharacterClass
     Advance();
     bool is_negated = false;
     if (current() == '^') {
         is_negated = true;
         Advance();
     }
     CharacterRangeVector *ranges = alloc->newInfallible<CharacterRangeVector>(*alloc);
     while (has_more() && current() != ']') {
-        jschar char_class = kNoCharClass;
+        char16_t char_class = kNoCharClass;
         CharacterRange first;
         if (!ParseClassAtom(&char_class, &first))
             return nullptr;
         if (current() == '-') {
             Advance();
             if (current() == kEndMarker) {
                 // If we reach the end we break out of the loop and let the
                 // following code report an error.
                 break;
             } else if (current() == ']') {
                 AddRangeOrEscape(alloc, ranges, char_class, first);
                 ranges->append(CharacterRange::Singleton('-'));
                 break;
             }
-            jschar char_class_2 = kNoCharClass;
+            char16_t char_class_2 = kNoCharClass;
             CharacterRange next;
             if (!ParseClassAtom(&char_class_2, &next))
                 return nullptr;
             if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
                 // Either end is an escaped character class. Treat the '-' verbatim.
                 AddRangeOrEscape(alloc, ranges, char_class, first);
                 ranges->append(CharacterRange::Singleton('-'));
                 AddRangeOrEscape(alloc, ranges, char_class_2, next);
@@ -467,17 +467,17 @@ RegExpParser<CharT>::ParseCharacterClass
         ranges->append(CharacterRange::Everything());
         is_negated = !is_negated;
     }
     return alloc->newInfallible<RegExpCharacterClass>(ranges, is_negated);
 }
 
 template <typename CharT>
 bool
-RegExpParser<CharT>::ParseClassAtom(jschar* char_class, CharacterRange *char_range)
+RegExpParser<CharT>::ParseClassAtom(char16_t* char_class, CharacterRange *char_range)
 {
     JS_ASSERT(*char_class == kNoCharClass);
     widechar first = current();
     if (first == '\\') {
         switch (Next()) {
           case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
             *char_class = Next();
             Advance(2);
@@ -992,17 +992,17 @@ RegExpParser<CharT>::ParseDisjunction()
             quantifier_type = RegExpQuantifier::NON_GREEDY;
             Advance();
         }
         builder->AddQuantifierToAtom(min, max, quantifier_type);
     }
 }
 
 template class irregexp::RegExpParser<Latin1Char>;
-template class irregexp::RegExpParser<jschar>;
+template class irregexp::RegExpParser<char16_t>;
 
 template <typename CharT>
 static bool
 ParsePattern(frontend::TokenStream &ts, LifoAlloc &alloc, const CharT *chars, size_t length,
              bool multiline, RegExpCompileData *data)
 {
     RegExpParser<CharT> parser(ts, &alloc, chars, chars + length, multiline);
     data->tree = parser.ParsePattern();
--- a/js/src/irregexp/RegExpParser.h
+++ b/js/src/irregexp/RegExpParser.h
@@ -132,17 +132,17 @@ class BufferedVector
 };
 
 
 // Accumulates RegExp atoms and assertions into lists of terms and alternatives.
 class RegExpBuilder
 {
   public:
     explicit RegExpBuilder(LifoAlloc *alloc);
-    void AddCharacter(jschar character);
+    void AddCharacter(char16_t character);
     // "Adds" an empty expression. Does nothing except consume a
     // following quantifier
     void AddEmpty();
     void AddAtom(RegExpTree* tree);
     void AddAssertion(RegExpTree* tree);
     void NewAlternative();  // '|'
     void AddQuantifierToAtom(int min, int max, RegExpQuantifier::QuantifierType type);
     RegExpTree* ToRegExp();
@@ -160,17 +160,17 @@ class RegExpBuilder
     BufferedVector<RegExpTree, 2> alternatives_;
 
     enum LastAdded {
         ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM
     };
     mozilla::DebugOnly<LastAdded> last_added_;
 };
 
-// Characters parsed by RegExpParser can be either jschars or kEndMarker.
+// Characters parsed by RegExpParser can be either char16_t or kEndMarker.
 typedef uint32_t widechar;
 
 template <typename CharT>
 class RegExpParser
 {
   public:
     RegExpParser(frontend::TokenStream &ts, LifoAlloc *alloc,
                  const CharT *chars, const CharT *end, bool multiline_mode);
@@ -195,17 +195,17 @@ class RegExpParser
     size_t ParseOctalLiteral();
 
     // Tries to parse the input as a back reference.  If successful it
     // stores the result in the output parameter and returns true.  If
     // it fails it will push back the characters read so the same characters
     // can be reparsed.
     bool ParseBackReferenceIndex(int* index_out);
 
-    bool ParseClassAtom(jschar* char_class, CharacterRange *char_range);
+    bool ParseClassAtom(char16_t* char_class, CharacterRange *char_range);
     RegExpTree* ReportError(unsigned errorNumber);
     void Advance();
     void Advance(int dist) {
         next_pos_ += dist - 1;
         Advance();
     }
 
     void Reset(const CharT *pos) {
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -5172,18 +5172,19 @@ CodeGenerator::visitConcatPar(LConcatPar
 
     return emitConcat(lir, lhs, rhs, output);
 }
 
 static void
 CopyStringChars(MacroAssembler &masm, Register to, Register from, Register len, Register scratch,
                 size_t fromWidth, size_t toWidth)
 {
-    // Copy |len| jschars from |from| to |to|. Assumes len > 0 (checked below in
-    // debug builds), and when done |to| must point to the next available char.
+    // Copy |len| char16_t code units from |from| to |to|. Assumes len > 0
+    // (checked below in debug builds), and when done |to| must point to the
+    // next available char.
 
 #ifdef DEBUG
     Label ok;
     masm.branch32(Assembler::GreaterThan, len, Imm32(0), &ok);
     masm.assumeUnreachable("Length should be greater than 0.");
     masm.bind(&ok);
 #endif
 
@@ -5214,23 +5215,23 @@ CopyStringCharsMaybeInflate(MacroAssembl
     // have to inflate.
 
     Label isLatin1, done;
     masm.loadStringLength(input, temp1);
     masm.branchTest32(Assembler::NonZero, Address(input, JSString::offsetOfFlags()),
                       Imm32(JSString::LATIN1_CHARS_BIT), &isLatin1);
     {
         masm.loadStringChars(input, input);
-        CopyStringChars(masm, destChars, input, temp1, temp2, sizeof(jschar), sizeof(jschar));
+        CopyStringChars(masm, destChars, input, temp1, temp2, sizeof(char16_t), sizeof(char16_t));
         masm.jump(&done);
     }
     masm.bind(&isLatin1);
     {
         masm.loadStringChars(input, input);
-        CopyStringChars(masm, destChars, input, temp1, temp2, sizeof(char), sizeof(jschar));
+        CopyStringChars(masm, destChars, input, temp1, temp2, sizeof(char), sizeof(char16_t));
     }
     masm.bind(&done);
 }
 
 static void
 ConcatFatInlineString(MacroAssembler &masm, Register lhs, Register rhs, Register output,
                       Register temp1, Register temp2, Register temp3, Register forkJoinContext,
                       ExecutionMode mode, Label *failure, Label *failurePopTemps, bool isTwoByte)
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -1286,17 +1286,17 @@ IonBuilder::inlineConstantCharCodeAt(Cal
 
     int32_t idx = idxval->toInt32();
     if (idx < 0 || (uint32_t(idx) >= str->length()))
         return InliningStatus_NotInlined;
 
     callInfo.setImplicitlyUsedUnchecked();
 
     JSLinearString &linstr = str->asLinear();
-    jschar ch = linstr.latin1OrTwoByteChar(idx);
+    char16_t ch = linstr.latin1OrTwoByteChar(idx);
     MConstant *result = MConstant::New(alloc(), Int32Value(ch));
     current->add(result);
     current->push(result);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineStrFromCharCode(CallInfo &callInfo)
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -508,27 +508,27 @@ ArrayJoin(JSContext *cx, HandleObject ar
     // Step 6 to 11
     return js::ArrayJoin<false>(cx, obj, sepstr, length);
 }
 
 
 bool
 CharCodeAt(JSContext *cx, HandleString str, int32_t index, uint32_t *code)
 {
-    jschar c;
+    char16_t c;
     if (!str->getChar(cx, index, &c))
         return false;
     *code = c;
     return true;
 }
 
 JSFlatString *
 StringFromCharCode(JSContext *cx, int32_t code)
 {
-    jschar c = jschar(code);
+    char16_t c = char16_t(code);
 
     if (StaticStrings::hasUnit(c))
         return cx->staticStrings().getUnit(c);
 
     return NewStringCopyN<CanGC>(cx, &c, 1);
 }
 
 bool
@@ -742,18 +742,18 @@ FilterArgumentsOrEval(JSContext *cx, JSS
     // character buffer for the flattened string. If this call fails then the
     // calling Ion code will bailout, resume in Baseline and likely fail again
     // when trying to flatten the string and unwind the stack.
     JS::AutoCheckCannotGC nogc;
     JSLinearString *linear = str->ensureLinear(cx);
     if (!linear)
         return false;
 
-    static const jschar arguments[] = {'a', 'r', 'g', 'u', 'm', 'e', 'n', 't', 's'};
-    static const jschar eval[] = {'e', 'v', 'a', 'l'};
+    static const char16_t arguments[] = {'a', 'r', 'g', 'u', 'm', 'e', 'n', 't', 's'};
+    static const char16_t eval[] = {'e', 'v', 'a', 'l'};
 
     return !StringHasPattern(linear, arguments, mozilla::ArrayLength(arguments)) &&
         !StringHasPattern(linear, eval, mozilla::ArrayLength(eval));
 }
 
 #ifdef JSGC_GENERATIONAL
 void
 PostWriteBarrier(JSRuntime *rt, JSObject *obj)
--- a/js/src/jsapi-tests/testExternalStrings.cpp
+++ b/js/src/jsapi-tests/testExternalStrings.cpp
@@ -5,34 +5,34 @@
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/PodOperations.h"
 
 #include "jsapi-tests/tests.h"
 
 using mozilla::ArrayLength;
 using mozilla::PodEqual;
 
-static const jschar arr[] = {
+static const char16_t arr[] = {
     'h', 'i', ',', 'd', 'o', 'n', '\'', 't', ' ', 'd', 'e', 'l', 'e', 't', 'e', ' ', 'm', 'e', '\0'
 };
 static const size_t arrlen = ArrayLength(arr) - 1;
 
 static int finalized1 = 0;
 static int finalized2 = 0;
 
 static void
-finalize_str(const JSStringFinalizer *fin, jschar *chars);
+finalize_str(const JSStringFinalizer *fin, char16_t *chars);
 
 static const JSStringFinalizer finalizer1 = { finalize_str };
 static const JSStringFinalizer finalizer2 = { finalize_str };
 
 static void
-finalize_str(const JSStringFinalizer *fin, jschar *chars)
+finalize_str(const JSStringFinalizer *fin, char16_t *chars)
 {
-    if (chars && PodEqual(const_cast<const jschar *>(chars), arr, arrlen)) {
+    if (chars && PodEqual(const_cast<const char16_t *>(chars), arr, arrlen)) {
         if (fin == &finalizer1) {
             ++finalized1;
         } else if (fin == &finalizer2) {
             ++finalized2;
         }
     }
 }
 
--- a/js/src/jsapi-tests/testIndexToString.cpp
+++ b/js/src/jsapi-tests/testIndexToString.cpp
@@ -82,36 +82,36 @@ BEGIN_TEST(testStringIsIndex)
     return true;
 }
 END_TEST(testStringIsIndex)
 
 BEGIN_TEST(testStringToPropertyName)
 {
     uint32_t index;
 
-    static const jschar hiChars[] = { 'h', 'i' };
+    static const char16_t hiChars[] = { 'h', 'i' };
     JSFlatString *hiStr = NewString(cx, hiChars);
     CHECK(hiStr);
     CHECK(!hiStr->isIndex(&index));
     CHECK(hiStr->toPropertyName(cx) != nullptr);
 
-    static const jschar maxChars[] = { '4', '2', '9', '4', '9', '6', '7', '2', '9', '5' };
+    static const char16_t maxChars[] = { '4', '2', '9', '4', '9', '6', '7', '2', '9', '5' };
     JSFlatString *maxStr = NewString(cx, maxChars);
     CHECK(maxStr);
     CHECK(maxStr->isIndex(&index));
     CHECK(index == UINT32_MAX);
 
-    static const jschar maxPlusOneChars[] = { '4', '2', '9', '4', '9', '6', '7', '2', '9', '6' };
+    static const char16_t maxPlusOneChars[] = { '4', '2', '9', '4', '9', '6', '7', '2', '9', '6' };
     JSFlatString *maxPlusOneStr = NewString(cx, maxPlusOneChars);
     CHECK(maxPlusOneStr);
     CHECK(!maxPlusOneStr->isIndex(&index));
     CHECK(maxPlusOneStr->toPropertyName(cx) != nullptr);
 
     return true;
 }
 
 template<size_t N> static JSFlatString *
-NewString(JSContext *cx, const jschar (&chars)[N])
+NewString(JSContext *cx, const char16_t (&chars)[N])
 {
     return js::NewStringCopyN<js::CanGC>(cx, chars, N);
 }
 
 END_TEST(testStringToPropertyName)
--- a/js/src/jsapi-tests/testOOM.cpp
+++ b/js/src/jsapi-tests/testOOM.cpp
@@ -5,17 +5,17 @@
 #include "mozilla/DebugOnly.h"
 
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testOOM)
 {
     JS::RootedValue v(cx, JS::Int32Value(9));
     JS::RootedString jsstr(cx, JS::ToString(cx, v));
-    jschar ch;
+    char16_t ch;
     if (!JS_GetStringCharAt(cx, jsstr, 0, &ch))
         return false;
     JS_ASSERT(ch == '9');
     return true;
 }
 
 virtual JSRuntime * createRuntime()
 {
--- a/js/src/jsapi-tests/testOriginPrincipals.cpp
+++ b/js/src/jsapi-tests/testOriginPrincipals.cpp
@@ -50,17 +50,17 @@ ErrorReporter(JSContext *cx, const char 
 {
     sOriginPrincipalsInErrorReporter = report->originPrincipals;
 }
 
 bool
 eval(const char *asciiChars, JSPrincipals *principals, JSPrincipals *originPrincipals, JS::MutableHandleValue rval)
 {
     size_t len = strlen(asciiChars);
-    jschar *chars = new jschar[len+1];
+    char16_t *chars = new char16_t[len+1];
     for (size_t i = 0; i < len; ++i)
         chars[i] = asciiChars[i];
     chars[len] = 0;
 
     JS::RootedObject global(cx, JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook));
     CHECK(global);
     JSAutoCompartment ac(cx, global);
     CHECK(JS_InitStandardClasses(cx, global));
--- a/js/src/jsapi-tests/testParseJSON.cpp
+++ b/js/src/jsapi-tests/testParseJSON.cpp
@@ -10,33 +10,33 @@
 #include "jsstr.h"
 
 #include "jsapi-tests/tests.h"
 
 using namespace js;
 
 class AutoInflatedString {
     JSContext * const cx;
-    jschar *chars_;
+    char16_t *chars_;
     size_t length_;
 
   public:
     explicit AutoInflatedString(JSContext *cx) : cx(cx), chars_(nullptr), length_(0) { }
     ~AutoInflatedString() {
         JS_free(cx, chars_);
     }
 
     template<size_t N> void operator=(const char (&str)[N]) {
         length_ = N - 1;
         chars_ = InflateString(cx, str, &length_);
         if (!chars_)
             abort();
     }
 
-    const jschar *chars() const { return chars_; }
+    const char16_t *chars() const { return chars_; }
     size_t length() const { return length_; }
 };
 
 BEGIN_TEST(testParseJSON_success)
 {
     // Primitives
     JS::RootedValue expected(cx);
     expected = JSVAL_TRUE;
@@ -66,36 +66,36 @@ BEGIN_TEST(testParseJSON_success)
     expected = DOUBLE_TO_JSVAL(9e9);
     CHECK(TryParse(cx, "9e9", expected));
 
     expected = DOUBLE_TO_JSVAL(std::numeric_limits<double>::infinity());
     CHECK(TryParse(cx, "9e99999", expected));
 
     JS::Rooted<JSFlatString*> str(cx);
 
-    const jschar emptystr[] = { '\0' };
+    const char16_t emptystr[] = { '\0' };
     str = js::NewStringCopyN<CanGC>(cx, emptystr, 0);
     CHECK(str);
     expected = STRING_TO_JSVAL(str);
     CHECK(TryParse(cx, "\"\"", expected));
 
-    const jschar nullstr[] = { '\0' };
+    const char16_t nullstr[] = { '\0' };
     str = NewString(cx, nullstr);
     CHECK(str);
     expected = STRING_TO_JSVAL(str);
     CHECK(TryParse(cx, "\"\\u0000\"", expected));
 
-    const jschar backstr[] = { '\b' };
+    const char16_t backstr[] = { '\b' };
     str = NewString(cx, backstr);
     CHECK(str);
     expected = STRING_TO_JSVAL(str);
     CHECK(TryParse(cx, "\"\\b\"", expected));
     CHECK(TryParse(cx, "\"\\u0008\"", expected));
 
-    const jschar newlinestr[] = { '\n', };
+    const char16_t newlinestr[] = { '\n', };
     str = NewString(cx, newlinestr);
     CHECK(str);
     expected = STRING_TO_JSVAL(str);
     CHECK(TryParse(cx, "\"\\n\"", expected));
     CHECK(TryParse(cx, "\"\\u000A\"", expected));
 
 
     // Arrays
@@ -131,17 +131,17 @@ BEGIN_TEST(testParseJSON_success)
     CHECK(!JS_IsArrayObject(cx, obj));
     CHECK(JS_GetProperty(cx, obj, "f", &v2));
     CHECK_SAME(v2, INT_TO_JSVAL(17));
 
     return true;
 }
 
 template<size_t N> static JSFlatString *
-NewString(JSContext *cx, const jschar (&chars)[N])
+NewString(JSContext *cx, const char16_t (&chars)[N])
 {
     return js::NewStringCopyN<CanGC>(cx, chars, N);
 }
 
 template<size_t N> inline bool
 Parse(JSContext *cx, const char (&input)[N], JS::MutableHandleValue vp)
 {
     AutoInflatedString str(cx);
@@ -301,25 +301,25 @@ Error(JSContext *cx, const char (&input)
 
     return true;
 }
 
 struct ContextPrivate {
     static const size_t MaxSize = sizeof("4294967295");
     unsigned unexpectedErrorCount;
     unsigned expectedErrorCount;
-    jschar column[MaxSize];
-    jschar line[MaxSize];
+    char16_t column[MaxSize];
+    char16_t line[MaxSize];
 };
 
 static void
 ReportJSONError(JSContext *cx, const char *message, JSErrorReport *report)
 {
     ContextPrivate *p = static_cast<ContextPrivate *>(JS_GetContextPrivate(cx));
-    // Although messageArgs[1] and messageArgs[2] are jschar*, we cast them to char*
+    // Although messageArgs[1] and messageArgs[2] are char16_t*, we cast them to char*
     // here because JSONParser::error() stores char* strings in them.
     js_strncpy(p->line, report->messageArgs[1], js_strlen(report->messageArgs[1]));
     js_strncpy(p->column, report->messageArgs[2], js_strlen(report->messageArgs[2]));
     if (report->errorNumber == JSMSG_JSON_BAD_PARSE)
         p->expectedErrorCount++;
     else
         p->unexpectedErrorCount++;
 }
--- a/js/src/jsapi-tests/testScriptInfo.cpp
+++ b/js/src/jsapi-tests/testScriptInfo.cpp
@@ -32,24 +32,24 @@ BEGIN_TEST(testScriptInfo)
     JS::RootedScript script(cx);
     CHECK(JS_CompileScript(cx, global, code, strlen(code), options, &script));
     CHECK(script);
 
     jsbytecode *start = JS_LineNumberToPC(cx, script, startLine);
     CHECK_EQUAL(JS_GetScriptBaseLineNumber(cx, script), startLine);
     CHECK_EQUAL(JS_PCToLineNumber(cx, script, start), startLine);
     CHECK(strcmp(JS_GetScriptFilename(script), __FILE__) == 0);
-    const jschar *sourceMap = JS_GetScriptSourceMap(cx, script);
+    const char16_t *sourceMap = JS_GetScriptSourceMap(cx, script);
     CHECK(sourceMap);
     CHECK(CharsMatch(sourceMap, "http://example.com/path/to/source-map.json"));
 
     return true;
 }
 static bool
-CharsMatch(const jschar *p, const char *q)
+CharsMatch(const char16_t *p, const char *q)
 {
     while (*q) {
         if (*p++ != *q++)
             return false;
     }
     return true;
 }
 END_TEST(testScriptInfo)
--- a/js/src/jsapi-tests/testScriptObject.cpp
+++ b/js/src/jsapi-tests/testScriptObject.cpp
@@ -5,17 +5,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsapi-tests/tests.h"
 
 struct ScriptObjectFixture : public JSAPITest {
     static const int code_size;
     static const char code[];
-    static jschar uc_code[];
+    static char16_t uc_code[];
 
     ScriptObjectFixture()
     {
         for (int i = 0; i < code_size; i++)
             uc_code[i] = code[i];
     }
 
     bool tryScript(JS::HandleObject global, JS::HandleScript script)
@@ -30,17 +30,17 @@ struct ScriptObjectFixture : public JSAP
 
         return true;
     }
 };
 
 const char ScriptObjectFixture::code[] =
     "(function(a, b){return a+' '+b;}('hello', 'world'))";
 const int ScriptObjectFixture::code_size = sizeof(ScriptObjectFixture::code) - 1;
-jschar ScriptObjectFixture::uc_code[ScriptObjectFixture::code_size];
+char16_t ScriptObjectFixture::uc_code[ScriptObjectFixture::code_size];
 
 BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_CompileScript)
 {
     JS::CompileOptions options(cx);
     options.setFileAndLine(__FILE__, __LINE__);
     JS::RootedScript script(cx);
     CHECK(JS_CompileScript(cx, global, code, code_size, options, &script));
     return tryScript(global, script);
--- a/js/src/jsapi-tests/testUTF8.cpp
+++ b/js/src/jsapi-tests/testUTF8.cpp
@@ -13,39 +13,39 @@
 #include "js/CharacterEncoding.h"
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testUTF8_badUTF8)
 {
     static const char badUTF8[] = "...\xC0...";
     JSString *str = JS_NewStringCopyZ(cx, badUTF8);
     CHECK(str);
-    jschar ch;
+    char16_t ch;
     if (!JS_GetStringCharAt(cx, str, 3, &ch))
         return false;
     CHECK(ch == 0x00C0);
     return true;
 }
 END_TEST(testUTF8_badUTF8)
 
 BEGIN_TEST(testUTF8_bigUTF8)
 {
     static const char bigUTF8[] = "...\xFB\xBF\xBF\xBF\xBF...";
     JSString *str = JS_NewStringCopyZ(cx, bigUTF8);
     CHECK(str);
-    jschar ch;
+    char16_t ch;
     if (!JS_GetStringCharAt(cx, str, 3, &ch))
         return false;
     CHECK(ch == 0x00FB);
     return true;
 }
 END_TEST(testUTF8_bigUTF8)
 
 BEGIN_TEST(testUTF8_badSurrogate)
 {
-    static const jschar badSurrogate[] = { 'A', 'B', 'C', 0xDEEE, 'D', 'E', 0 };
-    mozilla::Range<const jschar> tbchars(badSurrogate, js_strlen(badSurrogate));
+    static const char16_t badSurrogate[] = { 'A', 'B', 'C', 0xDEEE, 'D', 'E', 0 };
+    mozilla::Range<const char16_t> tbchars(badSurrogate, js_strlen(badSurrogate));
     JS::Latin1CharsZ latin1 = JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars);
     CHECK(latin1);
     CHECK(latin1[3] == 0x00EE);
     return true;
 }
 END_TEST(testUTF8_badSurrogate)
--- a/js/src/jsapi-tests/testXDR.cpp
+++ b/js/src/jsapi-tests/testXDR.cpp
@@ -17,17 +17,17 @@ CompileScriptForPrincipalsVersionOrigin(
                                         JSPrincipals *originPrincipals,
                                         const char *bytes, size_t nbytes,
                                         const char *filename, unsigned lineno,
                                         JSVersion version)
 {
     size_t nchars;
     if (!JS_DecodeBytes(cx, bytes, nbytes, nullptr, &nchars))
         return nullptr;
-    jschar *chars = static_cast<jschar *>(JS_malloc(cx, nchars * sizeof(jschar)));
+    char16_t *chars = static_cast<char16_t *>(JS_malloc(cx, nchars * sizeof(char16_t)));
     if (!chars)
         return nullptr;
     JS_ALWAYS_TRUE(JS_DecodeBytes(cx, bytes, nbytes, chars, &nchars));
     JS::CompileOptions options(cx);
     options.setOriginPrincipals(originPrincipals)
            .setFileAndLine(filename, lineno)
            .setVersion(version);
     JS::RootedScript script(cx);
@@ -239,27 +239,27 @@ BEGIN_TEST(testXDR_sourceMap)
     JS::RootedScript script(cx);
     for (const char **sm = sourceMaps; *sm; sm++) {
         JS::CompileOptions options(cx);
         options.setFileAndLine(__FILE__, __LINE__);
         CHECK(JS_CompileScript(cx, global, "", 0, options, &script));
         CHECK(script);
 
         size_t len = strlen(*sm);
-        jschar *expected = js::InflateString(cx, *sm, &len);
+        char16_t *expected = js::InflateString(cx, *sm, &len);
         CHECK(expected);
 
         // The script source takes responsibility of free'ing |expected|.
         CHECK(script->scriptSource()->setSourceMapURL(cx, expected));
         script = FreezeThaw(cx, script);
         CHECK(script);
         CHECK(script->scriptSource());
         CHECK(script->scriptSource()->hasSourceMapURL());
 
-        const jschar *actual = script->scriptSource()->sourceMapURL();
+        const char16_t *actual = script->scriptSource()->sourceMapURL();
         CHECK(actual);
 
         while (*expected) {
             CHECK(*actual);
             CHECK(*expected == *actual);
             expected++;
             actual++;
         }
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -109,19 +109,19 @@ using JS::AutoGCRooter;
 using js::frontend::Parser;
 
 #ifdef HAVE_VA_LIST_AS_ARRAY
 #define JS_ADDRESSOF_VA_LIST(ap) ((va_list *)(ap))
 #else
 #define JS_ADDRESSOF_VA_LIST(ap) (&(ap))
 #endif
 
-/* Make sure that jschar is two bytes unsigned integer */
-JS_STATIC_ASSERT((jschar)-1 > 0);
-JS_STATIC_ASSERT(sizeof(jschar) == 2);
+/* Make sure that char16_t is two bytes unsigned integer */
+JS_STATIC_ASSERT((char16_t)-1 > 0);
+JS_STATIC_ASSERT(sizeof(char16_t) == 2);
 
 bool
 JS::CallArgs::requireAtLeast(JSContext *cx, const char *fnname, unsigned required) {
     if (length() < required) {
         char numArgsStr[40];
         JS_snprintf(numArgsStr, sizeof numArgsStr, "%u", required - 1);
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
                              fnname, numArgsStr, required == 2 ? "" : "s");
@@ -1987,17 +1987,17 @@ JS_SetGCParametersBasedOnAvailableMemory
     }
 
     for (size_t i = 0; i < NumGCConfigs; i++)
         JS_SetGCParameter(rt, config[i].key, config[i].value);
 }
 
 
 JS_PUBLIC_API(JSString *)
-JS_NewExternalString(JSContext *cx, const jschar *chars, size_t length,
+JS_NewExternalString(JSContext *cx, const char16_t *chars, size_t length,
                      const JSStringFinalizer *fin)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     JSString *s = JSExternalString::new_(cx, chars, length, fin);
     return s;
 }
 
@@ -2655,17 +2655,17 @@ JS_LookupProperty(JSContext *cx, HandleO
     if (!atom)
         return false;
 
     RootedId id(cx, AtomToId(atom));
     return JS_LookupPropertyById(cx, obj, id, vp);
 }
 
 JS_PUBLIC_API(bool)
-JS_LookupUCProperty(JSContext *cx, HandleObject objArg, const jschar *name, size_t namelen,
+JS_LookupUCProperty(JSContext *cx, HandleObject objArg, const char16_t *name, size_t namelen,
                     MutableHandleValue vp)
 {
     RootedObject obj(cx, objArg);
     JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
     if (!atom)
         return false;
 
     RootedId id(cx, AtomToId(atom));
@@ -2699,17 +2699,17 @@ JS_HasProperty(JSContext *cx, HandleObje
     JSAtom *atom = Atomize(cx, name, strlen(name));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
     return JS_HasPropertyById(cx, obj, id, foundp);
 }
 
 JS_PUBLIC_API(bool)
-JS_HasUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen, bool *foundp)
+JS_HasUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen, bool *foundp)
 {
     JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
     return JS_HasPropertyById(cx, obj, id, foundp);
 }
 
@@ -2767,17 +2767,17 @@ JS_AlreadyHasOwnProperty(JSContext *cx, 
     JSAtom *atom = Atomize(cx, name, strlen(name));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
     return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
 }
 
 JS_PUBLIC_API(bool)
-JS_AlreadyHasOwnUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
+JS_AlreadyHasOwnUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
                            bool *foundp)
 {
     JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
     return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
 }
@@ -3118,78 +3118,78 @@ JS_DefineProperty(JSContext *cx, HandleO
                   PropertyOp getter /* = nullptr */, JSStrictPropertyOp setter /* = nullptr */)
 {
     Value value = NumberValue(valueArg);
     return DefineProperty(cx, obj, name, HandleValue::fromMarkedLocation(&value),
                           GetterWrapper(getter), SetterWrapper(setter), attrs, 0);
 }
 
 static bool
-DefineUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
+DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
                  const Value &value_, PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
                  unsigned flags)
 {
     RootedValue value(cx, value_);
     AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
     JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
     return DefinePropertyById(cx, obj, id, value, GetterWrapper(getter), SetterWrapper(setter),
                               attrs, flags);
 }
 
 JS_PUBLIC_API(bool)
-JS_DefineUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
+JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
                     HandleValue value, unsigned attrs,
                     JSPropertyOp getter, JSStrictPropertyOp setter)
 {
     return DefineUCProperty(cx, obj, name, namelen, value, getter, setter, attrs, 0);
 }
 
 JS_PUBLIC_API(bool)
-JS_DefineUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
+JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
                     HandleObject valueArg, unsigned attrs,
                     JSPropertyOp getter, JSStrictPropertyOp setter)
 {
     RootedValue value(cx, ObjectValue(*valueArg));
     return DefineUCProperty(cx, obj, name, namelen, value, getter, setter, attrs, 0);
 }
 
 JS_PUBLIC_API(bool)
-JS_DefineUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
+JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
                     HandleString valueArg, unsigned attrs,
                     JSPropertyOp getter, JSStrictPropertyOp setter)
 {
     RootedValue value(cx, StringValue(valueArg));
     return DefineUCProperty(cx, obj, name, namelen, value, getter, setter, attrs, 0);
 }
 
 JS_PUBLIC_API(bool)
-JS_DefineUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
+JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
                     int32_t valueArg, unsigned attrs,
                     JSPropertyOp getter, JSStrictPropertyOp setter)
 {
     Value value = Int32Value(valueArg);
     return DefineUCProperty(cx, obj, name, namelen, HandleValue::fromMarkedLocation(&value),
                             getter, setter, attrs, 0);
 }
 
 JS_PUBLIC_API(bool)
-JS_DefineUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
+JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
                     uint32_t valueArg, unsigned attrs,
                     JSPropertyOp getter, JSStrictPropertyOp setter)
 {
     Value value = UINT_TO_JSVAL(valueArg);
     return DefineUCProperty(cx, obj, name, namelen, HandleValue::fromMarkedLocation(&value),
                             getter, setter, attrs, 0);
 }
 
 JS_PUBLIC_API(bool)
-JS_DefineUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
+JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
                     double valueArg, unsigned attrs,
                     JSPropertyOp getter, JSStrictPropertyOp setter)
 {
     Value value = NumberValue(valueArg);
     return DefineUCProperty(cx, obj, name, namelen, HandleValue::fromMarkedLocation(&value),
                             getter, setter, attrs, 0);
 }
 
@@ -3414,17 +3414,17 @@ JS_GetProperty(JSContext *cx, HandleObje
     JSAtom *atom = Atomize(cx, name, strlen(name));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
     return JS_GetPropertyById(cx, obj, id, vp);
 }
 
 JS_PUBLIC_API(bool)
-JS_GetUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
+JS_GetUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
                  MutableHandleValue vp)
 {
     JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
     return JS_GetPropertyById(cx, obj, id, vp);
 }
@@ -3498,17 +3498,17 @@ JS_SetProperty(JSContext *cx, HandleObje
     JSAtom *atom = Atomize(cx, name, strlen(name));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
     return JS_SetPropertyById(cx, obj, id, v);
 }
 
 JS_PUBLIC_API(bool)
-JS_SetUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
+JS_SetUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
                  HandleValue v)
 {
     JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
     return JS_SetPropertyById(cx, obj, id, v);
 }
@@ -3542,17 +3542,17 @@ JS_DeleteProperty2(JSContext *cx, Handle
     JSAtom *atom = Atomize(cx, name, strlen(name));
     if (!atom)
         return false;
     RootedId id(cx, AtomToId(atom));
     return JSObject::deleteGeneric(cx, obj, id, result);
 }
 
 JS_PUBLIC_API(bool)
-JS_DeleteUCProperty2(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
+JS_DeleteUCProperty2(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
                      bool *result)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
 
     JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
     if (!atom)
         return false;
@@ -4143,17 +4143,17 @@ JS_DefineFunction(JSContext *cx, HandleO
     if (!atom)
         return nullptr;
     Rooted<jsid> id(cx, AtomToId(atom));
     return DefineFunction(cx, obj, id, call, nargs, attrs);
 }
 
 JS_PUBLIC_API(JSFunction *)
 JS_DefineUCFunction(JSContext *cx, HandleObject obj,
-                    const jschar *name, size_t namelen, JSNative call,
+                    const char16_t *name, size_t namelen, JSNative call,
                     unsigned nargs, unsigned attrs)
 {
     JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
     if (!atom)
@@ -4325,17 +4325,17 @@ JS::OwningCompileOptions::OwningCompileO
 
 JS::OwningCompileOptions::~OwningCompileOptions()
 {
     if (originPrincipals_)
         JS_DropPrincipals(runtime, originPrincipals_);
 
     // OwningCompileOptions always owns these, so these casts are okay.
     js_free(const_cast<char *>(filename_));
-    js_free(const_cast<jschar *>(sourceMapURL_));
+    js_free(const_cast<char16_t *>(sourceMapURL_));
     js_free(const_cast<char *>(introducerFilename_));
 }
 
 bool
 JS::OwningCompileOptions::copy(JSContext *cx, const ReadOnlyCompileOptions &rhs)
 {
     copyPODOptions(rhs);
 
@@ -4372,27 +4372,27 @@ JS::OwningCompileOptions::setFileAndLine
     if (!setFile(cx, f))
         return false;
 
     lineno = l;
     return true;
 }
 
 bool
-JS::OwningCompileOptions::setSourceMapURL(JSContext *cx, const jschar *s)
-{
-    UniquePtr<jschar[], JS::FreePolicy> copy;
+JS::OwningCompileOptions::setSourceMapURL(JSContext *cx, const char16_t *s)
+{
+    UniquePtr<char16_t[], JS::FreePolicy> copy;
     if (s) {
         copy = DuplicateString(cx, s);
         if (!copy)
             return false;
     }
 
     // OwningCompileOptions always owns sourceMapURL_, so this cast is okay.
-    js_free(const_cast<jschar *>(sourceMapURL_));
+    js_free(const_cast<char16_t *>(sourceMapURL_));
 
     sourceMapURL_ = copy.release();
     return true;
 }
 
 bool
 JS::OwningCompileOptions::setIntroducerFilename(JSContext *cx, const char *s)
 {
@@ -4434,27 +4434,27 @@ JS::Compile(JSContext *cx, HandleObject 
     AutoLastFrameCheck lfc(cx);
 
     script.set(frontend::CompileScript(cx, &cx->tempLifoAlloc(), obj, NullPtr(), options, srcBuf));
     return !!script;
 }
 
 bool
 JS::Compile(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
-            const jschar *chars, size_t length, MutableHandleScript script)
+            const char16_t *chars, size_t length, MutableHandleScript script)
 {
     SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
     return Compile(cx, obj, options, srcBuf, script);
 }
 
 bool
 JS::Compile(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
             const char *bytes, size_t length, MutableHandleScript script)
 {
-    mozilla::ScopedFreePtr<jschar> chars;
+    mozilla::ScopedFreePtr<char16_t> chars;
     if (options.utf8)
         chars = UTF8CharsToNewTwoByteCharsZ(cx, UTF8Chars(bytes, length), &length).get();
     else
         chars = InflateString(cx, bytes, &length);
     if (!chars)
         return false;
 
     return Compile(cx, obj, options, chars, length, script);
@@ -4504,17 +4504,17 @@ JS::CanCompileOffThread(JSContext *cx, c
             return false;
     }
 
     return cx->runtime()->canUseParallelParsing() && CanUseExtraThreads();
 }
 
 JS_PUBLIC_API(bool)
 JS::CompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options,
-                     const jschar *chars, size_t length,
+                     const char16_t *chars, size_t length,
                      OffThreadCompileCallback callback, void *callbackData)
 {
     JS_ASSERT(CanCompileOffThread(cx, options, length));
     return StartOffThreadParseScript(cx, options, chars, length, callback, callbackData);
 }
 
 JS_PUBLIC_API(JSScript *)
 JS::FinishOffThreadScript(JSContext *maybecx, JSRuntime *rt, void *token)
@@ -4536,32 +4536,32 @@ JS::FinishOffThreadScript(JSContext *may
 JS_PUBLIC_API(bool)
 JS_CompileScript(JSContext *cx, JS::HandleObject obj, const char *ascii,
                  size_t length, const JS::CompileOptions &options, MutableHandleScript script)
 {
     return Compile(cx, obj, options, ascii, length, script);
 }
 
 JS_PUBLIC_API(bool)
-JS_CompileUCScript(JSContext *cx, JS::HandleObject obj, const jschar *chars,
+JS_CompileUCScript(JSContext *cx, JS::HandleObject obj, const char16_t *chars,
                    size_t length, const JS::CompileOptions &options, MutableHandleScript script)
 {
     return Compile(cx, obj, options, chars, length, script);
 }
 
 JS_PUBLIC_API(bool)
 JS_BufferIsCompilableUnit(JSContext *cx, HandleObject obj, const char *utf8, size_t length)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
 
     cx->clearPendingException();
 
-    jschar *chars = JS::UTF8CharsToNewTwoByteCharsZ(cx, JS::UTF8Chars(utf8, length), &length).get();
+    char16_t *chars = JS::UTF8CharsToNewTwoByteCharsZ(cx, JS::UTF8Chars(utf8, length), &length).get();
     if (!chars)
         return true;
 
     // Return true on any out-of-memory error or non-EOF-related syntax error, so our
     // caller doesn't try to collect more buffered source.
     bool result = true;
 
     CompileOptions options(cx);
@@ -4633,42 +4633,42 @@ JS::CompileFunction(JSContext *cx, Handl
     }
 
     return true;
 }
 
 JS_PUBLIC_API(bool)
 JS::CompileFunction(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
                     const char *name, unsigned nargs, const char *const *argnames,
-                    const jschar *chars, size_t length, MutableHandleFunction fun)
+                    const char16_t *chars, size_t length, MutableHandleFunction fun)
 {
     SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
     return JS::CompileFunction(cx, obj, options, name, nargs, argnames, srcBuf, fun);
 }
 
 JS_PUBLIC_API(bool)
 JS::CompileFunction(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
                     const char *name, unsigned nargs, const char *const *argnames,
                     const char *bytes, size_t length, MutableHandleFunction fun)
 {
-    mozilla::ScopedFreePtr<jschar> chars;
+    mozilla::ScopedFreePtr<char16_t> chars;
     if (options.utf8)
         chars = UTF8CharsToNewTwoByteCharsZ(cx, UTF8Chars(bytes, length), &length).get();
     else
         chars = InflateString(cx, bytes, &length);
     if (!chars)
         return false;
 
     return CompileFunction(cx, obj, options, name, nargs, argnames, chars, length, fun);
 }
 
 JS_PUBLIC_API(bool)
 JS_CompileUCFunction(JSContext *cx, JS::HandleObject obj, const char *name,
                      unsigned nargs, const char *const *argnames,
-                     const jschar *chars, size_t length,
+                     const char16_t *chars, size_t length,
                      const CompileOptions &options, MutableHandleFunction fun)
 {
     return CompileFunction(cx, obj, options, name, nargs, argnames, chars, length, fun);
 }
 
 JS_PUBLIC_API(bool)
 JS_CompileFunction(JSContext *cx, JS::HandleObject obj, const char *name,
                    unsigned nargs, const char *const *argnames,
@@ -4807,27 +4807,27 @@ Evaluate(JSContext *cx, HandleObject obj
         cx->runtime()->gc.gc(GC_NORMAL, JS::gcreason::FINISH_LARGE_EVALUATE);
     }
 
     return result;
 }
 
 static bool
 Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
-         const jschar *chars, size_t length, JS::Value *rval)
+         const char16_t *chars, size_t length, JS::Value *rval)
 {
   SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
   return ::Evaluate(cx, obj, optionsArg, srcBuf, rval);
 }
 
 static bool
 Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
          const char *bytes, size_t length, JS::Value *rval)
 {
-    jschar *chars;
+    char16_t *chars;
     if (options.utf8)
         chars = UTF8CharsToNewTwoByteCharsZ(cx, JS::UTF8Chars(bytes, length), &length).get();
     else
         chars = InflateString(cx, bytes, &length);
     if (!chars)
         return false;
 
     SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::GiveOwnership);
@@ -4855,17 +4855,17 @@ extern JS_PUBLIC_API(bool)
 JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
              SourceBufferHolder &srcBuf, MutableHandleValue rval)
 {
     return ::Evaluate(cx, obj, optionsArg, srcBuf, rval.address());
 }
 
 extern JS_PUBLIC_API(bool)
 JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
-             const jschar *chars, size_t length, MutableHandleValue rval)
+             const char16_t *chars, size_t length, MutableHandleValue rval)
 {
     return ::Evaluate(cx, obj, optionsArg, chars, length, rval.address());
 }
 
 extern JS_PUBLIC_API(bool)
 JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
              const char *bytes, size_t length, MutableHandleValue rval)
 {
@@ -4883,17 +4883,17 @@ extern JS_PUBLIC_API(bool)
 JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
              SourceBufferHolder &srcBuf)
 {
     return ::Evaluate(cx, obj, optionsArg, srcBuf, nullptr);
 }
 
 extern JS_PUBLIC_API(bool)
 JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
-             const jschar *chars, size_t length)
+             const char16_t *chars, size_t length)
 {
     return ::Evaluate(cx, obj, optionsArg, chars, length, nullptr);
 }
 
 extern JS_PUBLIC_API(bool)
 JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
              const char *bytes, size_t length)
 {
@@ -4903,17 +4903,17 @@ JS::Evaluate(JSContext *cx, HandleObject
 extern JS_PUBLIC_API(bool)
 JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
              const char *filename)
 {
     return ::Evaluate(cx, obj, optionsArg, filename, nullptr);
 }
 
 JS_PUBLIC_API(bool)
-JS_EvaluateUCScript(JSContext *cx, HandleObject obj, const jschar *chars, unsigned length,
+JS_EvaluateUCScript(JSContext *cx, HandleObject obj, const char16_t *chars, unsigned length,
                     const char *filename, unsigned lineno, MutableHandleValue rval)
 {
     CompileOptions options(cx);
     options.setFileAndLine(filename, lineno);
 
     return ::Evaluate(cx, obj, options, chars, length, rval.address());
 }
 
@@ -5188,55 +5188,55 @@ JS_InternStringN(JSContext *cx, const ch
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     JSAtom *atom = Atomize(cx, s, length, InternAtom);
     JS_ASSERT_IF(atom, JS_StringHasBeenInterned(cx, atom));
     return atom;
 }
 
 JS_PUBLIC_API(JSString *)
-JS_NewUCString(JSContext *cx, jschar *chars, size_t length)
+JS_NewUCString(JSContext *cx, char16_t *chars, size_t length)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     return NewString<CanGC>(cx, chars, length);
 }
 
 JS_PUBLIC_API(JSString *)
-JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n)
+JS_NewUCStringCopyN(JSContext *cx, const char16_t *s, size_t n)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     if (!n)
         return cx->names().empty;
     return NewStringCopyN<CanGC>(cx, s, n);
 }
 
 JS_PUBLIC_API(JSString *)
-JS_NewUCStringCopyZ(JSContext *cx, const jschar *s)
+JS_NewUCStringCopyZ(JSContext *cx, const char16_t *s)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     if (!s)
         return cx->runtime()->emptyString;
     return NewStringCopyZ<CanGC>(cx, s);
 }
 
 JS_PUBLIC_API(JSString *)
-JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length)
+JS_InternUCStringN(JSContext *cx, const char16_t *s, size_t length)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     JSAtom *atom = AtomizeChars(cx, s, length, InternAtom);
     JS_ASSERT_IF(atom, JS_StringHasBeenInterned(cx, atom));
     return atom;
 }
 
 JS_PUBLIC_API(JSString *)
-JS_InternUCString(JSContext *cx, const jschar *s)
+JS_InternUCString(JSContext *cx, const char16_t *s)
 {
     return JS_InternUCStringN(cx, s, js_strlen(s));
 }
 
 JS_PUBLIC_API(size_t)
 JS_GetStringLength(JSString *str)
 {
     return str->length();
@@ -5264,60 +5264,60 @@ JS_GetLatin1StringCharsAndLength(JSConte
     assertSameCompartment(cx, str);
     JSLinearString *linear = str->ensureLinear(cx);
     if (!linear)
         return nullptr;
     *plength = linear->length();
     return linear->latin1Chars(nogc);
 }
 
-JS_PUBLIC_API(const jschar *)
+JS_PUBLIC_API(const char16_t *)
 JS_GetTwoByteStringCharsAndLength(JSContext *cx, const JS::AutoCheckCannotGC &nogc, JSString *str,
                                   size_t *plength)
 {
     JS_ASSERT(plength);
     AssertHeapIsIdleOrStringIsFlat(cx, str);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, str);
     JSLinearString *linear = str->ensureLinear(cx);
     if (!linear)
         return nullptr;
     *plength = linear->length();
     return linear->twoByteChars(nogc);
 }
 
-JS_PUBLIC_API(const jschar *)
+JS_PUBLIC_API(const char16_t *)
 JS_GetTwoByteExternalStringChars(JSString *str)
 {
     return str->asExternal().twoByteChars();
 }
 
 JS_PUBLIC_API(bool)
-JS_GetStringCharAt(JSContext *cx, JSString *str, size_t index, jschar *res)
+JS_GetStringCharAt(JSContext *cx, JSString *str, size_t index, char16_t *res)
 {
     AssertHeapIsIdleOrStringIsFlat(cx, str);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, str);
 
     JSLinearString *linear = str->ensureLinear(cx);
     if (!linear)
         return false;
 
     *res = linear->latin1OrTwoByteChar(index);
     return true;
 }
 
-JS_PUBLIC_API(jschar)
+JS_PUBLIC_API(char16_t)
 JS_GetFlatStringCharAt(JSFlatString *str, size_t index)
 {
     return str->latin1OrTwoByteChar(index);
 }
 
 JS_PUBLIC_API(bool)
-JS_CopyStringChars(JSContext *cx, mozilla::Range<jschar> dest, JSString *str)
+JS_CopyStringChars(JSContext *cx, mozilla::Range<char16_t> dest, JSString *str)
 {
     AssertHeapIsIdleOrStringIsFlat(cx, str);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, str);
 
     JSLinearString *linear = str->ensureLinear(cx);
     if (!linear)
         return false;
@@ -5332,17 +5332,17 @@ JS_Latin1InternedStringChars(const JS::A
 {
     JS_ASSERT(str->isAtom());
     JSFlatString *flat = str->ensureFlat(nullptr);
     if (!flat)
         return nullptr;
     return flat->latin1Chars(nogc);
 }
 
-JS_PUBLIC_API(const jschar *)
+JS_PUBLIC_API(const char16_t *)
 JS_GetTwoByteInternedStringChars(const JS::AutoCheckCannotGC &nogc, JSString *str)
 {
     JS_ASSERT(str->isAtom());
     JSFlatString *flat = str->ensureFlat(nullptr);
     if (!flat)
         return nullptr;
     return flat->twoByteChars(nogc);
 }
@@ -5360,17 +5360,17 @@ JS_FlattenString(JSContext *cx, JSString
 }
 
 extern JS_PUBLIC_API(const Latin1Char *)
 JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC &nogc, JSFlatString *str)
 {
     return str->latin1Chars(nogc);
 }
 
-extern JS_PUBLIC_API(const jschar *)
+extern JS_PUBLIC_API(const char16_t *)
 JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC &nogc, JSFlatString *str)
 {
     return str->twoByteChars(nogc);
 }
 
 JS_PUBLIC_API(bool)
 JS_CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *result)
 {
@@ -5434,17 +5434,17 @@ JS_PUBLIC_API(JSString *)
 JS_ConcatStrings(JSContext *cx, HandleString left, HandleString right)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     return ConcatStrings<CanGC>(cx, left, right);
 }
 
 JS_PUBLIC_API(bool)
-JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst, size_t *dstlenp)
+JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, char16_t *dst, size_t *dstlenp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
     if (!dst) {
         *dstlenp = srclen;
         return true;
     }
@@ -5611,35 +5611,35 @@ JS_Stringify(JSContext *cx, MutableHandl
     if (!js_Stringify(cx, vp, replacer, space, sb))
         return false;
     if (sb.empty() && !sb.append(cx->names().null))
         return false;
     return callback(sb.rawTwoByteBegin(), sb.length(), data);
 }
 
 JS_PUBLIC_API(bool)
-JS_ParseJSON(JSContext *cx, const jschar *chars, uint32_t len, MutableHandleValue vp)
-{
-    AssertHeapIsIdle(cx);
-    CHECK_REQUEST(cx);
-    return ParseJSONWithReviver(cx, mozilla::Range<const jschar>(chars, len), NullHandleValue, vp);
+JS_ParseJSON(JSContext *cx, const char16_t *chars, uint32_t len, MutableHandleValue vp)
+{
+    AssertHeapIsIdle(cx);
+    CHECK_REQUEST(cx);
+    return ParseJSONWithReviver(cx, mozilla::Range<const char16_t>(chars, len), NullHandleValue, vp);
 }
 
 JS_PUBLIC_API(bool)
 JS_ParseJSON(JSContext *cx, HandleString str, MutableHandleValue vp)
 {
     return JS_ParseJSONWithReviver(cx, str, NullHandleValue, vp);
 }
 
 JS_PUBLIC_API(bool)
-JS_ParseJSONWithReviver(JSContext *cx, const jschar *chars, uint32_t len, HandleValue reviver, MutableHandleValue vp)
-{
-    AssertHeapIsIdle(cx);
-    CHECK_REQUEST(cx);
-    return ParseJSONWithReviver(cx, mozilla::Range<const jschar>(chars, len), reviver, vp);
+JS_ParseJSONWithReviver(JSContext *cx, const char16_t *chars, uint32_t len, HandleValue reviver, MutableHandleValue vp)
+{
+    AssertHeapIsIdle(cx);
+    CHECK_REQUEST(cx);
+    return ParseJSONWithReviver(cx, mozilla::Range<const char16_t>(chars, len), reviver, vp);
 }
 
 JS_PUBLIC_API(bool)
 JS_ParseJSONWithReviver(JSContext *cx, HandleString str, HandleValue reviver, MutableHandleValue vp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, str);
@@ -5697,17 +5697,17 @@ JS_ReportErrorNumberUC(JSContext *cx, JS
     js_ReportErrorNumberVA(cx, JSREPORT_ERROR, errorCallback, userRef,
                            errorNumber, ArgumentsAreUnicode, ap);
     va_end(ap);
 }
 
 JS_PUBLIC_API(void)
 JS_ReportErrorNumberUCArray(JSContext *cx, JSErrorCallback errorCallback,
                             void *userRef, const unsigned errorNumber,
-                            const jschar **args)
+                            const char16_t **args)
 {
     AssertHeapIsIdle(cx);
     js_ReportErrorNumberUCArray(cx, JSREPORT_ERROR, errorCallback, userRef,
                                 errorNumber, args);
 }
 
 JS_PUBLIC_API(bool)
 JS_ReportWarning(JSContext *cx, const char *format, ...)
@@ -5823,31 +5823,31 @@ JS_ClearDateCaches(JSContext *cx)
 /*
  * Regular Expressions.
  */
 JS_PUBLIC_API(JSObject *)
 JS_NewRegExpObject(JSContext *cx, HandleObject obj, char *bytes, size_t length, unsigned flags)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
-    ScopedJSFreePtr<jschar> chars(InflateString(cx, bytes, &length));
+    ScopedJSFreePtr<char16_t> chars(InflateString(cx, bytes, &length));
     if (!chars)
         return nullptr;
 
     RegExpStatics *res = obj->as<GlobalObject>().getRegExpStatics(cx);
     if (!res)
         return nullptr;
 
     RegExpObject *reobj = RegExpObject::create(cx, res, chars, length,
                                                RegExpFlag(flags), nullptr, cx->tempLifoAlloc());
     return reobj;
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_NewUCRegExpObject(JSContext *cx, HandleObject obj, jschar *chars, size_t length,
+JS_NewUCRegExpObject(JSContext *cx, HandleObject obj, char16_t *chars, size_t length,
                      unsigned flags)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     RegExpStatics *res = obj->as<GlobalObject>().getRegExpStatics(cx);
     if (!res)
         return nullptr;
 
@@ -5881,17 +5881,17 @@ JS_ClearRegExpStatics(JSContext *cx, Han
     if (!res)
         return false;
 
     res->clear();
     return true;
 }
 
 JS_PUBLIC_API(bool)
-JS_ExecuteRegExp(JSContext *cx, HandleObject obj, HandleObject reobj, jschar *chars,
+JS_ExecuteRegExp(JSContext *cx, HandleObject obj, HandleObject reobj, char16_t *chars,
                  size_t length, size_t *indexp, bool test, MutableHandleValue rval)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
     RegExpStatics *res = obj->as<GlobalObject>().getRegExpStatics(cx);
     if (!res)
         return false;
@@ -5903,36 +5903,36 @@ JS_ExecuteRegExp(JSContext *cx, HandleOb
     return ExecuteRegExpLegacy(cx, res, reobj->as<RegExpObject>(), input, indexp, test, rval);
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_NewRegExpObjectNoStatics(JSContext *cx, char *bytes, size_t length, unsigned flags)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
-    jschar *chars = InflateString(cx, bytes, &length);
+    char16_t *chars = InflateString(cx, bytes, &length);
     if (!chars)
         return nullptr;
     RegExpObject *reobj = RegExpObject::createNoStatics(cx, chars, length,
                                                         RegExpFlag(flags), nullptr, cx->tempLifoAlloc());
     js_free(chars);
     return reobj;
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_NewUCRegExpObjectNoStatics(JSContext *cx, jschar *chars, size_t length, unsigned flags)
+JS_NewUCRegExpObjectNoStatics(JSContext *cx, char16_t *chars, size_t length, unsigned flags)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     return RegExpObject::createNoStatics(cx, chars, length,
                                          RegExpFlag(flags), nullptr, cx->tempLifoAlloc());
 }
 
 JS_PUBLIC_API(bool)
-JS_ExecuteRegExpNoStatics(JSContext *cx, HandleObject obj, jschar *chars, size_t length,
+JS_ExecuteRegExpNoStatics(JSContext *cx, HandleObject obj, char16_t *chars, size_t length,
                           size_t *indexp, bool test, MutableHandleValue rval)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
     RootedLinearString input(cx, NewStringCopyN<CanGC>(cx, chars, length));
     if (!input)
         return false;
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -819,52 +819,52 @@ namespace JS {
 //     must be kept alive until the JS compilation is complete.
 //  3) Any code calling SourceBufferHolder::take() must guarantee to keep the
 //     memory alive until JS compilation completes.  Normally only the JS
 //     engine should be calling take().
 //
 // Example use:
 //
 //    size_t length = 512;
-//    jschar* chars = static_cast<jschar*>(js_malloc(sizeof(jschar) * length));
+//    char16_t* chars = static_cast<char16_t*>(js_malloc(sizeof(char16_t) * length));
 //    JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership);
 //    JS::Compile(cx, obj, options, srcBuf);
 //
 class MOZ_STACK_CLASS SourceBufferHolder MOZ_FINAL
 {
   public:
     enum Ownership {
       NoOwnership,
       GiveOwnership
     };
 
-    SourceBufferHolder(const jschar *data, size_t dataLength, Ownership ownership)
+    SourceBufferHolder(const char16_t *data, size_t dataLength, Ownership ownership)
       : data_(data),
         length_(dataLength),
         ownsChars_(ownership == GiveOwnership)
     {
         // Ensure that null buffers properly return an unowned, empty,
         // null-terminated string.
-        static const jschar NullChar_ = 0;
+        static const char16_t NullChar_ = 0;
         if (!get()) {
             data_ = &NullChar_;
             length_ = 0;
             ownsChars_ = false;
         }
     }
 
     ~SourceBufferHolder() {
         if (ownsChars_)
-            js_free(const_cast<jschar *>(data_));
+            js_free(const_cast<char16_t *>(data_));
     }
 
     // Access the underlying source buffer without affecting ownership.
-    const jschar *get() const { return data_; }
-
-    // Length of the source buffer in jschars (not bytes)
+    const char16_t *get() const { return data_; }
+
+    // Length of the source buffer in char16_t code units (not bytes)
     size_t length() const { return length_; }
 
     // Returns true if the SourceBufferHolder owns the buffer and will free
     // it upon destruction.  If true, it is legal to call take().
     bool ownsChars() const { return ownsChars_; }
 
     // Retrieve and take ownership of the underlying data buffer.  The caller
     // is now responsible for calling js_free() on the returned value, *but only
@@ -873,27 +873,27 @@ class MOZ_STACK_CLASS SourceBufferHolder
     // After the buffer has been taken the SourceBufferHolder functions as if
     // it had been constructed on an unowned buffer;  get() and length() still
     // work.  In order for this to be safe the taken buffer must be kept alive
     // until after JS script compilation completes as noted above.
     //
     // Note, it's the caller's responsibility to check ownsChars() before taking
     // the buffer.  Taking and then free'ing an unowned buffer will have dire
     // consequences.
-    jschar *take() {
+    char16_t *take() {
         JS_ASSERT(ownsChars_);
         ownsChars_ = false;
-        return const_cast<jschar *>(data_);
+        return const_cast<char16_t *>(data_);
     }
 
   private:
     SourceBufferHolder(SourceBufferHolder &) MOZ_DELETE;
     SourceBufferHolder &operator=(SourceBufferHolder &) MOZ_DELETE;
 
-    const jschar *data_;
+    const char16_t *data_;
     size_t length_;
     bool ownsChars_;
 };
 
 } /* namespace JS */
 
 /************************************************************************/
 
@@ -984,24 +984,24 @@ JS_GetEmptyStringValue(JSContext *cx);
 extern JS_PUBLIC_API(JSString *)
 JS_GetEmptyString(JSRuntime *rt);
 
 /*
  * Format is a string of the following characters (spaces are insignificant),
  * specifying the tabulated type conversions:
  *
  *   b      bool            Boolean
- *   c      uint16_t/jschar ECMA uint16_t, Unicode char
+ *   c      char16_t        ECMA uint16_t, Unicode character
  *   i      int32_t         ECMA int32_t
  *   j      int32_t         ECMA int32_t (used to be different)
  *   u      uint32_t        ECMA uint32_t
  *   d      double          IEEE double
  *   I      double          Integral IEEE double
  *   S      JSString *      Unicode string, accessed by a JSString pointer
- *   W      jschar *        Unicode character vector, 0-terminated (W for wide)
+ *   W      char16_t *      Unicode character vector, 0-terminated (W for wide)
  *   o      JSObject *      Object reference
  *   f      JSFunction *    Function private
  *   v      jsval           Argument value (no conversion)
  *   *      N/A             Skip this argument (no vararg)
  *   /      N/A             End of required arguments
  *
  * The variable argument list after format must consist of &b, &c, &s, e.g.,
  * where those variables have the types given above.  For the pointer types
@@ -1359,17 +1359,16 @@ class JSAutoCheckRequest
     }
 
     ~JSAutoCheckRequest() {
 #ifdef JS_DEBUG
         JS_ASSERT(JS_IsInRequest(JS_GetRuntime(mContext)));
 #endif
     }
 
-
   private:
 #ifdef JS_DEBUG
     JSContext *mContext;
 #endif
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 extern JS_PUBLIC_API(void)
@@ -1824,17 +1823,17 @@ extern JS_PUBLIC_API(bool)
 JS_InitCTypesClass(JSContext *cx, JS::HandleObject global);
 
 /*
  * Convert a unicode string 'source' of length 'slen' to the platform native
  * charset, returning a null-terminated string allocated with JS_malloc. On
  * failure, this function should report an error.
  */
 typedef char *
-(* JSCTypesUnicodeToNativeFun)(JSContext *cx, const jschar *source, size_t slen);
+(* JSCTypesUnicodeToNativeFun)(JSContext *cx, const char16_t *source, size_t slen);
 
 /*
  * Set of function pointers that ctypes can use for various internal functions.
  * See JS_SetCTypesCallbacks below. Providing nullptr for a function is safe,
  * and will result in the applicable ctypes functionality not being available.
  */
 struct JSCTypesCallbacks {
     JSCTypesUnicodeToNativeFun unicodeToNative;
@@ -2161,17 +2160,17 @@ JS_GetGCParameterForThread(JSContext *cx
 extern JS_PUBLIC_API(void)
 JS_SetGCParametersBasedOnAvailableMemory(JSRuntime *rt, uint32_t availMem);
 
 /*
  * Create a new JSString whose chars member refers to external memory, i.e.,
  * memory requiring application-specific finalization.
  */
 extern JS_PUBLIC_API(JSString *)
-JS_NewExternalString(JSContext *cx, const jschar *chars, size_t length,
+JS_NewExternalString(JSContext *cx, const char16_t *chars, size_t length,
                      const JSStringFinalizer *fin);
 
 /*
  * Return whether 'str' was created with JS_NewExternalString or
  * JS_NewExternalStringWithClosure.
  */
 extern JS_PUBLIC_API(bool)
 JS_IsExternalString(JSString *str);
@@ -2595,17 +2594,16 @@ class JS_PUBLIC_API(CompartmentOptions)
     // For certain globals, we know enough about the code that will run in them
     // that we can discard script source entirely.
     bool discardSource() const { return discardSource_; }
     CompartmentOptions &setDiscardSource(bool flag) {
         discardSource_ = flag;
         return *this;
     }
 
-
     bool cloneSingletons() const { return cloneSingletons_; }
     CompartmentOptions &setCloneSingletons(bool flag) {
         cloneSingletons_ = flag;
         return *this;
     }
 
     bool extraWarnings(JSRuntime *rt) const;
     bool extraWarnings(JSContext *cx) const;
@@ -3072,71 +3070,71 @@ JS_DeleteProperty2(JSContext *cx, JS::Ha
 
 extern JS_PUBLIC_API(bool)
 JS_DeletePropertyById(JSContext *cx, JS::HandleObject obj, jsid id);
 
 extern JS_PUBLIC_API(bool)
 JS_DeletePropertyById2(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *succeeded);
 
 extern JS_PUBLIC_API(bool)
-JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const jschar *name, size_t namelen,
+JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
                     JS::HandleValue value, unsigned attrs,
                     JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
 
 extern JS_PUBLIC_API(bool)
-JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const jschar *name, size_t namelen,
+JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
                     JS::HandleObject value, unsigned attrs,
                     JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
 
 extern JS_PUBLIC_API(bool)
-JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const jschar *name, size_t namelen,
+JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
                     JS::HandleString value, unsigned attrs,
                     JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
 
 extern JS_PUBLIC_API(bool)
-JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const jschar *name, size_t namelen,
+JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
                     int32_t value, unsigned attrs,
                     JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
 
 extern JS_PUBLIC_API(bool)
-JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const jschar *name, size_t namelen,
+JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
                     uint32_t value, unsigned attrs,
                     JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
 
 extern JS_PUBLIC_API(bool)
-JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const jschar *name, size_t namelen,
+JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
                     double value, unsigned attrs,
                     JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
 
 extern JS_PUBLIC_API(bool)
-JS_AlreadyHasOwnUCProperty(JSContext *cx, JS::HandleObject obj, const jschar *name,
+JS_AlreadyHasOwnUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name,
                            size_t namelen, bool *foundp);
 
 extern JS_PUBLIC_API(bool)
 JS_HasUCProperty(JSContext *cx, JS::HandleObject obj,
-                 const jschar *name, size_t namelen,
+                 const char16_t *name, size_t namelen,
                  bool *vp);
 
 extern JS_PUBLIC_API(bool)
 JS_LookupUCProperty(JSContext *cx, JS::HandleObject obj,
-                    const jschar *name, size_t namelen,
+                    const char16_t *name, size_t namelen,
                     JS::MutableHandleValue vp);
 
 extern JS_PUBLIC_API(bool)
 JS_GetUCProperty(JSContext *cx, JS::HandleObject obj,
-                 const jschar *name, size_t namelen,
+                 const char16_t *name, size_t namelen,
                  JS::MutableHandleValue vp);
 
 extern JS_PUBLIC_API(bool)
 JS_SetUCProperty(JSContext *cx, JS::HandleObject obj,
-                 const jschar *name, size_t namelen,
+                 const char16_t *name, size_t namelen,
                  JS::HandleValue v);
 
 extern JS_PUBLIC_API(bool)
-JS_DeleteUCProperty2(JSContext *cx, JS::HandleObject obj, const jschar *name, size_t namelen,
+JS_DeleteUCProperty2(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
                      bool *succeeded);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_NewArrayObject(JSContext *cx, const JS::HandleValueArray& contents);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_NewArrayObject(JSContext *cx, size_t length);
 
@@ -3380,17 +3378,17 @@ extern JS_PUBLIC_API(bool)
 JS_DefineFunctions(JSContext *cx, JS::Handle<JSObject*> obj, const JSFunctionSpec *fs);
 
 extern JS_PUBLIC_API(JSFunction *)
 JS_DefineFunction(JSContext *cx, JS::Handle<JSObject*> obj, const char *name, JSNative call,
                   unsigned nargs, unsigned attrs);
 
 extern JS_PUBLIC_API(JSFunction *)
 JS_DefineUCFunction(JSContext *cx, JS::Handle<JSObject*> obj,
-                    const jschar *name, size_t namelen, JSNative call,
+                    const char16_t *name, size_t namelen, JSNative call,
                     unsigned nargs, unsigned attrs);
 
 extern JS_PUBLIC_API(JSFunction *)
 JS_DefineFunctionById(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JSNative call,
                       unsigned nargs, unsigned attrs);
 
 /*
  * Clone a top-level function into a new scope. This function will dynamically
@@ -3419,17 +3417,17 @@ JS_CompileScript(JSContext *cx, JS::Hand
                  const JS::CompileOptions &options,
                  JS::MutableHandleScript script);
 
 /*
  * |script| will always be set. On failure, it will be set to nullptr.
  */
 extern JS_PUBLIC_API(bool)
 JS_CompileUCScript(JSContext *cx, JS::HandleObject obj,
-                   const jschar *chars, size_t length,
+                   const char16_t *chars, size_t length,
                    const JS::CompileOptions &options,
                    JS::MutableHandleScript script);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_GetGlobalFromScript(JSScript *script);
 
 /*
  * |fun| will always be set. On failure, it will be set to nullptr.
@@ -3442,17 +3440,17 @@ JS_CompileFunction(JSContext *cx, JS::Ha
                    JS::MutableHandleFunction fun);
 
 /*
  * |fun| will always be set. On failure, it will be set to nullptr.
  */
 extern JS_PUBLIC_API(bool)
 JS_CompileUCFunction(JSContext *cx, JS::HandleObject obj, const char *name,
                      unsigned nargs, const char *const *argnames,
-                     const jschar *chars, size_t length,
+                     const char16_t *chars, size_t length,
                      const JS::CompileOptions &options,
                      JS::MutableHandleFunction fun);
 
 namespace JS {
 
 /* Options for JavaScript compilation. */
 
 /*
@@ -3500,17 +3498,17 @@ namespace JS {
 class JS_FRIEND_API(ReadOnlyCompileOptions)
 {
     friend class CompileOptions;
 
   protected:
     JSPrincipals *originPrincipals_;
     const char *filename_;
     const char *introducerFilename_;
-    const jschar *sourceMapURL_;
+    const char16_t *sourceMapURL_;
 
     // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure
     // is unusable until that's set to something more specific; the derived
     // classes' constructors take care of that, in ways appropriate to their
     // purpose.
     ReadOnlyCompileOptions()
       : originPrincipals_(nullptr),
         filename_(nullptr),
@@ -3545,17 +3543,17 @@ class JS_FRIEND_API(ReadOnlyCompileOptio
     void copyPODOptions(const ReadOnlyCompileOptions &rhs);
 
   public:
     // Read-only accessors for non-POD options. The proper way to set these
     // depends on the derived type.
     JSPrincipals *originPrincipals(js::ExclusiveContext *cx) const;
     const char *filename() const { return filename_; }
     const char *introducerFilename() const { return introducerFilename_; }
-    const jschar *sourceMapURL() const { return sourceMapURL_; }
+    const char16_t *sourceMapURL() const { return sourceMapURL_; }
     virtual JSObject *element() const = 0;
     virtual JSString *elementAttributeName() const = 0;
     virtual JSScript *introductionScript() const = 0;
 
     // POD options.
     JSVersion version;
     bool versionSet;
     bool utf8;
@@ -3620,21 +3618,21 @@ class JS_FRIEND_API(OwningCompileOptions
     JSScript *introductionScript() const MOZ_OVERRIDE { return introductionScriptRoot; }
 
     // Set this to a copy of |rhs|. Return false on OOM.
     bool copy(JSContext *cx, const ReadOnlyCompileOptions &rhs);
 
     /* These setters make copies of their string arguments, and are fallible. */
     bool setFile(JSContext *cx, const char *f);
     bool setFileAndLine(JSContext *cx, const char *f, unsigned l);
-    bool setSourceMapURL(JSContext *cx, const jschar *s);
+    bool setSourceMapURL(JSContext *cx, const char16_t *s);
     bool setIntroducerFilename(JSContext *cx, const char *s);
 
     /* These setters are infallible, and can be chained. */
-    OwningCompileOptions &setLine(unsigned l)             { lineno = l;              return *this; }
+    OwningCompileOptions &setLine(unsigned l)             { lineno = l; return *this; }
     OwningCompileOptions &setElement(JSObject *e) {
         elementRoot = e;
         return *this;
     }
     OwningCompileOptions &setElementAttributeName(JSString *p) {
         elementAttributeNameRoot = p;
         return *this;
     }
@@ -3713,18 +3711,18 @@ class MOZ_STACK_CLASS JS_FRIEND_API(Comp
     JSString *elementAttributeName() const MOZ_OVERRIDE { return elementAttributeNameRoot; }
     JSScript *introductionScript() const MOZ_OVERRIDE { return introductionScriptRoot; }
 
     CompileOptions &setFile(const char *f) { filename_ = f; return *this; }
     CompileOptions &setLine(unsigned l) { lineno = l; return *this; }
     CompileOptions &setFileAndLine(const char *f, unsigned l) {
         filename_ = f; lineno = l; return *this;
     }
-    CompileOptions &setSourceMapURL(const jschar *s) { sourceMapURL_ = s;       return *this; }
-    CompileOptions &setElement(JSObject *e)          { elementRoot = e;         return *this; }
+    CompileOptions &setSourceMapURL(const char16_t *s) { sourceMapURL_ = s; return *this; }
+    CompileOptions &setElement(JSObject *e)          { elementRoot = e; return *this; }
     CompileOptions &setElementAttributeName(JSString *p) {
         elementAttributeNameRoot = p;
         return *this;
     }
     CompileOptions &setIntroductionScript(JSScript *s) {
         introductionScriptRoot = s;
         return *this;
     }
@@ -3771,17 +3769,17 @@ Compile(JSContext *cx, JS::HandleObject 
         SourceBufferHolder &srcBuf, JS::MutableHandleScript script);
 
 extern JS_PUBLIC_API(bool)
 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
         const char *bytes, size_t length, JS::MutableHandleScript script);
 
 extern JS_PUBLIC_API(bool)
 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
-        const jschar *chars, size_t length, JS::MutableHandleScript script);
+        const char16_t *chars, size_t length, JS::MutableHandleScript script);
 
 extern JS_PUBLIC_API(bool)
 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options, FILE *file,
         JS::MutableHandleScript script);
 
 extern JS_PUBLIC_API(bool)
 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options, const char *filename,
         JS::MutableHandleScript script);
@@ -3802,17 +3800,17 @@ CanCompileOffThread(JSContext *cx, const
  *
  * The characters passed in to CompileOffThread must remain live until the
  * callback is invoked, and the resulting script will be rooted until the call
  * to FinishOffThreadScript.
  */
 
 extern JS_PUBLIC_API(bool)
 CompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options,
-                 const jschar *chars, size_t length,
+                 const char16_t *chars, size_t length,
                  OffThreadCompileCallback callback, void *callbackData);
 
 extern JS_PUBLIC_API(JSScript *)
 FinishOffThreadScript(JSContext *maybecx, JSRuntime *rt, void *token);
 
 extern JS_PUBLIC_API(bool)
 CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
                 const char *name, unsigned nargs, const char *const *argnames,
@@ -3821,17 +3819,17 @@ CompileFunction(JSContext *cx, JS::Handl
 extern JS_PUBLIC_API(bool)
 CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
                 const char *name, unsigned nargs, const char *const *argnames,
                 const char *bytes, size_t length, JS::MutableHandleFunction fun);
 
 extern JS_PUBLIC_API(bool)
 CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
                 const char *name, unsigned nargs, const char *const *argnames,
-                const jschar *chars, size_t length, JS::MutableHandleFunction fun);
+                const char16_t *chars, size_t length, JS::MutableHandleFunction fun);
 
 } /* namespace JS */
 
 extern JS_PUBLIC_API(JSString *)
 JS_DecompileScript(JSContext *cx, JS::Handle<JSScript*> script, const char *name, unsigned indent);
 
 /*
  * API extension: OR this into indent to avoid pretty-printing the decompiled
@@ -3911,45 +3909,45 @@ JS_EvaluateScript(JSContext *cx, JS::Han
 
 extern JS_PUBLIC_API(bool)
 JS_EvaluateScript(JSContext *cx, JS::HandleObject obj,
                   const char *bytes, unsigned length,
                   const char *filename, unsigned lineno);
 
 extern JS_PUBLIC_API(bool)
 JS_EvaluateUCScript(JSContext *cx, JS::Handle<JSObject*> obj,
-                    const jschar *chars, unsigned length,
+                    const char16_t *chars, unsigned length,
                     const char *filename, unsigned lineno,
                     JS::MutableHandle<JS::Value> rval);
 
 namespace JS {
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
          SourceBufferHolder &srcBuf, JS::MutableHandleValue rval);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
-         const jschar *chars, size_t length, JS::MutableHandleValue rval);
+         const char16_t *chars, size_t length, JS::MutableHandleValue rval);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
          const char *bytes, size_t length, JS::MutableHandleValue rval);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
          const char *filename, JS::MutableHandleValue rval);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
          SourceBufferHolder &srcBuf);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
-         const jschar *chars, size_t length);
+         const char16_t *chars, size_t length);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
          const char *bytes, size_t length);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
          const char *filename);
@@ -4092,29 +4090,29 @@ JS_InternJSString(JSContext *cx, JS::Han
 
 extern JS_PUBLIC_API(JSString *)
 JS_InternStringN(JSContext *cx, const char *s, size_t length);
 
 extern JS_PUBLIC_API(JSString *)
 JS_InternString(JSContext *cx, const char *s);
 
 extern JS_PUBLIC_API(JSString *)
-JS_NewUCString(JSContext *cx, jschar *chars, size_t length);
+JS_NewUCString(JSContext *cx, char16_t *chars, size_t length);
 
 extern JS_PUBLIC_API(JSString *)
-JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n);
+JS_NewUCStringCopyN(JSContext *cx, const char16_t *s, size_t n);
 
 extern JS_PUBLIC_API(JSString *)
-JS_NewUCStringCopyZ(JSContext *cx, const jschar *s);
+JS_NewUCStringCopyZ(JSContext *cx, const char16_t *s);
 
 extern JS_PUBLIC_API(JSString *)
-JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length);
+JS_InternUCStringN(JSContext *cx, const char16_t *s, size_t length);
 
 extern JS_PUBLIC_API(JSString *)
-JS_InternUCString(JSContext *cx, const jschar *s);
+JS_InternUCString(JSContext *cx, const char16_t *s);
 
 extern JS_PUBLIC_API(bool)
 JS_CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *result);
 
 extern JS_PUBLIC_API(bool)
 JS_StringEqualsAscii(JSContext *cx, JSString *str, const char *asciiBytes, bool *match);
 
 extern JS_PUBLIC_API(size_t)
@@ -4145,24 +4143,24 @@ JS_FileEscapedString(FILE *fp, JSString 
  *   // in a fallible context
  *   JSFlatString *fstr = JS_FlattenString(cx, str);
  *   if (!fstr)
  *     return false;
  *   JS_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str));
  *
  *   // in an infallible context, for the same 'str'
  *   AutoCheckCannotGC nogc;
- *   const jschar *chars = JS_GetTwoByteFlatStringChars(nogc, fstr)
+ *   const char16_t *chars = JS_GetTwoByteFlatStringChars(nogc, fstr)
  *   JS_ASSERT(chars);
  *
  * Flat strings and interned strings are always null-terminated, so
  * JS_FlattenString can be used to get a null-terminated string.
  *
  * Additionally, string characters are stored as either Latin1Char (8-bit)
- * or jschar (16-bit). Clients can use JS_StringHasLatin1Chars and can then
+ * or char16_t (16-bit). Clients can use JS_StringHasLatin1Chars and can then
  * call either the Latin1* or TwoByte* functions. Some functions like
  * JS_CopyStringChars and JS_GetStringCharAt accept both Latin1 and TwoByte
  * strings.
  */
 
 extern JS_PUBLIC_API(size_t)
 JS_GetStringLength(JSString *str);
 
@@ -4172,45 +4170,45 @@ JS_StringIsFlat(JSString *str);
 /* Returns true iff the string's characters are stored as Latin1. */
 extern JS_PUBLIC_API(bool)
 JS_StringHasLatin1Chars(JSString *str);
 
 extern JS_PUBLIC_API(const JS::Latin1Char *)
 JS_GetLatin1StringCharsAndLength(JSContext *cx, const JS::AutoCheckCannotGC &nogc, JSString *str,
                                  size_t *length);
 
-extern JS_PUBLIC_API(const jschar *)
+extern JS_PUBLIC_API(const char16_t *)
 JS_GetTwoByteStringCharsAndLength(JSContext *cx, const JS::AutoCheckCannotGC &nogc, JSString *str,
                                   size_t *length);
 
 extern JS_PUBLIC_API(bool)
-JS_GetStringCharAt(JSContext *cx, JSString *str, size_t index, jschar *res);
-
-extern JS_PUBLIC_API(jschar)
+JS_GetStringCharAt(JSContext *cx, JSString *str, size_t index, char16_t *res);
+
+extern JS_PUBLIC_API(char16_t)
 JS_GetFlatStringCharAt(JSFlatString *str, size_t index);
 
-extern JS_PUBLIC_API(const jschar *)
+extern JS_PUBLIC_API(const char16_t *)
 JS_GetTwoByteExternalStringChars(JSString *str);
 
 extern JS_PUBLIC_API(bool)
-JS_CopyStringChars(JSContext *cx, mozilla::Range<jschar> dest, JSString *str);
+JS_CopyStringChars(JSContext *cx, mozilla::Range<char16_t> dest, JSString *str);
 
 extern JS_PUBLIC_API(const JS::Latin1Char *)
 JS_GetLatin1InternedStringChars(const JS::AutoCheckCannotGC &nogc, JSString *str);
 
-extern JS_PUBLIC_API(const jschar *)
+extern JS_PUBLIC_API(const char16_t *)
 JS_GetTwoByteInternedStringChars(const JS::AutoCheckCannotGC &nogc, JSString *str);
 
 extern JS_PUBLIC_API(JSFlatString *)
 JS_FlattenString(JSContext *cx, JSString *str);
 
 extern JS_PUBLIC_API(const JS::Latin1Char *)
 JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC &nogc, JSFlatString *str);
 
-extern JS_PUBLIC_API(const jschar *)
+extern JS_PUBLIC_API(const char16_t *)
 JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC &nogc, JSFlatString *str);
 
 static MOZ_ALWAYS_INLINE JSFlatString *
 JSID_TO_FLAT_STRING(jsid id)
 {
     JS_ASSERT(JSID_IS_STRING(id));
     return (JSFlatString *)(JSID_BITS(id));
 }
@@ -4251,29 +4249,29 @@ JS_NewDependentString(JSContext *cx, JS:
  * Concatenate two strings, possibly resulting in a rope.
  * See above for thread safety comments.
  */
 extern JS_PUBLIC_API(JSString *)
 JS_ConcatStrings(JSContext *cx, JS::HandleString left, JS::HandleString right);
 
 /*
  * For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before
- * the call; on return, *dstlenp contains the number of jschars actually stored.
- * To determine the necessary destination buffer size, make a sizing call that
- * passes nullptr for dst.
+ * the call; on return, *dstlenp contains the number of characters actually
+ * stored. To determine the necessary destination buffer size, make a sizing
+ * call that passes nullptr for dst.
  *
  * On errors, the functions report the error. In that case, *dstlenp contains
  * the number of characters or bytes transferred so far.  If cx is nullptr, no
  * error is reported on failure, and the functions simply return false.
  *
- * NB: This function does not store an additional zero byte or jschar after the
+ * NB: This function does not store an additional zero byte or char16_t after the
  * transcoded string.
  */
 JS_PUBLIC_API(bool)
-JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst,
+JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, char16_t *dst,
                size_t *dstlenp);
 
 /*
  * A variation on JS_EncodeCharacters where a null terminated string is
  * returned that you are expected to call JS_free on when done.
  */
 JS_PUBLIC_API(char *)
 JS_EncodeString(JSContext *cx, JSString *str);
@@ -4451,36 +4449,36 @@ JS_PUBLIC_API(Symbol *)
 GetWellKnownSymbol(JSContext *cx, SymbolCode which);
 
 } /* namespace JS */
 
 /************************************************************************/
 /*
  * JSON functions
  */
-typedef bool (* JSONWriteCallback)(const jschar *buf, uint32_t len, void *data);
+typedef bool (* JSONWriteCallback)(const char16_t *buf, uint32_t len, void *data);
 
 /*
  * JSON.stringify as specified by ES5.
  */
 JS_PUBLIC_API(bool)
 JS_Stringify(JSContext *cx, JS::MutableHandleValue value, JS::HandleObject replacer,
              JS::HandleValue space, JSONWriteCallback callback, void *data);
 
 /*
  * JSON.parse as specified by ES5.
  */
 JS_PUBLIC_API(bool)
-JS_ParseJSON(JSContext *cx, const jschar *chars, uint32_t len, JS::MutableHandleValue vp);
+JS_ParseJSON(JSContext *cx, const char16_t *chars, uint32_t len, JS::MutableHandleValue vp);
 
 JS_PUBLIC_API(bool)
 JS_ParseJSON(JSContext *cx, JS::HandleString str, JS::MutableHandleValue vp);
 
 JS_PUBLIC_API(bool)
-JS_ParseJSONWithReviver(JSContext *cx, const jschar *chars, uint32_t len, JS::HandleValue reviver,
+JS_ParseJSONWithReviver(JSContext *cx, const char16_t *chars, uint32_t len, JS::HandleValue reviver,
                         JS::MutableHandleValue vp);
 
 JS_PUBLIC_API(bool)
 JS_ParseJSONWithReviver(JSContext *cx, JS::HandleString str, JS::HandleValue reviver,
                         JS::MutableHandleValue vp);
 
 /************************************************************************/
 
@@ -4547,26 +4545,26 @@ JS_ReportErrorNumber(JSContext *cx, JSEr
 
 #ifdef va_start
 extern JS_PUBLIC_API(void)
 JS_ReportErrorNumberVA(JSContext *cx, JSErrorCallback errorCallback,
                        void *userRef, const unsigned errorNumber, va_list ap);
 #endif
 
 /*
- * Use an errorNumber to retrieve the format string, args are jschar *
+ * Use an errorNumber to retrieve the format string, args are char16_t *
  */
 extern JS_PUBLIC_API(void)
 JS_ReportErrorNumberUC(JSContext *cx, JSErrorCallback errorCallback,
                      void *userRef, const unsigned errorNumber, ...);
 
 extern JS_PUBLIC_API(void)
 JS_ReportErrorNumberUCArray(JSContext *cx, JSErrorCallback errorCallback,
                             void *userRef, const unsigned errorNumber,
-                            const jschar **args);
+                            const char16_t **args);
 
 /*
  * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)).
  * Return true if there was no error trying to issue the warning, and if the
  * warning was not converted into an error due to the JSOPTION_WERROR option
  * being set, false otherwise.
  */
 extern JS_PUBLIC_API(bool)
@@ -4595,22 +4593,22 @@ extern JS_PUBLIC_API(void)
 JS_ReportAllocationOverflow(JSContext *cx);
 
 struct JSErrorReport {
     const char      *filename;      /* source file name, URL, etc., or null */
     JSPrincipals    *originPrincipals; /* see 'originPrincipals' comment above */
     unsigned        lineno;         /* source line number */
     const char      *linebuf;       /* offending source line without final \n */
     const char      *tokenptr;      /* pointer to error token in linebuf */
-    const jschar    *uclinebuf;     /* unicode (original) line buffer */
-    const jschar    *uctokenptr;    /* unicode (original) token pointer */
+    const char16_t  *uclinebuf;     /* unicode (original) line buffer */
+    const char16_t  *uctokenptr;    /* unicode (original) token pointer */
     unsigned        flags;          /* error/warning, etc. */
     unsigned        errorNumber;    /* the error number, e.g. see js.msg */
-    const jschar    *ucmessage;     /* the (default) error message */
-    const jschar    **messageArgs;  /* arguments for the error message */
+    const char16_t  *ucmessage;     /* the (default) error message */
+    const char16_t  **messageArgs;  /* arguments for the error message */
     int16_t         exnType;        /* One of the JSExnType constants */
     unsigned        column;         /* zero-based column index in line */
 };
 
 /*
  * JSErrorReport flag values.  These may be freely composed.
  */
 #define JSREPORT_ERROR      0x0     /* pseudo-flag for default case */
@@ -4707,41 +4705,41 @@ JS_ClearDateCaches(JSContext *cx);
 #define JSREG_MULTILINE 0x04u   /* treat ^ and $ as begin and end of line */
 #define JSREG_STICKY    0x08u   /* only match starting at lastIndex */
 
 extern JS_PUBLIC_API(JSObject *)
 JS_NewRegExpObject(JSContext *cx, JS::HandleObject obj, char *bytes, size_t length,
                    unsigned flags);
 
 extern JS_PUBLIC_API(JSObject *)
-JS_NewUCRegExpObject(JSContext *cx, JS::HandleObject obj, jschar *chars, size_t length,
+JS_NewUCRegExpObject(JSContext *cx, JS::HandleObject obj, char16_t *chars, size_t length,
                      unsigned flags);
 
 extern JS_PUBLIC_API(bool)
 JS_SetRegExpInput(JSContext *cx, JS::HandleObject obj, JS::HandleString input,
                   bool multiline);
 
 extern JS_PUBLIC_API(bool)
 JS_ClearRegExpStatics(JSContext *cx, JS::HandleObject obj);
 
 extern JS_PUBLIC_API(bool)
 JS_ExecuteRegExp(JSContext *cx, JS::HandleObject obj, JS::HandleObject reobj,
-                 jschar *chars, size_t length, size_t *indexp, bool test,
+                 char16_t *chars, size_t length, size_t *indexp, bool test,
                  JS::MutableHandleValue rval);
 
 /* RegExp interface for clients without a global object. */
 
 extern JS_PUBLIC_API(JSObject *)
 JS_NewRegExpObjectNoStatics(JSContext *cx, char *bytes, size_t length, unsigned flags);
 
 extern JS_PUBLIC_API(JSObject *)
-JS_NewUCRegExpObjectNoStatics(JSContext *cx, jschar *chars, size_t length, unsigned flags);
-
-extern JS_PUBLIC_API(bool)
-JS_ExecuteRegExpNoStatics(JSContext *cx, JS::HandleObject reobj, jschar *chars, size_t length,
+JS_NewUCRegExpObjectNoStatics(JSContext *cx, char16_t *chars, size_t length, unsigned flags);
+
+extern JS_PUBLIC_API(bool)
+JS_ExecuteRegExpNoStatics(JSContext *cx, JS::HandleObject reobj, char16_t *chars, size_t length,
                           size_t *indexp, bool test, JS::MutableHandleValue rval);
 
 extern JS_PUBLIC_API(bool)
 JS_ObjectIsRegExp(JSContext *cx, JS::HandleObject obj);
 
 extern JS_PUBLIC_API(unsigned)
 JS_GetRegExpFlags(JSContext *cx, JS::HandleObject obj);
 
@@ -5035,17 +5033,17 @@ namespace JS {
  * existing cache entry for the given global and char range that may contain a
  * module. If a cache entry exists, the callback shall return 'true' and return
  * the size, base address and an opaque file handle as outparams. If the
  * callback returns 'true', the JS engine guarantees a call to
  * CloseAsmJSCacheEntryForReadOp, passing the same base address, size and
  * handle.
  */
 typedef bool
-(* OpenAsmJSCacheEntryForReadOp)(HandleObject global, const jschar *begin, const jschar *limit,
+(* OpenAsmJSCacheEntryForReadOp)(HandleObject global, const char16_t *begin, const char16_t *limit,
                                  size_t *size, const uint8_t **memory, intptr_t *handle);
 typedef void
 (* CloseAsmJSCacheEntryForReadOp)(size_t size, const uint8_t *memory, intptr_t handle);
 
 /*
  * This callback represents a request by the JS engine to open for writing a
  * cache entry of the given size for the given global and char range containing
  * the just-compiled module. If cache entry space is available, the callback
@@ -5057,17 +5055,17 @@ typedef void
  * If 'installed' is true, then the cache entry is associated with a permanently
  * installed JS file (e.g., in a packaged webapp). This information allows the
  * embedding to store the cache entry in a installed location associated with
  * the principal of 'global' where it will not be evicted until the associated
  * installed JS file is removed.
  */
 typedef bool
 (* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, bool installed,
-                                  const jschar *begin, const jschar *end,
+                                  const char16_t *begin, const char16_t *end,
                                   size_t size, uint8_t **memory, intptr_t *handle);
 typedef void
 (* CloseAsmJSCacheEntryForWriteOp)(size_t size, uint8_t *memory, intptr_t handle);
 
 typedef js::Vector<char, 0, js::SystemAllocPolicy> BuildIdCharVector;
 
 // Return the buildId (represented as a sequence of characters) associated with
 // the currently-executing build. If the JS engine is embedded such that a
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -1089,23 +1089,23 @@ js::ArrayJoin(JSContext *cx, HandleObjec
         return nullptr;
 
     // Various optimized versions of steps 7-10.
     if (seplen == 0) {
         EmptySeparatorOp op;
         if (!ArrayJoinKernel<Locale>(cx, op, obj, length, sb))
             return nullptr;
     } else if (seplen == 1) {
-        jschar c = sepstr->latin1OrTwoByteChar(0);
+        char16_t c = sepstr->latin1OrTwoByteChar(0);
         if (c <= JSString::MAX_LATIN1_CHAR) {
             CharSeparatorOp<Latin1Char> op(c);
             if (!ArrayJoinKernel<Locale>(cx, op, obj, length, sb))
                 return nullptr;
         } else {
-            CharSeparatorOp<jschar> op(c);
+            CharSeparatorOp<char16_t> op(c);
             if (!ArrayJoinKernel<Locale>(cx, op, obj, length, sb))
                 return nullptr;
         }
     } else {
         StringSeparatorOp op(sepstr);
         if (!ArrayJoinKernel<Locale>(cx, op, obj, length, sb))
             return nullptr;
     }
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -355,17 +355,17 @@ AtomizeAndCopyChars(ExclusiveContext *cx
         js_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report OOM. */
         return nullptr;
     }
 
     return atom;
 }
 
 template JSAtom *
-AtomizeAndCopyChars(ExclusiveContext *cx, const jschar *tbchars, size_t length, InternBehavior ib);
+AtomizeAndCopyChars(ExclusiveContext *cx, const char16_t *tbchars, size_t length, InternBehavior ib);
 
 template JSAtom *
 AtomizeAndCopyChars(ExclusiveContext *cx, const Latin1Char *tbchars, size_t length, InternBehavior ib);
 
 JSAtom *
 js::AtomizeString(ExclusiveContext *cx, JSString *str,
                   js::InternBehavior ib /* = js::DoNotInternAtom */)
 {
@@ -441,26 +441,26 @@ js::AtomizeChars(ExclusiveContext *cx, c
 
     return AtomizeAndCopyChars(cx, chars, length, ib);
 }
 
 template JSAtom *
 js::AtomizeChars(ExclusiveContext *cx, const Latin1Char *chars, size_t length, InternBehavior ib);
 
 template JSAtom *
-js::AtomizeChars(ExclusiveContext *cx, const jschar *chars, size_t length, InternBehavior ib);
+js::AtomizeChars(ExclusiveContext *cx, const char16_t *chars, size_t length, InternBehavior ib);
 
 bool
 js::IndexToIdSlow(ExclusiveContext *cx, uint32_t index, MutableHandleId idp)
 {
     JS_ASSERT(index > JSID_INT_MAX);
 
-    jschar buf[UINT32_CHAR_BUFFER_LENGTH];
-    RangedPtr<jschar> end(ArrayEnd(buf), buf, ArrayEnd(buf));
-    RangedPtr<jschar> start = BackfillIndexInCharBuffer(index, end);
+    char16_t buf[UINT32_CHAR_BUFFER_LENGTH];
+    RangedPtr<char16_t> end(ArrayEnd(buf), buf, ArrayEnd(buf));
+    RangedPtr<char16_t> start = BackfillIndexInCharBuffer(index, end);
 
     JSAtom *atom = AtomizeChars(cx, start.get(), end - start);
     if (!atom)
         return false;
 
     idp.set(JSID_FROM_BITS((size_t)atom));
     return true;
 }
@@ -523,17 +523,17 @@ js::XDRAtom(XDRState<mode> *xdr, Mutable
         uint32_t length = atomp->length();
         uint32_t lengthAndEncoding = (length << 1) | uint32_t(atomp->hasLatin1Chars());
         if (!xdr->codeUint32(&lengthAndEncoding))
             return false;
 
         JS::AutoCheckCannotGC nogc;
         return atomp->hasLatin1Chars()
                ? xdr->codeChars(atomp->latin1Chars(nogc), length)
-               : xdr->codeChars(const_cast<jschar*>(atomp->twoByteChars(nogc)), length);
+               : xdr->codeChars(const_cast<char16_t*>(atomp->twoByteChars(nogc)), length);
     }
 
     /* Avoid JSString allocation for already existing atoms. See bug 321985. */
     uint32_t lengthAndEncoding;
     if (!xdr->codeUint32(&lengthAndEncoding))
         return false;
 
     uint32_t length = lengthAndEncoding >> 1;
@@ -542,34 +542,34 @@ js::XDRAtom(XDRState<mode> *xdr, Mutable
     JSContext *cx = xdr->cx();
     JSAtom *atom;
     if (latin1) {
         const Latin1Char *chars = reinterpret_cast<const Latin1Char *>(xdr->buf.read(length));
         atom = AtomizeChars(cx, chars, length);
     } else {
 #if IS_LITTLE_ENDIAN
         /* Directly access the little endian chars in the XDR buffer. */
-        const jschar *chars = reinterpret_cast<const jschar *>(xdr->buf.read(length * sizeof(jschar)));
+        const char16_t *chars = reinterpret_cast<const char16_t *>(xdr->buf.read(length * sizeof(char16_t)));
         atom = AtomizeChars(cx, chars, length);
 #else
         /*
          * We must copy chars to a temporary buffer to convert between little and
          * big endian data.
          */
-        jschar *chars;
-        jschar stackChars[256];
+        char16_t *chars;
+        char16_t stackChars[256];
         if (length <= ArrayLength(stackChars)) {
             chars = stackChars;
         } else {
             /*
              * This is very uncommon. Don't use the tempLifoAlloc arena for this as
              * most allocations here will be bigger than tempLifoAlloc's default
              * chunk size.
              */
-            chars = cx->runtime()->pod_malloc<jschar>(length);
+            chars = cx->runtime()->pod_malloc<char16_t>(length);
             if (!chars)
                 return false;
         }
 
         JS_ALWAYS_TRUE(xdr->codeChars(chars, length));
         atom = AtomizeChars(cx, chars, length);
         if (chars != stackChars)
             js_free(chars);
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -83,26 +83,26 @@ class AtomStateEntry
 };
 
 struct AtomHasher
 {
     struct Lookup
     {
         union {
             const JS::Latin1Char *latin1Chars;
-            const jschar *twoByteChars;
+            const char16_t *twoByteChars;
         };
         bool isLatin1;
         size_t length;
         const JSAtom *atom; /* Optional. */
         JS::AutoCheckCannotGC nogc;
 
         HashNumber hash;
 
-        Lookup(const jschar *chars, size_t length)
+        Lookup(const char16_t *chars, size_t length)
           : twoByteChars(chars), isLatin1(false), length(length), atom(nullptr)
         {
             hash = mozilla::HashString(chars, length);
         }
         Lookup(const JS::Latin1Char *chars, size_t length)
           : latin1Chars(chars), isLatin1(true), length(length), atom(nullptr)
         {
             hash = mozilla::HashString(chars, length);
--- a/js/src/jsatominlines.h
+++ b/js/src/jsatominlines.h
@@ -169,17 +169,17 @@ AtomHasher::match(const AtomStateEntry &
 
     if (key->hasLatin1Chars()) {
         const Latin1Char *keyChars = key->latin1Chars(lookup.nogc);
         if (lookup.isLatin1)
             return mozilla::PodEqual(keyChars, lookup.latin1Chars, lookup.length);
         return EqualChars(keyChars, lookup.twoByteChars, lookup.length);
     }
 
-    const jschar *keyChars = key->twoByteChars(lookup.nogc);
+    const char16_t *keyChars = key->twoByteChars(lookup.nogc);
     if (lookup.isLatin1)
         return EqualChars(lookup.latin1Chars, keyChars, lookup.length);
     return mozilla::PodEqual(keyChars, lookup.twoByteChars, lookup.length);
 }
 
 inline Handle<PropertyName*>
 TypeName(JSType type, const JSAtomState &names)
 {
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -485,17 +485,17 @@ checkReportFlags(JSContext *cx, unsigned
 
     return false;
 }
 
 bool
 js_ReportErrorVA(JSContext *cx, unsigned flags, const char *format, va_list ap)
 {
     char *message;
-    jschar *ucmessage;
+    char16_t *ucmessage;
     size_t messagelen;
     JSErrorReport report;
     bool warning;
 
     if (checkReportFlags(cx, &flags))
         return true;
 
     message = JS_vsmprintf(format, ap);
@@ -665,61 +665,61 @@ js_ExpandErrorArguments(ExclusiveContext
              * Gather the arguments into an array, and accumulate
              * their sizes. We allocate 1 more than necessary and
              * null it out to act as the caboose when we free the
              * pointers later.
              */
             if (messageArgsPassed) {
                 JS_ASSERT(!reportp->messageArgs[argCount]);
             } else {
-                reportp->messageArgs = cx->pod_malloc<const jschar*>(argCount + 1);
+                reportp->messageArgs = cx->pod_malloc<const char16_t*>(argCount + 1);
                 if (!reportp->messageArgs)
                     return false;
                 /* nullptr-terminate for easy copying. */
                 reportp->messageArgs[argCount] = nullptr;
             }
             for (i = 0; i < argCount; i++) {
                 if (messageArgsPassed) {
                     /* Do nothing. */
                 } else if (argumentsType == ArgumentsAreASCII) {
                     char *charArg = va_arg(ap, char *);
                     size_t charArgLength = strlen(charArg);
                     reportp->messageArgs[i] = InflateString(cx, charArg, &charArgLength);
                     if (!reportp->messageArgs[i])
                         goto error;
                 } else {
-                    reportp->messageArgs[i] = va_arg(ap, jschar *);
+                    reportp->messageArgs[i] = va_arg(ap, char16_t *);
                 }
                 argLengths[i] = js_strlen(reportp->messageArgs[i]);
                 totalArgsLength += argLengths[i];
             }
         }
         /*
          * Parse the error format, substituting the argument X
          * for {X} in the format.
          */
         if (argCount > 0) {
             if (efs->format) {
-                jschar *buffer, *fmt, *out;
+                char16_t *buffer, *fmt, *out;
                 int expandedArgs = 0;
                 size_t expandedLength;
                 size_t len = strlen(efs->format);
 
                 buffer = fmt = InflateString(cx, efs->format, &len);
                 if (!buffer)
                     goto error;
                 expandedLength = len
                                  - (3 * argCount)       /* exclude the {n} */
                                  + totalArgsLength;
 
                 /*
                 * Note - the above calculation assumes that each argument
                 * is used once and only once in the expansion !!!
                 */
-                reportp->ucmessage = out = cx->pod_malloc<jschar>(expandedLength + 1);
+                reportp->ucmessage = out = cx->pod_malloc<char16_t>(expandedLength + 1);
                 if (!out) {
                     js_free(buffer);
                     goto error;
                 }
                 while (*fmt) {
                     if (*fmt == '{') {
                         if (isdigit(fmt[1])) {
                             int d = JS7_UNDEC(fmt[1]);
@@ -732,19 +732,19 @@ js_ExpandErrorArguments(ExclusiveContext
                             continue;
                         }
                     }
                     *out++ = *fmt++;
                 }
                 JS_ASSERT(expandedArgs == argCount);
                 *out = 0;
                 js_free(buffer);
-                size_t msgLen = PointerRangeSize(static_cast<const jschar *>(reportp->ucmessage),
-                                                 static_cast<const jschar *>(out));
-                mozilla::Range<const jschar> ucmsg(reportp->ucmessage, msgLen);
+                size_t msgLen = PointerRangeSize(static_cast<const char16_t *>(reportp->ucmessage),
+                                                 static_cast<const char16_t *>(out));
+                mozilla::Range<const char16_t> ucmsg(reportp->ucmessage, msgLen);
                 *messagep = JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, ucmsg).c_str();
                 if (!*messagep)
                     goto error;
             }
         } else {
             /* Non-null messageArgs should have at least one non-null arg. */
             JS_ASSERT(!reportp->messageArgs);
             /*
@@ -838,17 +838,17 @@ js_ReportErrorNumberVA(JSContext *cx, un
     js_free((void *)report.ucmessage);
 
     return warning;
 }
 
 bool
 js_ReportErrorNumberUCArray(JSContext *cx, unsigned flags, JSErrorCallback callback,
                             void *userRef, const unsigned errorNumber,
-                            const jschar **args)
+                            const char16_t **args)
 {
     if (checkReportFlags(cx, &flags))
         return true;
     bool warning = JSREPORT_IS_WARNING(flags);
 
     JSErrorReport report;
     PodZero(&report);
     report.flags = flags;
@@ -1037,17 +1037,17 @@ js::InvokeInterruptCallback(JSContext *c
         return true;
     }
 
     // No need to set aside any pending exception here: ComputeStackString
     // already does that.
     JSString *stack = ComputeStackString(cx);
     JSFlatString *flat = stack ? stack->ensureFlat(cx) : nullptr;
 
-    const jschar *chars;
+    const char16_t *chars;
     AutoStableStringChars stableChars(cx);
     if (flat && stableChars.initTwoByte(cx, flat))
         chars = stableChars.twoByteRange().start().get();
     else
         chars = MOZ_UTF16("(stack not available)");
     JS_ReportErrorFlagsAndNumberUC(cx, JSREPORT_WARNING, js_GetErrorMessage, nullptr,
                                    JSMSG_TERMINATED, chars);
 
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -717,17 +717,17 @@ js_ReportErrorVA(JSContext *cx, unsigned
 extern bool
 js_ReportErrorNumberVA(JSContext *cx, unsigned flags, JSErrorCallback callback,
                        void *userRef, const unsigned errorNumber,
                        js::ErrorArgumentsType argumentsType, va_list ap);
 
 extern bool
 js_ReportErrorNumberUCArray(JSContext *cx, unsigned flags, JSErrorCallback callback,
                             void *userRef, const unsigned errorNumber,
-                            const jschar **args);
+                            const char16_t **args);
 #endif
 
 extern bool
 js_ExpandErrorArguments(js::ExclusiveContext *cx, JSErrorCallback callback,
                         void *userRef, const unsigned errorNumber,
                         char **message, JSErrorReport *reportp,
                         js::ErrorArgumentsType argumentsType, va_list ap);
 
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -293,17 +293,17 @@ CopyStringPure(JSContext *cx, JSString *
     if (str->hasLatin1Chars()) {
         ScopedJSFreePtr<Latin1Char> copiedChars;
         if (!str->asRope().copyLatin1CharsZ(cx, copiedChars))
             return nullptr;
 
         return NewString<CanGC>(cx, copiedChars.forget(), len);
     }
 
-    ScopedJSFreePtr<jschar> copiedChars;
+    ScopedJSFreePtr<char16_t> copiedChars;
     if (!str->asRope().copyTwoByteCharsZ(cx, copiedChars))
         return nullptr;
 
     return NewStringDontDeflate<CanGC>(cx, copiedChars.forget(), len);
 }
 
 bool
 JSCompartment::wrap(JSContext *cx, JSString **strp)
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -2551,17 +2551,17 @@ date_format(JSContext *cx, double date, 
              * encoding, and we probably won't display it correctly.
              */
             usetz = true;
             tzlen = strlen(tzbuf);
             if (tzlen > 100) {
                 usetz = false;
             } else {
                 for (i = 0; i < tzlen; i++) {
-                    jschar c = tzbuf[i];
+                    char16_t c = tzbuf[i];
                     if (c > 127 ||
                         !(isalpha(c) || isdigit(c) ||
                           c == ' ' || c == '(' || c == ')')) {
                         usetz = false;
                     }
                 }
             }
 
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -88,53 +88,53 @@ const Class ErrorObject::class_ = {
 JSErrorReport *
 js::CopyErrorReport(JSContext *cx, JSErrorReport *report)
 {
     /*
      * We use a single malloc block to make a deep copy of JSErrorReport with
      * the following layout:
      *   JSErrorReport
      *   array of copies of report->messageArgs
-     *   jschar array with characters for all messageArgs
-     *   jschar array with characters for ucmessage
-     *   jschar array with characters for uclinebuf and uctokenptr
+     *   char16_t array with characters for all messageArgs
+     *   char16_t array with characters for ucmessage
+     *   char16_t array with characters for uclinebuf and uctokenptr
      *   char array with characters for linebuf and tokenptr
      *   char array with characters for filename
      * Such layout together with the properties enforced by the following
      * asserts does not need any extra alignment padding.
      */
     JS_STATIC_ASSERT(sizeof(JSErrorReport) % sizeof(const char *) == 0);
-    JS_STATIC_ASSERT(sizeof(const char *) % sizeof(jschar) == 0);
+    JS_STATIC_ASSERT(sizeof(const char *) % sizeof(char16_t) == 0);
 
     size_t filenameSize;
     size_t linebufSize;
     size_t uclinebufSize;
     size_t ucmessageSize;
     size_t i, argsArraySize, argsCopySize, argSize;
     size_t mallocSize;
     JSErrorReport *copy;
     uint8_t *cursor;
 
-#define JS_CHARS_SIZE(jschars) ((js_strlen(jschars) + 1) * sizeof(jschar))
+#define JS_CHARS_SIZE(chars) ((js_strlen(chars) + 1) * sizeof(char16_t))
 
     filenameSize = report->filename ? strlen(report->filename) + 1 : 0;
     linebufSize = report->linebuf ? strlen(report->linebuf) + 1 : 0;
     uclinebufSize = report->uclinebuf ? JS_CHARS_SIZE(report->uclinebuf) : 0;
     ucmessageSize = 0;
     argsArraySize = 0;
     argsCopySize = 0;
     if (report->ucmessage) {
         ucmessageSize = JS_CHARS_SIZE(report->ucmessage);
         if (report->messageArgs) {
             for (i = 0; report->messageArgs[i]; ++i)
                 argsCopySize += JS_CHARS_SIZE(report->messageArgs[i]);
 
             /* Non-null messageArgs should have at least one non-null arg. */
             JS_ASSERT(i != 0);
-            argsArraySize = (i + 1) * sizeof(const jschar *);
+            argsArraySize = (i + 1) * sizeof(const char16_t *);
         }
     }
 
     /*
      * The mallocSize can not overflow since it represents the sum of the
      * sizes of already allocated objects.
      */
     mallocSize = sizeof(JSErrorReport) + argsArraySize + argsCopySize +
@@ -143,36 +143,36 @@ js::CopyErrorReport(JSContext *cx, JSErr
     if (!cursor)
         return nullptr;
 
     copy = (JSErrorReport *)cursor;
     memset(cursor, 0, sizeof(JSErrorReport));
     cursor += sizeof(JSErrorReport);
 
     if (argsArraySize != 0) {
-        copy->messageArgs = (const jschar **)cursor;
+        copy->messageArgs = (const char16_t **)cursor;
         cursor += argsArraySize;
         for (i = 0; report->messageArgs[i]; ++i) {
-            copy->messageArgs[i] = (const jschar *)cursor;
+            copy->messageArgs[i] = (const char16_t *)cursor;
             argSize = JS_CHARS_SIZE(report->messageArgs[i]);
             js_memcpy(cursor, report->messageArgs[i], argSize);
             cursor += argSize;
         }
         copy->messageArgs[i] = nullptr;
         JS_ASSERT(cursor == (uint8_t *)copy->messageArgs[0] + argsCopySize);
     }
 
     if (report->ucmessage) {
-        copy->ucmessage = (const jschar *)cursor;
+        copy->ucmessage = (const char16_t *)cursor;
         js_memcpy(cursor, report->ucmessage, ucmessageSize);
         cursor += ucmessageSize;
     }
 
     if (report->uclinebuf) {
-        copy->uclinebuf = (const jschar *)cursor;
+        copy->uclinebuf = (const char16_t *)cursor;
         js_memcpy(cursor, report->uclinebuf, uclinebufSize);
         cursor += uclinebufSize;
         if (report->uctokenptr) {
             copy->uctokenptr = copy->uclinebuf + (report->uctokenptr -
                                                   report->uclinebuf);
         }
     }
 
@@ -662,20 +662,20 @@ ErrorReport::~ErrorReport()
     if (ownedReport.messageArgs) {
         /*
          * js_ExpandErrorArguments owns its messageArgs only if it had to
          * inflate the arguments (from regular |char *|s), which is always in
          * our case.
          */
         size_t i = 0;
         while (ownedReport.messageArgs[i])
-            js_free(const_cast<jschar*>(ownedReport.messageArgs[i++]));
+            js_free(const_cast<char16_t*>(ownedReport.messageArgs[i++]));
         js_free(ownedReport.messageArgs);
     }
-    js_free(const_cast<jschar*>(ownedReport.ucmessage));
+    js_free(const_cast<char16_t*>(ownedReport.ucmessage));
 }
 
 bool
 ErrorReport::init(JSContext *cx, HandleValue exn)
 {
     MOZ_ASSERT(!cx->isExceptionPending());
 
     /*
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -683,19 +683,19 @@ js_DumpString(JSString *str)
 
 JS_FRIEND_API(void)
 js_DumpAtom(JSAtom *atom)
 {
     atom->dump();
 }
 
 JS_FRIEND_API(void)
-js_DumpChars(const jschar *s, size_t n)
+js_DumpChars(const char16_t *s, size_t n)
 {
-    fprintf(stderr, "jschar * (%p) = ", (void *) s);
+    fprintf(stderr, "char16_t * (%p) = ", (void *) s);
     JSString::dumpChars(s, n);
     fputc('\n', stderr);
 }
 
 JS_FRIEND_API(void)
 js_DumpObject(JSObject *obj)
 {
     if (!obj) {
@@ -846,23 +846,23 @@ JS::SetGCSliceCallback(JSRuntime *rt, GC
 }
 
 JS_FRIEND_API(bool)
 JS::WasIncrementalGC(JSRuntime *rt)
 {
     return rt->gc.isIncrementalGc();
 }
 
-jschar *
+char16_t *
 GCDescription::formatMessage(JSRuntime *rt) const
 {
     return rt->gc.stats.formatMessage();
 }
 
-jschar *
+char16_t *
 GCDescription::formatJSON(JSRuntime *rt, uint64_t timestamp) const
 {
     return rt->gc.stats.formatJSON(timestamp);
 }
 
 JS_FRIEND_API(void)
 JS::NotifyDidPaint(JSRuntime *rt)
 {
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -192,17 +192,17 @@ js_DumpString(JSString *str);
 
 extern JS_FRIEND_API(void)
 js_DumpAtom(JSAtom *atom);
 
 extern JS_FRIEND_API(void)
 js_DumpObject(JSObject *obj);
 
 extern JS_FRIEND_API(void)
-js_DumpChars(const jschar *s, size_t n);
+js_DumpChars(const char16_t *s, size_t n);
 #endif
 
 /*
  * Copies all own properties from |obj| to |target|. |obj| must be a "native"
  * object (that is to say, normal-ish - not an Array or a Proxy).
  *
  * This function immediately enters a compartment, and does not impose any
  * restrictions on the compartment of |cx|.
@@ -411,17 +411,17 @@ class SourceHook {
   public:
     virtual ~SourceHook() { }
 
     /*
      * Set |*src| and |*length| to refer to the source code for |filename|.
      * On success, the caller owns the buffer to which |*src| points, and
      * should use JS_free to free it.
      */
-    virtual bool load(JSContext *cx, const char *filename, jschar **src, size_t *length) = 0;
+    virtual bool load(JSContext *cx, const char *filename, char16_t **src, size_t *length) = 0;
 };
 
 /*
  * Have |rt| use |hook| to retrieve lazily-retrieved source code. See the
  * comments for SourceHook. The runtime takes ownership of the hook, and
  * will delete it when the runtime itself is deleted, or when a new hook is
  * set.
  */
@@ -603,19 +603,19 @@ struct String
     static const uint32_t INLINE_CHARS_BIT = JS_BIT(2);
     static const uint32_t LATIN1_CHARS_BIT = JS_BIT(6);
     static const uint32_t ROPE_FLAGS       = 0;
     static const uint32_t TYPE_FLAGS_MASK  = JS_BIT(6) - 1;
     uint32_t flags;
     uint32_t length;
     union {
         const JS::Latin1Char *nonInlineCharsLatin1;
-        const jschar *nonInlineCharsTwoByte;
+        const char16_t *nonInlineCharsTwoByte;
         JS::Latin1Char inlineStorageLatin1[1];
-        jschar inlineStorageTwoByte[1];
+        char16_t inlineStorageTwoByte[1];
     };
 };
 
 } /* namespace shadow */
 
 // This is equal to |&JSObject::class_|.  Use it in places where you don't want
 // to #include jsobj.h.
 extern JS_FRIEND_DATA(const js::Class* const) ObjectClassPtr;
@@ -865,17 +865,17 @@ GetLatin1LinearStringChars(const JS::Aut
 
     using shadow::String;
     String *s = reinterpret_cast<String *>(linear);
     if (s->flags & String::INLINE_CHARS_BIT)
         return s->inlineStorageLatin1;
     return s->nonInlineCharsLatin1;
 }
 
-MOZ_ALWAYS_INLINE const jschar *
+MOZ_ALWAYS_INLINE const char16_t *
 GetTwoByteLinearStringChars(const JS::AutoCheckCannotGC &nogc, JSLinearString *linear)
 {
     MOZ_ASSERT(!LinearStringHasLatin1Chars(linear));
 
     using shadow::String;
     String *s = reinterpret_cast<String *>(linear);
     if (s->flags & String::INLINE_CHARS_BIT)
         return s->inlineStorageTwoByte;
@@ -895,17 +895,17 @@ FlatStringToLinearString(JSFlatString *s
 }
 
 MOZ_ALWAYS_INLINE const JS::Latin1Char *
 GetLatin1AtomChars(const JS::AutoCheckCannotGC &nogc, JSAtom *atom)
 {
     return GetLatin1LinearStringChars(nogc, AtomToLinearString(atom));
 }
 
-MOZ_ALWAYS_INLINE const jschar *
+MOZ_ALWAYS_INLINE const char16_t *
 GetTwoByteAtomChars(const JS::AutoCheckCannotGC &nogc, JSAtom *atom)
 {
     return GetTwoByteLinearStringChars(nogc, AtomToLinearString(atom));
 }
 
 JS_FRIEND_API(JSLinearString *)
 StringToLinearStringSlow(JSContext *cx, JSString *str);
 
@@ -915,42 +915,42 @@ StringToLinearString(JSContext *cx, JSSt
     using shadow::String;
     String *s = reinterpret_cast<String *>(str);
     if (MOZ_UNLIKELY((s->flags & String::TYPE_FLAGS_MASK) == String::ROPE_FLAGS))
         return StringToLinearStringSlow(cx, str);
     return reinterpret_cast<JSLinearString *>(str);
 }
 
 MOZ_ALWAYS_INLINE void
-CopyLinearStringChars(jschar *dest, JSLinearString *s, size_t len)
+CopyLinearStringChars(char16_t *dest, JSLinearString *s, size_t len)
 {
     JS::AutoCheckCannotGC nogc;
     if (LinearStringHasLatin1Chars(s)) {
         const JS::Latin1Char *src = GetLatin1LinearStringChars(nogc, s);
         for (size_t i = 0; i < len; i++)
             dest[i] = src[i];
     } else {
-        const jschar *src = GetTwoByteLinearStringChars(nogc, s);
+        const char16_t *src = GetTwoByteLinearStringChars(nogc, s);
         mozilla::PodCopy(dest, src, len);
     }
 }
 
 inline bool
-CopyStringChars(JSContext *cx, jschar *dest, JSString *s, size_t len)
+CopyStringChars(JSContext *cx, char16_t *dest, JSString *s, size_t len)
 {
     JSLinearString *linear = StringToLinearString(cx, s);
     if (!linear)
         return false;
 
     CopyLinearStringChars(dest, linear, len);
     return true;
 }
 
 inline void
-CopyFlatStringChars(jschar *dest, JSFlatString *s, size_t len)
+CopyFlatStringChars(char16_t *dest, JSFlatString *s, size_t len)
 {
     CopyLinearStringChars(dest, FlatStringToLinearString(s), len);
 }
 
 JS_FRIEND_API(bool)
 GetPropertyNames(JSContext *cx, JSObject *obj, unsigned flags, JS::AutoIdVector *props);
 
 JS_FRIEND_API(bool)
@@ -1290,17 +1290,17 @@ namespace js {
  * JSString methods and often the code can be rewritten so that only indexes
  * instead of char pointers are used in parts of the code that can GC.
  */
 class MOZ_STACK_CLASS AutoStableStringChars
 {
     /* Ensure the string is kept alive while we're using its chars. */
     JS::RootedString s_;
     union {
-        const jschar *twoByteChars_;
+        const char16_t *twoByteChars_;
         const JS::Latin1Char *latin1Chars_;
     };
     enum State { Uninitialized, Latin1, TwoByte };
     State state_;
     bool ownsChars_;
 
   public:
     explicit AutoStableStringChars(JSContext *cx)
@@ -1311,30 +1311,30 @@ class MOZ_STACK_CLASS AutoStableStringCh
     bool init(JSContext *cx, JSString *s);
 
     /* Like init(), but Latin1 chars are inflated to TwoByte. */
     bool initTwoByte(JSContext *cx, JSString *s);
 
     bool isLatin1() const { return state_ == Latin1; }
     bool isTwoByte() const { return state_ == TwoByte; }
 
-    const jschar *twoByteChars() const {
+    const char16_t *twoByteChars() const {
         MOZ_ASSERT(state_ == TwoByte);
         return twoByteChars_;
     }
 
     mozilla::Range<const JS::Latin1Char> latin1Range() const {
         MOZ_ASSERT(state_ == Latin1);
         return mozilla::Range<const JS::Latin1Char>(latin1Chars_,
                                                     GetStringLength(s_));
     }
 
-    mozilla::Range<const jschar> twoByteRange() const {
+    mozilla::Range<const char16_t> twoByteRange() const {
         MOZ_ASSERT(state_ == TwoByte);
-        return mozilla::Range<const jschar>(twoByteChars_,
+        return mozilla::Range<const char16_t>(twoByteChars_,
                                             GetStringLength(s_));
     }
 
     /* If we own the chars, transfer ownership to the caller. */
     bool maybeGiveOwnershipToCaller() {
         MOZ_ASSERT(state_ != Uninitialized);
         if (!ownsChars_)
             return false;
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -808,17 +808,17 @@ CreateFunctionPrototype(JSContext *cx, J
             return nullptr;
 
         JS_ASSERT(proto == functionProto);
         functionProto->setIsFunctionPrototype();
     }
 
     const char *rawSource = "() {\n}";
     size_t sourceLen = strlen(rawSource);
-    jschar *source = InflateString(cx, rawSource, &sourceLen);
+    char16_t *source = InflateString(cx, rawSource, &sourceLen);
     if (!source)
         return nullptr;
 
     ScriptSource *ss =
         cx->new_<ScriptSource>();
     if (!ss) {
         js_free(source);
         return nullptr;
@@ -918,17 +918,17 @@ js::FindBody(JSContext *cx, HandleFuncti
         options.setVersion(fun->nonLazyScript()->getVersion());
 
     AutoKeepAtoms keepAtoms(cx->perThreadData);
 
     AutoStableStringChars stableChars(cx);
     if (!stableChars.initTwoByte(cx, src))
         return false;
 
-    const mozilla::Range<const jschar> srcChars = stableChars.twoByteRange();
+    const mozilla::Range<const char16_t> srcChars = stableChars.twoByteRange();
     TokenStream ts(cx, options, srcChars.start().get(), srcChars.length(), nullptr);
     int nest = 0;
     bool onward = true;
     // Skip arguments list.
     do {
         switch (ts.getToken()) {
           case TOK_NAME:
           case TOK_YIELD:
@@ -954,17 +954,17 @@ js::FindBody(JSContext *cx, HandleFuncti
         tt = ts.getToken();
     if (tt == TOK_ERROR)
         return false;
     bool braced = tt == TOK_LC;
     JS_ASSERT_IF(fun->isExprClosure(), !braced);
     *bodyStart = ts.currentToken().pos.begin;
     if (braced)
         *bodyStart += 1;
-    mozilla::RangedPtr<const jschar> end = srcChars.end();
+    mozilla::RangedPtr<const char16_t> end = srcChars.end();
     if (end[-1] == '}') {
         end--;
     } else {
         JS_ASSERT(!braced);
         for (; unicode::IsSpaceOrBOM2(end[-1]); end--)
             ;
     }
     *bodyEnd = end - srcChars.start();
@@ -1434,21 +1434,21 @@ JSFunction::createScriptForLazilyInterpr
                 lazy->initScript(clonedScript);
             return true;
         }
 
         JS_ASSERT(lazy->source()->hasSourceData());
 
         // Parse and compile the script from source.
         UncompressedSourceCache::AutoHoldEntry holder;
-        const jschar *chars = lazy->source()->chars(cx, holder);
+        const char16_t *chars = lazy->source()->chars(cx, holder);
         if (!chars)
             return false;
 
-        const jschar *lazyStart = chars + lazy->begin();
+        const char16_t *lazyStart = chars + lazy->begin();
         size_t lazyLength = lazy->end() - lazy->begin();
 
         if (!frontend::CompileLazyFunction(cx, lazy, lazyStart, lazyLength))
             return false;
 
         script = fun->nonLazyScript();
 
         // Remember the compiled script on the lazy script itself, in case
@@ -1749,28 +1749,28 @@ FunctionConstructor(JSContext *cx, unsig
                 return false;
             }
         }
 
         /* Add 1 for each joining comma and check for overflow (two ways). */
         size_t old_args_length = args_length;
         args_length = old_args_length + n - 1;
         if (args_length < old_args_length ||
-            args_length >= ~(size_t)0 / sizeof(jschar)) {
+            args_length >= ~(size_t)0 / sizeof(char16_t)) {
             js_ReportAllocationOverflow(cx);
             return false;
         }
 
         /*
          * Allocate a string to hold the concatenated arguments, including room
          * for a terminating 0. Mark cx->tempLifeAlloc for later release, to
          * free collected_args and its tokenstream in one swoop.
          */
         LifoAllocScope las(&cx->tempLifoAlloc());
-        jschar *cp = cx->tempLifoAlloc().newArray<jschar>(args_length + 1);
+        char16_t *cp = cx->tempLifoAlloc().newArray<char16_t>(args_length + 1);
         if (!cp) {
             js_ReportOutOfMemory(cx);
             return false;
         }
         ConstTwoByteChars collected_args(cp, args_length + 1);
 
         /*
          * Concatenate the arguments into the new string, separated by commas.
@@ -1889,17 +1889,17 @@ FunctionConstructor(JSContext *cx, unsig
 
     if (hasRest)
         fun->setHasRest();
 
     AutoStableStringChars stableChars(cx);
     if (!stableChars.initTwoByte(cx, str))
         return false;
 
-    mozilla::Range<const jschar> chars = stableChars.twoByteRange();
+    mozilla::Range<const char16_t> chars = stableChars.twoByteRange();
     SourceBufferHolder::Ownership ownership = stableChars.maybeGiveOwnershipToCaller()
                                               ? SourceBufferHolder::GiveOwnership
                                               : SourceBufferHolder::NoOwnership;
     bool ok;
     SourceBufferHolder srcBuf(chars.start().get(), chars.length(), ownership);
     if (isStarGenerator)
         ok = frontend::CompileStarGeneratorBody(cx, &fun, options, formals, srcBuf);
     else
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -194,17 +194,17 @@ js::ParseDecimalNumber(const mozilla::Ra
     } while (++s < end);
     return static_cast<double>(dec);
 }
 
 template double
 js::ParseDecimalNumber(const mozilla::Range<const Latin1Char> chars);
 
 template double
-js::ParseDecimalNumber(const mozilla::Range<const jschar> chars);
+js::ParseDecimalNumber(const mozilla::Range<const char16_t> chars);
 
 template <typename CharT>
 bool
 js::GetPrefixInteger(ThreadSafeContext *cx, const CharT *start, const CharT *end, int base,
                      const CharT **endp, double *dp)
 {
     JS_ASSERT(start <= end);
     JS_ASSERT(2 <= base && base <= 36);
@@ -244,32 +244,32 @@ js::GetPrefixInteger(ThreadSafeContext *
 
     if ((base & (base - 1)) == 0)
         *dp = ComputeAccurateBinaryBaseInteger(start, s, base);
 
     return true;
 }
 
 template bool
-js::GetPrefixInteger(ThreadSafeContext *cx, const jschar *start, const jschar *end, int base,
-                     const jschar **endp, double *dp);
+js::GetPrefixInteger(ThreadSafeContext *cx, const char16_t *start, const char16_t *end, int base,
+                     const char16_t **endp, double *dp);
 
 template bool
 js::GetPrefixInteger(ThreadSafeContext *cx, const Latin1Char *start, const Latin1Char *end,
                      int base, const Latin1Char **endp, double *dp);
 
 bool
-js::GetDecimalInteger(ExclusiveContext *cx, const jschar *start, const jschar *end, double *dp)
+js::GetDecimalInteger(ExclusiveContext *cx, const char16_t *start, const char16_t *end, double *dp)
 {
     JS_ASSERT(start <= end);
 
-    const jschar *s = start;
+    const char16_t *s = start;
     double d = 0.0;
     for (; s < end; s++) {
-        jschar c = *s;
+        char16_t c = *s;
         JS_ASSERT('0' <= c && c <= '9');
         int digit = c - '0';
         d = d * 10 + digit;
     }
 
     *dp = d;
 
     // If we haven't reached the limit of integer precision, we're done.
@@ -303,18 +303,18 @@ num_parseFloat(JSContext *cx, unsigned a
     if (linear->hasLatin1Chars()) {
         const Latin1Char *begin = linear->latin1Chars(nogc);
         const Latin1Char *end;
         if (!js_strtod(cx, begin, begin + linear->length(), &end, &d))
             return false;
         if (end == begin)
             d = GenericNaN();
     } else {
-        const jschar *begin = linear->twoByteChars(nogc);
-        const jschar *end;
+        const char16_t *begin = linear->twoByteChars(nogc);
+        const char16_t *end;
         if (!js_strtod(cx, begin, begin + linear->length(), &end, &d))
             return false;
         if (end == begin)
             d = GenericNaN();
     }
 
     args.rval().setDouble(d);
     return true;
@@ -1289,17 +1289,17 @@ js_NumberToStringWithBase(ThreadSafeCont
 
     int32_t i;
     if (mozilla::NumberIsInt32(d, &i)) {
         if (base == 10 && StaticStrings::hasInt(i))
             return cx->staticStrings().getInt(i);
         if (unsigned(i) < unsigned(base)) {
             if (i < 10)
                 return cx->staticStrings().getInt(i);
-            jschar c = 'a' + i - 10;
+            char16_t c = 'a' + i - 10;
             JS_ASSERT(StaticStrings::hasUnit(c));
             return cx->staticStrings().getUnit(c);
         }
 
         if (comp) {
             if (JSFlatString *str = comp->dtoaCache.lookup(base, d))
                 return str;
         }
@@ -1421,18 +1421,18 @@ js::NumberValueToStringBuffer(JSContext 
         if (!cstr) {
             JS_ReportOutOfMemory(cx);
             return false;
         }
         cstrlen = strlen(cstr);
     }
 
     /*
-     * Inflate to jschar string.  The input C-string characters are < 127, so
-     * even if jschars are UTF-8, all chars should map to one jschar.
+     * Inflate to char16_t string.  The input C-string characters are < 127, so
+     * even if char16_t units are UTF-8, all chars should map to one char16_t.
      */
     JS_ASSERT(!cbuf.dbuf && cstrlen < cbuf.sbufSize);
     return sb.append(cstr, cstrlen);
 }
 
 template <typename CharT>
 static bool
 CharsToNumber(ThreadSafeContext *cx, const CharT *chars, size_t length, double *result)
@@ -1708,17 +1708,17 @@ js_strtod(ThreadSafeContext *cx, const C
     size_t length = end - s;
 
     Vector<char, 32> chars(cx);
     if (!chars.growByUninitialized(length + 1))
         return false;
 
     size_t i = 0;
     for (; i < length; i++) {
-        jschar c = s[i];
+        char16_t c = s[i];
         if (c >> 8)
             break;
         chars[i] = char(c);
     }
     chars[i] = 0;
 
     /* Try to parse +Infinity, -Infinity or Infinity. */
     {
@@ -1745,14 +1745,14 @@ js_strtod(ThreadSafeContext *cx, const C
         *dEnd = begin;
     else
         *dEnd = s + (ep - chars.begin());
 
     return true;
 }
 
 template bool
-js_strtod(ThreadSafeContext *cx, const jschar *begin, const jschar *end, const jschar **dEnd,
+js_strtod(ThreadSafeContext *cx, const char16_t *begin, const char16_t *end, const char16_t **dEnd,
           double *d);
 
 template bool
 js_strtod(ThreadSafeContext *cx, const Latin1Char *begin, const Latin1Char *end,
           const Latin1Char **dEnd, double *d);
--- a/js/src/jsnum.h
+++ b/js/src/jsnum.h
@@ -136,21 +136,21 @@ ParseDecimalNumber(const mozilla::Range<
  */
 template <typename CharT>
 extern bool
 GetPrefixInteger(ThreadSafeContext *cx, const CharT *start, const CharT *end, int base,
                  const CharT **endp, double *dp);
 
 /*
  * This is like GetPrefixInteger, but only deals with base 10, and doesn't have
- * and |endp| outparam.  It should only be used when the jschars are known to
+ * and |endp| outparam.  It should only be used when the characters are known to
  * only contain digits.
  */
 extern bool
-GetDecimalInteger(ExclusiveContext *cx, const jschar *start, const jschar *end, double *dp);
+GetDecimalInteger(ExclusiveContext *cx, const char16_t *start, const char16_t *end, double *dp);
 
 extern bool
 StringToNumber(ThreadSafeContext *cx, JSString *str, double *result);
 
 /* ES5 9.3 ToNumber, overwriting *vp with the appropriate number value. */
 MOZ_ALWAYS_INLINE bool
 ToNumber(JSContext *cx, JS::MutableHandleValue vp)
 {
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -41,17 +41,17 @@ const Class js::JSONClass = {
     JS_DeletePropertyStub,  /* delProperty */
     JS_PropertyStub,        /* getProperty */
     JS_StrictPropertyStub,  /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub
 };
 
-static inline bool IsQuoteSpecialCharacter(jschar c)
+static inline bool IsQuoteSpecialCharacter(char16_t c)
 {
     JS_STATIC_ASSERT('\b' < ' ');
     JS_STATIC_ASSERT('\f' < ' ');
     JS_STATIC_ASSERT('\n' < ' ');
     JS_STATIC_ASSERT('\r' < ' ');
     JS_STATIC_ASSERT('\t' < ' ');
     return c == '"' || c == '\\' || c < ' ';
 }
@@ -79,22 +79,22 @@ Quote(StringBuffer &sb, JSLinearString *
         } while (++i < len);
         if (i > mark) {
             if (!sb.appendSubstring(str, mark, i - mark))
                 return false;
             if (i == len)
                 break;
         }
 
-        jschar c = buf[i];
+        char16_t c = buf[i];
         if (c == '"' || c == '\\') {
             if (!sb.append('\\') || !sb.append(c))
                 return false;
         } else if (c == '\b' || c == '\f' || c == '\n' || c == '\r' || c == '\t') {
-           jschar abbrev = (c == '\b')
+           char16_t abbrev = (c == '\b')
                          ? 'b'
                          : (c == '\f')
                          ? 'f'
                          : (c == '\n')
                          ? 'n'
                          : (c == '\r')
                          ? 'r'
                          : 't';
@@ -123,17 +123,17 @@ Quote(JSContext *cx, StringBuffer &sb, J
 {
     JS::Anchor<JSString *> anchor(str);
     JSLinearString *linear = str->ensureLinear(cx);
     if (!linear)
         return false;
 
     return linear->hasLatin1Chars()
            ? Quote<Latin1Char>(sb, linear)
-           : Quote<jschar>(sb, linear);
+           : Quote<char16_t>(sb, linear);
 }
 
 namespace {
 
 class StringifyContext
 {
   public:
     StringifyContext(JSContext *cx, StringBuffer &sb, const StringBuffer &gap,
@@ -812,17 +812,17 @@ js::ParseJSONWithReviver(JSContext *cx, 
     return true;
 }
 
 template bool
 js::ParseJSONWithReviver(JSContext *cx, const mozilla::Range<const Latin1Char> chars,
                          HandleValue reviver, MutableHandleValue vp);
 
 template bool
-js::ParseJSONWithReviver(JSContext *cx, const mozilla::Range<const jschar> chars, HandleValue reviver,
+js::ParseJSONWithReviver(JSContext *cx, const mozilla::Range<const char16_t> chars, HandleValue reviver,
                          MutableHandleValue vp);
 
 #if JS_HAS_TOSOURCE
 static bool
 json_toSource(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     args.rval().setString(cx->names().JSON);
--- a/js/src/jsonparser.cpp
+++ b/js/src/jsonparser.cpp
@@ -157,17 +157,17 @@ JSONParser<CharT>::readString()
     StringBuffer buffer(cx);
     do {
         if (start < current && !buffer.append(start.get(), current.get()))
             return token(OOM);
 
         if (current >= end)
             break;
 
-        jschar c = *current++;
+        char16_t c = *current++;
         if (c == '"') {
             JSFlatString *str = (ST == JSONParser::PropertyName)
                                 ? buffer.finishAtom()
                                 : buffer.finishString();
             if (!str)
                 return token(OOM);
             return stringToken(str);
         }
@@ -336,17 +336,17 @@ JSONParser<CharT>::readNumber()
     const CharT *finish;
     if (!js_strtod(cx, digitStart.get(), current.get(), &finish, &d))
         return token(OOM);
     JS_ASSERT(current == finish);
     return numberToken(negative ? -d : d);
 }
 
 static inline bool
-IsJSONWhitespace(jschar c)
+IsJSONWhitespace(char16_t c)
 {
     return c == '\t' || c == '\r' || c == '\n' || c == ' ';
 }
 
 template <typename CharT>
 JSONParserBase::Token
 JSONParser<CharT>::advance()
 {
@@ -825,9 +825,9 @@ JSONParser<CharT>::parse(MutableHandleVa
     JS_ASSERT(end == current);
     JS_ASSERT(stack.empty());
 
     vp.set(value);
     return true;
 }
 
 template class js::JSONParser<Latin1Char>;
-template class js::JSONParser<jschar>;
+template class js::JSONParser<char16_t>;
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -787,17 +787,17 @@ js_DumpScriptDepth(JSContext *cx, JSScri
         return false;
     RootedScript script(cx, scriptArg);
     bool ok = js_DisassembleAtPC(cx, script, true, pc, true, &sprinter);
     fprintf(stdout, "%s", sprinter.string());
     return ok;
 }
 
 static char *
-QuoteString(Sprinter *sp, JSString *str, jschar quote);
+QuoteString(Sprinter *sp, JSString *str, char16_t quote);
 
 static bool
 ToDisassemblySource(JSContext *cx, HandleValue v, JSAutoByteString *bytes)
 {
     if (v.isString()) {
         Sprinter sprinter(cx);
         if (!sprinter.init())
             return false;
@@ -1285,30 +1285,30 @@ const char js_EscapeMap[] = {
     '"',  '"',
     '\'', '\'',
     '\\', '\\',
     '\0'
 };
 
 template <typename CharT>
 static char *
-QuoteString(Sprinter *sp, const CharT *s, size_t length, jschar quote)
+QuoteString(Sprinter *sp, const CharT *s, size_t length, char16_t quote)
 {
     /* Sample off first for later return value pointer computation. */
     ptrdiff_t offset = sp->getOffset();
 
     if (quote && Sprint(sp, "%c", char(quote)) < 0)
         return nullptr;
 
     const CharT *end = s + length;
 
     /* Loop control variables: end points at end of string sentinel. */
     for (const CharT *t = s; t < end; s = ++t) {
         /* Move t forward from s past un-quote-worthy characters. */
-        jschar c = *t;
+        char16_t c = *t;
         while (c < 127 && isprint(c) && c != quote && c != '\\' && c != '\t') {
             c = *++t;
             if (t == end)
                 break;
         }
 
         {
             ptrdiff_t len = t - s;
@@ -1350,30 +1350,30 @@ QuoteString(Sprinter *sp, const CharT *s
      */
     if (offset == sp->getOffset() && Sprint(sp, "") < 0)
         return nullptr;
 
     return sp->stringAt(offset);
 }
 
 static char *
-QuoteString(Sprinter *sp, JSString *str, jschar quote)
+QuoteString(Sprinter *sp, JSString *str, char16_t quote)
 {
     JSLinearString *linear = str->ensureLinear(sp->context);
     if (!linear)
         return nullptr;
 
     AutoCheckCannotGC nogc;
     return linear->hasLatin1Chars()
            ? QuoteString(sp, linear->latin1Chars(nogc), linear->length(), quote)
            : QuoteString(sp, linear->twoByteChars(nogc), linear->length(), quote);
 }
 
 JSString *
-js_QuoteString(ExclusiveContext *cx, JSString *str, jschar quote)
+js_QuoteString(ExclusiveContext *cx, JSString *str, char16_t quote)
 {
     Sprinter sprinter(cx);
     if (!sprinter.init())
         return nullptr;
     char *bytes = QuoteString(&sprinter, str, quote);
     if (!bytes)
         return nullptr;
     return NewStringCopyZ<CanGC>(cx, bytes);
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -269,17 +269,17 @@ extern const char       js_EscapeMap[];
 #endif
 
 /*
  * Return a GC'ed string containing the chars in str, with any non-printing
  * chars or quotes (' or " as specified by the quote argument) escaped, and
  * with the quote character at the beginning and end of the result string.
  */
 extern JSString *
-js_QuoteString(js::ExclusiveContext *cx, JSString *str, jschar quote);
+js_QuoteString(js::ExclusiveContext *cx, JSString *str, char16_t quote);
 
 namespace js {
 
 static inline bool
 IsJumpOpcode(JSOp op)
 {
     uint32_t type = JOF_TYPE(js_CodeSpec[op].format);
 
--- a/js/src/jsprf.cpp
+++ b/js/src/jsprf.cpp
@@ -84,17 +84,17 @@ typedef mozilla::Vector<NumArgState, 20,
 
 inline int
 generic_write(SprintfState *ss, const char *src, size_t srclen)
 {
     return (*ss->stuff)(ss, src, srclen);
 }
 
 inline int
-generic_write(SprintfState *ss, const jschar *src, size_t srclen)
+generic_write(SprintfState *ss, const char16_t *src, size_t srclen)
 {
     const size_t CHUNK_SIZE = 64;
     char chunk[CHUNK_SIZE];
 
     int rv = 0;
     size_t j = 0;
     size_t i = 0;
     while (i < srclen) {
@@ -339,20 +339,20 @@ static int cvt_f(SprintfState *ss, doubl
     // debugging on. At least this way we can track down the evil piece
     // of calling code and fix it!
     JS_ASSERT(strlen(fout) < sizeof(fout));
 
     return (*ss->stuff)(ss, fout, strlen(fout));
 }
 
 static inline const char *generic_null_str(const char *) { return "(null)"; }
-static inline const jschar *generic_null_str(const jschar *) { return MOZ_UTF16("(null)"); }
+static inline const char16_t *generic_null_str(const char16_t *) { return MOZ_UTF16("(null)"); }
 
 static inline size_t generic_strlen(const char *s) { return strlen(s); }
-static inline size_t generic_strlen(const jschar *s) { return js_strlen(s); }
+static inline size_t generic_strlen(const char16_t *s) { return js_strlen(s); }
 
 /*
  * Convert a string into its printable form.  "width" is the output
  * width. "prec" is the maximum number of characters of "s" to output,
  * where -1 means until NUL.
  */
 template <typename Char>
 static int
@@ -569,17 +569,17 @@ BuildArgArray(const char *fmt, va_list a
         case TYPE_UINT16:
         case TYPE_INTN:
         case TYPE_UINTN:        (void) va_arg(ap, int);         break;
         case TYPE_INT32:        (void) va_arg(ap, int32_t);     break;
         case TYPE_UINT32:       (void) va_arg(ap, uint32_t);    break;
         case TYPE_INT64:        (void) va_arg(ap, int64_t);     break;
         case TYPE_UINT64:       (void) va_arg(ap, uint64_t);    break;
         case TYPE_STRING:       (void) va_arg(ap, char*);       break;
-        case TYPE_WSTRING:      (void) va_arg(ap, jschar*);     break;
+        case TYPE_WSTRING:      (void) va_arg(ap, char16_t*);   break;
         case TYPE_INTSTR:       (void) va_arg(ap, int*);        break;
         case TYPE_DOUBLE:       (void) va_arg(ap, double);      break;
 
         default: return false;
         }
 
         cn++;
     }
@@ -592,23 +592,23 @@ BuildArgArray(const char *fmt, va_list a
  */
 static int
 dosprintf(SprintfState *ss, const char *fmt, va_list ap)
 {
     char c;
     int flags, width, prec, radix, type;
     union {
         char ch;
-        jschar wch;
+        char16_t wch;
         int i;
         long l;
         int64_t ll;
         double d;
         const char *s;
-        const jschar* ws;
+        const char16_t* ws;
         int *ip;
     } u;
     const char *fmt0;
     static const char hex[] = "0123456789abcdef";
     static const char HEX[] = "0123456789ABCDEF";
     const char *hexp;
     int rv, i;
     char pattern[20];
@@ -879,17 +879,17 @@ dosprintf(SprintfState *ss, const char *
           case 'G':
             // XXX not supported I suppose
             JS_ASSERT(0);
             break;
 #endif
 
           case 's':
             if(type == TYPE_INT16) {
-                u.ws = va_arg(ap, const jschar*);
+                u.ws = va_arg(ap, const char16_t*);
                 rv = cvt_s(ss, u.ws, width, prec, flags);
             } else {
                 u.s = va_arg(ap, const char*);
                 rv = cvt_s(ss, u.s, width, prec, flags);
             }
             if (rv < 0) {
                 return rv;
             }
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -34,17 +34,17 @@ js::AutoEnterPolicy::reportErrorIfExcept
         return;
 
     if (JSID_IS_VOID(id)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
                              JSMSG_OBJECT_ACCESS_DENIED);
     } else {
         JSString *str = IdToString(cx, id);
         AutoStableStringChars chars(cx);
-        const jschar *prop = nullptr;
+        const char16_t *prop = nullptr;
         if (str->ensureFlat(cx) && chars.initTwoByte(cx, str))
             prop = chars.twoByteChars();
 
         JS_ReportErrorNumberUC(cx, js_GetErrorMessage, nullptr, JSMSG_PROPERTY_ACCESS_DENIED,
                                prop);
     }
 }
 
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -3477,17 +3477,17 @@ reflect_parse(JSContext *cx, uint32_t ar
 
     AutoStableStringChars flatChars(cx);
     if (!flatChars.initTwoByte(cx, flat))
         return false;
 
     CompileOptions options(cx);
     options.setFileAndLine(filename, lineno);
     options.setCanLazilyParse(false);
-    mozilla::Range<const jschar> chars = flatChars.twoByteRange();
+    mozilla::Range<const char16_t> chars = flatChars.twoByteRange();
     Parser<FullParseHandler> parser(cx, &cx->tempLifoAlloc(), options, chars.start().get(),
                                     chars.length(), /* foldConstants = */ false, nullptr, nullptr);
 
     serialize.setParser(&parser);
 
     ParseNode *pn = parser.parse(nullptr);
     if (!pn)
         return false;
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1342,17 +1342,17 @@ ScriptSourceObject::initFromOptions(JSCo
 
 /* static */ bool
 JSScript::loadSource(JSContext *cx, ScriptSource *ss, bool *worked)
 {
     JS_ASSERT(!ss->hasSourceData());
     *worked = false;
     if (!cx->runtime()->sourceHook || !ss->sourceRetrievable())
         return true;
-    jschar *src = nullptr;
+    char16_t *src = nullptr;
     size_t length;
     if (!cx->runtime()->sourceHook->load(cx, ss->filename(), &src, &length))
         return false;
     if (!src)
         return true;
     ss->setSource(src, length);
     *worked = true;
     return true;
@@ -1376,33 +1376,33 @@ UncompressedSourceCache::AutoHoldEntry::
     // Initialise the holder for a specific cache and script source. This will
     // hold on to the cached source chars in the event that the cache is purged.
     JS_ASSERT(!cache_ && !source_ && !charsToFree_);
     cache_ = cache;
     source_ = source;
 }
 
 void
-UncompressedSourceCache::AutoHoldEntry::deferDelete(const jschar *chars)
+UncompressedSourceCache::AutoHoldEntry::deferDelete(const char16_t *chars)
 {
     // Take ownership of source chars now the cache is being purged. Remove our
     // reference to the ScriptSource which might soon be destroyed.
     JS_ASSERT(cache_ && source_ && !charsToFree_);
     cache_ = nullptr;
     source_ = nullptr;
     charsToFree_ = chars;
 }
 
 UncompressedSourceCache::AutoHoldEntry::~AutoHoldEntry()
 {
     // The holder is going out of scope. If it has taken ownership of cached
     // chars then delete them, otherwise unregister ourself with the cache.
     if (charsToFree_) {
         JS_ASSERT(!cache_ && !source_);
-        js_free(const_cast<jschar *>(charsToFree_));
+        js_free(const_cast<char16_t *>(charsToFree_));
     } else if (cache_) {
         JS_ASSERT(source_);
         cache_->releaseEntry(*this);
     }
 }
 
 void
 UncompressedSourceCache::holdEntry(AutoHoldEntry &holder, ScriptSource *ss)
@@ -1414,31 +1414,31 @@ UncompressedSourceCache::holdEntry(AutoH
 
 void
 UncompressedSourceCache::releaseEntry(AutoHoldEntry &holder)
 {
     JS_ASSERT(holder_ == &holder);
     holder_ = nullptr;
 }
 
-const jschar *
+const char16_t *
 UncompressedSourceCache::lookup(ScriptSource *ss, AutoHoldEntry &holder)
 {
     JS_ASSERT(!holder_);
     if (!map_)
         return nullptr;
     if (Map::Ptr p = map_->lookup(ss)) {
         holdEntry(holder, ss);
         return p->value();
     }
     return nullptr;
 }
 
 bool
-UncompressedSourceCache::put(ScriptSource *ss, const jschar *str, AutoHoldEntry &holder)
+UncompressedSourceCache::put(ScriptSource *ss, const char16_t *str, AutoHoldEntry &holder)
 {
     JS_ASSERT(!holder_);
 
     if (!map_) {
         map_ = js_new<Map>();
         if (!map_)
             return false;
 
@@ -1458,56 +1458,56 @@ UncompressedSourceCache::put(ScriptSourc
 
 void
 UncompressedSourceCache::purge()
 {
     if (!map_)
         return;
 
     for (Map::Range r = map_->all(); !r.empty(); r.popFront()) {
-        const jschar *chars = r.front().value();
+        const char16_t *chars = r.front().value();
         if (holder_ && r.front().key() == holder_->source()) {
             holder_->deferDelete(chars);
             holder_ = nullptr;
         } else {
-            js_free(const_cast<jschar*>(chars));
+            js_free(const_cast<char16_t*>(chars));
         }
     }
 
     js_delete(map_);
     map_ = nullptr;
 }
 
 size_t
 UncompressedSourceCache::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
 {
     size_t n = 0;
     if (map_ && !map_->empty()) {
         n += map_->sizeOfIncludingThis(mallocSizeOf);
         for (Map::Range r = map_->all(); !r.empty(); r.popFront()) {
-            const jschar *v = r.front().value();
+            const char16_t *v = r.front().value();
             n += mallocSizeOf(v);
         }
     }
     return n;
 }
 
-const jschar *
+const char16_t *
 ScriptSource::chars(JSContext *cx, UncompressedSourceCache::AutoHoldEntry &holder)
 {
     switch (dataType) {
       case DataUncompressed:
         return uncompressedChars();
 
       case DataCompressed: {
-        if (const jschar *decompressed = cx->runtime()->uncompressedSourceCache.lookup(this, holder))
+        if (const char16_t *decompressed = cx->runtime()->uncompressedSourceCache.lookup(this, holder))
             return decompressed;
 
-        const size_t nbytes = sizeof(jschar) * (length_ + 1);
-        jschar *decompressed = static_cast<jschar *>(js_malloc(nbytes));
+        const size_t nbytes = sizeof(char16_t) * (length_ + 1);
+        char16_t *decompressed = static_cast<char16_t *>(js_malloc(nbytes));
         if (!decompressed)
             return nullptr;
 
         if (!DecompressString((const unsigned char *) compressedData(), compressedBytes(),
                               reinterpret_cast<unsigned char *>(decompressed), nbytes)) {
             JS_ReportOutOfMemory(cx);
             js_free(decompressed);
             return nullptr;
@@ -1532,51 +1532,51 @@ ScriptSource::chars(JSContext *cx, Uncom
     }
 }
 
 JSFlatString *
 ScriptSource::substring(JSContext *cx, uint32_t start, uint32_t stop)
 {
     JS_ASSERT(start <= stop);
     UncompressedSourceCache::AutoHoldEntry holder;
-    const jschar *chars = this->chars(cx, holder);
+    const char16_t *chars = this->chars(cx, holder);
     if (!chars)
         return nullptr;
     return NewStringCopyN<CanGC>(cx, chars + start, stop - start);
 }
 
 JSFlatString *
 ScriptSource::substringDontDeflate(JSContext *cx, uint32_t start, uint32_t stop)
 {
     JS_ASSERT(start <= stop);
     UncompressedSourceCache::AutoHoldEntry holder;
-    const jschar *chars = this->chars(cx, holder);
+    const char16_t *chars = this->chars(cx, holder);
     if (!chars)
         return nullptr;
     return NewStringCopyNDontDeflate<CanGC>(cx, chars + start, stop - start);
 }
 
 void
-ScriptSource::setSource(const jschar *chars, size_t length, bool ownsChars /* = true */)
+ScriptSource::setSource(const char16_t *chars, size_t length, bool ownsChars /* = true */)
 {
     JS_ASSERT(dataType == DataMissing);
 
     dataType = DataUncompressed;
     data.uncompressed.chars = chars;
     data.uncompressed.ownsChars = ownsChars;
 
     length_ = length;
 }
 
 void
 ScriptSource::setCompressedSource(JSRuntime *maybert, void *raw, size_t nbytes, HashNumber hash)
 {
     JS_ASSERT(dataType == DataMissing || dataType == DataUncompressed);
     if (dataType == DataUncompressed && ownsUncompressedChars())
-        js_free(const_cast<jschar *>(uncompressedChars()));
+        js_free(const_cast<char16_t *>(uncompressedChars()));
 
     dataType = DataCompressed;
     data.compressed.raw = raw;
     data.compressed.nbytes = nbytes;
     data.compressed.hash = hash;
 
     if (maybert)
         updateCompressedSourceSet(maybert);
@@ -1607,17 +1607,17 @@ ScriptSource::updateCompressedSourceSet(
 
 bool
 ScriptSource::ensureOwnsSource(ExclusiveContext *cx)
 {
     JS_ASSERT(dataType == DataUncompressed);
     if (ownsUncompressedChars())
         return true;
 
-    jschar *uncompressed = cx->zone()->pod_malloc<jschar>(Max<size_t>(length_, 1));
+    char16_t *uncompressed = cx->zone()->pod_malloc<char16_t>(Max<size_t>(length_, 1));
     if (!uncompressed)
         return false;
     PodCopy(uncompressed, uncompressedChars(), length_);
 
     data.uncompressed.chars = uncompressed;
     data.uncompressed.ownsChars = true;
     return true;
 }
@@ -1670,17 +1670,17 @@ ScriptSource::setSourceCopy(ExclusiveCon
     return true;
 }
 
 SourceCompressionTask::ResultType
 SourceCompressionTask::work()
 {
     // Try to keep the maximum memory usage down by only allocating half the
     // size of the string, first.
-    size_t inputBytes = ss->length() * sizeof(jschar);
+    size_t inputBytes = ss->length() * sizeof(char16_t);
     size_t firstSize = inputBytes / 2;
     compressed = js_malloc(firstSize);
     if (!compressed)
         return OOM;
 
     Compressor comp(reinterpret_cast<const unsigned char *>(ss->uncompressedChars()), inputBytes);
     if (!comp.init())
         return OOM;
@@ -1728,17 +1728,17 @@ SourceCompressionTask::work()
 
 ScriptSource::~ScriptSource()
 {
     JS_ASSERT_IF(inCompressedSourceSet, dataType == DataCompressed);
 
     switch (dataType) {
       case DataUncompressed:
         if (ownsUncompressedChars())
-            js_free(const_cast<jschar *>(uncompressedChars()));
+            js_free(const_cast<char16_t *>(uncompressedChars()));
         break;
 
       case DataCompressed:
         // Script source references are only manipulated on the main thread,
         // except during off thread parsing when the source may be created
         // and used exclusively by the thread doing the parse. In this case the
         // ScriptSource might be destroyed while off the main thread, but it
         // will not have been added to the runtime's compressed source set
@@ -1815,29 +1815,29 @@ ScriptSource::performXDR(XDRState<mode> 
             if (mode == XDR_ENCODE)
                 argumentsNotIncluded = argumentsNotIncluded_;
             if (!xdr->codeUint8(&argumentsNotIncluded))
                 return false;
             if (mode == XDR_DECODE)
                 argumentsNotIncluded_ = argumentsNotIncluded;
         }
 
-        size_t byteLen = compressedLength ? compressedLength : (length_ * sizeof(jschar));
+        size_t byteLen = compressedLength ? compressedLength : (length_ * sizeof(char16_t));
         if (mode == XDR_DECODE) {
             uint8_t *p = xdr->cx()->template pod_malloc<uint8_t>(Max<size_t>(byteLen, 1));
             if (!p || !xdr->codeBytes(p, byteLen)) {
                 js_free(p);
                 return false;
             }
 
             if (compressedLength)
                 setCompressedSource(xdr->cx()->runtime(), p, compressedLength,
                                     CompressedSourceHasher::computeHash(p, compressedLength));
             else
-                setSource((const jschar *) p, length_);
+                setSource((const char16_t *) p, length_);
         } else {
             void *p;
             switch (dataType) {
               case DataUncompressed:
                 p = (void *) uncompressedChars();
                 break;
               case DataCompressed:
                 p = compressedData();
@@ -1858,17 +1858,17 @@ ScriptSource::performXDR(XDRState<mode> 
         return false;
 
     if (haveSourceMap) {
         uint32_t sourceMapURLLen = (mode == XDR_DECODE) ? 0 : js_strlen(sourceMapURL_.get());
         if (!xdr->codeUint32(&sourceMapURLLen))
             return false;
 
         if (mode == XDR_DECODE) {
-            sourceMapURL_ = xdr->cx()->template make_pod_array<jschar>(sourceMapURLLen + 1);
+            sourceMapURL_ = xdr->cx()->template make_pod_array<char16_t>(sourceMapURLLen + 1);
             if (!sourceMapURL_)
                 return false;
         }
         if (!xdr->codeChars(sourceMapURL_.get(), sourceMapURLLen)) {
             if (mode == XDR_DECODE)
                 sourceMapURL_ = nullptr;
             return false;
         }
@@ -1880,17 +1880,17 @@ ScriptSource::performXDR(XDRState<mode> 
         return false;
 
     if (haveDisplayURL) {
         uint32_t displayURLLen = (mode == XDR_DECODE) ? 0 : js_strlen(displayURL_.get());
         if (!xdr->codeUint32(&displayURLLen))
             return false;
 
         if (mode == XDR_DECODE) {
-            displayURL_ = xdr->cx()->template make_pod_array<jschar>(displayURLLen + 1);
+            displayURL_ = xdr->cx()->template make_pod_array<char16_t>(displayURLLen + 1);
             if (!displayURL_)
                 return false;
         }
         if (!xdr->codeChars(displayURL_.get(), displayURLLen)) {
             if (mode == XDR_DECODE)
                 displayURL_ = nullptr;
             return false;
         }
@@ -1986,17 +1986,17 @@ bool
 ScriptSource::setFilename(ExclusiveContext *cx, const char *filename)
 {
     JS_ASSERT(!filename_);
     filename_ = DuplicateString(cx, filename);
     return filename_ != nullptr;
 }
 
 bool
-ScriptSource::setDisplayURL(ExclusiveContext *cx, const jschar *displayURL)
+ScriptSource::setDisplayURL(ExclusiveContext *cx, const char16_t *displayURL)
 {
     JS_ASSERT(displayURL);
     if (hasDisplayURL()) {
         if (cx->isJSContext() &&
             !JS_ReportErrorFlagsAndNumber(cx->asJSContext(), JSREPORT_WARNING,
                                           js_GetErrorMessage, nullptr,
                                           JSMSG_ALREADY_HAS_PRAGMA, filename_.get(),
                                           "//# sourceURL"))
@@ -2008,17 +2008,17 @@ ScriptSource::setDisplayURL(ExclusiveCon
     if (len == 1)
         return true;
 
     displayURL_ = DuplicateString(cx, displayURL);
     return displayURL_ != nullptr;
 }
 
 bool
-ScriptSource::setSourceMapURL(ExclusiveContext *cx, const jschar *sourceMapURL)
+ScriptSource::setSourceMapURL(ExclusiveContext *cx, const char16_t *sourceMapURL)
 {
     JS_ASSERT(sourceMapURL);
     if (hasSourceMapURL()) {
         // Warn about the replacement, but use the new one.
         if (cx->isJSContext()) {
             JS_ReportErrorFlagsAndNumber(cx->asJSContext(), JSREPORT_WARNING,
                                          js_GetErrorMessage, nullptr,
                                          JSMSG_ALREADY_HAS_PRAGMA, filename_.get(),
@@ -2035,17 +2035,17 @@ ScriptSource::setSourceMapURL(ExclusiveC
     sourceMapURL_ = DuplicateString(cx, sourceMapURL);
     return sourceMapURL_ != nullptr;
 }
 
 size_t
 ScriptSource::computedSizeOfData() const
 {
     if (dataType == DataUncompressed && ownsUncompressedChars())
-        return sizeof(jschar) * length_;
+        return sizeof(char16_t) * length_;
     if (dataType == DataCompressed)
         return compressedBytes();
     return 0;
 }
 
 /*
  * Shared script data management.
  */
@@ -3832,20 +3832,20 @@ LazyScriptHashPolicy::match(JSScript *sc
         script->sourceStart() != lazy->begin() ||
         script->sourceEnd() != lazy->end())
     {
         return false;
     }
 
     UncompressedSourceCache::AutoHoldEntry holder;
 
-    const jschar *scriptChars = script->scriptSource()->chars(cx, holder);
+    const char16_t *scriptChars = script->scriptSource()->chars(cx, holder);
     if (!scriptChars)
         return false;
 
-    const jschar *lazyChars = lazy->source()->chars(cx, holder);
+    const char16_t *lazyChars = lazy->source()->chars(cx, holder);
     if (!lazyChars)
         return false;
 
     size_t begin = script->sourceStart();
     size_t length = script->sourceEnd() - begin;
     return !memcmp(scriptChars + begin, lazyChars + begin, length);
 }
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -336,46 +336,46 @@ typedef HashMap<JSScript *,
                 DefaultHasher<JSScript *>,
                 SystemAllocPolicy> DebugScriptMap;
 
 class ScriptSource;
 
 class UncompressedSourceCache
 {
     typedef HashMap<ScriptSource *,
-                    const jschar *,
+                    const char16_t *,
                     DefaultHasher<ScriptSource *>,
                     SystemAllocPolicy> Map;
 
   public:
     // Hold an entry in the source data cache and prevent it from being purged on GC.
     class AutoHoldEntry
     {
         UncompressedSourceCache *cache_;
         ScriptSource *source_;
-        const jschar *charsToFree_;
+        const char16_t *charsToFree_;
       public:
         explicit AutoHoldEntry();
         ~AutoHoldEntry();
       private:
         void holdEntry(UncompressedSourceCache *cache, ScriptSource *source);
-        void deferDelete(const jschar *chars);
+        void deferDelete(const char16_t *chars);
         ScriptSource *source() const { return source_; }
         friend class UncompressedSourceCache;
     };
 
   private:
     Map *map_;
     AutoHoldEntry *holder_;
 
   public:
     UncompressedSourceCache() : map_(nullptr), holder_(nullptr) {}
 
-    const jschar *lookup(ScriptSource *ss, AutoHoldEntry &asp);
-    bool put(ScriptSource *ss, const jschar *chars, AutoHoldEntry &asp);
+    const char16_t *lookup(ScriptSource *ss, AutoHoldEntry &asp);
+    bool put(ScriptSource *ss, const char16_t *chars, AutoHoldEntry &asp);
 
     void purge();
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
 
   private:
     void holdEntry(AutoHoldEntry &holder, ScriptSource *ss);
     void releaseEntry(AutoHoldEntry &holder);
@@ -396,17 +396,17 @@ class ScriptSource
         DataMissing,
         DataUncompressed,
         DataCompressed,
         DataParent
     } dataType;
 
     union {
         struct {
-            const jschar *chars;
+            const char16_t *chars;
             bool ownsChars;
         } uncompressed;
 
         struct {
             void *raw;
             size_t nbytes;
             HashNumber hash;
         } compressed;
@@ -414,18 +414,18 @@ class ScriptSource
         ScriptSource *parent;
     } data;
 
     uint32_t length_;
 
     // The filename of this script.
     mozilla::UniquePtr<char[], JS::FreePolicy> filename_;
 
-    mozilla::UniquePtr<jschar[], JS::FreePolicy> displayURL_;
-    mozilla::UniquePtr<jschar[], JS::FreePolicy> sourceMapURL_;
+    mozilla::UniquePtr<char16_t[], JS::FreePolicy> displayURL_;
+    mozilla::UniquePtr<char16_t[], JS::FreePolicy> sourceMapURL_;
     JSPrincipals *originPrincipals_;
 
     // bytecode offset in caller script that generated this code.
     // This is present for eval-ed code, as well as "new Function(...)"-introduced
     // scripts.
     uint32_t introductionOffset_;
 
     // If this ScriptSource was generated by a code-introduction mechanism such
@@ -500,23 +500,23 @@ class ScriptSource
     size_t length() const {
         JS_ASSERT(hasSourceData());
         return length_;
     }
     bool argumentsNotIncluded() const {
         JS_ASSERT(hasSourceData());
         return argumentsNotIncluded_;
     }
-    const jschar *chars(JSContext *cx, UncompressedSourceCache::AutoHoldEntry &asp);
+    const char16_t *chars(JSContext *cx, UncompressedSourceCache::AutoHoldEntry &asp);
     JSFlatString *substring(JSContext *cx, uint32_t start, uint32_t stop);
     JSFlatString *substringDontDeflate(JSContext *cx, uint32_t start, uint32_t stop);
     void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
                                 JS::ScriptSourceInfo *info) const;
 
-    const jschar *uncompressedChars() const {
+    const char16_t *uncompressedChars() const {
         JS_ASSERT(dataType == DataUncompressed);
         return data.uncompressed.chars;
     }
 
     bool ownsUncompressedChars() const {
         JS_ASSERT(dataType == DataUncompressed);
         return data.uncompressed.ownsChars;
     }
@@ -536,17 +536,17 @@ class ScriptSource
         return data.compressed.hash;
     }
 
     ScriptSource *parent() const {
         JS_ASSERT(dataType == DataParent);
         return data.parent;
     }
 
-    void setSource(const jschar *chars, size_t length, bool ownsChars = true);
+    void setSource(const char16_t *chars, size_t length, bool ownsChars = true);
     void setCompressedSource(JSRuntime *maybert, void *raw, size_t nbytes, HashNumber hash);
     void updateCompressedSourceSet(JSRuntime *rt);
     bool ensureOwnsSource(ExclusiveContext *cx);
 
     // XDR handling
     template <XDRMode mode>
     bool performXDR(XDRState<mode> *xdr);
 
@@ -561,27 +561,27 @@ class ScriptSource
         JS_ASSERT(hasIntroductionType());
         return introductionType_;
     }
     const char *filename() const {
         return filename_.get();
     }
 
     // Display URLs
-    bool setDisplayURL(ExclusiveContext *cx, const jschar *displayURL);
+    bool setDisplayURL(ExclusiveContext *cx, const char16_t *displayURL);
     bool hasDisplayURL() const { return displayURL_ != nullptr; }
-    const jschar * displayURL() {
+    const char16_t * displayURL() {
         MOZ_ASSERT(hasDisplayURL());
         return displayURL_.get();
     }
 
     // Source maps
-    bool setSourceMapURL(ExclusiveContext *cx, const jschar *sourceMapURL);
+    bool setSourceMapURL(ExclusiveContext *cx, const char16_t *sourceMapURL);
     bool hasSourceMapURL() const { return sourceMapURL_ != nullptr; }
-    const jschar * sourceMapURL() {
+    const char16_t * sourceMapURL() {
         MOZ_ASSERT(hasSourceMapURL());
         return sourceMapURL_.get();
     }
 
     JSPrincipals *originPrincipals() const { return originPrincipals_; }
 
     bool hasIntroductionOffset() const { return hasIntroductionOffset_; }
     uint32_t introductionOffset() const {
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -119,17 +119,17 @@ Escape(JSContext *cx, const CharT *chars
          1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,       /*   PQRSTUVWXYZ[\]^_  */
          0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,       /*   `abcdefghijklmno  */
          1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,       /*   pqrstuvwxyz{\}~  DEL */
     };
 
     /* Take a first pass and see how big the result string will need to be. */
     uint32_t newLength = length;
     for (size_t i = 0; i < length; i++) {
-        jschar ch = chars[i];
+        char16_t ch = chars[i];
         if (ch < 128 && shouldPassThrough[ch])
             continue;
 
         /* The character will be encoded as %XX or %uXXXX. */
         newLength += (ch < 256) ? 2 : 5;
 
         /*
          * newlength is incremented by at most 5 on each iteration, so worst
@@ -142,17 +142,17 @@ Escape(JSContext *cx, const CharT *chars
     Latin1Char *newChars = cx->pod_malloc<Latin1Char>(newLength + 1);
     if (!newChars)
         return nullptr;
 
     static const char digits[] = "0123456789ABCDEF";
 
     size_t i, ni;
     for (i = 0, ni = 0; i < length; i++) {
-        jschar ch = chars[i];
+        char16_t ch = chars[i];
         if (ch < 128 && shouldPassThrough[ch]) {
             newChars[ni++] = ch;
         } else if (ch < 256) {
             newChars[ni++] = '%';
             newChars[ni++] = digits[ch >> 4];
             newChars[ni++] = digits[ch & 0xF];
         } else {
             newChars[ni++] = '%';
@@ -198,36 +198,36 @@ str_escape(JSContext *cx, unsigned argc,
 
     newChars.forget();
     args.rval().setString(res);
     return true;
 }
 
 template <typename CharT>
 static inline bool
-Unhex4(const RangedPtr<const CharT> chars, jschar *result)
+Unhex4(const RangedPtr<const CharT> chars, char16_t *result)
 {
-    jschar a = chars[0],
-           b = chars[1],
-           c = chars[2],
-           d = chars[3];
+    char16_t a = chars[0],
+             b = chars[1],
+             c = chars[2],
+             d = chars[3];
 
     if (!(JS7_ISHEX(a) && JS7_ISHEX(b) && JS7_ISHEX(c) && JS7_ISHEX(d)))
         return false;
 
     *result = (((((JS7_UNHEX(a) << 4) + JS7_UNHEX(b)) << 4) + JS7_UNHEX(c)) << 4) + JS7_UNHEX(d);
     return true;
 }
 
 template <typename CharT>
 static inline bool
-Unhex2(const RangedPtr<const CharT> chars, jschar *result)
+Unhex2(const RangedPtr<const CharT> chars, char16_t *result)
 {
-    jschar a = chars[0],
-           b = chars[1];
+    char16_t a = chars[0],
+             b = chars[1];
 
     if (!(JS7_ISHEX(a) && JS7_ISHEX(b)))
         return false;
 
     *result = (JS7_UNHEX(a) << 4) + JS7_UNHEX(b);
     return true;
 }
 
@@ -249,17 +249,17 @@ Unescape(StringBuffer &sb, const mozilla
 
     /* Step 4. */
     int k = 0;
     bool building = false;
 
     /* Step 5. */
     while (k < length) {
         /* Step 6. */
-        jschar c = chars[k];
+        char16_t c = chars[k];
 
         /* Step 7. */
         if (c != '%')
             goto step_18;
 
         /* Step 8. */
         if (k > length - 6)
             goto step_14;
@@ -696,33 +696,33 @@ ToLowerCase(JSContext *cx, JSLinearStrin
     size_t length = str->length();
     {
         AutoCheckCannotGC nogc;
         const CharT *chars = str->chars<CharT>(nogc);
 
         // Look for the first upper case character.
         size_t i = 0;
         for (; i < length; i++) {
-            jschar c = chars[i];
+            char16_t c = chars[i];
             if (unicode::ToLowerCase(c) != c)
                 break;
         }
 
         // If all characters are lower case, return the input string.
         if (i == length)
             return str;
 
         newChars = cx->make_pod_array<CharT>(length + 1);
         if (!newChars)
             return nullptr;
 
         PodCopy(newChars.get(), chars, i);
 
         for (; i < length; i++) {
-            jschar c = unicode::ToLowerCase(chars[i]);
+            char16_t c = unicode::ToLowerCase(chars[i]);
             MOZ_ASSERT_IF((IsSame<CharT, Latin1Char>::value), c <= JSString::MAX_LATIN1_CHAR);
             newChars[i] = c;