From bbb871a202abdca49aeb9b010634d34043a0fcda Mon Sep 17 00:00:00 2001 From: islandryu Date: Fri, 9 Jan 2026 20:26:32 +0900 Subject: [PATCH 1/5] build: enable -DV8_ENABLE_CHECKS flag Fixes: https://github.com/nodejs/node/issues/61301 --- configure.py | 19 +++++++++++++++++-- lib/util.js | 2 ++ src/heap_utils.cc | 2 +- src/node_builtins.cc | 3 ++- src/node_util.cc | 2 +- src/util-inl.h | 8 +++++++- 6 files changed, 30 insertions(+), 6 deletions(-) diff --git a/configure.py b/configure.py index 04a7db46856016..f7cfd8eb987b89 100755 --- a/configure.py +++ b/configure.py @@ -1481,6 +1481,15 @@ def set_configuration_variable(configs, name, release=None, debug=None): configs['Release']['variables'][name] = release configs['Debug']['variables'][name] = debug +def set_configuration_variable_and_defines(configs, name, define, release=None, debug=None): + set_configuration_variable(configs, name, release, debug) + if configs['Debug'].get('defines') is None: + configs['Debug']['defines'] = [] + if configs['Release'].get('defines') is None: + configs['Release']['defines'] = [] + configs['Debug']['defines'].append(define) + configs['Release']['defines'].append(define) + def configure_arm(o): if options.arm_float_abi: arm_float_abi = options.arm_float_abi @@ -1817,8 +1826,14 @@ def configure_rust(o, configs): def configure_v8(o, configs): - set_configuration_variable(configs, 'v8_enable_v8_checks', release=1, debug=0) - + set_configuration_variable_and_defines( + configs, + 'v8_enable_v8_checks', + 'V8_ENABLE_CHECKS', + release='0', + debug='1' + ) + o['variables']['v8_enable_webassembly'] = 0 if options.v8_lite_mode else 1 o['variables']['v8_enable_javascript_promise_hooks'] = 1 o['variables']['v8_enable_lite_mode'] = 1 if options.v8_lite_mode else 0 diff --git a/lib/util.js b/lib/util.js index 7c75615e5c70da..a2b4ec36c566cd 100644 --- a/lib/util.js +++ b/lib/util.js @@ -456,6 +456,8 @@ function getCallSites(frameCount = 10, options) { if (options.sourceMap === true || (getOptionValue('--enable-source-maps') && options.sourceMap !== false)) { return mapCallSite(binding.getCallSites(frameCount)); } + + frameCount = Math.floor(frameCount); return binding.getCallSites(frameCount); }; diff --git a/src/heap_utils.cc b/src/heap_utils.cc index 7b93698c7fe125..98bab1c5404fe2 100644 --- a/src/heap_utils.cc +++ b/src/heap_utils.cc @@ -89,7 +89,7 @@ class JSGraph : public EmbedderGraph { } Node* V8Node(const Local& value) override { - return V8Node(value.As()); + return V8Node(v8::Local(value)); } Node* AddNode(std::unique_ptr node) override { diff --git a/src/node_builtins.cc b/src/node_builtins.cc index 2a77bf6d7a4715..93295d83f9676d 100644 --- a/src/node_builtins.cc +++ b/src/node_builtins.cc @@ -9,6 +9,7 @@ #include "quic/guard.h" #include "simdutf.h" #include "util-inl.h" +#include "v8-value.h" namespace node { namespace builtins { @@ -441,7 +442,7 @@ void BuiltinLoader::SaveCodeCache(const std::string& id, Local data) { new_cached_data.reset( ScriptCompiler::CreateCodeCache(mod->GetUnboundModuleScript())); } else { - Local fun = data.As(); + Local fun = data.As().As(); new_cached_data.reset(ScriptCompiler::CreateCodeCacheForFunction(fun)); } CHECK_NOT_NULL(new_cached_data); diff --git a/src/node_util.cc b/src/node_util.cc index 2e4d98a8a66a18..ff43d2aeca86f2 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -258,7 +258,7 @@ static void GetCallSites(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(context); CHECK_EQ(args.Length(), 1); - CHECK(args[0]->IsNumber()); + CHECK(args[0]->IsUint32()); const uint32_t frames = args[0].As()->Value(); CHECK(frames >= 1 && frames <= 200); diff --git a/src/util-inl.h b/src/util-inl.h index 6898e8ea794675..f8cccfef6b65b3 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -22,6 +22,7 @@ #ifndef SRC_UTIL_INL_H_ #define SRC_UTIL_INL_H_ +#include "v8-isolate.h" #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #include @@ -678,10 +679,15 @@ T FromV8Value(v8::Local value) { "Type is out of unsigned integer range"); if constexpr (!loose) { CHECK(value->IsUint32()); + return static_cast(value.As()->Value()); } else { CHECK(value->IsNumber()); + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Local context = isolate->GetCurrentContext(); + v8::Maybe maybe = value->Uint32Value(context); + CHECK(!maybe.IsNothing()); + return static_cast(maybe.FromJust()); } - return static_cast(value.As()->Value()); } else if constexpr (std::is_integral_v && std::is_signed_v) { static_assert( std::numeric_limits::max() <= std::numeric_limits::max() && From a737f4f0e4bed08d6cac635ad1086c7be2e5fb15 Mon Sep 17 00:00:00 2001 From: islandryu Date: Fri, 9 Jan 2026 20:40:14 +0900 Subject: [PATCH 2/5] fix lint --- configure.py | 2 +- lib/util.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/configure.py b/configure.py index f7cfd8eb987b89..502403ce02d6a5 100755 --- a/configure.py +++ b/configure.py @@ -1833,7 +1833,7 @@ def configure_v8(o, configs): release='0', debug='1' ) - + o['variables']['v8_enable_webassembly'] = 0 if options.v8_lite_mode else 1 o['variables']['v8_enable_javascript_promise_hooks'] = 1 o['variables']['v8_enable_lite_mode'] = 1 if options.v8_lite_mode else 0 diff --git a/lib/util.js b/lib/util.js index a2b4ec36c566cd..0d9689e080c563 100644 --- a/lib/util.js +++ b/lib/util.js @@ -29,6 +29,7 @@ const { Error, ErrorCaptureStackTrace, FunctionPrototypeBind, + MathFloor, NumberIsSafeInteger, ObjectDefineProperties, ObjectDefineProperty, @@ -457,7 +458,7 @@ function getCallSites(frameCount = 10, options) { return mapCallSite(binding.getCallSites(frameCount)); } - frameCount = Math.floor(frameCount); + frameCount = MathFloor(frameCount); return binding.getCallSites(frameCount); }; From 7478be684227c2a9a9b177ef42a5ac7b29ef157f Mon Sep 17 00:00:00 2001 From: islandryu Date: Sat, 10 Jan 2026 22:35:16 +0900 Subject: [PATCH 3/5] fix set_configuration_variable_and_defines --- configure.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/configure.py b/configure.py index 502403ce02d6a5..a26d41e898fca3 100755 --- a/configure.py +++ b/configure.py @@ -1481,14 +1481,16 @@ def set_configuration_variable(configs, name, release=None, debug=None): configs['Release']['variables'][name] = release configs['Debug']['variables'][name] = debug -def set_configuration_variable_and_defines(configs, name, define, release=None, debug=None): +def set_configuration_variable_and_defines(configs, name, release=None, debug=None, release_define=None, debug_define=None): set_configuration_variable(configs, name, release, debug) if configs['Debug'].get('defines') is None: configs['Debug']['defines'] = [] if configs['Release'].get('defines') is None: configs['Release']['defines'] = [] - configs['Debug']['defines'].append(define) - configs['Release']['defines'].append(define) + if debug_define: + configs['Debug']['defines'].append(debug_define) + if release_define: + configs['Release']['defines'].append(release_define) def configure_arm(o): if options.arm_float_abi: @@ -1829,9 +1831,10 @@ def configure_v8(o, configs): set_configuration_variable_and_defines( configs, 'v8_enable_v8_checks', - 'V8_ENABLE_CHECKS', release='0', - debug='1' + debug='1', + release_define=None, + debug_define='V8_ENABLE_CHECKS', ) o['variables']['v8_enable_webassembly'] = 0 if options.v8_lite_mode else 1 From c3eb3ff30a563f4c22cc4c06bb68e110fd394d1d Mon Sep 17 00:00:00 2001 From: Ryuhei Shima <65934663+islandryu@users.noreply.github.com> Date: Sat, 10 Jan 2026 23:03:33 +0900 Subject: [PATCH 4/5] Update lib/util.js Co-authored-by: Yagiz Nizipli --- lib/util.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/util.js b/lib/util.js index 0d9689e080c563..0500cb2ff762ed 100644 --- a/lib/util.js +++ b/lib/util.js @@ -458,8 +458,7 @@ function getCallSites(frameCount = 10, options) { return mapCallSite(binding.getCallSites(frameCount)); } - frameCount = MathFloor(frameCount); - return binding.getCallSites(frameCount); +return binding.getCallSites(MathFloor(frameCount)); }; // Public util.deprecate API From fef59e57f706cd42f1c508302264270cc36e2cb5 Mon Sep 17 00:00:00 2001 From: islandryu Date: Sat, 10 Jan 2026 23:27:27 +0900 Subject: [PATCH 5/5] validate frameCount is an integer --- doc/api/util.md | 2 +- lib/util.js | 7 +++---- test/parallel/test-util-getcallsites.js | 15 +++++++-------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/doc/api/util.md b/doc/api/util.md index 9a02eb43c45b76..031062ba5d6ea4 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -548,7 +548,7 @@ changes: > Stability: 1.1 - Active development -* `frameCount` {number} Optional number of frames to capture as call site objects. +* `frameCount` {integer} Optional number of frames to capture as call site objects. **Default:** `10`. Allowable range is between 1 and 200. * `options` {Object} Optional * `sourceMap` {boolean} Reconstruct the original location in the stacktrace from the source-map. diff --git a/lib/util.js b/lib/util.js index 0500cb2ff762ed..5e185f13f00ce7 100644 --- a/lib/util.js +++ b/lib/util.js @@ -29,7 +29,6 @@ const { Error, ErrorCaptureStackTrace, FunctionPrototypeBind, - MathFloor, NumberIsSafeInteger, ObjectDefineProperties, ObjectDefineProperty, @@ -67,6 +66,7 @@ const { validateString, validateOneOf, validateObject, + validateInteger, } = require('internal/validators'); const { isReadableStream, @@ -452,13 +452,12 @@ function getCallSites(frameCount = 10, options) { } // Using kDefaultMaxCallStackSizeToCapture as reference - validateNumber(frameCount, 'frameCount', 1, 200); + validateInteger(frameCount, 'frameCount', 1, 200); // If options.sourceMaps is true or if sourceMaps are enabled but the option.sourceMaps is not set explictly to false if (options.sourceMap === true || (getOptionValue('--enable-source-maps') && options.sourceMap !== false)) { return mapCallSite(binding.getCallSites(frameCount)); } - -return binding.getCallSites(MathFloor(frameCount)); + return binding.getCallSites(frameCount); }; // Public util.deprecate API diff --git a/test/parallel/test-util-getcallsites.js b/test/parallel/test-util-getcallsites.js index 7cab4f6cac6397..a14fcb3482cdf9 100644 --- a/test/parallel/test-util-getcallsites.js +++ b/test/parallel/test-util-getcallsites.js @@ -31,15 +31,14 @@ const assert = require('node:assert'); ); } -// Guarantee dot-right numbers are ignored +// frameCount must be an integer { - const callSites = getCallSites(3.6); - assert.strictEqual(callSites.length, 3); -} - -{ - const callSites = getCallSites(3.4); - assert.strictEqual(callSites.length, 3); + assert.throws(() => { + const callSites = getCallSites(3.6); + assert.strictEqual(callSites.length, 3); + }, common.expectsError({ + code: 'ERR_OUT_OF_RANGE' + })); } {