From 84087531dcaf6314a32cd8031a9e4f0004cbbc19 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 21 Aug 2026 12:58:48 -0500 Subject: [PATCH] deps: V8: backport 9fb4444bfc46 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original commit message: Fix Temporal compilation with system or no ICU build: Fix Temporal compilation with system or no ICU Add new build flag, v8_enable_temporal_systemicu, off by default When on, it will remove references to the internal ICU udatamem.h header file Obviates CLs 7769990 / 7831715 See: https://unicode-org.atlassian.net/browse/ICU-23400 See: Node: https://github.com/nodejs/node/issues/62676 See: V8: https://chromium-review.googlesource.com/c/v8/v8/+/7831715 See: Homebrew: https://github.com/Homebrew/homebrew-core/pull/281707 Change-Id: Ibc460c68189d32e154c53eddfcda56bc7bca4fc6 Also includes: fix: fix for no-icu build thanks @aduh95 https://github.com/nodejs/node/issues/62676#issuecomment-5371270979 NO_IFTTT=No Temporal via Bazel Change-Id: Ibc460c68189d32e154c53eddfcda56bc7bca4fc6 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/8281487 Reviewed-by: Toon Verwaest Commit-Queue: Chengzhong Wu Reviewed-by: Olivier Flückiger Cr-Commit-Position: refs/heads/main@{#110039} Refs: https://github.com/v8/v8/commit/9fb4444bfc464a5e54219acb04f0828b83dd15b5 Fixes: https://github.com/nodejs/node/issues/62676 Refs: https://github.com/srl295/v8/commit/cd89fe6f7acb6f5d069f6cc741fa68303214e98f Signed-off-by: Joyee Cheung PR-URL: https://github.com/nodejs/node/pull/65161 Reviewed-By: Antoine du Hamel Reviewed-By: Richard Lau --- common.gypi | 2 +- deps/v8/AUTHORS | 1 + deps/v8/BUILD.gn | 4 ++ deps/v8/gni/v8.gni | 4 ++ deps/v8/src/objects/js-temporal-zoneinfo64.cc | 48 +++++++++++++++++-- 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/common.gypi b/common.gypi index 08fd76b8c2a..db9b665b6ca 100644 --- a/common.gypi +++ b/common.gypi @@ -44,7 +44,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.19', + 'v8_embedder_string': '-node.20', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index d5beee57e11..e3c97a9fdf3 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -303,6 +303,7 @@ Stefan Penner Stefan Stojanovic Stephan Hartmann Stephen Belanger +Steven R. Loomis Sylvestre Ledru Takeshi Yoneda Taketoshi Aono diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn index 31aa5aab6fc..72163489956 100644 --- a/deps/v8/BUILD.gn +++ b/deps/v8/BUILD.gn @@ -1391,6 +1391,9 @@ config("features") { if (v8_enable_temporal_support) { defines += [ "V8_TEMPORAL_SUPPORT" ] } + if (v8_enable_temporal_systemicu) { + defines += [ "V8_ENABLE_TEMPORAL_SYSTEMICU" ] + } if (v8_enable_local_handle_zapping) { defines += [ "ENABLE_LOCAL_HANDLE_ZAPPING" ] } @@ -3233,6 +3236,7 @@ generated_file("v8_generate_features_json") { v8_enable_hugepage = v8_enable_hugepage v8_enable_i18n_support = v8_enable_i18n_support v8_enable_temporal_support = v8_enable_temporal_support + v8_enable_temporal_systemicu = v8_enable_temporal_systemicu v8_enable_javascript_promise_hooks = v8_enable_javascript_promise_hooks v8_enable_lite_mode = v8_enable_lite_mode v8_enable_map_packing = v8_enable_map_packing diff --git a/deps/v8/gni/v8.gni b/deps/v8/gni/v8.gni index b0dc87c8458..b54c2d74057 100644 --- a/deps/v8/gni/v8.gni +++ b/deps/v8/gni/v8.gni @@ -62,6 +62,10 @@ declare_args() { # Furthermore, some architectures don't have Rust toolchains in Chromium v8_enable_temporal_support = !(defined(build_with_node) && build_with_node) + # by default, don't enable compiling Temporal with a system ICU4C + # (assume private headers are available) + v8_enable_temporal_systemicu = false + # Use static libraries instead of source_sets. v8_static_library = false diff --git a/deps/v8/src/objects/js-temporal-zoneinfo64.cc b/deps/v8/src/objects/js-temporal-zoneinfo64.cc index 99dd3a84c1e..007d63589c5 100644 --- a/deps/v8/src/objects/js-temporal-zoneinfo64.cc +++ b/deps/v8/src/objects/js-temporal-zoneinfo64.cc @@ -11,8 +11,36 @@ #include "temporal_rs/TimeZone.hpp" #ifdef V8_INTL_SUPPORT +#ifndef V8_ENABLE_TEMPORAL_SYSTEMICU +// ICU internal header file #include "udatamem.h" #else +/** + * Shadow definition of UDataMemory + * This is functionally identical to the definition in udatamem.h + * Irrelevant fields are marked 'ignored' and should not be used. + * + * This definition is copied here so that the result of udata_open() + * can be used and length-checked without needing to resort to + * calling internal ICU functions. + * + * Note, there is an ICU ticket, + * https://unicode-org.atlassian.net/browse/ICU-23400 + * to consider whether the API surface should be changed + * here. If and when this is done, such an API could be used. + */ +struct UDataMemoryShadow { + const void* ignored1; + const void* data; //< pointer to header of data object + const void* ignored2; + UBool ignored3; + void* ignored4; + void* ignored5; + int32_t + length; //< length of entire region pointed to by data if known, else -1 +}; +#endif +#else // Defined in builtins-temporal-zoneinfo64-data.cc, generated by // include-file-as-bytes.py extern "C" uint32_t zoneinfo64_static_data[]; @@ -30,17 +58,29 @@ ZoneInfo64Provider::ZoneInfo64Provider() { provider = temporal_rs::Provider::empty(); return; } +#ifndef V8_ENABLE_TEMPORAL_SYSTEMICU // NOT udata_getLength: this ignores the header, // and we're parsing resb files with the header auto length = memory->length; const void* data = udata_getRawMemory(memory); - DCHECK_WITH_MSG(length % 4 == 0, "ICU4C should align udata to uint32_t"); - if (length % 4 != 0) { - // This really shouldn't happen: ICU4C aligns these files - // to 4 when baking them in +#else + // reinterpret with a local struct + const UDataMemoryShadow* shadowMemory = + reinterpret_cast(memory); + // just need the length and data + auto length = shadowMemory->length; + auto data = shadowMemory->data; +#endif + // This really shouldn't happen: ICU4C pads these files + // to 4 when baking them in + DCHECK_WITH_MSG(length % 4 == 0, "ICU4C should pad udata to uint32_t"); + // Length may not be known. If we're not OK with that, don't proceed. + DCHECK_WITH_MSG(length != -1, "ICU4C usually knows the length"); + if (length % 4 != 0 || length == -1) { provider = temporal_rs::Provider::empty(); return; } + DCHECK_WITH_MSG(data != nullptr, "ICU4C returned nullptr"); const uint32_t* data_32 = static_cast(data); std::span data_span(data_32, length / 4);