bug 926980 - load ICU data from an archive file. r?glandium,waldo draft
authorTed Mielczarek <ted@mielczarek.org>
Thu, 14 Jan 2016 11:05:27 -0500
changeset 330331 d7bf237841e0fb7d0af4d948c6090e96e101833b
parent 330328 aaa941ff6a994fa73bc6fd128f4885512dac0403
child 514150 59996fd8dab2de8815cdfc52c4b054c9b12e969f
push id10732
push usertmielczarek@mozilla.com
push dateThu, 11 Feb 2016 13:34:58 +0000
reviewersglandium, waldo
bugs926980
milestone47.0a1
bug 926980 - load ICU data from an archive file. r?glandium,waldo MozReview-Commit-ID: 3M0UhN2CPhI
b2g/installer/Makefile.in
b2g/installer/package-manifest.in
browser/installer/Makefile.in
browser/installer/package-manifest.in
build/autoconf/icu.m4
config/check_spidermonkey_style.py
config/external/icu/Makefile.in
config/external/icu/moz.build
intl/update-icu.sh
js/src/jsapi-tests/moz.build
js/src/jsapi-tests/tests.cpp
js/src/shell/js.cpp
js/src/shell/moz.build
js/src/tests/lib/jittests.py
toolkit/mozapps/installer/upload-files.mk
xpcom/build/XPCOMInit.cpp
xpcom/build/moz.build
--- a/b2g/installer/Makefile.in
+++ b/b2g/installer/Makefile.in
@@ -101,16 +101,17 @@ endif
 DEFINES += -DMOZ_ICU_VERSION=$(MOZ_ICU_VERSION)
 ifdef MOZ_SYSTEM_ICU
 DEFINES += -DMOZ_SYSTEM_ICU
 endif
 ifdef MOZ_SHARED_ICU
 DEFINES += -DMOZ_SHARED_ICU
 endif
 DEFINES += -DMOZ_ICU_DBG_SUFFIX=$(MOZ_ICU_DBG_SUFFIX)
+DEFINES += -DICU_DATA_FILE=$(ICU_DATA_FILE)
 
 ifdef MOZ_WIDGET_GTK
 DEFINES += -DMOZ_GTK=1
 ifdef MOZ_ENABLE_GTK3
 DEFINES += -DMOZ_GTK3=1
 endif
 endif
 
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -67,16 +67,17 @@
 @BINPATH@/@MSVC_CXX_RUNTIME_DLL@
 #endif
 #if MOZ_PACKAGE_WIN_UCRT_DLLS
 @BINPATH@/api-ms-win-*.dll
 @BINPATH@/ucrtbase.dll
 #endif
 #endif
 #ifndef MOZ_SYSTEM_ICU
+@RESPATH@/@ICU_DATA_FILE@
 #ifdef MOZ_SHARED_ICU
 #ifdef XP_WIN
 @BINPATH@/icudt@MOZ_ICU_DBG_SUFFIX@@MOZ_ICU_VERSION@.dll
 @BINPATH@/icuin@MOZ_ICU_DBG_SUFFIX@@MOZ_ICU_VERSION@.dll
 @BINPATH@/icuuc@MOZ_ICU_DBG_SUFFIX@@MOZ_ICU_VERSION@.dll
 #elif defined(XP_MACOSX)
 @BINPATH@/libicudata.@MOZ_ICU_VERSION@.dylib
 @BINPATH@/libicui18n.@MOZ_ICU_VERSION@.dylib
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -120,16 +120,17 @@ DEFINES += -DLPROJ_ROOT=$(LPROJ_ROOT)
 DEFINES += -DMOZ_ICU_VERSION=$(MOZ_ICU_VERSION)
 ifdef MOZ_SYSTEM_ICU
 DEFINES += -DMOZ_SYSTEM_ICU
 endif
 ifdef MOZ_SHARED_ICU
 DEFINES += -DMOZ_SHARED_ICU
 endif
 DEFINES += -DMOZ_ICU_DBG_SUFFIX=$(MOZ_ICU_DBG_SUFFIX)
+DEFINES += -DICU_DATA_FILE=$(ICU_DATA_FILE)
 ifdef CLANG_CXX
 DEFINES += -DCLANG_CXX
 endif
 ifdef CLANG_CL
 DEFINES += -DCLANG_CL
 endif
 ifeq (x86,$(CPU_ARCH))
 ifdef _MSC_VER
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -93,16 +93,17 @@
 @BINPATH@/@MSVC_CXX_RUNTIME_DLL@
 #endif
 #if MOZ_PACKAGE_WIN_UCRT_DLLS
 @BINPATH@/api-ms-win-*.dll
 @BINPATH@/ucrtbase.dll
 #endif
 #endif
 #ifndef MOZ_SYSTEM_ICU
+@RESPATH@/@ICU_DATA_FILE@
 #ifdef MOZ_SHARED_ICU
 #ifdef XP_WIN
 @BINPATH@/icudt@MOZ_ICU_DBG_SUFFIX@@MOZ_ICU_VERSION@.dll
 @BINPATH@/icuin@MOZ_ICU_DBG_SUFFIX@@MOZ_ICU_VERSION@.dll
 @BINPATH@/icuuc@MOZ_ICU_DBG_SUFFIX@@MOZ_ICU_VERSION@.dll
 #elif defined(XP_MACOSX)
 @BINPATH@/libicudata.@MOZ_ICU_VERSION@.dylib
 @BINPATH@/libicui18n.@MOZ_ICU_VERSION@.dylib
--- a/build/autoconf/icu.m4
+++ b/build/autoconf/icu.m4
@@ -88,35 +88,52 @@ if test -n "$USE_ICU"; then
     fi
 
     AC_SUBST(MOZ_ICU_VERSION)
     AC_SUBST(MOZ_SHARED_ICU)
 
     if test -z "$MOZ_SYSTEM_ICU"; then
         case "$OS_TARGET" in
             WINNT)
-                ICU_LIB_NAMES="icuin icuuc icudt"
+                ICU_LIB_NAMES="icuin icuuc"
+                ICU_DATA_LIB=icudt
                 MOZ_ICU_DBG_SUFFIX=
                 if test -n "$MOZ_DEBUG" -a -z "$MOZ_NO_DEBUG_RTL"; then
                     MOZ_ICU_DBG_SUFFIX=d
                 fi
                 ;;
             Darwin|Linux|DragonFly|FreeBSD|NetBSD|OpenBSD|GNU/kFreeBSD|SunOS|Android)
-                ICU_LIB_NAMES="icui18n icuuc icudata"
+                ICU_LIB_NAMES="icui18n icuuc"
+                ICU_DATA_LIB=icudata
                 ;;
             *)
                 AC_MSG_ERROR([ECMAScript Internationalization API is not yet supported on this platform])
         esac
+
+        dnl We won't build ICU data as a separate file when building
+        dnl JS standalone so that embeddors don't have to deal with it.
+        if test -z "$JS_STANDALONE"; then
+            MOZ_ICU_DATA_ARCHIVE=1
+            #TODO: the l is actually endian-dependent
+            ICU_DATA_FILE="icudt${version}l.dat"
+            AC_DEFINE(MOZ_ICU_DATA_ARCHIVE)
+        else
+            # In this case we won't link to the stubdata library.
+            ICU_LIB_NAMES="$ICU_LIB_NAMES $ICU_DATA_LIB"
+        fi
     fi
 fi
 
 AC_SUBST(MOZ_ICU_DBG_SUFFIX)
 AC_SUBST(ENABLE_INTL_API)
 AC_SUBST(USE_ICU)
 AC_SUBST_LIST(ICU_LIB_NAMES)
+AC_SUBST(ICU_DATA_LIB)
+AC_SUBST(ICU_DATA_FILE)
+AC_SUBST(MOZ_ICU_DATA_ARCHIVE)
 
 if test -n "$USE_ICU" -a -z "$MOZ_SYSTEM_ICU"; then
     dnl We build ICU as a static library for non-shared js builds and as a shared library for shared js builds.
     if test -z "$MOZ_SHARED_ICU"; then
         AC_DEFINE(U_STATIC_IMPLEMENTATION)
     fi
     dnl Source files that use ICU should have control over which parts of the ICU
     dnl namespace they want to use.
@@ -163,16 +180,19 @@ if test -z "$BUILDING_JS" -o -n "$JS_STA
             elif test "$_MSC_VER"; then
                 HOST_ICU_CXXFLAGS=`echo $HOST_ICU_CXXFLAGS | sed 's|-GR-|-GR|g'`
             fi
 
             HOST_ICU_BUILD_OPTS=""
             if test -n "$MOZ_DEBUG"; then
                 HOST_ICU_BUILD_OPTS="$HOST_ICU_BUILD_OPTS --enable-debug"
             fi
+            if test -n "$MOZ_ICU_DATA_ARCHIVE"; then
+                HOST_ICU_BUILD_OPTS="$HOST_ICU_BUILD_OPTS --with-data-packaging=archive"
+            fi
 
             abs_srcdir=`(cd $srcdir; pwd)`
             mkdir -p $_objdir/intl/icu/host
             (export AR="$HOST_AR"
              export RANLIB="$HOST_RANLIB"
              export CC="$HOST_CC"
              export CXX="$HOST_CXX"
              export CPP="$HOST_CPP"
@@ -235,16 +255,19 @@ if test -z "$BUILDING_JS" -o -n "$JS_STA
             fi
         fi
         if test -z "$MOZ_OPTIMIZE"; then
             ICU_BUILD_OPTS="$ICU_BUILD_OPTS --disable-release"
         else
             ICU_CFLAGS="$ICU_CFLAGS $MOZ_OPTIMIZE_FLAGS"
             ICU_CXXFLAGS="$ICU_CXXFLAGS $MOZ_OPTIMIZE_FLAGS"
         fi
+        if test -n "$MOZ_ICU_DATA_ARCHIVE"; then
+            ICU_BUILD_OPTS="$ICU_BUILD_OPTS --with-data-packaging=archive"
+        fi
 
         if test "$am_cv_langinfo_codeset" = "no"; then
             # ex. Android
             ICU_CPPFLAGS="$ICU_CPPFLAGS -DU_HAVE_NL_LANGINFO_CODESET=0"
         fi
 
         # ICU requires RTTI
         if test "$GNU_CC"; then
--- a/config/check_spidermonkey_style.py
+++ b/config/check_spidermonkey_style.py
@@ -74,16 +74,17 @@ included_inclnames_to_ignore = set([
     'prlock.h',                 # NSPR
     'prprf.h',                  # NSPR
     'prthread.h',               # NSPR
     'prtypes.h',                # NSPR
     'selfhosted.out.h',         # generated in $OBJDIR
     'shellmoduleloader.out.h',  # generated in $OBJDIR
     'unicode/locid.h',          # ICU
     'unicode/numsys.h',         # ICU
+    'unicode/putil.h',          # ICU
     'unicode/timezone.h',       # ICU
     'unicode/ucal.h',           # ICU
     'unicode/uclean.h',         # ICU
     'unicode/ucol.h',           # ICU
     'unicode/udat.h',           # ICU
     'unicode/udatpg.h',         # ICU
     'unicode/uenum.h',          # ICU
     'unicode/unorm.h',          # ICU
--- a/config/external/icu/Makefile.in
+++ b/config/external/icu/Makefile.in
@@ -5,42 +5,56 @@
 # Ensure that this happens before including rules.mk
 ifdef USE_ICU
   ifndef MOZ_SYSTEM_ICU
   # Library names: On Windows, ICU uses modified library names for static
   # and debug libraries.
     ifdef MOZ_SHARED_ICU
       ifeq ($(OS_ARCH),WINNT)
         ICU_FILES := $(foreach libname,$(ICU_LIB_NAMES),$(DEPTH)/intl/icu/target/lib/$(libname)$(MOZ_ICU_DBG_SUFFIX)$(MOZ_ICU_VERSION).dll)
+        ifdef MOZ_ICU_DATA_ARCHIVE
+          ICU_FILES += $(DEPTH)/intl/icu/target/stubdata/$(ICU_DATA_LIB)$(MOZ_ICU_DBG_SUFFIX)$(MOZ_ICU_VERSION).dll
+        endif
       else # ! WINNT
         ifeq ($(OS_ARCH),Darwin)
           ICU_FILES := $(foreach libname,$(ICU_LIB_NAMES),$(DEPTH)/intl/icu/target/lib/$(DLL_PREFIX)$(libname).$(MOZ_ICU_VERSION)$(DLL_SUFFIX))
+          ifdef MOZ_ICU_DATA_ARCHIVE
+            ICU_FILES += $(DEPTH)/intl/icu/target/stubdata/$(DLL_PREFIX)$(ICU_DATA_LIB).$(MOZ_ICU_VERSION)$(DLL_SUFFIX)
+          endif
         else # ! Darwin
           ICU_FILES := $(foreach libname,$(ICU_LIB_NAMES),$(DEPTH)/intl/icu/target/lib/$(DLL_PREFIX)$(libname)$(DLL_SUFFIX).$(MOZ_ICU_VERSION))
+          ifdef MOZ_ICU_DATA_ARCHIVE
+            ICU_FILES += $(DEPTH)/intl/icu/target/stubdata/$(DLL_PREFIX)$(ICU_DATA_LIB)$(DLL_SUFFIX).$(MOZ_ICU_VERSION)
+          endif
         endif
       endif # WINNT
-      ifdef ICU_FILES
-        ICU_DEST := $(DIST)/bin
-        INSTALL_TARGETS += ICU
-        $(ICU_FILES): buildicu
-        ICU_TARGET := target
-      endif
     else # !MOZ_SHARED_ICU
       ifeq ($(OS_ARCH),WINNT)
-        ICU_LIB_RENAME = $(foreach libname,$(ICU_LIB_NAMES),\
-                             cp -p $(DEPTH)/intl/icu/target/lib/s$(libname)$(MOZ_ICU_DBG_SUFFIX).lib $(DEPTH)/intl/icu/target/lib/$(libname)$(MOZ_ICU_DBG_SUFFIX).lib;)
+        $(error Windows non-shared-ICU is not currently supported)
       endif
     endif # MOZ_SHARED_ICU
+
+  ifdef MOZ_ICU_DATA_ARCHIVE
+    ICU_FILES += $(DEPTH)/intl/icu/target/data/out/$(ICU_DATA_FILE)
+  endif
+  ifdef ICU_FILES
+    ICU_DEST := $(DIST)/bin
+    INSTALL_TARGETS += ICU
+    $(ICU_FILES): buildicu
+   ICU_TARGET := target
+  endif
+
   endif # !MOZ_SYSTEM_ICU
 endif # USE_ICU
 
 include $(topsrcdir)/config/rules.mk
 
 ifdef USE_ICU
 ifndef MOZ_SYSTEM_ICU
+
 target:: buildicu
 $(STATIC_LIBS): buildicu
 
 # - Force ICU to use the standard suffix for object files because expandlibs
 #   will discard all files with a non-standard suffix (bug 857450).
 # - Options for genrb: -k strict parsing; -R omit collation tailoring rules.
 buildicu::
 # ICU's build system is full of races, so force non-parallel build.
--- a/config/external/icu/moz.build
+++ b/config/external/icu/moz.build
@@ -11,16 +11,23 @@ if CONFIG['MOZ_SYSTEM_ICU']:
 else:
     # Order needs to be preserved
     for l in CONFIG['ICU_LIB_NAMES']:
         USE_LIBS += ['%s/intl/icu/target/lib/%s%s' % (
             'static:' if not CONFIG['MOZ_SHARED_ICU'] else '',
             l,
             CONFIG['MOZ_ICU_DBG_SUFFIX']
         )]
+    if CONFIG['MOZ_ICU_DATA_ARCHIVE']:
+        # Link the stubdata lib as well.
+        USE_LIBS += ['%s/intl/icu/target/stubdata/%s%s' % (
+            'static:' if not CONFIG['MOZ_SHARED_ICU'] else '',
+            CONFIG['ICU_DATA_LIB'],
+            CONFIG['MOZ_ICU_DBG_SUFFIX']
+        )]
 
     if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
         OS_LIBS += [
             'gabi++',
         ]
     if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android' and CONFIG['MOZ_ANDROID_CXX_STL'] == 'mozstlport':
         USE_LIBS += [
             'gabi++'
--- a/intl/update-icu.sh
+++ b/intl/update-icu.sh
@@ -58,10 +58,13 @@ patch -d ${icu_dir}/../../ -p1 < ${icu_d
 patch -d ${icu_dir}/../../ -p1 < ${icu_dir}/../icu-patches/bug-1172609-timezone-recreateDefault.diff
 patch -d ${icu_dir}/../../ -p1 < ${icu_dir}/../icu-patches/bug-1198952-workaround-make-3.82-bug.diff
 patch -d ${icu_dir}/../../ -p1 < ${icu_dir}/../icu-patches/icu-release-56-1-flagparser-fix.patch
 patch -d ${icu_dir}/../../ -p1 < ${icu_dir}/../icu-patches/bug-1228227-libc++-gcc_hidden.diff
 
 # NOTE: If you're updating this script for a new ICU version, you have to rerun
 # js/src/tests/ecma_6/String/make-normalize-generateddata-input.py for any
 # normalization changes the new ICU implements.
+#
+# You must also edit js/src/tests/lib/jittests.py `push_libs` to make the
+# version number of icudtNNl.dat match the current ICU version.
 
 hg addremove ${icu_dir}
--- a/js/src/jsapi-tests/moz.build
+++ b/js/src/jsapi-tests/moz.build
@@ -111,13 +111,20 @@ if CONFIG['ENABLE_ION']:
 
 DEFINES['EXPORT_JS_API'] = True
 
 LOCAL_INCLUDES += [
     '!..',
     '..',
 ]
 
+CFLAGS += CONFIG['MOZ_ICU_CFLAGS']
+CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
+LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
+
 USE_LIBS += [
     'static:js',
 ]
 
 OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
+
+if CONFIG['OS_TARGET'] == 'WINNT':
+    OS_LIBS += ['shlwapi']
--- a/js/src/jsapi-tests/tests.cpp
+++ b/js/src/jsapi-tests/tests.cpp
@@ -2,20 +2,30 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsapi-tests/tests.h"
 
 #include <stdio.h>
+#include <string>
+#ifdef XP_WIN
+# include <shlwapi.h>
+#else
+# include <libgen.h>
+#endif
 
 #include "js/Initialization.h"
 #include "js/RootingAPI.h"
 
+#if EXPOSE_INTL_API
+# include "unicode/putil.h"
+#endif
+
 JSAPITest* JSAPITest::list;
 
 bool JSAPITest::init()
 {
     rt = createRuntime();
     if (!rt)
         return false;
     cx = createContext();
@@ -97,16 +107,27 @@ JSObject* JSAPITest::createGlobal(JSPrin
 }
 
 int main(int argc, char* argv[])
 {
     int total = 0;
     int failures = 0;
     const char* filter = (argc == 2) ? argv[1] : nullptr;
 
+#if EXPOSE_INTL_API && defined(MOZ_ICU_DATA_ARCHIVE)
+    std::string binpath = argv[0];
+#if defined(XP_WIN)
+    char* bindir = &binpath[0];
+    PathRemoveFileSpecA(bindir);
+#else
+    char* bindir = dirname(&binpath[0]);
+#endif
+    u_setDataDirectory(bindir);
+#endif
+
     if (!JS_Init()) {
         printf("TEST-UNEXPECTED-FAIL | jsapi-tests | JS_Init() failed.\n");
         return 1;
     }
 
     for (JSAPITest* test = JSAPITest::list; test; test = test->next) {
         const char* name = test->name();
         if (filter && strstr(name, filter) == nullptr)
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -17,25 +17,31 @@
 #ifdef XP_WIN
 # include <direct.h>
 # include <process.h>
 #endif
 #include <errno.h>
 #include <fcntl.h>
 #if defined(XP_WIN)
 # include <io.h>     /* for isatty() */
+#else
+# include <libgen.h>
 #endif
 #include <locale.h>
 #if defined(MALLOC_H)
 # include MALLOC_H    /* for malloc_usable_size, malloc_size, _msize */
 #endif
 #include <math.h>
+#ifdef XP_WIN
+# include <shlwapi.h>
+#endif
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string>
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #ifdef XP_UNIX
 # include <sys/mman.h>
 # include <sys/stat.h>
 # include <sys/wait.h>
 # include <unistd.h>
@@ -85,16 +91,20 @@
 #include "vm/StringBuffer.h"
 #include "vm/Time.h"
 #include "vm/TypedArrayObject.h"
 #include "vm/WrapperObject.h"
 
 #include "jscompartmentinlines.h"
 #include "jsobjinlines.h"
 
+#if EXPOSE_INTL_API
+#include "unicode/putil.h"
+#endif
+
 #include "vm/ErrorObject-inl.h"
 #include "vm/Interpreter-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace js;
 using namespace js::cli;
 using namespace js::shell;
 
@@ -6968,16 +6978,27 @@ main(int argc, char** argv, char** envp)
         js::jit::CPUInfo::SetAVXEnabled();
         PropagateFlagToNestedShells("--enable-avx");
     }
 #endif
 
     if (op.getBoolOption("no-threads"))
         js::DisableExtraThreads();
 
+#if EXPOSE_INTL_API && defined(MOZ_ICU_DATA_ARCHIVE)
+    std::string binpath = sArgv[0];
+#if defined(XP_WIN)
+    char* bindir = &binpath[0];
+    PathRemoveFileSpecA(bindir);
+#else
+    char* bindir = dirname(&binpath[0]);
+#endif
+    u_setDataDirectory(bindir);
+#endif
+
     // Start the engine.
     if (!JS_Init())
         return 1;
 
     if (!InitSharedArrayBufferMailbox())
         return 1;
 
     // The fake thread count must be set before initializing the Runtime,
--- a/js/src/shell/moz.build
+++ b/js/src/shell/moz.build
@@ -30,16 +30,23 @@ if CONFIG['_MSC_VER']:
 LOCAL_INCLUDES += [
     '!..',
     '..',
 ]
 
 OS_LIBS += CONFIG['EDITLINE_LIBS']
 OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
 
+if CONFIG['OS_TARGET'] == 'WINNT':
+    OS_LIBS += ['shlwapi']
+
+CFLAGS += CONFIG['MOZ_ICU_CFLAGS']
+CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
+LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
+
 # Prepare module loader JS code for embedding
 GENERATED_FILES += ['shellmoduleloader.out.h']
 shellmoduleloader = GENERATED_FILES['shellmoduleloader.out.h']
 shellmoduleloader.script = '../builtin/embedjs.py:generate_shellmoduleloader'
 shellmoduleloader.inputs = [
     '../js.msg',
     'ModuleLoader.js',
 ]
--- a/js/src/tests/lib/jittests.py
+++ b/js/src/tests/lib/jittests.py
@@ -579,17 +579,17 @@ def get_remote_results(tests, device, pr
         # state where all further tests will fail so there is no point in
         # continuing here.
         sys.stderr.write("Error running remote tests: {}".format(e.message))
 
 def push_libs(options, device):
     # This saves considerable time in pushing unnecessary libraries
     # to the device but needs to be updated if the dependencies change.
     required_libs = ['libnss3.so', 'libmozglue.so', 'libnspr4.so',
-                     'libplc4.so', 'libplds4.so']
+                     'libplc4.so', 'libplds4.so', 'icudt56l.dat']
 
     for file in os.listdir(options.local_lib):
         if file in required_libs:
             remote_file = posixpath.join(options.remote_test_root, file)
             device.pushFile(os.path.join(options.local_lib, file), remote_file)
 
 def push_progs(options, device, progs):
     for local_file in progs:
--- a/toolkit/mozapps/installer/upload-files.mk
+++ b/toolkit/mozapps/installer/upload-files.mk
@@ -80,16 +80,18 @@ JSSHELL_BINS += $(DLL_PREFIX)nss3$(DLL_S
 else
 JSSHELL_BINS += \
   $(DLL_PREFIX)nspr4$(DLL_SUFFIX) \
   $(DLL_PREFIX)plds4$(DLL_SUFFIX) \
   $(DLL_PREFIX)plc4$(DLL_SUFFIX) \
   $(NULL)
 endif # MOZ_FOLD_LIBS
 endif # MOZ_SYSTEM_NSPR
+ifdef USE_ICU
+JSSHELL_BINS += $(ICU_DATA_FILE)
 ifdef MOZ_SHARED_ICU
 ifeq ($(OS_TARGET), WINNT)
 JSSHELL_BINS += \
   icudt$(MOZ_ICU_DBG_SUFFIX)$(MOZ_ICU_VERSION).dll \
   icuin$(MOZ_ICU_DBG_SUFFIX)$(MOZ_ICU_VERSION).dll \
   icuuc$(MOZ_ICU_DBG_SUFFIX)$(MOZ_ICU_VERSION).dll \
   $(NULL)
 else
@@ -102,17 +104,18 @@ JSSHELL_BINS += \
 else
 JSSHELL_BINS += \
   libicudata.so.$(MOZ_ICU_VERSION) \
   libicui18n.so.$(MOZ_ICU_VERSION) \
   libicuuc.so.$(MOZ_ICU_VERSION) \
   $(NULL)
 endif # Darwin
 endif # WINNT
-endif # MOZ_STATIC_JS
+endif # MOZ_SHARED_ICU
+endif # USE_ICU
 MAKE_JSSHELL  = $(call py_action,zip,-C $(DIST)/bin $(abspath $(PKG_JSSHELL)) $(JSSHELL_BINS))
 
 JARLOG_DIR = $(topobjdir)/jarlog/
 JARLOG_FILE_AB_CD = $(JARLOG_DIR)/$(AB_CD).log
 
 TAR_CREATE_FLAGS := --exclude=.mkdir.done $(TAR_CREATE_FLAGS)
 CREATE_FINAL_TAR = $(TAR) -c --owner=0 --group=0 --numeric-owner \
   --mode=go-w --exclude=.mkdir.done -f
--- a/xpcom/build/XPCOMInit.cpp
+++ b/xpcom/build/XPCOMInit.cpp
@@ -154,16 +154,20 @@ extern nsresult nsStringInputStreamConst
 
 #include "GeckoProfiler.h"
 
 #include "jsapi.h"
 #include "js/Initialization.h"
 
 #include "gfxPlatform.h"
 
+#if EXPOSE_INTL_API
+#include "unicode/putil.h"
+#endif
+
 using namespace mozilla;
 using base::AtExitManager;
 using mozilla::ipc::BrowserProcessSubThread;
 
 namespace {
 
 static AtExitManager* sExitManager;
 static MessageLoop* sMessageLoop;
@@ -683,16 +687,27 @@ NS_InitXPCOM2(nsIServiceManager** aResul
 #ifdef MOZ_WEBM
   // And for libnestegg.
   // libnestegg expects that its realloc implementation will free
   // the pointer argument when a size of 0 is passed in, so we need
   // the special version of the counting realloc.
   nestegg_set_halloc_func(NesteggReporter::CountingFreeingRealloc);
 #endif
 
+#if EXPOSE_INTL_API && defined(MOZ_ICU_DATA_ARCHIVE)
+  nsCOMPtr<nsIFile> greDir;
+  nsDirectoryService::gService->Get(NS_GRE_DIR,
+                                    NS_GET_IID(nsIFile),
+                                    getter_AddRefs(greDir));
+  MOZ_ASSERT(greDir);
+  nsAutoCString nativeGREPath;
+  greDir->GetNativePath(nativeGREPath);
+  u_setDataDirectory(nativeGREPath.get());
+#endif
+
   // Initialize the JS engine.
   if (!JS_Init()) {
     NS_RUNTIMEABORT("JS_Init failed");
   }
 
   rv = nsComponentManagerImpl::gComponentManager->Init();
   if (NS_FAILED(rv)) {
     NS_RELEASE(nsComponentManagerImpl::gComponentManager);
--- a/xpcom/build/moz.build
+++ b/xpcom/build/moz.build
@@ -95,8 +95,11 @@ LOCAL_INCLUDES += [
 
 if CONFIG['MOZ_VPX']:
     LOCAL_INCLUDES += [
         '/media/libvpx',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     CXXFLAGS += CONFIG['TK_CFLAGS']
+
+CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
+LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']