Skip to content

Commit 67771dd

Browse files
committed
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 See: https://unicode-org.atlassian.net/browse/ICU-23400 See: Node: nodejs/node#62676 See: V8: https://chromium-review.googlesource.com/c/v8/v8/+/8281487 Bug: 8281487
1 parent 66474ec commit 67771dd

3 files changed

Lines changed: 52 additions & 4 deletions

File tree

‎BUILD.gn‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,9 @@ config("features") {
14101410
if (v8_enable_temporal_support) {
14111411
defines += [ "V8_TEMPORAL_SUPPORT" ]
14121412
}
1413+
if (v8_enable_temporal_systemicu) {
1414+
defines += [ "V8_ENABLE_TEMPORAL_SYSTEMICU" ]
1415+
}
14131416
if (v8_enable_local_handle_zapping) {
14141417
defines += [ "ENABLE_LOCAL_HANDLE_ZAPPING" ]
14151418
}
@@ -3248,6 +3251,7 @@ generated_file("v8_generate_features_json") {
32483251
v8_enable_hugepage = v8_enable_hugepage
32493252
v8_enable_i18n_support = v8_enable_i18n_support
32503253
v8_enable_temporal_support = v8_enable_temporal_support
3254+
v8_enable_temporal_systemicu = v8_enable_temporal_systemicu
32513255
v8_enable_javascript_promise_hooks = v8_enable_javascript_promise_hooks
32523256
v8_enable_lite_mode = v8_enable_lite_mode
32533257
v8_enable_map_packing = v8_enable_map_packing

‎gni/v8.gni‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ declare_args() {
6363
# Furthermore, some architectures don't have Rust toolchains in Chromium
6464
v8_enable_temporal_support = !(defined(build_with_node) && build_with_node)
6565

66+
# by default, don't enable compiling Temporal with a system ICU4C
67+
# (assume private headers are available)
68+
v8_enable_temporal_systemicu = false
69+
6670
# Use static libraries instead of source_sets.
6771
v8_static_library = false
6872

‎src/objects/js-temporal-zoneinfo64.cc‎

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,36 @@
1111
#include "temporal_rs/TimeZone.hpp"
1212

1313
#ifdef V8_INTL_SUPPORT
14+
#ifndef V8_ENABLE_TEMPORAL_SYSTEMICU
15+
// ICU internal header file
1416
#include "udatamem.h"
1517
#else
18+
/**
19+
* Shadow definition of UDataMemory
20+
* This is functionally identical to the definition in udatamem.h
21+
* Irrelevant fields are marked 'ignored' and should not be used.
22+
*
23+
* This definition is copied here so that the result of udata_open()
24+
* can be used and length-checked without needing to resort to
25+
* calling internal ICU functions.
26+
*
27+
* Note, there is an ICU ticket,
28+
* https://unicode-org.atlassian.net/browse/ICU-23400
29+
* to consider whether the API surface should be changed
30+
* here. If and when this is done, such an API could be used.
31+
*/
32+
struct UDataMemoryShadow {
33+
const void* ignored1;
34+
const void* data; //< pointer to header of data object
35+
const void* ignored2;
36+
UBool ignored3;
37+
void* ignored4;
38+
void* ignored5;
39+
int32_t
40+
length; //< length of entire region pointed to by data if known, else -1
41+
};
42+
#endif
43+
#else
1644
// Defined in builtins-temporal-zoneinfo64-data.cc, generated by
1745
// include-file-as-bytes.py
1846
extern "C" uint32_t zoneinfo64_static_data[];
@@ -30,17 +58,29 @@ ZoneInfo64Provider::ZoneInfo64Provider() {
3058
provider = temporal_rs::Provider::empty();
3159
return;
3260
}
61+
#ifndef V8_ENABLE_TEMPORAL_SYSTEMICU
3362
// NOT udata_getLength: this ignores the header,
3463
// and we're parsing resb files with the header
3564
auto length = memory->length;
3665
const void* data = udata_getRawMemory(memory);
37-
DCHECK_WITH_MSG(length % 4 == 0, "ICU4C should align udata to uint32_t");
38-
if (length % 4 != 0) {
39-
// This really shouldn't happen: ICU4C aligns these files
40-
// to 4 when baking them in
66+
#else
67+
// reinterpret with a local struct
68+
const UDataMemoryShadow* shadowMemory =
69+
reinterpret_cast<const UDataMemoryShadow*>(memory);
70+
// just need the length and data
71+
auto length = shadowMemory->length;
72+
auto data = shadowMemory->data;
73+
#endif
74+
// This really shouldn't happen: ICU4C pads these files
75+
// to 4 when baking them in
76+
DCHECK_WITH_MSG(length % 4 == 0, "ICU4C should pad udata to uint32_t");
77+
// Length may not be known. If we're not OK with that, don't proceed.
78+
DCHECK_WITH_MSG(length != -1, "ICU4C usually knows the length");
79+
if (length % 4 != 0 || length == -1) {
4180
provider = temporal_rs::Provider::empty();
4281
return;
4382
}
83+
DCHECK_WITH_MSG(data != nullptr, "ICU4C returned nullptr");
4484

4585
const uint32_t* data_32 = static_cast<const uint32_t*>(data);
4686
std::span<const uint32_t> data_span(data_32, length / 4);

0 commit comments

Comments
 (0)