Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,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.17',
'v8_embedder_string': '-node.18',

##### V8 defaults for Node.js #####

Expand Down
77 changes: 57 additions & 20 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1156,6 +1156,11 @@
default=None,
help='Enable the built-in snapshot compression in V8.')

parser.add_argument('--v8-disable-temporal-support',
action='store_true',
dest='v8_disable_temporal_support',
default=None,
help='Disable Temporal support in V8.')

parser.add_argument('--v8-enable-temporal-support',
action='store_true',
Expand Down Expand Up @@ -1450,11 +1455,7 @@ def get_cargo_version(cargo):
stdin=subprocess.PIPE, stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
except OSError:
error('''No acceptable cargo found!

Please make sure you have cargo installed on your system and/or
consider adjusting the CARGO environment variable if you have installed
it in a non-standard prefix.''')
return '0.0'

with proc:
cargo_ret = to_utf8(proc.communicate()[0])
Expand All @@ -1473,11 +1474,7 @@ def get_rustc_version(rustc):
stdin=subprocess.PIPE, stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
except OSError:
error('''No acceptable rustc compiler found!

Please make sure you have a rust compiler installed on your system and/or
consider adjusting the RUSTC environment variable if you have installed
it in a non-standard prefix.''')
return '0.0'

with proc:
rustc_ret = to_utf8(proc.communicate()[0])
Expand Down Expand Up @@ -1538,23 +1535,51 @@ def check_compiler(o):
o['variables']['llvm_version'] = get_llvm_version(CC) if is_clang else '0.0'

# cargo and rustc are needed for Temporal.
if options.v8_enable_temporal_support and not options.shared_temporal_capi:
if not options.v8_disable_temporal_support or not options.shared_temporal_capi:
# Minimum cargo and rustc versions should match values in BUILDING.md.
min_cargo_ver_tuple = (1, 82)
min_rustc_ver_tuple = (1, 82)
cargo = os.environ.get('CARGO', 'cargo')
cargo_ver = get_cargo_version(cargo)
print_verbose(f'Detected cargo (CARGO={cargo}): {cargo_ver}')
cargo_ver_tuple = tuple(map(int, cargo_ver.split('.')))
if cargo_ver_tuple < min_cargo_ver_tuple:
warn(f'cargo {cargo_ver} too old, need cargo {".".join(map(str, min_cargo_ver_tuple))}')
if cargo_ver == '0.0':
# Error if --v8-enable-temporal-support is explicitly set,
# otherwise disable support for Temporal.
if options.v8_enable_temporal_support:
error('''No acceptable cargo found!

Enabling Temporal support requires cargo.
Please make sure you have cargo installed on your system and/or
consider adjusting the CARGO environment variable if you have installed
it in a non-standard prefix.''')
else:
warn('cargo not found! Support for Temporal will be disabled.')
options.v8_disable_temporal_support = True
else:
cargo_ver_tuple = tuple(map(int, cargo_ver.split('.')))
if cargo_ver_tuple < min_cargo_ver_tuple:
warn(f'cargo {cargo_ver} too old, need cargo {".".join(map(str, min_cargo_ver_tuple))}')
# cargo supports RUSTC environment variable to override "rustc".
rustc = os.environ.get('RUSTC', 'rustc')
rustc_ver = get_rustc_version(rustc)
print_verbose(f'Detected rustc (RUSTC={rustc}): {rustc_ver}')
rust_ver_tuple = tuple(map(int, rustc_ver.split('.')))
if rust_ver_tuple < min_rustc_ver_tuple:
warn(f'rustc {rustc_ver} too old, need rustc {".".join(map(str, min_rustc_ver_tuple))}')
if rustc_ver == '0.0':
# Error if --v8-enable-temporal-support is explicitly set,
# otherwise disable support for Temporal.
if options.v8_enable_temporal_support:
error('''No acceptable rustc compiler found!

Enabling Temporal support requires a Rust toolchain.
Please make sure you have a Rust compiler installed on your system and/or
consider adjusting the RUSTC environment variable if you have installed
it in a non-standard prefix.''')
else:
warn(f'{rustc} not found! Support for Temporal will be disabled.')
options.v8_disable_temporal_support = True
else:
print_verbose(f'Detected rustc (RUSTC={rustc}): {rustc_ver}')
rust_ver_tuple = tuple(map(int, rustc_ver.split('.')))
if rust_ver_tuple < min_rustc_ver_tuple:
warn(f'rustc {rustc_ver} too old, need rustc {".".join(map(str, min_rustc_ver_tuple))}')

# Need xcode_version or gas_version when openssl asm files are compiled.
if options.without_ssl or options.openssl_no_asm or options.shared_openssl:
Expand Down Expand Up @@ -1780,6 +1805,14 @@ def configure_node(o):
o['variables']['target_arch'] = target_arch
o['variables']['node_byteorder'] = sys.byteorder

# On Windows, cargo may default to the GNU target (e.g. x86_64-pc-windows-gnu)
# but Node.js requires MSVC-compatible libraries. Set explicit Rust target
# triple for the target architecture.
o['variables']['cargo_rust_target'] = ''
if flavor == 'win':
o['variables']['cargo_rust_target'] = \
'aarch64-pc-windows-msvc' if target_arch == 'arm64' else 'x86_64-pc-windows-msvc'

# Allow overriding the compiler - needed by embedders.
if options.use_clang:
o['variables']['clang'] = 1
Expand Down Expand Up @@ -2057,7 +2090,7 @@ def configure_v8(o, configs):
o['variables']['v8_enable_external_code_space'] = 1 if options.enable_pointer_compression else 0
o['variables']['v8_enable_31bit_smis_on_64bit_arch'] = 1 if options.enable_pointer_compression else 0
o['variables']['v8_enable_extensible_ro_snapshot'] = 0
o['variables']['v8_enable_temporal_support'] = 1 if options.v8_enable_temporal_support else 0
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']['node_use_v8_platform'] = b(not options.without_v8_platform)
o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8)
Expand Down Expand Up @@ -2089,6 +2122,10 @@ def configure_v8(o, configs):
raise Exception(
'Only one of the --v8-enable-object-print or --v8-disable-object-print options '
'can be specified at a time.')
if all(opt in sys.argv for opt in ['--v8-enable-temporal-support', '--v8-disable-temporal-support']):
raise Exception(
'Only one of the --v8-enable-temporal-support or --v8-disable-temporal-support options '
'can be specified at a time.')
if sys.platform != 'darwin':
if o['variables']['v8_enable_webassembly'] and o['variables']['target_arch'] == 'x64':
o['variables']['v8_enable_wasm_simd256_revec'] = 1
Expand Down Expand Up @@ -2754,7 +2791,7 @@ def make_bin_override():
# will fail to run python scripts.
gyp_args += ['-Dpython=' + python]

if options.v8_enable_temporal_support and not options.shared_temporal_capi:
if not options.v8_disable_temporal_support or not options.shared_temporal_capi:
cargo = os.environ.get('CARGO')
if cargo:
gyp_args += ['-Dcargo=' + cargo]
Expand Down
60 changes: 60 additions & 0 deletions deps/crates/cargo_build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env python3

"""Invoke cargo with the correct Rust target on Windows cross-compilation.

Works around three issues: GYP's MSVS generator mangles executable names in
host-toolset actions (breaking direct cargo calls), GYP cannot set different
variable values per toolset, and cargo's output directory layout uses Rust
target triples while MSBuild expects platform names (x64/arm64). This script
reads MSBuild's $(Platform) to select the right Rust target and copies the
built library to a path MSBuild can resolve per-project.
"""

import os
import shutil
import subprocess
import sys


def main():
# Arguments: <platform> <output_dir> [cargo_args...]
if len(sys.argv) < 3:
print('Usage: cargo_build.py <platform> <output_dir> [cargo_args...]', file=sys.stderr)
sys.exit(1)

platform = sys.argv[1] # x64 or arm64
output_dir = sys.argv[2] # SHARED_INTERMEDIATE_DIR
cargo_args = sys.argv[3:]
build_profile = 'release' if '--release' in cargo_args else 'debug'

cargo = os.environ.get('CARGO', 'cargo')
if not os.path.isabs(cargo) and shutil.which(cargo) is None:
home = os.environ.get('USERPROFILE', '')
cargo_home = os.path.join(home, '.cargo', 'bin', 'cargo.exe')
if os.path.isfile(cargo_home):
cargo = cargo_home

rust_target_map = {
'x64': 'x86_64-pc-windows-msvc',
'arm64': 'aarch64-pc-windows-msvc',
}
rust_target = rust_target_map.get(platform)
if rust_target is None:
print(f'Unsupported platform: {platform}', file=sys.stderr)
sys.exit(1)

cmd = [cargo, 'rustc', '--target', rust_target, '--target-dir', output_dir] + cargo_args
ret = subprocess.call(cmd)
if ret != 0:
sys.exit(ret)

# Copy output to the platform-specific directory that MSBuild expects.
src = os.path.join(output_dir, rust_target, build_profile, 'node_crates.lib')
dst_dir = os.path.join(output_dir, platform, build_profile)
os.makedirs(dst_dir, exist_ok=True)
dst = os.path.join(dst_dir, 'node_crates.lib')
shutil.copy2(src, dst)


if __name__ == '__main__':
main()
83 changes: 65 additions & 18 deletions deps/crates/crates.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,46 @@
'variables': {
'cargo%': 'cargo',
'cargo_vendor_dir': './vendor',
'cargo_rust_target%': '',
},
'conditions': [
['build_type == "Release"', {
'variables': {
'cargo_build_flags': ['--release'],
'node_crates_libpath': '<(SHARED_INTERMEDIATE_DIR)/release/<(STATIC_LIB_PREFIX)node_crates<(STATIC_LIB_SUFFIX)',
},
'conditions': [
['cargo_rust_target!=""', {
'variables': {
'node_crates_libpath': '<(SHARED_INTERMEDIATE_DIR)/$(Platform)/release/node_crates.lib',
},
}, {
'variables': {
'node_crates_libpath': '<(SHARED_INTERMEDIATE_DIR)/release/<(STATIC_LIB_PREFIX)node_crates<(STATIC_LIB_SUFFIX)',
},
}],
],
}, {
'variables': {
'cargo_build_flags': [],
'node_crates_libpath': '<(SHARED_INTERMEDIATE_DIR)/debug/<(STATIC_LIB_PREFIX)node_crates<(STATIC_LIB_SUFFIX)',
},
'conditions': [
['cargo_rust_target!=""', {
'variables': {
'node_crates_libpath': '<(SHARED_INTERMEDIATE_DIR)/$(Platform)/debug/node_crates.lib',
},
}, {
'variables': {
'node_crates_libpath': '<(SHARED_INTERMEDIATE_DIR)/debug/<(STATIC_LIB_PREFIX)node_crates<(STATIC_LIB_SUFFIX)',
},
}],
],
}]
],
'targets': [
{
'target_name': 'node_crates',
'type': 'none',
'toolsets': ['host', 'target'],
'hard_dependency': 1,
'sources': [
'Cargo.toml',
Expand All @@ -39,29 +61,54 @@
}],
],
},
'actions': [
{
'action_name': 'cargo_build',
'inputs': [
'<@(_sources)'
],
'outputs': [
'<(node_crates_libpath)'
'conditions': [
['cargo_rust_target!=""', {
'actions': [
{
'action_name': 'cargo_build',
'inputs': [
'<@(_sources)'
],
'outputs': [
'<(node_crates_libpath)'
],
'action': [
'<(python)',
'cargo_build.py',
'$(Platform)',
'<(SHARED_INTERMEDIATE_DIR)',
'<@(cargo_build_flags)',
'--frozen',
],
}
],
'action': [
'<(cargo)',
'rustc',
'<@(cargo_build_flags)',
'--frozen',
'--target-dir',
'<(SHARED_INTERMEDIATE_DIR)'
}, {
'actions': [
{
'action_name': 'cargo_build',
'inputs': [
'<@(_sources)'
],
'outputs': [
'<(node_crates_libpath)'
],
'action': [
'<(cargo)',
'rustc',
'<@(cargo_build_flags)',
'--frozen',
'--target-dir',
'<(SHARED_INTERMEDIATE_DIR)'
],
}
],
}
}],
],
},
{
'target_name': 'temporal_capi',
'type': 'none',
'toolsets': ['host', 'target'],
'sources': [],
'dependencies': [
'node_crates',
Expand Down
40 changes: 36 additions & 4 deletions deps/v8/src/objects/js-temporal-zoneinfo64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,44 @@
#include "temporal_rs/TimeZone.hpp"

#ifdef V8_INTL_SUPPORT
#include "udatamem.h"
#include "unicode/udata.h"
typedef struct {
uint16_t headerSize;
uint8_t magic1;
uint8_t magic2;
} MappedData;
typedef struct {
MappedData dataHeader;
UDataInfo info;
} DataHeader;
typedef struct {
void* Lookup;
void* NumEntries;
} commonDataFuncs;
struct UDataMemory {
const commonDataFuncs *vFuncs; /* Function Pointers for accessing TOC */

const DataHeader *pHeader; /* Header of the memory being described by this */
/* UDataMemory object. */
const void *toc; /* For common memory, table of contents for */
/* the pieces within. */
UBool heapAllocated; /* True if this UDataMemory Object is on the */
/* heap and thus needs to be deleted when closed. */

void *mapAddr; /* For mapped or allocated memory, the start addr. */
/* Only non-null if a close operation should unmap */
/* the associated data. */
void *map; /* Handle, or other data, OS dependent. */
/* Only non-null if a close operation should unmap */
/* the associated data, and additional info */
/* beyond the mapAddr is needed to do that. */
int32_t length; /* Length of the data in bytes; -1 if unknown. */
};
#else
// 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;
static uint32_t zoneinfo64_static_data[] = {};
static size_t zoneinfo64_static_data_len = 0;
#endif

namespace v8::internal {
Expand All @@ -33,7 +65,7 @@ ZoneInfo64Provider::ZoneInfo64Provider() {
// 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);
const void* data = udata_getMemory(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
Expand Down
Loading