Преглед изворни кода

[MERGE #5011 @jackhorton] Only pre-initialize ICU when using Windows Kit ICU

Merge pull request #5011 from jackhorton:icu/init-windows-kit

Third attempt at this after #4984 and #5001, but I have actually confirmed that this makes Node-ChakraCore's chakracore-master branch build, launch, and run Intl code successfully once more. This definitely isn't the best solution, however if we refer to https://github.com/nodejs/node-chakracore/blob/d94b22785fb6ab7dde77cb13b7e95e958e581375/src/node_i18n.cc#L568-L581, we can see that Node somewhat explicitly also does not call u_init if they call udata_setCommonData.
Jack Horton (CHAKRA) пре 7 година
родитељ
комит
07dcb9a235

+ 13 - 6
lib/Runtime/Library/IntlEngineInterfaceExtensionObject.cpp

@@ -503,22 +503,29 @@ namespace Js
 #else
         library->AddMember(intlNativeInterfaces, Js::PropertyIds::winglob, library->GetFalse());
 
-        // when using ICU, we need to call u_init to ensure that ICU is functioning properly before allowing Intl to continue.
-        // u_init will cause the data file to be loaded, and if we don't have enough memory to do so, we can throw OutOfMemory here.
+        // when using ICU, we can call ulocdata_getCLDRVersion to ensure that ICU is functioning properly before allowing Intl to continue.
+        // ulocdata_getCLDRVersion will cause the data file to be loaded, and if we don't have enough memory to do so, we can throw OutOfMemory here.
         // This is to protect against spurious U_MISSING_RESOURCE_ERRORs and U_FILE_ACCESS_ERRORs coming from early-lifecycle
         // functions that require ICU data.
         // See OS#16897150, OS#16896933, and others relating to bad statuses returned by GetLocaleData and IsLocaleAvailable
+        // This was initially attempted using u_init, however u_init does not work with Node's default small-icu data file
+        // because it contains no converters.
         UErrorCode status = U_ZERO_ERROR;
-        u_init(&status);
+        UVersionInfo cldrVersion;
+        ulocdata_getCLDRVersion(cldrVersion, &status);
         if (status == U_MEMORY_ALLOCATION_ERROR || status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR)
         {
             // Trace that this happens in case there are build system changes that actually cause the data file to be not found
-            INTL_TRACE("Could not initialize ICU - u_init returned status %S", u_errorName(status));
+            INTL_TRACE("Could not initialize ICU - ulocdata_getCLDRVersion returned status %S", u_errorName(status));
             Throw::OutOfMemory();
         }
+        else
+        {
+            INTL_TRACE("Using CLDR version %d.%d.%d.%d", cldrVersion[0], cldrVersion[1], cldrVersion[2], cldrVersion[3]);
+        }
 
-        AssertOrFailFastMsg(U_SUCCESS(status), "u_init returned non-OOM failure");
-#endif
+        AssertOrFailFastMsg(U_SUCCESS(status), "ulocdata_getCLDRVersion returned non-OOM failure");
+#endif // else !INTL_WINGLOB
 
         intlNativeInterfaces->SetHasNoEnumerableProperties(true);
 

+ 1 - 0
lib/Runtime/PlatformAgnostic/ChakraICU.h

@@ -22,6 +22,7 @@
 #include "unicode/udat.h"
 #include "unicode/udatpg.h"
 #include "unicode/uloc.h"
+#include "unicode/ulocdata.h"
 #include "unicode/unumsys.h"
 #include "unicode/ustring.h"
 #include "unicode/unorm2.h"