-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
Expand file tree
/
Copy pathjs-temporal-zoneinfo64.cc
More file actions
87 lines (73 loc) Β· 2.7 KB
/
js-temporal-zoneinfo64.cc
File metadata and controls
87 lines (73 loc) Β· 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Copyright 2025 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/objects/js-temporal-zoneinfo64.h"
#include <iostream>
#include "src/base/logging.h"
#include "temporal_rs/Provider.hpp"
#include "temporal_rs/TimeZone.hpp"
#if defined(V8_INTL_SUPPORT) && defined(__has_include) && __has_include("udatamem.h")
#include "udatamem.h"
#define V8_TEMPORAL_USE_ICU_RAW_MEMORY
#endif
#ifndef V8_TEMPORAL_USE_ICU_RAW_MEMORY
// Defined in builtins-temporal-zoneinfo64-data.cc, generated by
// include-file-as-bytes.py
extern "C" uint32_t zoneinfo64_static_data[];
extern "C" size_t zoneinfo64_static_data_len;
#endif
namespace v8::internal {
ZoneInfo64Provider::ZoneInfo64Provider() {
#ifdef V8_TEMPORAL_USE_ICU_RAW_MEMORY
UErrorCode status = U_ZERO_ERROR;
memory = udata_open(0, "res", "zoneinfo64", &status);
if (U_FAILURE(status)) {
DCHECK_WITH_MSG(false, "Failed to open zoneinfo64.res");
provider = temporal_rs::Provider::empty();
return;
}
// 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
provider = temporal_rs::Provider::empty();
return;
}
const uint32_t* data_32 = static_cast<const uint32_t*>(data);
std::span<const uint32_t> data_span(data_32, length / 4);
#else
std::span<const uint32_t> data_span(zoneinfo64_static_data,
zoneinfo64_static_data_len);
#endif
auto result = temporal_rs::Provider::new_zoneinfo64(data_span);
DCHECK_WITH_MSG(result.is_ok(), "Baked-in zoneinfo64 file must parse");
if (result.is_ok()) {
provider = std::move(result).ok().value();
} else {
provider = temporal_rs::Provider::empty();
}
}
ZoneInfo64Provider& ZoneInfo64Provider::Singleton() {
// Allocate it so that it gets leaked (-Wno-exit-destructors)
static ZoneInfo64Provider* SINGLETON = new ZoneInfo64Provider();
return *SINGLETON;
}
// This destructor exists for completeness in case someone decides to use this
// as a stack value, though the default way of accessing this is via singleton.
ZoneInfo64Provider::~ZoneInfo64Provider() {
// Release provider first since it
// may reference memory
provider = nullptr;
// Then clean up memory
// This ideally is a no-op when using static data
#ifdef V8_TEMPORAL_USE_ICU_RAW_MEMORY
if (memory) {
udata_close(memory);
}
#endif
}
} // namespace v8::internal