Skip to content

deps: update V8 to 14.6#61898

Open
targos wants to merge 26 commits intonodejs:mainfrom
targos:v8-146
Open

deps: update V8 to 14.6#61898
targos wants to merge 26 commits intonodejs:mainfrom
targos:v8-146

Conversation

@targos
Copy link
Copy Markdown
Member

@targos targos commented Feb 20, 2026

PR for previous version: #61681

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/gyp
  • @nodejs/security-wg
  • @nodejs/v8-update

@nodejs-github-bot nodejs-github-bot added build Issues and PRs related to build files or the CI. needs-ci PRs that need a full CI run. v8 engine Issues and PRs related to the V8 dependency. labels Feb 20, 2026
@targos
Copy link
Copy Markdown
Member Author

targos commented Feb 20, 2026

Compared to version 14.5, there is a new test failure that is not obvious. Local run:

=== release test-repl-mode ===                                                
Path: parallel/test-repl-mode
node:internal/assert/utils:146
  throw error;
  ^

AssertionError [ERR_ASSERTION]: The input did not match the regular expression /ReferenceError: x is not defined/. Input:

'> 3\n> '

    at testStrictMode (/home/targos/git/nodejs/v8-next-update/test/parallel/test-repl-mode.js:38:10)
    at /home/targos/git/nodejs/v8-next-update/test/parallel/test-repl-mode.js:18:3
    at Array.forEach (<anonymous>)
    at Object.<anonymous> (/home/targos/git/nodejs/v8-next-update/test/parallel/test-repl-mode.js:17:7)
    at Module._compile (node:internal/modules/cjs/loader:1811:14)
    at Object..js (node:internal/modules/cjs/loader:1951:10)
    at Module.load (node:internal/modules/cjs/loader:1532:32)
    at Module._load (node:internal/modules/cjs/loader:1334:12)
    at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
    at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5) {
  generatedMessage: true,
  code: 'ERR_ASSERTION',
  actual: '> 3\n> ',
  expected: /ReferenceError: x is not defined/,
  operator: 'match',
  diff: 'simple'
}

Node.js v26.0.0-pre
Command: out/Release/node /home/targos/git/nodejs/v8-next-update/test/parallel/test-repl-mode.js

This was referenced Feb 20, 2026
@targos targos added the semver-major PRs that contain breaking changes and should be released in the next major version. label Feb 20, 2026
@targos
Copy link
Copy Markdown
Member Author

targos commented Feb 20, 2026

Additionally, snapshot is no longer reproducible:

Edit: not macOS-specific: https://github.com/nodejs/node/actions/runs/22221811293/job/64279253109

=== release test-snapshot-reproducible ===
Path: parallel/test-snapshot-reproducible
Error: --- stderr ---
node:internal/assert/utils:146
  throw error;
  ^

AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
... Skipped lines

  [
    '#include <cstddef>',
    '#include "env.h"',
    '#include "node_snapshot_builder.h"',
    '#include "v8.h"',
...
    'namespace node {',
+   'static const char v8_snapshot_blob_data[] = {4,0,0,0,1,0,0,0,3,126,58,75,100,19,-88,-44,49,52,46,54,46,50,48,50,46,52,45,110,111,100,101,46,54,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  // 0',
-   'static const char v8_snapshot_blob_data[] = {4,0,0,0,1,0,0,0,-72,125,-78,63,100,19,-88,-44,49,52,46,54,46,50,48,50,46,52,45,110,111,100,101,46,54,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  // 0',
    '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,-95,18,0,40,-48,24,0,104,-6,28,0,-48,-8,29,0,-24,-11,30,0,-48,-15,31,0,-88,6,-34,-64,-80,-96,18,0,-95,24,96,0,0,0,0,83,0,0,0,96,0,0,0,0,  // 1',
    '0,0,0,0,96,0,0,0,0,0,0,0,0,96,0,0,0,0,-61,1,0,0,96,0,0,0,0,60,0,0,0,96,0,0,0,0,-28,1,0,0,96,0,0,0,0,0,0,0,0,96,0,0,0,0,36,1,0,0,11,5,24,-30,-1,1,  // 2',
    '5,24,-94,0,2,5,24,98,1,2,5,24,34,2,2,5,24,-30,2,2,5,24,-94,3,2,5,24,98,4,2,5,24,34,5,2,5,24,-30,5,2,5,24,-94,6,2,5,24,98,7,2,5,24,34,8,2,5,24,-30,8,2,1,76,7,101,  // 3',
    '15,69,64,97,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,98,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,64,96,0,0,0,0,0,0,0,0,7,-123,2,64,96,0,0,0,  // 4',
    '0,8,0,0,0,-127,0,91,64,1,20,83,69,97,0,0,0,0,96,0,0,0,0,0,0,0,1,0,0,0,93,1,20,83,69,97,0,0,0,0,96,0,0,0,0,0,0,0,1,0,0,0,93,1,20,83,69,97,0,0,0,0,96,0,  // 5',
...
    '0,0,0,4,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-124,0,7,33,10,1,28,-108,-128,27,31,16,5,24,-94,-65,2,6,77,31,4,-67,52,1,12,7,29,1,64,32,109,18,96,  // 34655',
+   '0,0,0,0,0,2,0,0,7,13,13,1,28,4,40,-128,27,31,20,5,24,-94,-65,2,6,81,31,-109,1,12,-108,64,32,113,18,96,0,0,0,0,0,1,0,0,91,96,0,0,0,0,-45,31,0,0,1,28,4,33,53,1,-128,-111,102,0,  // 34656',
-   '0,0,0,0,0,2,0,0,7,13,13,1,28,4,40,-128,27,31,20,5,24,-94,-65,2,6,81,31,-109,1,12,-108,64,32,113,18,96,0,0,0,0,0,1,0,0,91,96,0,0,0,0,-122,33,0,0,1,28,4,33,53,1,-128,-111,102,0,  // 34656',
    '0,0,0,30,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-115,0,9,53,8,1,12,7,1,  // 34657',
    '15,1,28,-106,-128,27,32,4,6,5,1,1,40,4,92,96,0,0,0,0,8,0,0,0,6,9,1,4,100,1,28,-106,-128,27,31,8,5,24,-94,-65,2,6,85,31,-109,1,12,-108,64,32,117,18,9,-107,2,1,32,4,-124,-128,27,32,81,15,  // 34658',
    '6,-31,27,4,61,59,4,29,47,65,1,28,-106,-128,27,32,85,15,6,-27,27,-108,4,37,47,64,1,28,4,40,-128,27,32,89,15,6,-23,27,-108,4,45,47,4,49,47,66,96,0,0,0,0,1,3,0,0,71,7,117,16,96,0,0,0,0,  // 34659',
    '13,2,0,0,72,7,121,16,96,0,0,0,0,13,1,0,0,91,32,93,15,6,-19,27,-108,4,53,47,1,28,-105,-128,27,31,8,5,24,-94,-65,2,6,89,31,4,-67,52,1,12,7,29,1,64,32,121,18,1,32,4,-124,-128,27,31,20,5,  // 34660',
    '24,-94,-65,2,6,93,31,-107,1,12,-106,64,32,125,18,65,1,32,-105,-128,27,31,12,5,24,-94,-65,2,6,97,31,-107,1,12,-106,64,32,-127,18,65,1,32,-105,-128,27,31,16,5,24,-94,-65,2,6,101,31,-107,1,12,-106,64,32,-123,18,65,  // 34661',

    at Object.<anonymous> (/Users/runner/work/node/node/node/test/parallel/test-snapshot-reproducible.js:47:8)
    at Module._compile (node:internal/modules/cjs/loader:1811:14)
    at Object..js (node:internal/modules/cjs/loader:1951:10)
    at Module.load (node:internal/modules/cjs/loader:1532:32)
    at Module._load (node:internal/modules/cjs/loader:1334:12)
    at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
    at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5)
    at node:internal/main/run_main_module:33:47 {
  generatedMessage: true,
  code: 'ERR_ASSERTION',
  actual: [
    '#include <cstddef>',
    '#include "env.h"',
    '#include "node_snapshot_builder.h"',
    '#include "v8.h"',
    '',
    '// This file is generated by tools/snapshot. Do not edit.',
    '',
    'namespace node {',
    'static const char v8_snapshot_blob_data[] = {4,0,0,0,1,0,0,0,3,126,58,75,100,19,-88

@targos targos added the help wanted Issues that need assistance from volunteers or PRs that need help to proceed. label Feb 20, 2026
@Renegade334
Copy link
Copy Markdown
Member

Note that this changeset does not compile with GCC <14.1, unless the following patch is applied:

diff --git a/deps/v8/src/objects/js-duration-format.cc b/deps/v8/src/objects/js-duration-format.cc
index 41bdbc2cc6..c9ef451713 100644
--- a/deps/v8/src/objects/js-duration-format.cc
+++ b/deps/v8/src/objects/js-duration-format.cc
@@ -807,7 +807,7 @@ void OutputFractional(const char* type, int64_t integer, int32_t powerOfTen,
   // Pass in the value as int64_t and ask ICU to scale down.
   nfOpts = nfOpts.scale(icu::number::Scale::powerOfTen(-powerOfTen));

-  int64_t factor = static_cast<int64_t>(std::powl(10, powerOfTen));
+  int64_t factor = static_cast<int64_t>(std::pow(10.0L, powerOfTen));
   int64_t bound = std::numeric_limits<int64_t>::max() / factor - 1;
   UErrorCode status = U_ZERO_ERROR;
   // Use faster ICU API formatInt if the value fit the precision int64_t,

@sxa
Copy link
Copy Markdown
Member

sxa commented Feb 22, 2026

Additionally, snapshot is no longer reproducible:

FYI @joyeecheung

@sxa
Copy link
Copy Markdown
Member

sxa commented Feb 22, 2026

For what it's worth this branch seems to build ok with a RISC-V cross compiler too 👍🏻 (An experimental platform but I thought I'd mention it anyway ;-) )

@targos
Copy link
Copy Markdown
Member Author

targos commented Mar 13, 2026

@nodejs/platform-windows Can you please have a look at the Windows build failure?

@targos
Copy link
Copy Markdown
Member Author

targos commented Mar 13, 2026

There's still this REPL strict mode issue: #61898 (comment)

@nodejs/repl

@targos
Copy link
Copy Markdown
Member Author

targos commented Mar 13, 2026

And the reproducible snapshot: #61898 (comment)

@nodejs/startup (for lack of a more specific team)

@Renegade334
Copy link
Copy Markdown
Member

Renegade334 commented Mar 13, 2026

There's still this REPL strict mode issue: #61898 (comment)

It's not so much a REPL issue as an issue with the VM global sandbox interceptors, introduced as a regression with 113b5cf. Previously, we were simulating CheckContextualStoreToJSGlobalObject-esque behaviour by rejecting interceptions on global proxy properties in strict mode if the receiver was not the global object. Now that we can no longer observe the receiver, that mechanism doesn't exist, and statements like nonExistantGlobalVariable = 42 are setting a property on the global sandbox instead of throwing in strict mode.

(We should probably have VM tests for this.)

@Renegade334
Copy link
Copy Markdown
Member

Note that this changeset does not compile with GCC <14.1, unless the following patch is applied:

diff --git a/deps/v8/src/objects/js-duration-format.cc b/deps/v8/src/objects/js-duration-format.cc
index 41bdbc2cc6..c9ef451713 100644
--- a/deps/v8/src/objects/js-duration-format.cc
+++ b/deps/v8/src/objects/js-duration-format.cc
@@ -807,7 +807,7 @@ void OutputFractional(const char* type, int64_t integer, int32_t powerOfTen,
   // Pass in the value as int64_t and ask ICU to scale down.
   nfOpts = nfOpts.scale(icu::number::Scale::powerOfTen(-powerOfTen));

-  int64_t factor = static_cast<int64_t>(std::powl(10, powerOfTen));
+  int64_t factor = static_cast<int64_t>(std::pow(10.0L, powerOfTen));
   int64_t bound = std::numeric_limits<int64_t>::max() / factor - 1;
   UErrorCode status = U_ZERO_ERROR;
   // Use faster ICU API formatInt if the value fit the precision int64_t,

We will either need to merge (or upstream) this, or change the GCC build requirement to >=14.1.

@targos
Copy link
Copy Markdown
Member Author

targos commented Mar 13, 2026

Would you like to try and upstream it?

@Renegade334
Copy link
Copy Markdown
Member

It would be easier if someone with existing Chromium contributor status did the honours, I'd rather not jump through the hoops for a one-liner!

@joyeecheung
Copy link
Copy Markdown
Member

joyeecheung commented Mar 14, 2026

Locally this fixes the snapshot reproducibility test for me

See diff
diff --git a/deps/v8/src/builtins/builtins-proxy-gen.cc b/deps/v8/src/builtins/builtins-proxy-gen.cc
index 0bc45bac300..f0047f044f2 100644
--- a/deps/v8/src/builtins/builtins-proxy-gen.cc
+++ b/deps/v8/src/builtins/builtins-proxy-gen.cc
@@ -63,6 +63,10 @@ TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy(
   StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kTargetOffset, target);
   StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kHandlerOffset, handler);
   StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kFlagsOffset, flags);
+#if TAGGED_SIZE_8_BYTES
+  StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kPaddingOffset,
+                                 Int32Constant(0));
+#endif
 
   return CAST(proxy);
 }
diff --git a/deps/v8/src/heap/factory.cc b/deps/v8/src/heap/factory.cc
index b6f6938450c..e0117df19f9 100644
--- a/deps/v8/src/heap/factory.cc
+++ b/deps/v8/src/heap/factory.cc
@@ -3945,6 +3945,9 @@ Handle<JSProxy> Factory::NewJSProxy(DirectHandle<JSReceiver> target,
   result->set_target(*target, SKIP_WRITE_BARRIER);
   result->set_handler(*handler, SKIP_WRITE_BARRIER);
   result->set_flags(JSProxy::IsRevocableBit::encode(revocable));
+#if TAGGED_SIZE_8_BYTES
+  result->set_padding(0);
+#endif
   return handle(result, isolate());
 }
 

Uploaded https://chromium-review.googlesource.com/c/v8/v8/+/7666243

@joyeecheung
Copy link
Copy Markdown
Member

It would be easier if someone with existing Chromium contributor status did the honours, I'd rather not jump through the hoops for a one-liner!

Also uploaded https://chromium-review.googlesource.com/c/v8/v8/+/7666244 (IIUC, it was a libstdc++ issue fixed by https://gcc.gnu.org/pipermail/libstdc++/2023-February/055493.html)

@StefanStojanovic
Copy link
Copy Markdown
Contributor

@nodejs/platform-windows Can you please have a look at the Windows build failure?

I'll take a look. Thanks for the ping.

@StefanStojanovic
Copy link
Copy Markdown
Contributor

@nodejs/platform-windows Can you please have a look at the Windows build failure?

Will look into it. Thanks for the ping.

hubot pushed a commit to v8/v8 that referenced this pull request Mar 16, 2026
So that snapshots with proxies can be reproducible.

Refs: nodejs/node#61898
Change-Id: I01fac5e18c73cd482a1ae63750dbadf42a12e08a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7666243
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#105830}
@StefanStojanovic
Copy link
Copy Markdown
Contributor

@targos, here is the patch to enable building on Windows: v8-146-fix.patch. Two small changes were needed.

targos pushed a commit to targos/node that referenced this pull request Mar 17, 2026
Original commit message:

    Zero-initialize proxy padding

    So that snapshots with proxies can be reproducible.

    Refs: nodejs#61898
    Change-Id: I01fac5e18c73cd482a1ae63750dbadf42a12e08a
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7666243
    Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Cr-Commit-Position: refs/heads/main@{#105830}

Refs: v8/v8@edeb0a4
@targos
Copy link
Copy Markdown
Member Author

targos commented Mar 17, 2026

Thanks @StefanStojanovic and @joyeecheung. I pushed your fixes. Let's see how it goes on GH runners.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@targos
Copy link
Copy Markdown
Member Author

targos commented Mar 26, 2026

Okay, now we're back to a debug build error that already happened with earlier V8 versions. @joyeecheung found a fix for it (093b60b) but that doesn't work anymore, because debug builds also create a release binary and the v8_enable_verify_write_barriers should not be set when creating the release binary. I don't know how to tweak the config to fix that!

@targos

This comment was marked as resolved.

@miladfarca

This comment was marked as resolved.

Original commit message:

    Mark MemCopyAndSwitchEndianness src input as `const`

    Needed after this CL: http://crrev.com/c/7600437
    Currently getting the following error:
    ```
    candidate function not viable: no known conversion from 'const unsigned char *' to 'void *'
    ```

    Change-Id: I0c0f065b822e0f95ffd06207d280fc8b7bab4403
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7601332
    Reviewed-by: Clemens Backes <clemensb@chromium.org>
    Commit-Queue: Milad Farazmand <mfarazma@ibm.com>
    Cr-Commit-Position: refs/heads/main@{#105413}

Refs: v8/v8@daf4656
@targos
Copy link
Copy Markdown
Member Author

targos commented Mar 26, 2026

@nodejs/platform-smartos PTAL:

On SmartOS 22, there is a compile error: https://ci.nodejs.org/job/node-test-commit-smartos/64813/nodes=smartos22-x64/console

On SmartOS 23, there is a linker error: https://ci.nodejs.org/job/node-test-commit-smartos/64813/nodes=smartos23-x64/console

@danmcd
Copy link
Copy Markdown
Contributor

danmcd commented Mar 26, 2026

@nodejs/platform-smartos PTAL:

On SmartOS 22, there is a compile error: https://ci.nodejs.org/job/node-test-commit-smartos/64813/nodes=smartos22-x64/console

On SmartOS 23, there is a linker error: https://ci.nodejs.org/job/node-test-commit-smartos/64813/nodes=smartos23-x64/console

Running this build on a SmartOS 24.4 LTS zone locally. If it fails I will provide appropriate diffs. If it succeeds, we'll need to see what is differeing in 23.4 LTS pkgsrc, OR the platform image your jenkins agent(s) are running on.

@legendecas
Copy link
Copy Markdown
Member

@isheludko: The interceptor callbacks should behave as follows:

1. when a property in question does not "exist in the interceptor object" the callbacks should return `Intercepted::kNo` to make V8 proceed with lookup.

2. when a property "exists in the interceptor object" the callbacks should return `Intercepted::kYes`.

3. some operations for existing properties (`[[Set]]`, `[[DefineOwnProperty]]`, `[[Delete]]`) return boolean result according to the spec and might not succeeed. In that case the callback in addition to (2) should set the result to `false`: `args.GetReturnValue().Set(false);` (by default the result of the operation is `true`).

4. handling `args.ShouldThrowOnError()` is optional since V8 14.4 (https://crrev.com/c/7168624). V8 reacts on `false` result and throws default exception in strict mode as it does in other non-interceptor cases. I'd suggest not to use `ShouldThrowOnError()` unless you really need to throw a customized error message.

But in this way, Node.js can no longer distinguish between "use strict"; x = 5 and globalThis.x = 5 in call interceptor's PropertySetterCallback directly. And thus, globalThis.x = 5 would only set on the global proxy, and the interceptor will not be able to forward the property on the sandbox. This breaks the API though.

@danmcd
Copy link
Copy Markdown
Contributor

danmcd commented Mar 27, 2026

Running this build on a SmartOS 24.4 LTS zone locally. If it fails I will provide appropriate diffs. If it succeeds, we'll need to see what is differeing in 23.4 LTS pkgsrc, OR the platform image your jenkins agent(s) are running on.

24.4 LTS misbehaves the same as 23.4 LTS. Duplicate symbols. Here's an example error:

(file /zones/d00f8241-409b-4b1c-8de6-546d4c16410f/data/danmcd/node/out/Release/obj.target/tools/v8_gypfiles/libv8_initializers.a(exported-macros-assembler.o) type=FUNC; file /zones/d00f8241-409b-4b1c-8de6-546d4c16410f/data/danmcd/node/out/Release/obj.target/tools/v8_gypfiles/libv8_initializers_slow.a(exported-macros-assembler.o) type=FUNC);

I don't know v8 well enough but why do we have both libv8_initializers{,_slow}.a ? That seems... wrong?

@targos
Copy link
Copy Markdown
Member Author

targos commented Mar 27, 2026

It is expected to have both. libv8_initializers_slow is here to work around a GCC 12 bug. It compiles only a couple of files with a different optimization level. See

{
# This target is used to work around a GCC issue that causes the
# compilation to take several minutes when using -O2 or -O3.
# This is fixed in GCC 13.
'target_name': 'v8_initializers_slow',
'type': 'static_library',
'toolsets': ['host', 'target'],
'dependencies': [
'generate_bytecode_builtins_list',
'run_torque',
'fp16',
'abseil.gyp:abseil',
],
'cflags!': ['-O3'],
'cflags': ['-O1'],
'sources': [
'<(SHARED_INTERMEDIATE_DIR)/torque-generated/src/builtins/js-to-wasm-tq-csa.h',
'<(SHARED_INTERMEDIATE_DIR)/torque-generated/src/builtins/js-to-wasm-tq-csa.cc',
'<(SHARED_INTERMEDIATE_DIR)/torque-generated/src/builtins/wasm-to-js-tq-csa.h',
'<(SHARED_INTERMEDIATE_DIR)/torque-generated/src/builtins/wasm-to-js-tq-csa.cc',
],
'conditions': [
['v8_enable_i18n_support==1', {
'dependencies': [
'<(icu_gyp_path):icui18n',
'<(icu_gyp_path):icuuc',
],
}],
['v8_enable_temporal_support==1 and node_shared_temporal_capi=="false"', {
'dependencies': [
'../../deps/crates/crates.gyp:temporal_capi',
],
}],
],
}, # v8_initializers_slow
{
'target_name': 'v8_initializers',
'type': 'static_library',
'toolsets': ['host', 'target'],
'dependencies': [
'torque_generated_initializers',
'v8_base_without_compiler',
'v8_shared_internal_headers',
'v8_pch',
'fp16',
'abseil.gyp:abseil',
],
'include_dirs': [
'<(SHARED_INTERMEDIATE_DIR)',
'<(generate_bytecode_output_root)',
],
'sources': [
'<!@pymod_do_main(GN-scraper "<(V8_ROOT)/BUILD.gn" "\\"v8_initializers.*?sources = ")',
],
'conditions': [
['v8_enable_webassembly==1', {
'dependencies': [
'v8_initializers_slow',
],
# Compiled by v8_initializers_slow target.
'sources!': [
'<(SHARED_INTERMEDIATE_DIR)/torque-generated/src/builtins/js-to-wasm-tq-csa.h',
'<(SHARED_INTERMEDIATE_DIR)/torque-generated/src/builtins/js-to-wasm-tq-csa.cc',
'<(SHARED_INTERMEDIATE_DIR)/torque-generated/src/builtins/wasm-to-js-tq-csa.h',
'<(SHARED_INTERMEDIATE_DIR)/torque-generated/src/builtins/wasm-to-js-tq-csa.cc',
],
'sources': [
'<!@pymod_do_main(GN-scraper "<(V8_ROOT)/BUILD.gn" "\\"v8_initializers.*?v8_enable_webassembly.*?sources \\+= ")',
],

@targos
Copy link
Copy Markdown
Member Author

targos commented Mar 27, 2026

I can try to remove this hack. Maybe V8 has changed enough to make the problem disappear?

@danmcd
Copy link
Copy Markdown
Contributor

danmcd commented Mar 27, 2026

I can try to remove this hack. Maybe V8 has changed enough to make the problem disappear?

It now builds (have not run gmake test yet, that's running now) on 24.4 LTS. I suspect it'll cure the 23.4 LTS Jenkins job as well.

@isheludko
Copy link
Copy Markdown
Contributor

@legendecas: The difference between contextual stores (x = 5) and non-contextual ones (globalThis.x = 5) from V8 perspective is that for the former in sloppy mode V8 just defines/stores the property to the global object (depending on the property existence), while in strict mode RefereceError is thrown instead of defining the property if it doesn't exist yet. IIUC, as long as the interceptor callbacks are agreed on whether the interceptor has a property or not everything should be handled by V8 - either the property would be added to context's internal global object's property storage or exception would be thrown.
Just for the record, another difference is that after detaching a context from the global (v8::Context::DetachGlobal()) the non-contextual accesses in existing functions created in that context would keep on referencing properties in the old global object while the non-contextual accesses would reference the new context's global object.

I think I don't understand the motivation for the necessity to distinguish the contextual stores (x = 5) from non-contextual ones (globalThis.x = 5) in the callback.

BTW, given that ContextifyContext's callbacks use GetRealNamedPropertyAttributes which searches the whole prototype chain except interceptors, please check whether non-masking interceptor mode would fulfill the desired behavior.
The GetRealNamedProperty* machinery was initially used by Chromium's interceptors to implement named property visibility algorithm for WebIDL interfaces not having [LegacyOverrideBuiltIns] attribute and then this lookup logic was moved to V8 side as non-masking interceptor mode.

@legendecas
Copy link
Copy Markdown
Member

legendecas commented Mar 27, 2026

@isheludko : I think I don't understand the motivation for the necessity to distinguish the contextual stores (x = 5) from non-contextual ones (globalThis.x = 5) in the callback.

With a code snippet like

const vm = require('node:vm')
const ctx = {};
vm.createContext(ctx);
vm.runInContext('"use strict"; x = 5', ctx); // ReferenceError
ctx.x // => should be undefined

Here, ctx is a plain JS object, and any interceptor calls on the global proxy object will be forwarded onto the ctx object. For example, globalThis.x = 5 will be forwarded by the global proxy interceptor to ctx as ctx.x = 5.

Both [[Set]] for x = 5 and globalThis.x = 5 will call the NamedPropertySetterCallback. But for contextual x = 5 in strict mode, the NamedPropertySetterCallback should not forward to ctx.x = 5, because V8 throws the ReferenceError, after NamedPropertySetterCallback. However, without comparing This(), a NamedPropertySetterCallback has no way to determine if this [[Set]] should be actually set or not.

According to https://tc39.es/ecma262/#sec-object-environment-records-setmutablebinding-n-v-s, if V8 could call NamedPropertyQueryCallback before NamedPropertySetterCallback to test if the property exist, and avoid call NamedPropertySetterCallback in strict-mode contextual set, it would be better. This is analogous to the spec step 2-4.

But right now, V8 calls NamedPropertySetterCallback unconditionally, using NamedPropertySetterCallback to detect if the property exist in interceptor.

@isheludko
Copy link
Copy Markdown
Contributor

isheludko commented Mar 27, 2026

@legendecas: Thank you for the explanation! Let me think what we can do to make SetMutableBinding logic better work with interceptors on a global object. Calling query callback in such a case sounds like a reasonable option.

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@danmcd
Copy link
Copy Markdown
Contributor

danmcd commented Mar 27, 2026

I can try to remove this hack. Maybe V8 has changed enough to make the problem disappear?

It now builds (have not run gmake test yet, that's running now) on 24.4 LTS. I suspect it'll cure the 23.4 LTS Jenkins job as well.

Seems to be better, but compared with prior releases seems to have a few more failures.

[08:50|% 100|+ 5095|-   6]: Done                                              

Failed tests:
out/Release/node /zones/d00f8241-409b-4b1c-8de6-546d4c16410f/data/danmcd/node/test/test-runner/test-output-coverage-with-mock.mjs
out/Release/node --test-reporter=./test/common/test-error-reporter.js --test-reporter-destination=stdout /zones/d00f8241-409b-4b1c-8de6-546d4c16410f/data/danmcd/node/test/es-module/test-esm-import-meta-main-eval.mjs
out/Release/node --test-reporter=./test/common/test-error-reporter.js --test-reporter-destination=stdout /zones/d00f8241-409b-4b1c-8de6-546d4c16410f/data/danmcd/node/test/es-module/test-esm-detect-ambiguous.mjs
out/Release/node /zones/d00f8241-409b-4b1c-8de6-546d4c16410f/data/danmcd/node/test/parallel/test-esm-loader-hooks-inspect-wait.js
out/Release/node /zones/d00f8241-409b-4b1c-8de6-546d4c16410f/data/danmcd/node/test/parallel/test-child-process-stdio-reuse-readable-stdio.js
out/Release/node --test-reporter=./test/common/test-error-reporter.js --test-reporter-destination=stdout /zones/d00f8241-409b-4b1c-8de6-546d4c16410f/data/danmcd/node/test/parallel/test-node-run.js

Full output available upon request.

@targos
Copy link
Copy Markdown
Member Author

targos commented Mar 28, 2026

@danmcd the tests passed on SmartOS 23 in the CI run: https://ci.nodejs.org/job/node-test-commit-smartos/64850/nodes=smartos23-x64/
SmartOS 22 still failed to compile. I suggest we skip this version for Node.js >=26. WDYT?

@targos
Copy link
Copy Markdown
Member Author

targos commented Mar 28, 2026

Well actually AIX failed with the same error (/cc @nodejs/platform-aix).
It is probably a problem with GCC 12:

03:52:08   g++-12 -o /home/iojs/build/workspace/node-test-commit-aix/nodes/aix72-power9/out/Release/obj.target/v8_compiler/deps/v8/src/compiler/turbofan-graph-visualizer.o ../deps/v8/src/compiler/turbofan-graph-visualizer.cc '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_FILE_OFFSET_BITS=64' '-DNODE_OPENSSL_CONF_NAME=nodejs_conf' '-DICU_NO_USER_DATA_OVERRIDE' '-DV8_GYP_BUILD' '-DV8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DV8_TARGET_ARCH_PPC64' '-D_LINUX_SOURCE_COMPAT=1' '-D_ALL_SOURCE=1' '-DV8_EMBEDDER_STRING="-node.12"' '-DENABLE_DISASSEMBLER' '-DV8_PROMISE_INTERNAL_FIELD_COUNT=1' '-DOBJECT_PRINT' '-DV8_INTL_SUPPORT' '-DV8_ATOMIC_OBJECT_FIELD_WRITES' '-DV8_ENABLE_LAZY_SOURCE_POSITIONS' '-DV8_USE_SIPHASH' '-DV8_ENABLE_SEEDED_ARRAY_INDEX_HASH' '-DNDEBUG' '-DV8_WIN64_UNWINDING_INFO' '-DV8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH' '-DV8_USE_ZLIB' '-DV8_ENABLE_LEAPTIERING' '-DV8_ENABLE_SPARKPLUG' '-DV8_ENABLE_TURBOFAN' '-DV8_ENABLE_WEBASSEMBLY' '-DV8_ENABLE_JAVASCRIPT_PROMISE_HOOKS' '-DV8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA' '-DV8_ALLOCATION_FOLDING' '-DV8_ALLOCATION_SITE_TRACKING' '-DV8_ADVANCED_BIGINT_ALGORITHMS' '-DTOOLCHAIN_MISS_ASM_HWCAP_H' '-DHWY_BROKEN_EMU128=0' '-DUCONFIG_NO_SERVICE=1' '-DU_ENABLE_DYLOAD=0' '-DU_STATIC_IMPLEMENTATION=1' '-DU_HAVE_STD_STRING=1' '-DUCONFIG_NO_BREAK_ITERATION=0' -I../deps/v8 -I../deps/v8/include -I../deps/v8/third_party/fp16/src/include -I../deps/v8/third_party/highway/src -I/home/iojs/build/workspace/node-test-commit-aix/nodes/aix72-power9/out/Release/obj/gen/generate-bytecode-output-root -I/home/iojs/build/workspace/node-test-commit-aix/nodes/aix72-power9/out/Release/obj/gen -I../deps/icu-small/source/i18n -I../deps/icu-small/source/common -I../deps/v8/third_party/abseil-cpp  -pthread -Wno-unused-parameter -maix64 -Wno-attributes -Wno-strict-overflow -Wno-return-type -Wno-int-in-bool-context -Wno-deprecated -Wno-stringop-overflow -Wno-stringop-overread -Wno-restrict -Wno-array-bounds -Wno-nonnull -Wno-dangling-pointer -flax-vector-conversions -ffp-contract=off -mcpu=power9 -mfprnd -mno-popcntb -maix64 -fdollars-in-identifiers -fno-extern-tls-init -O3 -fno-omit-frame-pointer -fdata-sections -ffunction-sections -O3 -fno-rtti -fno-exceptions -fno-strict-aliasing -std=gnu++20 -Wno-invalid-offsetof -MMD -MF /home/iojs/build/workspace/node-test-commit-aix/nodes/aix72-power9/out/Release/.deps//home/iojs/build/workspace/node-test-commit-aix/nodes/aix72-power9/out/Release/obj.target/v8_compiler/deps/v8/src/compiler/turbofan-graph-visualizer.o.d.raw   -c
03:52:15 In file included from ../deps/v8/src/compiler/turboshaft/block-instrumentation-reducer.h:8,
03:52:15                  from ../deps/v8/src/compiler/turboshaft/register-allocation-phase.h:12,
03:52:15                  from ../deps/v8/src/compiler/turboshaft/pipelines.h:27,
03:52:15                  from ../deps/v8/src/compiler/pipeline.cc:87:
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h: In member function 'v8::internal::compiler::turboshaft::V<v8::internal::compiler::turboshaft::WordWithBits<32> > v8::internal::compiler::turboshaft::AssemblerOpInterface<Next>::SmiLessThan(v8::internal::compiler::turboshaft::ConstOrV<v8::internal::Smi>, v8::internal::compiler::turboshaft::ConstOrV<v8::internal::Smi>)':
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h:1838:33: error: static assertion failed
03:52:15  1838 |       static_assert(kTaggedSize == kInt32Size);                            \
03:52:15       |                     ~~~~~~~~~~~~^~~~~~~~~~~~~
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h:1838:33: note: in definition of macro 'SMI_COMPARISON_OP'
03:52:15  1838 |       static_assert(kTaggedSize == kInt32Size);                            \
03:52:15       |                                 ^~
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h:1838:33: note: the comparison reduces to '(8 == 4)'
03:52:15  1838 |       static_assert(kTaggedSize == kInt32Size);                            \
03:52:15       |                     ~~~~~~~~~~~~^~~~~~~~~~~~~
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h:1838:33: note: in definition of macro 'SMI_COMPARISON_OP'
03:52:15  1838 |       static_assert(kTaggedSize == kInt32Size);                            \
03:52:15       |                                 ^~
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h:1839:53: error: static assertion failed
03:52:15  1839 |       static_assert(v8::internal::SmiValuesAre31Bits());                   \
03:52:15       |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h:1845:3: note: in expansion of macro 'SMI_COMPARISON_OP'
03:52:15  1845 |   SMI_COMPARISON_OP(SmiLessThan, IntPtrLessThan, Int32LessThan)
03:52:15       |   ^~~~~~~~~~~~~~~~~
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h: In member function 'v8::internal::compiler::turboshaft::V<v8::internal::compiler::turboshaft::WordWithBits<32> > v8::internal::compiler::turboshaft::AssemblerOpInterface<Next>::SmiLessThanOrEqual(v8::internal::compiler::turboshaft::ConstOrV<v8::internal::Smi>, v8::internal::compiler::turboshaft::ConstOrV<v8::internal::Smi>)':
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h:1838:33: error: static assertion failed
03:52:15  1838 |       static_assert(kTaggedSize == kInt32Size);                            \
03:52:15       |                     ~~~~~~~~~~~~^~~~~~~~~~~~~
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h:1838:33: note: in definition of macro 'SMI_COMPARISON_OP'
03:52:15  1838 |       static_assert(kTaggedSize == kInt32Size);                            \
03:52:15       |                                 ^~
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h:1838:33: note: the comparison reduces to '(8 == 4)'
03:52:15  1838 |       static_assert(kTaggedSize == kInt32Size);                            \
03:52:15       |                     ~~~~~~~~~~~~^~~~~~~~~~~~~
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h:1838:33: note: in definition of macro 'SMI_COMPARISON_OP'
03:52:15  1838 |       static_assert(kTaggedSize == kInt32Size);                            \
03:52:15       |                                 ^~
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h:1839:53: error: static assertion failed
03:52:15  1839 |       static_assert(v8::internal::SmiValuesAre31Bits());                   \
03:52:15       |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
03:52:15 ../deps/v8/src/compiler/turboshaft/assembler.h:1846:3: note: in expansion of macro 'SMI_COMPARISON_OP'
03:52:15  1846 |   SMI_COMPARISON_OP(SmiLessThanOrEqual, IntPtrLessThanOrEqual,
03:52:15       |   ^~~~~~~~~~~~~~~~~
03:52:15 gmake[2]: *** [tools/v8_gypfiles/v8_compiler.target.mk:414: /home/iojs/build/workspace/node-test-commit-aix/nodes/aix72-power9/out/Release/obj.target/v8_compiler/deps/v8/src/compiler/pipeline.o] Error 1

@targos
Copy link
Copy Markdown
Member Author

targos commented Mar 28, 2026

The main blocker is still the debug build, btw /cc @joyeecheung

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Issues and PRs related to build files or the CI. help wanted Issues that need assistance from volunteers or PRs that need help to proceed. needs-ci PRs that need a full CI run. request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. semver-major PRs that contain breaking changes and should be released in the next major version. v8 engine Issues and PRs related to the V8 dependency.

Projects

None yet

Development

Successfully merging this pull request may close these issues.