Revert "[Intl] Replace uloc_(to|for)Language w/ Locale API"

This reverts commit 7b744e3ae85f4725e343b97fefc9536444232b43.

Reason for revert: Break V8 Linux64 ASAN

Original change's description:
> [Intl] Replace uloc_(to|for)Language w/ Locale API
> 
> Bug: v8:8468
> Change-Id: Id2f8d165e5f29f429821b44def2512fe760c0a51
> Reviewed-on: https://chromium-review.googlesource.com/c/1377989
> Reviewed-by: Jungshik Shin <jshin@chromium.org>
> Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
> Commit-Queue: Frank Tang <ftang@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#58260}

TBR=jshin@chromium.org,gsathya@chromium.org,ftang@chromium.org

Change-Id: I5d6069245f468f7ca5d99f2973bd53524e2d4782
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:8468
Reviewed-on: https://chromium-review.googlesource.com/c/1378657
Reviewed-by: Frank Tang <ftang@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58261}
diff --git a/src/objects/intl-objects.cc b/src/objects/intl-objects.cc
index 0d9dece..459027a 100644
--- a/src/objects/intl-objects.cc
+++ b/src/objects/intl-objects.cc
@@ -407,9 +407,21 @@
 
   // Convert BCP47 into ICU locale format.
   UErrorCode status = U_ZERO_ERROR;
+  char icu_result[ULOC_FULLNAME_CAPACITY];
+  int parsed_length = 0;
 
-  icu::Locale icu_locale = icu::Locale::forLanguageTag(bcp47_locale, status);
+  // bcp47_locale_str should be a canonicalized language tag, which
+  // means this shouldn't fail.
+  uloc_forLanguageTag(bcp47_locale.c_str(), icu_result, ULOC_FULLNAME_CAPACITY,
+                      &parsed_length, &status);
   CHECK(U_SUCCESS(status));
+
+  // bcp47_locale is already checked for its structural validity
+  // so that it should be parsed completely.
+  size_t bcp47_length = bcp47_locale.length();
+  CHECK_EQ(bcp47_length, parsed_length);
+
+  icu::Locale icu_locale(icu_result);
   if (icu_locale.isBogus()) {
     FATAL("Failed to create ICU locale, are ICU data files missing?");
   }
diff --git a/src/objects/js-date-time-format.cc b/src/objects/js-date-time-format.cc
index 3b3de12..2453e4a 100644
--- a/src/objects/js-date-time-format.cc
+++ b/src/objects/js-date-time-format.cc
@@ -282,9 +282,14 @@
 
   Handle<Object> resolved_obj;
 
-  icu::Locale icu_locale = *(date_time_format->icu_locale()->raw());
-  Handle<String> locale = factory->NewStringFromAsciiChecked(
-      Intl::ToLanguageTag(icu_locale).c_str());
+  CHECK_NOT_NULL(date_time_format->icu_locale());
+  CHECK_NOT_NULL(date_time_format->icu_locale()->raw());
+  UErrorCode status = U_ZERO_ERROR;
+  char language[ULOC_FULLNAME_CAPACITY];
+  uloc_toLanguageTag(date_time_format->icu_locale()->raw()->getName(), language,
+                     ULOC_FULLNAME_CAPACITY, FALSE, &status);
+  CHECK(U_SUCCESS(status));
+  Handle<String> locale = factory->NewStringFromAsciiChecked(language);
 
   icu::SimpleDateFormat* icu_simple_date_format =
       date_time_format->icu_simple_date_format()->raw();
@@ -308,7 +313,7 @@
   const icu::TimeZone& tz = calendar->getTimeZone();
   icu::UnicodeString time_zone;
   tz.getID(time_zone);
-  UErrorCode status = U_ZERO_ERROR;
+  status = U_ZERO_ERROR;
   icu::UnicodeString canonical_time_zone;
   icu::TimeZone::getCanonicalID(time_zone, canonical_time_zone, status);
   Handle<Object> timezone_value;
diff --git a/src/objects/js-locale.cc b/src/objects/js-locale.cc
index 8c7d4ed..c3baecd 100644
--- a/src/objects/js-locale.cc
+++ b/src/objects/js-locale.cc
@@ -312,34 +312,48 @@
 }
 
 namespace {
-Handle<String> MorphLocale(Isolate* isolate, String locale,
-                           void (*morph_func)(icu::Locale* l,
-                                              UErrorCode* status)) {
+
+Handle<String> MorphLocale(Isolate* isolate, String language_tag,
+                           int32_t (*morph_func)(const char*, char*, int32_t,
+                                                 UErrorCode*)) {
+  Factory* factory = isolate->factory();
+  char localeBuffer[ULOC_FULLNAME_CAPACITY];
+  char morphBuffer[ULOC_FULLNAME_CAPACITY];
+
   UErrorCode status = U_ZERO_ERROR;
-  icu::Locale icu_locale =
-      icu::Locale::forLanguageTag(locale.ToCString().get(), status);
-  CHECK(U_SUCCESS(status));
-  CHECK(!icu_locale.isBogus());
-  (*morph_func)(&icu_locale, &status);
-  CHECK(U_SUCCESS(status));
-  CHECK(!icu_locale.isBogus());
-  return isolate->factory()->NewStringFromAsciiChecked(
-      Intl::ToLanguageTag(icu_locale).c_str());
+  // Convert from language id to locale.
+  int32_t parsed_length;
+  int32_t length =
+      uloc_forLanguageTag(language_tag->ToCString().get(), localeBuffer,
+                          ULOC_FULLNAME_CAPACITY, &parsed_length, &status);
+  CHECK(parsed_length == language_tag->length());
+  DCHECK(U_SUCCESS(status));
+  DCHECK_GT(length, 0);
+  DCHECK_NOT_NULL(morph_func);
+  // Add the likely subtags or Minimize the subtags on the locale id
+  length =
+      (*morph_func)(localeBuffer, morphBuffer, ULOC_FULLNAME_CAPACITY, &status);
+  DCHECK(U_SUCCESS(status));
+  DCHECK_GT(length, 0);
+  // Returns a well-formed language tag
+  length = uloc_toLanguageTag(morphBuffer, localeBuffer, ULOC_FULLNAME_CAPACITY,
+                              false, &status);
+  DCHECK(U_SUCCESS(status));
+  DCHECK_GT(length, 0);
+  std::string lang(localeBuffer, length);
+  std::replace(lang.begin(), lang.end(), '_', '-');
+
+  return factory->NewStringFromAsciiChecked(lang.c_str());
 }
+
 }  // namespace
 
 Handle<String> JSLocale::Maximize(Isolate* isolate, String locale) {
-  return MorphLocale(isolate, locale,
-                     [](icu::Locale* icu_locale, UErrorCode* status) {
-                       icu_locale->addLikelySubtags(*status);
-                     });
+  return MorphLocale(isolate, locale, uloc_addLikelySubtags);
 }
 
 Handle<String> JSLocale::Minimize(Isolate* isolate, String locale) {
-  return MorphLocale(isolate, locale,
-                     [](icu::Locale* icu_locale, UErrorCode* status) {
-                       icu_locale->minimizeSubtags(*status);
-                     });
+  return MorphLocale(isolate, locale, uloc_minimizeSubtags);
 }
 
 Handle<String> JSLocale::CaseFirstAsString() const {