From de81e9f50c7e5c6c796762503cef8c3dc66fbffe Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Thu, 1 Feb 2024 10:03:53 +0100 Subject: [PATCH] feat: node 20.11.0 and 18.19.0 patches (#18) --- .github/workflows/ci.yml | 2 +- ...18.2.cpp.patch => node.v18.19.0.cpp.patch} | 155 +++-- patches/node.v19.8.1.cpp.patch | 581 ------------------ ...10.0.cpp.patch => node.v20.11.0.cpp.patch} | 32 +- patches/patches.json | 5 +- 5 files changed, 139 insertions(+), 636 deletions(-) rename patches/{node.v18.18.2.cpp.patch => node.v18.19.0.cpp.patch} (80%) delete mode 100644 patches/node.v19.8.1.cpp.patch rename patches/{node.v20.10.0.cpp.patch => node.v20.11.0.cpp.patch} (96%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96253591..f1e980f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false # prevent test to stop if one fails matrix: - node-version: [12, 14, 16, 18, 19, 20] # match patched node versions + node-version: [12, 14, 16, 18, 20] # match patched node versions os: [ubuntu-latest] # Skip macos-latest, windows-latest for now runs-on: ${{ matrix.os }} diff --git a/patches/node.v18.18.2.cpp.patch b/patches/node.v18.19.0.cpp.patch similarity index 80% rename from patches/node.v18.18.2.cpp.patch rename to patches/node.v18.19.0.cpp.patch index a8c0f83c..d2dd0a78 100644 --- a/patches/node.v18.18.2.cpp.patch +++ b/patches/node.v18.19.0.cpp.patch @@ -1,5 +1,5 @@ diff --git node/common.gypi node/common.gypi -index 94fae06518..e4116f3c82 100644 +index dba2631f21..4c4c430dc1 100644 --- node/common.gypi +++ node/common.gypi @@ -174,7 +174,7 @@ @@ -12,7 +12,7 @@ index 94fae06518..e4116f3c82 100644 'lto': ' -flto ', # Clang }], diff --git node/configure.py node/configure.py -index 7006ee6581..12fb2ac8d1 100755 +index 4638f04b6a..ffa1c6338a 100755 --- node/configure.py +++ node/configure.py @@ -1289,9 +1289,7 @@ def configure_node(o): @@ -169,7 +169,7 @@ index 618cf9e975..64a57e8afe 100644 uint32_t max_payload_length = this->size_ - kHeaderSize; if (payload_length > max_payload_length) { diff --git node/lib/child_process.js node/lib/child_process.js -index 5bdc474c80..196778e7db 100644 +index 449013906e..3a85e4a541 100644 --- node/lib/child_process.js +++ node/lib/child_process.js @@ -169,7 +169,7 @@ function fork(modulePath, args = [], options) { @@ -237,59 +237,144 @@ index 0000000000..a697294fdf + }()); +}()); diff --git node/lib/internal/modules/cjs/loader.js node/lib/internal/modules/cjs/loader.js -index 88bb870a8f..22bbdd9058 100644 +index 316996a8c3..8cd0727556 100644 --- node/lib/internal/modules/cjs/loader.js +++ node/lib/internal/modules/cjs/loader.js -@@ -94,7 +94,7 @@ const fs = require('fs'); - const internalFS = require('internal/fs/utils'); +@@ -89,7 +89,7 @@ const { internalCompileFunction } = require('internal/vm'); + const assert = require('internal/assert'); + const fs = require('fs'); const path = require('path'); - const { sep } = path; -const { internalModuleStat } = internalBinding('fs'); +const internalModuleStat = function (f) { return require('fs').internalModuleStat(f); }; - const packageJsonReader = require('internal/modules/package_json_reader'); const { safeGetenv } = internalBinding('credentials'); const { + privateSymbols: { diff --git node/lib/internal/modules/package_json_reader.js node/lib/internal/modules/package_json_reader.js -index bb175d0df5..07f4834c07 100644 +index 1968960576..d73016f3fe 100644 --- node/lib/internal/modules/package_json_reader.js +++ node/lib/internal/modules/package_json_reader.js -@@ -1,7 +1,7 @@ - 'use strict'; - - const { SafeMap } = primordials; +@@ -12,7 +12,7 @@ const { + const { + ERR_INVALID_PACKAGE_CONFIG, + } = require('internal/errors').codes; -const { internalModuleReadJSON } = internalBinding('fs'); +const internalModuleReadJSON = function (f) { return require('fs').internalModuleReadJSON(f); }; - const { pathToFileURL } = require('url'); - const { toNamespacedPath } = require('path'); + const { resolve, sep, toNamespacedPath } = require('path'); + const { kEmptyObject } = require('internal/util'); diff --git node/lib/internal/process/pre_execution.js node/lib/internal/process/pre_execution.js -index b4a24bbffb..041ee4c715 100644 +index 4795be82e7..977124a014 100644 --- node/lib/internal/process/pre_execution.js +++ node/lib/internal/process/pre_execution.js -@@ -36,7 +36,12 @@ const { - isBuildingSnapshot, - } = require('v8').startupSnapshot; +@@ -36,7 +36,11 @@ const { + }, + } = require('internal/v8/startup_snapshot'); +let _alreadyPrepared = false; + function prepareMainThreadExecution(expandArgv1 = false, initializeModules = true) { + if (_alreadyPrepared === true) return; + _alreadyPrepared = true; -+ - prepareExecution({ + return prepareExecution({ expandArgv1, initializeModules, -@@ -155,7 +160,8 @@ function patchProcessObject(expandArgv1) { - process.argv[0] = process.execPath; - +@@ -191,7 +195,8 @@ function patchProcessObject(expandArgv1) { + // If requested, update process.argv[1] to replace whatever the user provided with the resolved absolute file path of + // the entry point. if (expandArgv1 && process.argv[1] && - !StringPrototypeStartsWith(process.argv[1], '-')) { -+ !StringPrototypeStartsWith(process.argv[1], '-') && -+ process.argv[1] !== 'PKG_DUMMY_ENTRYPOINT') { ++ !StringPrototypeStartsWith(process.argv[1], '-') && ++ process.argv[1] !== 'PKG_DUMMY_ENTRYPOINT') { // Expand process.argv[1] into a full path. const path = require('path'); try { -@@ -603,6 +609,7 @@ function loadPreloadModules() { +@@ -263,7 +268,7 @@ function setupWarningHandler() { + // https://fetch.spec.whatwg.org/ + function setupFetch() { + if (process.config.variables.node_no_browser_globals || +- getOptionValue('--no-experimental-fetch')) { ++ getOptionValue('--no-experimental-fetch')) { + return; + } + +@@ -313,7 +318,7 @@ function setupFetch() { + // removed. + function setupWebCrypto() { + if (process.config.variables.node_no_browser_globals || +- !getOptionValue('--experimental-global-webcrypto')) { ++ !getOptionValue('--experimental-global-webcrypto')) { + return; + } + +@@ -335,7 +340,7 @@ function setupCodeCoverage() { + // --experimental-test-coverage flag is present, as the test runner will + // handle coverage. + if (process.env.NODE_V8_COVERAGE && +- !getOptionValue('--experimental-test-coverage')) { ++ !getOptionValue('--experimental-test-coverage')) { + process.env.NODE_V8_COVERAGE = + setupCoverageHooks(process.env.NODE_V8_COVERAGE); + } +@@ -345,7 +350,7 @@ function setupCodeCoverage() { + // removed. + function setupCustomEvent() { + if (process.config.variables.node_no_browser_globals || +- !getOptionValue('--experimental-global-customevent')) { ++ !getOptionValue('--experimental-global-customevent')) { + return; + } + const { CustomEvent } = require('internal/event_target'); +@@ -468,10 +473,10 @@ function initializeDeprecations() { + ]) { + utilBinding[name] = pendingDeprecation ? + deprecate(types[name], +- 'Accessing native typechecking bindings of Node ' + +- 'directly is deprecated. ' + +- `Please use \`util.types.${name}\` instead.`, +- 'DEP0103') : ++ 'Accessing native typechecking bindings of Node ' + ++ 'directly is deprecated. ' + ++ `Please use \`util.types.${name}\` instead.`, ++ 'DEP0103') : + types[name]; + } + +@@ -492,12 +497,12 @@ function initializeDeprecations() { + + if (pendingDeprecation) { + process.binding = deprecate(process.binding, +- 'process.binding() is deprecated. ' + +- 'Please use public APIs instead.', 'DEP0111'); ++ 'process.binding() is deprecated. ' + ++ 'Please use public APIs instead.', 'DEP0111'); + + process._tickCallback = deprecate(process._tickCallback, +- 'process._tickCallback() is deprecated', +- 'DEP0134'); ++ 'process._tickCallback() is deprecated', ++ 'DEP0134'); + } + } + +@@ -533,7 +538,7 @@ function readPolicyFromDisk() { + const experimentalPolicy = getOptionValue('--experimental-policy'); + if (experimentalPolicy) { + process.emitWarning('Policies are experimental.', +- 'ExperimentalWarning'); ++ 'ExperimentalWarning'); + const { pathToFileURL, URL } = require('internal/url'); + // URL here as it is slightly different parsing + // no bare specifiers for now +@@ -611,7 +616,7 @@ function initializeSourceMapsHandlers() { + function initializeFrozenIntrinsics() { + if (getOptionValue('--frozen-intrinsics')) { + process.emitWarning('The --frozen-intrinsics flag is experimental', +- 'ExperimentalWarning'); ++ 'ExperimentalWarning'); + require('internal/freeze_intrinsics')(); + } + } +@@ -620,6 +625,7 @@ function loadPreloadModules() { // For user code, we preload modules if `-r` is passed const preloadModules = getOptionValue('--require'); if (preloadModules && preloadModules.length > 0) { @@ -298,7 +383,7 @@ index b4a24bbffb..041ee4c715 100644 Module: { _preloadModules, diff --git node/lib/vm.js node/lib/vm.js -index 21acc55e2e..8a128bcb5c 100644 +index b48e79c282..3b86fa8933 100644 --- node/lib/vm.js +++ node/lib/vm.js @@ -77,6 +77,7 @@ class Script extends ContextifyScript { @@ -320,10 +405,10 @@ index 21acc55e2e..8a128bcb5c 100644 throw e; /* node-do-not-add-exception-line */ } diff --git node/node.gyp node/node.gyp -index 6b554d75d8..fce4eb4bd5 100644 +index 08cb3f38e8..6c0d2761ab 100644 --- node/node.gyp +++ node/node.gyp -@@ -113,6 +113,9 @@ +@@ -116,6 +116,9 @@ }, 'conditions': [ @@ -347,10 +432,10 @@ index b1ba86b7b0..e2478e537c 100644 parent_env_->AddCleanupHook([](void* data) { Environment* env = static_cast(data); diff --git node/src/node.cc node/src/node.cc -index 96cdcd3064..cef0838d53 100644 +index 0c75b5a08e..385a03090f 100644 --- node/src/node.cc +++ node/src/node.cc -@@ -314,6 +314,8 @@ MaybeLocal StartExecution(Environment* env, StartExecutionCallback cb) { +@@ -304,6 +304,8 @@ MaybeLocal StartExecution(Environment* env, StartExecutionCallback cb) { return env->RunSnapshotDeserializeMain(); } @@ -359,7 +444,7 @@ index 96cdcd3064..cef0838d53 100644 if (env->worker_context() != nullptr) { return StartExecution(env, "internal/main/worker_thread"); } -@@ -546,14 +548,6 @@ static void PlatformInit(ProcessInitializationFlags::Flags flags) { +@@ -536,14 +538,6 @@ static void PlatformInit(ProcessInitializationFlags::Flags flags) { } if (!(flags & ProcessInitializationFlags::kNoDefaultSignalHandling)) { @@ -555,10 +640,10 @@ index 8099b2a3a1..9cc8a07a55 100644 + return adjacent(c, nargv); +} diff --git node/src/node_options.cc node/src/node_options.cc -index 26f205bc3b..e52a31f487 100644 +index 6ee79f7df8..cfc3e8d785 100644 --- node/src/node_options.cc +++ node/src/node_options.cc -@@ -307,7 +307,7 @@ DebugOptionsParser::DebugOptionsParser() { +@@ -314,7 +314,7 @@ DebugOptionsParser::DebugOptionsParser() { #ifndef DISABLE_SINGLE_EXECUTABLE_APPLICATION if (sea::IsSingleExecutable()) return; #endif diff --git a/patches/node.v19.8.1.cpp.patch b/patches/node.v19.8.1.cpp.patch deleted file mode 100644 index 0c678e74..00000000 --- a/patches/node.v19.8.1.cpp.patch +++ /dev/null @@ -1,581 +0,0 @@ -diff --git node/common.gypi node/common.gypi -index b1d87780db..659da7c790 100644 ---- node/common.gypi -+++ node/common.gypi -@@ -174,7 +174,7 @@ - 'MSVC_runtimeType': 2 # MultiThreadedDLL (/MD) - }], - ['llvm_version=="0.0"', { -- 'lto': ' -flto=4 -fuse-linker-plugin -ffat-lto-objects ', # GCC -+ 'lto': ' -flto=4 -ffat-lto-objects ', # GCC - }, { - 'lto': ' -flto ', # Clang - }], -diff --git node/configure.py node/configure.py -index d7765ef6bd..3c15a61215 100755 ---- node/configure.py -+++ node/configure.py -@@ -1265,9 +1265,7 @@ def configure_node(o): - - o['variables']['want_separate_host_toolset'] = int(cross_compiling) - -- # Enable branch protection for arm64 - if target_arch == 'arm64': -- o['cflags']+=['-msign-return-address=all'] - o['variables']['arm_fpu'] = options.arm_fpu or 'neon' - - if options.node_snapshot_main is not None: -diff --git node/deps/v8/include/v8-initialization.h node/deps/v8/include/v8-initialization.h -index d3e35d6ec5..6e9bbe3849 100644 ---- node/deps/v8/include/v8-initialization.h -+++ node/deps/v8/include/v8-initialization.h -@@ -89,6 +89,10 @@ class V8_EXPORT V8 { - static void SetFlagsFromCommandLine(int* argc, char** argv, - bool remove_flags); - -+ static void EnableCompilationForSourcelessUse(); -+ static void DisableCompilationForSourcelessUse(); -+ static void FixSourcelessScript(Isolate* v8_isolate, Local script); -+ - /** Get the version string. */ - static const char* GetVersion(); - -diff --git node/deps/v8/src/api/api.cc node/deps/v8/src/api/api.cc -index a4a4381614..2998f3c49b 100644 ---- node/deps/v8/src/api/api.cc -+++ node/deps/v8/src/api/api.cc -@@ -683,6 +683,29 @@ void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) { - HelpOptions(HelpOptions::kDontExit)); - } - -+bool save_lazy; -+bool save_predictable; -+ -+void V8::EnableCompilationForSourcelessUse() { -+ save_lazy = i::FLAG_lazy; -+ i::FLAG_lazy = false; -+ save_predictable = i::FLAG_predictable; -+ i::FLAG_predictable = true; -+} -+ -+void V8::DisableCompilationForSourcelessUse() { -+ i::FLAG_lazy = save_lazy; -+ i::FLAG_predictable = save_predictable; -+} -+ -+void V8::FixSourcelessScript(Isolate* v8_isolate, Local unbound_script) { -+ auto isolate = reinterpret_cast(v8_isolate); -+ auto function_info = -+ i::Handle::cast(Utils::OpenHandle(*unbound_script)); -+ i::Handle script(i::Script::cast(function_info->script()), isolate); -+ script->set_source(i::ReadOnlyRoots(isolate).undefined_value()); -+} -+ - RegisteredExtension* RegisteredExtension::first_extension_ = nullptr; - - RegisteredExtension::RegisteredExtension(std::unique_ptr extension) -diff --git node/deps/v8/src/codegen/compiler.cc node/deps/v8/src/codegen/compiler.cc -index 5431deb83e..d11f04ccac 100644 ---- node/deps/v8/src/codegen/compiler.cc -+++ node/deps/v8/src/codegen/compiler.cc -@@ -3497,7 +3497,7 @@ MaybeHandle GetSharedFunctionInfoForScriptImpl( - maybe_script = lookup_result.script(); - maybe_result = lookup_result.toplevel_sfi(); - is_compiled_scope = lookup_result.is_compiled_scope(); -- if (!maybe_result.is_null()) { -+ if (!maybe_result.is_null() && source->length()) { - compile_timer.set_hit_isolate_cache(); - } else if (can_consume_code_cache) { - compile_timer.set_consuming_code_cache(); -diff --git node/deps/v8/src/objects/js-function.cc node/deps/v8/src/objects/js-function.cc -index 62fe309a47..f1875ce023 100644 ---- node/deps/v8/src/objects/js-function.cc -+++ node/deps/v8/src/objects/js-function.cc -@@ -1245,6 +1245,9 @@ Handle JSFunction::ToString(Handle function) { - Handle maybe_class_positions = JSReceiver::GetDataProperty( - isolate, function, isolate->factory()->class_positions_symbol()); - if (maybe_class_positions->IsClassPositions()) { -+ if (String::cast(Script::cast(shared_info->script()).source()).IsUndefined(isolate)) { -+ return isolate->factory()->NewStringFromAsciiChecked("class {}"); -+ } - ClassPositions class_positions = - ClassPositions::cast(*maybe_class_positions); - int start_position = class_positions.start(); -diff --git node/deps/v8/src/objects/shared-function-info-inl.h node/deps/v8/src/objects/shared-function-info-inl.h -index 43ef0d3d17..79b774463f 100644 ---- node/deps/v8/src/objects/shared-function-info-inl.h -+++ node/deps/v8/src/objects/shared-function-info-inl.h -@@ -637,6 +637,14 @@ bool SharedFunctionInfo::ShouldFlushCode( - } - if (!data.IsBytecodeArray()) return false; - -+ Object script_obj = script(); -+ if (!script_obj.IsUndefined()) { -+ Script script = Script::cast(script_obj); -+ if (script.source().IsUndefined()) { -+ return false; -+ } -+ } -+ - if (IsStressFlushingEnabled(code_flush_mode)) return true; - - BytecodeArray bytecode = BytecodeArray::cast(data); -diff --git node/deps/v8/src/parsing/parsing.cc node/deps/v8/src/parsing/parsing.cc -index 8c55a6fb6e..70bf82a57d 100644 ---- node/deps/v8/src/parsing/parsing.cc -+++ node/deps/v8/src/parsing/parsing.cc -@@ -42,6 +42,7 @@ bool ParseProgram(ParseInfo* info, Handle