diff --git a/common.gypi b/common.gypi index 71712d308472..7eaad1e5ea1e 100644 --- a/common.gypi +++ b/common.gypi @@ -43,7 +43,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.34', + 'v8_embedder_string': '-node.35', ##### V8 defaults for Node.js ##### diff --git a/configure.py b/configure.py index 8b3332a461f4..4bf8e2e39ee0 100755 --- a/configure.py +++ b/configure.py @@ -2261,9 +2261,6 @@ def configure_v8(o, configs): case 'none': warn('Temporal support disabled when compiling without ICU') options.v8_disable_temporal_support = True - case 'system-icu': - warn('Temporal support disabled when compiling with a shared ICU library') - options.v8_disable_temporal_support = True o['variables']['v8_enable_temporal_support'] = 0 if options.v8_disable_temporal_support else 1 o['variables']['v8_trace_maps'] = 1 if options.trace_maps else 0 o['variables']['v8_use_perfetto'] = 1 if options.with_perfetto else 0 @@ -2544,6 +2541,8 @@ def icu_download(path): # always set icu_small, node.gyp depends on it being defined. o['variables']['icu_small'] = b(False) o['variables']['icu_system'] = b(False) + # always set this + o['variables']['v8_enable_temporal_systemicu'] = 1 # prevent data override o['defines'] += ['ICU_NO_USER_DATA_OVERRIDE'] diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn index 276641b09aa3..560d4d42a94f 100644 --- a/deps/v8/BUILD.gn +++ b/deps/v8/BUILD.gn @@ -1307,6 +1307,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" ] } @@ -3110,6 +3113,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 e29a7c5de3c4..ea430b3a0a93 100644 --- a/deps/v8/gni/v8.gni +++ b/deps/v8/gni/v8.gni @@ -63,6 +63,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 99dd3a84c1e5..007d63589c50 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); diff --git a/tools/v8_gypfiles/features.gypi b/tools/v8_gypfiles/features.gypi index 3f51d3da0044..95717992bcab 100644 --- a/tools/v8_gypfiles/features.gypi +++ b/tools/v8_gypfiles/features.gypi @@ -303,6 +303,11 @@ # Enable Temporal API. Enabling this feature will # add a dependency on the temporal_rs library. 'v8_enable_temporal_support%': 0, + # Enable Temporal even with system-icu. + # This will use an improved codepath which does not + # depend on internal ICU headers. + # This option can be on unconditionally. + 'v8_enable_temporal_systemicu%': 1, # Lite mode disables a number of performance optimizations to reduce memory # at the cost of performance. @@ -425,6 +430,9 @@ }], ['v8_enable_temporal_support==1', { 'defines': ['V8_TEMPORAL_SUPPORT',], + }], + ['v8_enable_temporal_systemicu==1', { + 'defines': ['V8_ENABLE_TEMPORAL_SYSTEMICU',], }], # Refs: https://github.com/nodejs/node/pull/23801 # ['v8_enable_handle_zapping==1', {