pkg-fetch/patches/node.v20.19.5.cpp.patch
github-actions[bot] 78d158cdcb
feat: add v20.19.5 patch (#109)
## Node.js Patch Update to v20.19.5

This PR updates the Node.js patch to version 20.19.5.

The workflow automatically attempts to resolve patch conflicts using AI
when the OpenAI API key is available.

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-04 17:29:39 +02:00

603 lines
21 KiB
Diff

diff --git node/common.gypi node/common.gypi
index 20e81dea95..3580f7f2e4 100644
--- node/common.gypi
+++ node/common.gypi
@@ -187,7 +187,7 @@
['clang==1', {
'lto': ' -flto ', # Clang
}, {
- 'lto': ' -flto=4 -fuse-linker-plugin -ffat-lto-objects ', # GCC
+ 'lto': ' -flto=4 -ffat-lto-objects ', # GCC
}],
],
},
diff --git node/deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c node/deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c
index 5e7775f1a5..eeebf67796 100644
--- node/deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c
+++ node/deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c
@@ -33,16 +33,6 @@
#include "nghttp3_macro.h"
-#if defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || defined(_M_ARM64))
-unsigned int __popcnt(unsigned int x) {
- unsigned int c = 0;
- for (; x; ++c) {
- x &= x - 1;
- }
- return c;
-}
-#endif
-
int nghttp3_ringbuf_init(nghttp3_ringbuf *rb, size_t nmemb, size_t size,
const nghttp3_mem *mem) {
if (nmemb) {
diff --git node/deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c node/deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c
index 74e488bce7..36ca05e80e 100644
--- node/deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c
+++ node/deps/ngtcp2/ngtcp2/lib/ngtcp2_ringbuf.c
@@ -31,16 +31,6 @@
#include "ngtcp2_macro.h"
-#if defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || defined(_M_ARM64))
-unsigned int __popcnt(unsigned int x) {
- unsigned int c = 0;
- for (; x; ++c) {
- x &= x - 1;
- }
- return c;
-}
-#endif
-
int ngtcp2_ringbuf_init(ngtcp2_ringbuf *rb, size_t nmemb, size_t size,
const ngtcp2_mem *mem) {
uint8_t *buf = ngtcp2_mem_malloc(mem, nmemb * size);
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<UnboundScript> 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 a06394e6c1..154b7a82a8 100644
--- node/deps/v8/src/api/api.cc
+++ node/deps/v8/src/api/api.cc
@@ -806,6 +806,28 @@ 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::v8_flags.lazy;
+ i::v8_flags.lazy = false;
+ save_predictable = i::v8_flags.predictable;
+ i::v8_flags.predictable = true;
+}
+
+void V8::DisableCompilationForSourcelessUse() {
+ i::v8_flags.lazy = save_lazy;
+ i::v8_flags.predictable = save_predictable;
+}
+
+void V8::FixSourcelessScript(Isolate* v8_isolate, Local<UnboundScript> unbound_script) {
+ auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
+ auto function_info = i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(*unbound_script));
+ i::Handle<i::Script> 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> extension)
diff --git node/deps/v8/src/codegen/compiler.cc node/deps/v8/src/codegen/compiler.cc
index 31c5acceeb..56cad8671f 100644
--- node/deps/v8/src/codegen/compiler.cc
+++ node/deps/v8/src/codegen/compiler.cc
@@ -3475,7 +3475,7 @@ MaybeHandle<SharedFunctionInfo> 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 94f7a672a7..57bb3fc7f1 100644
--- node/deps/v8/src/objects/js-function.cc
+++ node/deps/v8/src/objects/js-function.cc
@@ -1280,6 +1280,9 @@ Handle<String> JSFunction::ToString(Handle<JSFunction> function) {
Handle<Object> 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 5621b15d98..722e1d18cb 100644
--- node/deps/v8/src/objects/shared-function-info-inl.h
+++ node/deps/v8/src/objects/shared-function-info-inl.h
@@ -635,6 +635,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<Script> script,
Isolate* isolate, ReportStatisticsMode mode) {
DCHECK(info->flags().is_toplevel());
DCHECK_NULL(info->literal());
+ if (String::cast(script->source()).IsUndefined(isolate)) return false;
VMState<PARSER> state(isolate);
@@ -75,6 +76,7 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
// Create a character stream for the parser.
Handle<Script> script(Script::cast(shared_info->script()), isolate);
+ if (String::cast(script->source()).IsUndefined(isolate)) return false;
Handle<String> source(String::cast(script->source()), isolate);
std::unique_ptr<Utf16CharacterStream> stream(
ScannerStream::For(isolate, source, shared_info->StartPosition(),
diff --git node/deps/v8/src/snapshot/code-serializer.cc node/deps/v8/src/snapshot/code-serializer.cc
index c83e8e4581..8cb451e147 100644
--- node/deps/v8/src/snapshot/code-serializer.cc
+++ node/deps/v8/src/snapshot/code-serializer.cc
@@ -659,10 +659,6 @@ SerializedCodeSanityCheckResult SerializedCodeData::SanityCheck(
SerializedCodeSanityCheckResult SerializedCodeData::SanityCheckJustSource(
uint32_t expected_source_hash) const {
- uint32_t source_hash = GetHeaderValue(kSourceHashOffset);
- if (source_hash != expected_source_hash) {
- return SerializedCodeSanityCheckResult::kSourceMismatch;
- }
return SerializedCodeSanityCheckResult::kSuccess;
}
@@ -679,10 +675,6 @@ SerializedCodeSanityCheckResult SerializedCodeData::SanityCheckWithoutSource()
if (version_hash != Version::Hash()) {
return SerializedCodeSanityCheckResult::kVersionMismatch;
}
- uint32_t flags_hash = GetHeaderValue(kFlagHashOffset);
- if (flags_hash != FlagList::Hash()) {
- return SerializedCodeSanityCheckResult::kFlagsMismatch;
- }
uint32_t payload_length = GetHeaderValue(kPayloadLengthOffset);
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 cc81cb373d..e06da1048a 100644
--- node/lib/child_process.js
+++ node/lib/child_process.js
@@ -169,7 +169,7 @@ function fork(modulePath, args = [], options) {
throw new ERR_CHILD_PROCESS_IPC_REQUIRED('options.stdio');
}
- return spawn(options.execPath, args, options);
+ return module.exports.spawn(options.execPath, args, options);
}
function _forkChild(fd, serializationMode) {
diff --git node/lib/internal/bootstrap/pkg.js node/lib/internal/bootstrap/pkg.js
new file mode 100644
index 0000000000..a697294fdf
--- /dev/null
+++ node/lib/internal/bootstrap/pkg.js
@@ -0,0 +1,49 @@
+'use strict';
+
+const {
+ prepareWorkerThreadExecution,
+ prepareMainThreadExecution
+} = require('internal/process/pre_execution');
+
+if (internalBinding('worker').isMainThread) {
+ prepareMainThreadExecution(true);
+} else {
+ prepareWorkerThreadExecution();
+}
+
+(function () {
+ var __require__ = require;
+ var fs = __require__('fs');
+ var vm = __require__('vm');
+ function readPrelude (fd) {
+ var PAYLOAD_POSITION = '// PAYLOAD_POSITION //' | 0;
+ var PAYLOAD_SIZE = '// PAYLOAD_SIZE //' | 0;
+ var PRELUDE_POSITION = '// PRELUDE_POSITION //' | 0;
+ var PRELUDE_SIZE = '// PRELUDE_SIZE //' | 0;
+ if (!PRELUDE_POSITION) {
+ // no prelude - remove entrypoint from argv[1]
+ process.argv.splice(1, 1);
+ return { undoPatch: true };
+ }
+ var prelude = Buffer.alloc(PRELUDE_SIZE);
+ var read = fs.readSync(fd, prelude, 0, PRELUDE_SIZE, PRELUDE_POSITION);
+ if (read !== PRELUDE_SIZE) {
+ console.error('Pkg: Error reading from file.');
+ process.exit(1);
+ }
+ var s = new vm.Script(prelude, { filename: 'pkg/prelude/bootstrap.js' });
+ var fn = s.runInThisContext();
+ return fn(process, __require__,
+ console, fd, PAYLOAD_POSITION, PAYLOAD_SIZE);
+ }
+ (function () {
+ var fd = fs.openSync(process.execPath, 'r');
+ var result = readPrelude(fd);
+ if (result && result.undoPatch) {
+ var bindingFs = process.binding('fs');
+ fs.internalModuleStat = bindingFs.internalModuleStat;
+ fs.internalModuleReadJSON = bindingFs.internalModuleReadJSON;
+ fs.closeSync(fd);
+ }
+ }());
+}());
diff --git node/lib/internal/modules/cjs/loader.js node/lib/internal/modules/cjs/loader.js
index b12594cc36..bc0361d8aa 100644
--- node/lib/internal/modules/cjs/loader.js
+++ node/lib/internal/modules/cjs/loader.js
@@ -144,7 +144,7 @@ const {
const assert = require('internal/assert');
const fs = require('fs');
const path = require('path');
-const { internalModuleStat } = internalBinding('fs');
+const internalModuleStat = function (f) { return require('fs').internalModuleStat(f); }
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 88c079d10d..a7eaca0574 100644
--- node/lib/internal/modules/package_json_reader.js
+++ node/lib/internal/modules/package_json_reader.js
@@ -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 { resolve, sep, toNamespacedPath } = require('path');
const permission = require('internal/process/permission');
const { kEmptyObject } = require('internal/util');
diff --git node/lib/internal/process/pre_execution.js node/lib/internal/process/pre_execution.js
index 0bbabb80c2..5dd097b69e 100644
--- node/lib/internal/process/pre_execution.js
+++ node/lib/internal/process/pre_execution.js
@@ -50,7 +50,11 @@ const {
},
} = require('internal/v8/startup_snapshot');
+let _alreadyPrepared = false;
+
function prepareMainThreadExecution(expandArgv1 = false, initializeModules = true) {
+ if (_alreadyPrepared === true) return;
+ _alreadyPrepared = true;
return prepareExecution({
expandArgv1,
initializeModules,
@@ -243,7 +247,12 @@ function patchProcessObject(expandArgv1) {
let mainEntry;
// 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] && process.argv[1][0] !== '-') {
+ if (
+ expandArgv1 &&
+ process.argv[1] &&
+ process.argv[1][0] !== '-' &&
+ process.argv[1] !== 'PKG_DUMMY_ENTRYPOINT'
+ ) {
// Expand process.argv[1] into a full path.
const path = require('path');
try {
@@ -739,6 +748,7 @@ function loadPreloadModules() {
// For user code, we preload modules if `-r` is passed
const preloadModules = getOptionValue('--require');
if (preloadModules && preloadModules.length > 0) {
+ assert(false, '--require is not supported');
const {
Module: {
_preloadModules,
diff --git node/lib/vm.js node/lib/vm.js
index a12e932d8d..931a996330 100644
--- node/lib/vm.js
+++ node/lib/vm.js
@@ -98,6 +98,7 @@ class Script extends ContextifyScript {
produceCachedData = false,
importModuleDynamically,
[kParsingContext]: parsingContext,
+ sourceless = false,
} = options;
validateString(filename, 'options.filename');
@@ -121,7 +122,8 @@ class Script extends ContextifyScript {
cachedData,
produceCachedData,
parsingContext,
- hostDefinedOptionId);
+ hostDefinedOptionId,
+ sourceless);
} catch (e) {
throw e; /* node-do-not-add-exception-line */
}
diff --git node/src/inspector_agent.cc node/src/inspector_agent.cc
index bb39a0cb42..5fa6cb65cc 100644
--- node/src/inspector_agent.cc
+++ node/src/inspector_agent.cc
@@ -766,11 +766,6 @@ bool Agent::Start(const std::string& path,
StartIoThreadAsyncCallback));
uv_unref(reinterpret_cast<uv_handle_t*>(&start_io_thread_async));
start_io_thread_async.data = this;
- if (parent_env_->should_start_debug_signal_handler()) {
- // Ignore failure, SIGUSR1 won't work, but that should not block node
- // start.
- StartDebugSignalHandler();
- }
parent_env_->AddCleanupHook([](void* data) {
Environment* env = static_cast<Environment*>(data);
diff --git node/src/node.cc node/src/node.cc
index 1137dcafcd..482feb65b5 100644
--- node/src/node.cc
+++ node/src/node.cc
@@ -389,6 +389,8 @@ MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
return env->RunSnapshotDeserializeMain();
}
+ StartExecution(env, "internal/bootstrap/pkg");
+
if (env->worker_context() != nullptr) {
return StartExecution(env, "internal/main/worker_thread");
}
@@ -613,14 +615,6 @@ static void PlatformInit(ProcessInitializationFlags::Flags flags) {
}
if (!(flags & ProcessInitializationFlags::kNoDefaultSignalHandling)) {
-#if HAVE_INSPECTOR
- sigset_t sigmask;
- sigemptyset(&sigmask);
- sigaddset(&sigmask, SIGUSR1);
- const int err = pthread_sigmask(SIG_SETMASK, &sigmask, nullptr);
- CHECK_EQ(err, 0);
-#endif // HAVE_INSPECTOR
-
ResetSignalHandlers();
}
diff --git node/src/node_contextify.cc node/src/node_contextify.cc
index 2b93926a73..9f68232bd4 100644
--- node/src/node_contextify.cc
+++ node/src/node_contextify.cc
@@ -79,6 +79,7 @@ using v8::String;
using v8::Symbol;
using v8::Uint32;
using v8::UnboundScript;
+using v8::V8;
using v8::Value;
using v8::WeakCallbackInfo;
@@ -817,13 +818,14 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
Local<ArrayBufferView> cached_data_buf;
bool produce_cached_data = false;
Local<Context> parsing_context = context;
+ bool sourceless = false;
Local<Symbol> id_symbol;
if (argc > 2) {
// new ContextifyScript(code, filename, lineOffset, columnOffset,
// cachedData, produceCachedData, parsingContext,
- // hostDefinedOptionId)
- CHECK_EQ(argc, 8);
+ // hostDefinedOptionId, sourceless)
+ CHECK_GE(argc, 8);
CHECK(args[2]->IsNumber());
line_offset = args[2].As<Int32>()->Value();
CHECK(args[3]->IsNumber());
@@ -844,6 +846,10 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
}
CHECK(args[7]->IsSymbol());
id_symbol = args[7].As<Symbol>();
+ if (argc > 8) {
+ CHECK(args[8]->IsBoolean());
+ sourceless = args[8]->IsTrue();
+ }
}
ContextifyScript* contextify_script =
@@ -892,6 +898,10 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
ShouldNotAbortOnUncaughtScope no_abort_scope(env);
Context::Scope scope(parsing_context);
+ if (sourceless && produce_cached_data) {
+ V8::EnableCompilationForSourcelessUse();
+ }
+
MaybeLocal<UnboundScript> maybe_v8_script =
ScriptCompiler::CompileUnboundScript(isolate, &source, compile_options);
@@ -906,6 +916,11 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
return;
}
+ if (sourceless && compile_options == ScriptCompiler::kConsumeCodeCache) {
+ if (!source.GetCachedData()->rejected) {
+ V8::FixSourcelessScript(env->isolate(), v8_script);
+ }
+ }
contextify_script->script_.Reset(isolate, v8_script);
contextify_script->script_.SetWeak();
contextify_script->object()->SetInternalFieldForNodeCore(kUnboundScriptSlot,
@@ -939,6 +954,10 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) {
.IsNothing())
return;
+ if (sourceless && produce_cached_data) {
+ V8::DisableCompilationForSourcelessUse();
+ }
+
TRACE_EVENT_END0(TRACING_CATEGORY_NODE2(vm, script), "ContextifyScript::New");
}
diff --git node/src/node_main.cc node/src/node_main.cc
index f66099a557..4048f6bd93 100644
--- node/src/node_main.cc
+++ node/src/node_main.cc
@@ -22,6 +22,8 @@
#include "node.h"
#include <cstdio>
+int reorder(int argc, char** argv);
+
#ifdef _WIN32
#include <windows.h>
#include <VersionHelpers.h>
@@ -88,12 +90,95 @@ int wmain(int argc, wchar_t* wargv[]) {
}
argv[argc] = nullptr;
// Now that conversion is done, we can finally start.
- return node::Start(argc, argv);
+ return reorder(argc, argv);
}
#else
// UNIX
int main(int argc, char* argv[]) {
+ return reorder(argc, argv);
+}
+#endif
+
+#include <string.h>
+
+int strlen2 (char* s) {
+ int len = 0;
+ while (*s) {
+ len += 1;
+ s += 1;
+ }
+ return len;
+}
+
+bool should_set_dummy() {
+#ifdef _WIN32
+ #define MAX_ENV_LENGTH 32767
+ wchar_t execpath_env[MAX_ENV_LENGTH];
+ DWORD result = GetEnvironmentVariableW(L"PKG_EXECPATH", execpath_env, MAX_ENV_LENGTH);
+ if (result == 0 && GetLastError() != ERROR_SUCCESS) return true;
+ return wcscmp(execpath_env, L"PKG_INVOKE_NODEJS") != 0;
+#else
+ const char* execpath_env = getenv("PKG_EXECPATH");
+ if (!execpath_env) return true;
+ return strcmp(execpath_env, "PKG_INVOKE_NODEJS") != 0;
+#endif
+}
+
+// for uv_setup_args
+int adjacent(int argc, char** argv) {
+ size_t size = 0;
+ for (int i = 0; i < argc; i++) {
+ size += strlen(argv[i]) + 1;
+ }
+ char* args = new char[size];
+ size_t pos = 0;
+ for (int i = 0; i < argc; i++) {
+ memcpy(&args[pos], argv[i], strlen(argv[i]) + 1);
+ argv[i] = &args[pos];
+ pos += strlen(argv[i]) + 1;
+ }
return node::Start(argc, argv);
}
+
+volatile char* BAKERY = (volatile char*) "\0// BAKERY // BAKERY " \
+ "// BAKERY // BAKERY // BAKERY // BAKERY // BAKERY // BAKERY " \
+ "// BAKERY // BAKERY // BAKERY // BAKERY // BAKERY // BAKERY " \
+ "// BAKERY // BAKERY // BAKERY // BAKERY // BAKERY // BAKERY ";
+
+#ifdef __clang__
+__attribute__((optnone))
+#elif defined(__GNUC__)
+__attribute__((optimize(0)))
#endif
+
+int load_baked(char** nargv) {
+ int c = 1;
+
+ char* bakery = (char*) BAKERY;
+ while (true) {
+ size_t width = strlen2(bakery);
+ if (width == 0) break;
+ nargv[c++] = bakery;
+ bakery += width + 1;
+ }
+
+ return c;
+}
+
+int reorder(int argc, char** argv) {
+ char** nargv = new char*[argc + 64];
+
+ nargv[0] = argv[0];
+ int c = load_baked(nargv);
+
+ if (should_set_dummy()) {
+ nargv[c++] = (char*) "PKG_DUMMY_ENTRYPOINT";
+ }
+
+ for (int i = 1; i < argc; i++) {
+ nargv[c++] = argv[i];
+ }
+
+ return adjacent(c, nargv);
+}
diff --git node/src/node_options.cc node/src/node_options.cc
index 9d5accc3eb..8e3c304a13 100644
--- node/src/node_options.cc
+++ node/src/node_options.cc
@@ -316,6 +316,7 @@ void Parse(
// TODO(addaleax): Make that unnecessary.
DebugOptionsParser::DebugOptionsParser() {
+ return;
#ifndef DISABLE_SINGLE_EXECUTABLE_APPLICATION
if (sea::IsSingleExecutable()) return;
#endif
diff --git node/tools/icu/icu-generic.gyp node/tools/icu/icu-generic.gyp
index 2655b9e694..1d951571c7 100644
--- node/tools/icu/icu-generic.gyp
+++ node/tools/icu/icu-generic.gyp
@@ -52,7 +52,7 @@
'conditions': [
[ 'os_posix == 1 and OS != "mac" and OS != "ios"', {
'cflags': [ '-Wno-deprecated-declarations', '-Wno-strict-aliasing' ],
- 'cflags_cc': [ '-frtti' ],
+ 'cflags_cc': [ '-frtti', '-fno-lto' ],
'cflags_cc!': [ '-fno-rtti' ],
}],
[ 'OS == "mac" or OS == "ios"', {