diff --git a/DEPS b/DEPS index 66d21eb3649b..353c5c8b346f 100644 --- a/DEPS +++ b/DEPS @@ -8,7 +8,7 @@ deps = { "http://gyp.googlecode.com/svn/trunk@1831", "v8/third_party/icu": - "https://src.chromium.org/chrome/trunk/deps/third_party/icu46@239289", + "https://src.chromium.org/chrome/trunk/deps/third_party/icu46@258359", } deps_os = { diff --git a/Makefile b/Makefile index 6bd9bac8a854..f3900286cbd3 100644 --- a/Makefile +++ b/Makefile @@ -465,4 +465,4 @@ dependencies: --revision 1831 svn checkout --force \ https://src.chromium.org/chrome/trunk/deps/third_party/icu46 \ - third_party/icu --revision 239289 + third_party/icu --revision 258359 diff --git a/include/v8.h b/include/v8.h index 368748509c7a..6590ed51e953 100644 --- a/include/v8.h +++ b/include/v8.h @@ -4975,8 +4975,11 @@ class V8_EXPORT V8 { /** * Initialize the ICU library bundled with V8. The embedder should only * invoke this method when using the bundled ICU. Returns true on success. + * + * If V8 was compiled with the ICU data in an external file, the location + * of the data file has to be provided. */ - static bool InitializeICU(); + static bool InitializeICU(const char* icu_data_file = NULL); /** * Sets the v8::Platform to use. This should be invoked before V8 is diff --git a/src/api.cc b/src/api.cc index ea2edbce9cbe..f5ae10dbe8d7 100644 --- a/src/api.cc +++ b/src/api.cc @@ -5112,8 +5112,8 @@ int v8::V8::ContextDisposedNotification() { } -bool v8::V8::InitializeICU() { - return i::InitializeICU(); +bool v8::V8::InitializeICU(const char* icu_data_file) { + return i::InitializeICU(icu_data_file); } diff --git a/src/d8.cc b/src/d8.cc index d0711056e1bf..7ac0c6546aae 100644 --- a/src/d8.cc +++ b/src/d8.cc @@ -1440,6 +1440,9 @@ bool Shell::SetOptions(int argc, char* argv[]) { } else if (strcmp(argv[i], "--throws") == 0) { options.expected_to_throw = true; argv[i] = NULL; + } else if (strncmp(argv[i], "--icu-data-file=", 16) == 0) { + options.icu_data_file = argv[i] + 16; + argv[i] = NULL; } #ifdef V8_SHARED else if (strcmp(argv[i], "--dump-counters") == 0) { @@ -1674,7 +1677,7 @@ class MockArrayBufferAllocator : public v8::ArrayBuffer::Allocator { int Shell::Main(int argc, char* argv[]) { if (!SetOptions(argc, argv)) return 1; - v8::V8::InitializeICU(); + v8::V8::InitializeICU(options.icu_data_file); #ifndef V8_SHARED i::FLAG_trace_hydrogen_file = "hydrogen.cfg"; i::FLAG_redirect_code_traces_to = "code.asm"; diff --git a/src/d8.h b/src/d8.h index db2edb93c98e..3edd8a730722 100644 --- a/src/d8.h +++ b/src/d8.h @@ -233,7 +233,8 @@ class ShellOptions { expected_to_throw(false), mock_arraybuffer_allocator(false), num_isolates(1), - isolate_sources(NULL) { } + isolate_sources(NULL), + icu_data_file(NULL) { } ~ShellOptions() { #ifndef V8_SHARED @@ -258,6 +259,7 @@ class ShellOptions { bool mock_arraybuffer_allocator; int num_isolates; SourceGroup* isolate_sources; + const char* icu_data_file; }; #ifdef V8_SHARED diff --git a/src/icu_util.cc b/src/icu_util.cc index b9bd65edc69e..6441dbdd9f5f 100644 --- a/src/icu_util.cc +++ b/src/icu_util.cc @@ -27,12 +27,20 @@ #include "icu_util.h" -#if defined(_WIN32) && defined(V8_I18N_SUPPORT) +#if defined(_WIN32) #include +#endif + +#if defined(V8_I18N_SUPPORT) +#include #include "unicode/putil.h" #include "unicode/udata.h" +#define ICU_UTIL_DATA_FILE 0 +#define ICU_UTIL_DATA_SHARED 1 +#define ICU_UTIL_DATA_STATIC 2 + #define ICU_UTIL_DATA_SYMBOL "icudt" U_ICU_VERSION_SHORT "_dat" #define ICU_UTIL_DATA_SHARED_MODULE_NAME "icudt.dll" #endif @@ -41,8 +49,11 @@ namespace v8 { namespace internal { -bool InitializeICU() { -#if defined(_WIN32) && defined(V8_I18N_SUPPORT) +bool InitializeICU(const char* icu_data_file) { +#if !defined(V8_I18N_SUPPORT) + return true; +#else +#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_SHARED // We expect to find the ICU data module alongside the current module. HMODULE module = LoadLibraryA(ICU_UTIL_DATA_SHARED_MODULE_NAME); if (!module) return false; @@ -53,9 +64,30 @@ bool InitializeICU() { UErrorCode err = U_ZERO_ERROR; udata_setCommonData(reinterpret_cast(addr), &err); return err == U_ZERO_ERROR; -#else +#elif ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_STATIC // Mac/Linux bundle the ICU data in. return true; +#elif ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE + if (!icu_data_file) return false; + + FILE* inf = fopen(icu_data_file, "rb"); + if (!inf) return false; + + fseek(inf, 0, SEEK_END); + size_t size = ftell(inf); + rewind(inf); + + char* addr = new char[size]; + if (fread(addr, 1, size, inf) != size) { + delete[] addr; + fclose(inf); + return false; + } + fclose(inf); + UErrorCode err = U_ZERO_ERROR; + udata_setCommonData(reinterpret_cast(addr), &err); + return err == U_ZERO_ERROR; +#endif #endif } diff --git a/src/icu_util.h b/src/icu_util.h index 478abce508cc..6b50c185c513 100644 --- a/src/icu_util.h +++ b/src/icu_util.h @@ -35,7 +35,7 @@ namespace internal { // Call this function to load ICU's data tables for the current process. This // function should be called before ICU is used. -bool InitializeICU(); +bool InitializeICU(const char* icu_data_file); } } // namespace v8::internal diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp index be2dfd32a76a..52143e9e066d 100644 --- a/tools/gyp/v8.gyp +++ b/tools/gyp/v8.gyp @@ -27,6 +27,7 @@ { 'variables': { + 'icu_use_data_file_flag%': 0, 'v8_code': 1, 'v8_random_seed%': 314159265, }, @@ -1020,6 +1021,17 @@ '../../src/default-platform.h', ], }], + ['icu_use_data_file_flag==1', { + 'defines': ['ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE'], + }, { # else icu_use_data_file_flag !=1 + 'conditions': [ + ['OS=="win"', { + 'defines': ['ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_SHARED'], + }, { + 'defines': ['ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC'], + }], + ], + }], ], }, {