From 53c7e0488eed5e1265416e3a61fbcac296ca0621 Mon Sep 17 00:00:00 2001 From: islandryu Date: Fri, 9 Jan 2026 20:26:32 +0900 Subject: [PATCH 1/6] 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 27b827b8ed3e4b..bf0279ddc52b72 100755 --- a/configure.py +++ b/configure.py @@ -1627,6 +1627,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 @@ -1969,8 +1978,14 @@ def configure_library(lib, output, pkgname=None): 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 ce9452e8715a68..0ec075eef5a025 100644 --- a/lib/util.js +++ b/lib/util.js @@ -457,6 +457,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 4708e57e2bb9bb..b64e43eeccb629 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 db83c46c81f767..2e7b50511f24c3 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 af42a3bd72c3f4..fbfda9c1551e07 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 7cdc3a3f817536ef5eac0d0785affd167bbad4c3 Mon Sep 17 00:00:00 2001 From: islandryu Date: Fri, 9 Jan 2026 20:40:14 +0900 Subject: [PATCH 2/6] 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 bf0279ddc52b72..aa56bee03aa885 100755 --- a/configure.py +++ b/configure.py @@ -1985,7 +1985,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 0ec075eef5a025..423e28d963cf10 100644 --- a/lib/util.js +++ b/lib/util.js @@ -29,6 +29,7 @@ const { Error, ErrorCaptureStackTrace, FunctionPrototypeBind, + MathFloor, NumberIsSafeInteger, ObjectDefineProperties, ObjectDefineProperty, @@ -458,7 +459,7 @@ function getCallSites(frameCount = 10, options) { return mapCallSite(binding.getCallSites(frameCount)); } - frameCount = Math.floor(frameCount); + frameCount = MathFloor(frameCount); return binding.getCallSites(frameCount); }; From 3a222f84b1e4bb354cda55567f589504dc4865c5 Mon Sep 17 00:00:00 2001 From: islandryu Date: Sat, 10 Jan 2026 22:35:16 +0900 Subject: [PATCH 3/6] 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 aa56bee03aa885..52f8574176644d 100755 --- a/configure.py +++ b/configure.py @@ -1627,14 +1627,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: @@ -1981,9 +1983,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 6847a418d96c683d45d269d43c16573474e6bcce 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/6] 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 423e28d963cf10..40a996978f583b 100644 --- a/lib/util.js +++ b/lib/util.js @@ -459,8 +459,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 ed196658b287b2d7e8d6f329a07eabcc75fb40b6 Mon Sep 17 00:00:00 2001 From: islandryu Date: Sat, 10 Jan 2026 23:27:27 +0900 Subject: [PATCH 5/6] 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 a96907da58b240..fad18a4b8e0d37 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -582,7 +582,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 40a996978f583b..ebd486addc7eb2 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, @@ -453,13 +453,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 explicitly 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' + })); } { From 8541332a76376fa1e4d3ca209463918bafd3fe77 Mon Sep 17 00:00:00 2001 From: islandryu Date: Tue, 13 Jan 2026 18:24:59 +0900 Subject: [PATCH 6/6] use options.debug for branching --- configure.py | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/configure.py b/configure.py index 52f8574176644d..a37ebefe7c0507 100755 --- a/configure.py +++ b/configure.py @@ -1627,17 +1627,6 @@ 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, 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'] = [] - 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: arm_float_abi = options.arm_float_abi @@ -1980,14 +1969,7 @@ def configure_library(lib, output, pkgname=None): def configure_v8(o, configs): - set_configuration_variable_and_defines( - configs, - 'v8_enable_v8_checks', - release='0', - debug='1', - release_define=None, - debug_define='V8_ENABLE_CHECKS', - ) + set_configuration_variable(configs, 'v8_enable_v8_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 @@ -2618,11 +2600,10 @@ def make_bin_override(): del configurations['Release']['variables'] config_debug_vars = configurations['Debug']['variables'] del configurations['Debug']['variables'] -output['conditions'].append(['build_type=="Release"', { - 'variables': config_release_vars, -}, { - 'variables': config_debug_vars, -}]) +if options.debug: + variables = variables | config_debug_vars +else: + variables = variables | config_release_vars # make_global_settings should be a root level element too if 'make_global_settings' in output: