nodejs / nodejs/node

vm: eval cache mixes up script origins

未关闭
#65,866 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

主要语言
JavaScript
星标
122k
派生
37.4k
平均合并
4 天 3 小时
30 天内合并 PR
272

描述

Bug report

  • Node.js: v24.19.0, v26.8.1, v27.0.0-pre (local build)
  • Platform: Microsoft Windows NT 10.0.26200.0 x64
  • Subsystem: vm
// test.mjs
import assert from 'node:assert/strict';
import { Script } from 'node:vm';

const out = [];

function createScript(name) {
  return new Script(`globalThis.eval('import("node:fs")')`, {
    importModuleDynamically(specifier) {
      out.push(name);
      return import(specifier);
    },
  });
}

const a = createScript('A');
const b = createScript('B');

for (const script of [a, b, a]) {
  await script.runInThisContext();
}

assert.deepEqual(out, ['A', 'B', 'A']);

Running this example as node --experimental-vm-modules test.mjs will give different wrong answers between v24 and v26 because V8 removed delayed caching some time during those releases. However, running with --no-compilation-cache will pass the test assertion.

The bug is with V8. In deps/v8/src/codegen/compiler.cc, around the "cache lookup key" comment, indirect eval uses kNoSourcePosition (-1), and the cache key does not distinguish the originating script. This allows identical eval source text from different scripts in the same realm to produce a false positive cache hit.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

使用提供的 test.mjs 在 --experimental-vm-modules 下复现该问题,然后检查 deps/v8/src/codegen/compiler.cc 中 "cache lookup key" 注释附近的代码。跟踪 eval 缓存查找和相关测试,以了解脚本来源是如何表示的。启用编译缓存后 A/B/A 断言通过,同时现有的无编译缓存行为仍然正确,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
cpp, javascript, node.js
领域
backend
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
活跃
描述清晰度
基本清楚
新手友好度
45/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。