Python 进程内嵌 V8 的原生浏览器环境层——在 Python 里运行依赖浏览器环境的
JavaScript(指纹脚本、签名算法、风控 SDK),接口用 v8::FunctionTemplate
原生注册,[native code]、原型访问器、instanceof 语义天然正确。
零浏览器、零 Node、无头无渲染,MIT 开源(闭源商业产品 iv8 的开源替代)。
import v8env
ctx = v8env.JSContext(environment={
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Chrome/140 ...",
"platform": "Win32",
"screen_width": 2560, "screen_height": 1440,
})
sig = ctx.eval("signSdk.collect()") # JS 以为自己在 Chrome 里
print(sig) # Python 直接拿到结果| execjs / PyMiniRacer | jsdom (Node) | Playwright / 无头浏览器 | iv8(闭源) | v8env | |
|---|---|---|---|---|---|
| 形态 | 纯 JS 沙箱,无 DOM | Node + JS 重建的 DOM | 真浏览器 | Python + 内嵌 V8 | Python + 内嵌 V8 |
接口原生性([native code]/原型链/instanceof) |
— | JS 模拟,可被探穿 | 真 | 真 | 真(FunctionTemplate 原生注册) |
| DOM | 无 | 有(JS 实现) | 有 | 有(C++) | 有(C++ 树 + 原生包装) |
| WebCrypto / Streams / IndexedDB / Worker | — | 部分 | 有 | 有 | 有(第三轮起,见对齐清单) |
| Canvas / WebGL / WebGPU 像素 | — | 需 node-canvas | 有 | 有 | Canvas 2D 真像素 + PNG 编码;WebGL/WebGPU 见偏差表 |
| 指纹可注入 | — | 需 hack | 启动参数 | 配置表 | 配置表(snake_case 键) |
| 离线资源 / 请求拦截 | 无 | 需库 | 需 CDP hack | 有 | 有(三级桥接) |
| DevTools/CDP | 无 | 需库 | 有 | 有 | 有(with_devtools 子集) |
| 调用链监控 | 无 | 无 | trace | 有 | 有(debug 模式原生记录) |
| 并发 | 进程级 | 单线程为主 | 重 | 线程池 | ContextPool(每线程 Isolate,释放 GIL) |
| 依赖重量 | 轻 | 中 | 极重(百 MB 浏览器) | 中 | 中(仅 V8 动态库) |
| 启动/单次执行速度 | 快 | 中 | 慢(进程 + 协议) | 快 | 快(进程内) |
| 许可 | 各异 | MIT | Apache-2.0 | 商业闭源 | MIT |
一句话:要跑真实页面选 Playwright;要“进程内、快、原生语义、可注入指纹”地跑 环境敏感 JS,选 v8env。
brew install v8 cmake # V8 15.x(/opt/homebrew/opt/v8)
bash build.sh # CMake 构建,产物拷入 python/v8env/_v8env*.so
PYTHONPATH=python python3 examples/demo.py跑测试套件(13 套,均为纯 assert 脚本,失败非零退出,结尾 N/N PASSED):
PYTHONPATH=python python3 tests/test_native.py # 检测探针(验收线)
PYTHONPATH=python python3 tests/test_dom.py
PYTHONPATH=python python3 tests/test_net.py
PYTHONPATH=python python3 tests/test_monitor.py
PYTHONPATH=python python3 tests/test_gapfill.py # 第二轮缺口快补
PYTHONPATH=python python3 tests/test_idlgen.py # IDL 生成器(纯 Python)
# 第三轮“对齐 iv8 社区版”(H~M 六域 + 总验收矩阵):
PYTHONPATH=python python3 tests/test_crypto_full.py # WebCrypto 全量
PYTHONPATH=python python3 tests/test_cssom.py # CSSOM / 样式计算
PYTHONPATH=python python3 tests/test_dom3.py # Shadow/自定义元素/Range/...
PYTHONPATH=python python3 tests/test_storage3.py # IDB/Streams/Worker/...
PYTHONPATH=python python3 tests/test_gfx.py # Canvas/WebGL/WebGPU/音频/动画
PYTHONPATH=python python3 tests/test_devtools.py # CDP over WebSocket
PYTHONPATH=python python3 tests/test_align_checklist.py # 社区版对齐矩阵(总验收)
# 无 V8 环境时自测测试逻辑(纯 Python 契约模拟,跳过语义探针):
V8ENV_MOCK=1 python3 tests/test_native.py跑性能基准:
PYTHONPATH=python python3 benchmark/bench.py # 全量(写 bench.json + BENCH.md)
PYTHONPATH=python python3 benchmark/bench.py --quick # 1/10 规模(CI 烟雾用)iv8 社区版公开的能力清单,与 v8env 的逐项对齐状态。总验收线是
tests/test_align_checklist.py(181 条存在性探针);功能语义分别由六套
域套件覆盖。状态:✅ 对齐 / 简化(语义子集,见备注)/ 偏差(行为不同,
见“已知偏差总表”)。
| 社区版能力 | v8env 状态 | 验收套件 | 备注 |
|---|---|---|---|
| navigator.userAgentData(brands/mobile/platform/高熵值) | ✅ | test_gapfill / checklist | |
| WebCrypto:digest | ✅ | test_gapfill | SHA-1/256/384/512 对齐 hashlib |
| WebCrypto:sign/verify(HMAC/RSA-PSS/ECDSA) | ✅ | test_crypto_full | HMAC 对 RFC 4231;RSA/ECDSA 往返 + 篡改验签 |
| WebCrypto:encrypt/decrypt(AES-GCM/AES-CBC/RSA-OAEP) | ✅ | test_crypto_full | NIST GCM/SP800-38A 向量;往返 |
| WebCrypto:deriveBits/deriveKey(HKDF/PBKDF2/ECDH) | ✅ | test_crypto_full | RFC 5869 / hashlib 对照 |
| WebCrypto:importKey/exportKey(raw/jwk)/ generateKey | ✅ | test_crypto_full | |
| CSSStyleSheet / CSSStyleRule / 规则树 | ✅ | test_cssom | |
| @media/@keyframes/@import/@font-face 规则类 | ✅ | test_cssom | |
| insertRule/deleteRule | ✅ | test_cssom | |
| document.styleSheets 聚合 style+link | ✅ | test_cssom | link 走 add_resource 离线包 |
| element.style 双向同步 / setProperty/…/cssText | ✅ | test_cssom | |
| getComputedStyle | ✅ | test_cssom | 简化:类命中/行内优先/后者胜/常用默认值;不做级联全语义 |
| Typed OM(CSSUnitValue)/ CSS.highlights / Highlight | ✅ | test_cssom | Highlight 不参与渲染(无渲染层) |
| Shadow DOM(attachShadow open/closed、template、slot) | ✅ | test_dom3 | |
| customElements(define/get/whenDefined/生命周期) | ✅ | test_dom3 | |
| 未知标签 HTMLUnknownElement / 70 个 HTML 元素接口 | ✅ | test_dom3 / checklist | |
| Range(clone/extract/compareBoundaryPoints…) | ✅ | test_dom3 | |
| Touch/TouchEvent/PointerEvent | ✅ | test_dom3 / test_gapfill | TouchList 为数组形态(偏差表) |
| Geometry(DOMPoint/DOMRect/DOMMatrix/DOMQuad) | ✅ | test_dom3 | |
| FileReader | ✅ | test_dom3 | |
| IndexedDB | ✅ | test_storage3 | 简化:内存实现、单连接(偏差表) |
| CookieStore + document.cookie | ✅ | test_storage3 | |
| navigator.storage.estimate / storageBuckets | ✅ | test_storage3 | 数值为估算口径 |
| Streams 三件套(Readable/Writable/Transform) | ✅ | test_storage3 | |
| Response.body 流式读 | ✅ | test_storage3 | 离线 fetch |
| Worker | ✅ | test_storage3 | 简化:纯 JS 沙箱、add_resource 脚本(偏差表) |
| scheduler.postTask | ✅ | test_storage3 | 优先序语义 |
| navigation(currentEntry/navigate) | ✅ | test_storage3 | 简化 |
| DOMException(code/name) | ✅ | test_storage3 | |
| Canvas 2D(像素级 getImageData) | ✅ | test_gfx | 软件光栅;fillText 不渲染(偏差表) |
| toDataURL 真 PNG(zlib/struct 可解) | ✅ | test_gfx | |
| WebGL 1/2 | 简化 | test_gfx | 桩级上下文:常量/getParameter/getError/扩展表;无 GPU 光栅(偏差表) |
| WebGPU(requestAdapter/requestDevice) | 简化 | test_gfx | 对象链可达,无真实提交执行 |
| AudioContext / OfflineAudioContext | ✅ | test_gfx | 逻辑时钟驱动;默认 44100 可用 env 键覆盖 |
| Element.animate / document.getAnimations | ✅ | test_gfx | tick 驱动、不插值(偏差表) |
| with_devtools(CDP 子集) | ✅ | test_devtools | Runtime.enable/Runtime.evaluate;手写 WS 握手可接 |
| XMLHttpRequest / fetch / WebSocket | ✅(P1/P2 交付) | test_net / test_gapfill | 三级桥接 / Python 工厂 |
| MutationObserver | ✅(P2.5) | test_gapfill | tick 派发(偏差表) |
| SVG 元素接口(30+) | ✅(P2.5) | test_gapfill / checklist | 无几何 API |
| TextEncoder/TextDecoder、Blob/File | ✅(P2.5) | test_gapfill |
对齐矩阵当前状态可在真后端上运行
PYTHONPATH=python python3 tests/test_align_checklist.py复现:它输出 每组 ✅ 计数,全部为真即“社区版对齐完成”。六域(H 加密 / I CSSOM / J DOM 高级 / K 存储·流·Worker / L 图形·媒体 / M DevTools)合入前 该矩阵为红(退出码 1)。
契约以 SPEC.md 为准;签名与语义也写在 python/v8env/__init__.py 的
docstring 里(help(v8env))。
创建一个独立 Isolate + 浏览器环境上下文(非线程安全;跨线程用 ContextPool)。
environment——指纹覆盖表,snake_case 键。未覆盖键回落到内置 macOS/Chrome 默认指纹(user_agent、platform="MacIntel"、screen_width=1920、location_href="https://example.com/"、timezone="Asia/Shanghai"、languages="zh-CN,zh,en"……全表见 SPEC.md 与“环境键总表”附录 C)。mode——"prod"(默认,零监控开销)或"debug"(原生回调记录调用链)。ignore_apis——debug 模式下过滤指定 API(如["Navigator.userAgent"])。
ctx = v8env.JSContext(environment={"user_agent": "UA/1.0", "platform": "Win32"})
ctx.eval("navigator.userAgent") # -> 'UA/1.0'
ctx.eval("navigator instanceof Navigator") # -> True
ctx.eval("String(Navigator)") # -> 'function Navigator() { [native code] }'
ctx.eval("1+1") # -> 2方法:
| 方法 | 签名 | 说明 |
|---|---|---|
eval |
(src: str) -> None|bool|int|float|str|list|dict |
执行 JS;对象/数组尽量转 dict/list;JS 异常转 RuntimeError(消息含 JS stack) |
tick |
() -> int |
逻辑时钟推进一轮(到期定时器/微任务/动画/IDB 事务/Worker 消息),返回执行任务数 |
close |
() -> None |
释放 Isolate 与原生状态 |
monitor_log |
() -> list[str] |
debug 模式调用链,如 ["GET navigator.userAgent", "CALL Document.getElementById"];prod 恒 [] |
net_log |
() -> list[dict] |
XHR/fetch 记录,每条含 source("xhr"/"fetch")、method、url、status |
set_http_handler |
(fn) -> None |
fn(method, url, headers: dict, body: bytes) -> {"status": int, "headers": dict, "body": bytes} |
add_resource |
(url, status=200, headers=None, body=b"") -> None |
离线资源包:精确 URL 优先,其次最长前缀(link/Worker/import 脚本同走此通道) |
set_websocket_factory |
(fn) -> None |
注册 Python 侧 WebSocket 工厂:new WebSocket(url) 经 tick() 触发 fn(url, ws_id, ...),返回的 Python 对象接收 send(data) / close();不设工厂则 tick 后以 code=1006 失败关闭 |
ws_deliver |
(ws_id, kind, data=None, code=1000, reason="") -> None |
Python 向 JS 推送 WS 事件:kind 为 "open" / "message" / "close",经 tick() 派发到 onopen/onmessage/onclose |
with_devtools |
(port: int = 0) -> {url, port} |
启动进程内 DevTools/CDP 服务(M 域):port=0 内核分配;返回对象含 url(HTTP 基址,/json/version 可发现 webSocketDebuggerUrl)与 port;ctx.close() 一并关闭(端口释放)。不调用则零端口零线程 |
pool = v8env.ContextPool(4)
results = pool.map(lambda ctx, src: ctx.eval(src),
["1+1", "'a'+'b'", "[1,2,3]", "sign('x')"])
# -> [2, 'ab', [1, 2, 3], ...] 每线程独立 Isolate,执行期释放 GILJS XHR/fetch
│ ① add_resource 离线资源包(精确/前缀命中,最高优先级,测试确定性来源)
├─未命中→ ② set_http_handler 的 Python 回调(可 mock、可签名、可代理)
└─未设置→ ③ urllib 默认真实请求
全部键为 snake_case,经 JSContext(environment={...}) 覆盖;未覆盖回落到
一致的 macOS Chrome 141 指纹默认值。完整总表(含各轮新增与默认值来源)
见 SPEC.md 附录 C。分组概览:
| 组 | 代表键 | 说明 |
|---|---|---|
| 指纹核心 | user_agent、platform、language、languages、hardware_concurrency、device_memory、max_touch_points、timezone、referrer |
SPEC 正文“环境默认值”全表 |
| 屏幕与窗口 | screen_width/height、screen_avail_*、screen_color_depth/pixel_depth、device_pixel_ratio、window_inner_*、window_outer_*、window_screen_x/y |
|
| Location 族 | location_href(+自动派生 location_protocol/host/hostname/port/pathname/search/hash/origin、window_origin) |
派生键显式覆盖仍优先 |
| UA-Data | user_agent_data_json、user_agent_full_version_list、user_agent_platform_version、user_agent_ua_full_version、user_agent_architecture、user_agent_bitness、user_agent_model、user_agent_wow64 |
第二轮(E)新增 |
| 性能 | time_origin、perf_timing_*(21 键)、perf_navigation_type/redirect_count |
|
| 状态 | visibility_state、document_hidden、document_ready_state、history_length、history_scroll_restoration、charset、online、webdriver、cookie_enabled、do_not_track、plugins_json |
|
| Canvas 桩(历史) | canvas_to_data_url |
第三轮 L 域真 PNG 渲染落地后仅作回退 |
| WebGL(L 域) | webgl_*(待 L 冻结,见下) |
TODO:键名与默认值以 scratch/LREPORT.md 为准,集成方填表 |
| 音频(L 域) | audio_*(如采样率/当前时间步进) |
TODO:同上 |
| GPU(L 域) | gpu_*(WebGPU 适配器信息) |
TODO:同上 |
| CSS/媒体(I 域) | css_media_*(如 prefers-color-schema 等 media query 指纹) |
TODO:以 scratch/IREPORT.md 为准 |
| 存储(K 域) | storage_*(如 estimate 口径/桶配额) |
TODO:以 scratch/KREPORT.md 为准 |
TODO(集成方):L/I/K 域环境键在各自 REPORT 冻结后,把上表 TODO 行 替换为具体键名+默认值,并同步
SPEC.md附录 C 占位段。域内自定键不应 与既有键冲突,统一 snake_case。
Python 进程
┌──────────────────────────────────────────────────────────────┐
│ python/v8env/__init__.py JSContext / ContextPool │
│ │ import │
│ ▼ │
│ python/v8env/_v8env*.so CPython C API 绑定层 │
│ │ │
│ ▼ │
│ src/engine.* src/jscontext.* V8 Isolate/Context 生命周期 │
│ ├─ src/registry.{hpp,cpp} ←—— InterfaceDef 注册表(冻结) │
│ │ ▲ 接口/属性/方法数据表 │
│ │ └── tools/idlgen.py ←—— idl/*.idl │
│ │ └── src/generated/interfaces.gen.{hpp,cpp} │
│ ├─ src/env_config.* 指纹默认值 + environment 覆盖│
│ ├─ src/dom/*(C++ DOM 树/innerHTML 解析/事件/Shadow/自定义元素)│
│ │ └─ RegisterDomBuiltins() → RegisterBuiltin(...) │
│ ├─ src/crypto.* / textcodec.* / file.* WebCrypto/编码/文件│
│ ├─ src/net/{xhr,fetch,ws}.* 三级桥接 + WS 工厂 │
│ ├─ src/timers.* 逻辑时钟(setTimeout/rAF) │
│ ├─ src/monitoring.* / refmonitor.* debug 调用链 + 反射路径 │
│ ├─ src/console.* console 捕获 │
│ └─ src/pool.* ContextPool(每线程 Isolate)│
└──────────────────────────────────────────────────────────────┘
接口安装流水线:idl/*.idl → tools/idlgen.py 生成
src/generated/interfaces.gen.{hpp,cpp}(纯数据表)→ 引擎按表用
FunctionTemplate 搭原型链/访问器 → 方法实现由核心与 DOM 层经
RegisterBuiltin("Interface.method", fn) 注册,装不上就不挂(不崩溃)。
P2 交付面内做:~40+ 接口(Navigator/Location/Screen/Document/元素接口/ Storage/事件…);C++ DOM 树与 innerHTML 简化解析;事件冒泡 (addEventListener/dispatchEvent/preventDefault/stopPropagation/once/ CustomEvent/createEvent 兼容路径);XMLHttpRequest + fetch 三级桥接;逻辑 时钟定时器;debug 调用链监控;ContextPool 多线程;console 捕获。
第二轮“缺口快补”新增(已做):
| 能力 | 状态 |
|---|---|
| SubtleCrypto digest(SHA-1/256/384/512,Promise 结果经 tick 取回) | ✅ |
| TextEncoder / TextDecoder(encode/encodeInto/decode,fatal 与 label 语义) | ✅ |
| Blob / File(size/type/slice 负索引/text()/arrayBuffer()) | ✅ |
WebSocket(Python 工厂桥接 set_websocket_factory + ws_deliver) |
✅ |
| MutationObserver(childList/attributes/subtree/takeRecords/disconnect) | ✅ |
SVG 接口(innerHTML 中 <svg><rect/></svg> 的 SVGSVGElement/SVGRectElement 原型链) |
✅ |
| navigator.userAgentData(brands/mobile/platform + getHighEntropyValues) | ✅ |
反射路径监控(debug 模式 REFLECT Object.keys -> Navigator 类条目,ignore_apis 可过滤) |
✅ |
| requestIdleCallback / cancelIdleCallback(tick 驱动) | ✅ |
| 14 个新事件类(Pointer/Drag/Focus/Input/Composition/Animation/Transition/Message/Close/Storage/HashChange/PopState/PageTransition/BeforeUnload) | ✅ |
第三轮“对齐 iv8 社区版”新增(H~M 六域 + 测试 N):
| 域 | 能力 | 状态 |
|---|---|---|
| H 加密 | WebCrypto 全量:HMAC/HKDF/PBKDF2/AES-GCM/AES-CBC/RSA-OAEP/RSA-PSS/ECDH/ECDSA、importKey(raw/jwk)/generateKey/CryptoKey 语义、非法算法/用法抛错 | ✅(NIST/RFC 向量) |
| I CSSOM | CSSStyleSheet 规则树、@media/@keyframes/@import/@font-face、insertRule/deleteRule、styleSheets 聚合(style+link)、element.style 双向同步、getComputedStyle(级联简化)、Typed OM(CSSUnitValue)、CSS Custom Highlight(CSS.highlights/Highlight) | ✅(级联简化) |
| J DOM 高级 | attachShadow(open/closed)、template.content、slot、customElements(define/get/whenDefined/生命周期/observedAttributes)、HTMLUnknownElement、12+ 新标签接口、Range、Touch/TouchEvent、DOMPoint/DOMRect/DOMMatrix/DOMQuad、FileReader | ✅ |
| K 存储·流·Worker | IndexedDB 全链(内存实现)、CookieStore、storage.estimate/storageBuckets、Streams 三件套 + tee/pipeThrough、Response.body、Worker(add_resource 脚本沙箱)、scheduler.postTask、navigation、DOMException | ✅(见偏差表) |
| L 图形·媒体 | Canvas 2D 软件光栅(getImageData 像素级)、toDataURL 真 PNG、WebGL 1/2 桩级上下文、WebGPU 对象链、AudioContext/OfflineAudioContext、Element.animate/getAnimations | ✅(见偏差表) |
| M DevTools | with_devtools(port) 进程内 CDP:/json/version 发现、WS 握手、Runtime.enable/Runtime.evaluate | ✅(子集) |
| N 测试·文档 | 六域功能套件 + 181 条对齐矩阵 + 本 README/SPEC 附录 C/CI | ✅ |
各域实现与真实浏览器/iv8 的已知差异(诚实清单,测试断言均按这些
口径写;详见各域 REPORT,scratch/):
| 能力 | 偏差 | 域 |
|---|---|---|
| Canvas 2D 文本 | fillText/strokeText 不渲染(度量与绘制为空实现,measureText 返回全 0) | L |
| WebGL | 桩级上下文:常量表/getParameter/getError/getSupportedExtensions/getExtension 可用,无着色器编译与 GPU 光栅(drawArrays 等为 no-op) | L |
| WebGPU | requestAdapter/requestDevice 对象链可达(含 instanceof),无真实命令提交/呈现 | L |
| Web Animations | 动画不插值:playState/onfinish/getAnimations 语义完整,但不计算中间样式帧 | L |
| AudioContext | 逻辑时钟驱动(tick 推进 currentTime),不混音、不跑真实音频图 | L |
| MutationObserver | 记录即时入队,但回调由 tick() 派发(非微任务时机) |
P2.5 |
| IndexedDB | 内存实现、单连接:无持久化,版本升级语义简化,事务隔离为回调序 | K |
| Worker | 纯 JS 沙箱:脚本经 add_resource 注入,无真实线程/DOM 访问,terminate 语义简化 | K |
| CookieStore/存储 | 内存态;estimate 的 usage/quota 为估算口径数字 | K |
| TouchList | 数组形态(Array.isArray 为 true),非只读类数组 | J |
| StyleSheetList | 数组形态(item()/length 可用,非原型类 NodeList 语义) | I |
| querySelectorAll 返回 | 数组(非静态 NodeList;forEach 可用) | P2 |
| getComputedStyle | 级联简化:类命中/行内优先/同特异性后者胜/常用默认值;不做继承全表与简写展开 | I |
| Shadow DOM | 无 slot 分配算法/无 focus 委派;渲染无关 API 齐备 | J |
| 自定义元素 | 无内置元素扩展(extends)、无异步升级队列入微任务的确切时机(tick 驱动) | J |
| DevTools/CDP | Runtime 域子集;无 Debugger/Network/Profiler 面板域 | M |
| WebSocket | 需 Python 侧工厂(无内置网络栈);握手/帧协议在 Python 侧 | P2 |
| 网络 | 请求经三级桥接到 Python/urllib,TLS/JA3 指纹是 Python 侧的 | P2 |
| CSS 布局 | getBoundingClientRect() 返回全 0 对象(jsdom 同款策略) |
P2 |
| innerHTML | 简化解析器(标签/文本/属性,容错),不执行脚本 | P2 |
| window | window !== globalThis(window 是安装到全局的接口对象,非严格代理网) |
P2 |
| 反射监控包装器 | debug 模式下 Object.keys 等包装函数 .name/.length 为 ""/0(真实为 "keys"/1) |
E |
不做/保持诚实预期:
- 反爬对抗是长期军备:v8env 保证“环境语义层”的原生性(探针层), 不承诺通过所有商业风控的行为分析。
- 源码级 WPT 全量回归不在目标内(对齐矩阵 + 定向向量为准)。
实测(Apple M4 / 10 逻辑核 / Python 3.11,全量数据与复现命令见
benchmark/BENCH.md,机器可读结果 benchmark/bench.json):
| 指标 | v8env 实测 | iv8 公开参考(i7-14700/Win10,仅供参考) |
|---|---|---|
| JSContext 创建 + eval + close | ~0.6 ms | ~3.3 ms |
| Python 侧 eval 吞吐 | ~344 万 ops/s | ~95 万 ops/s |
| DOM 解析 ~400KB(8000+ 节点) | ~4.5 ms(~90 KB/ms) | 440KB ≈ 7 ms |
| ContextPool 8 线程加速比 | ~4.1x | 4.71x |
- P2.5 已补齐(第二轮缺口快补):SubtleCrypto digest、TextEncoder/ TextDecoder、Blob/File、WebSocket Python 工厂桥接、14 个事件类、 MutationObserver、SVG 元素接口、navigator.userAgentData、 requestIdleCallback、反射路径监控、性能基准。
- P3-对齐(第三轮,本轮):WebCrypto 全量、CSSOM/样式计算、 Shadow DOM/自定义元素/Range/Geometry、IndexedDB/Streams/Worker/ scheduler/navigation、Canvas 像素级/WebGL 桩/WebGPU 链/音频/动画、 DevTools CDP 子集(见“对齐 iv8 社区版”表与各域套件)。
- P3-网络:真网络栈(curl-impersonate 级 TLS 指纹)、请求录制回放。
- P3-渲染:Canvas 文本度量/渲染、WebGL 着色器级实现、WAAPI 插值。
- P3-兼容:WebPT 子集回归、被动监听/捕获阶段全语义等 Event 深水区、 slot 分配算法。
- P3-分发:Linux 构建(等 V8 官方二进制打包方案)、pip wheel。
构建要求:macOS arm64、Apple clang、Python 3.11(含 Python.h)、
brew install v8 cmake。V8 15.5+,编译定义必须含 -DV8_COMPRESS_POINTERS
(详见 SPEC.md 环境节)。
文件所有权(并行开发契约,详见 SPEC.md):
| 区域 | 负责模块 |
|---|---|
tools/idlgen.py, idl/*.idl, tests/test_idlgen.py, src/generated/interfaces.gen.* |
A(生成器) |
CMakeLists.txt, build.sh, src/engine.*, src/jscontext.*, src/env_config.*, src/registry.cpp, src/monitoring.*, src/timers.*, src/console.*, src/net/*, src/pool.* |
B(引擎核心) |
src/dom/*, src/dom/dom_builtins.cpp |
C(DOM 层) |
python/v8env/__init__.py, tests/test_{native,dom,net,monitor}.py, tests/mock_v8env.py, examples/*.py |
D(Python 面) |
src/crypto.*(digest)、src/textcodec.*、src/file.*、src/net/ws.*、src/refmonitor.* |
E(第二轮缺口快补·核心) |
src/dom/{events,mutation,wrappers}.cpp 增量 |
F(第二轮缺口快补·DOM) |
第三轮 H~M 六域源码(src/ 各新增文件,以各域 REPORT 为准) |
H 加密 / I CSSOM / J DOM 高级 / K 存储·流·Worker / L 图形·媒体 / M DevTools |
tests/test_{crypto_full,cssom,dom3,storage3,gfx,devtools,align_checklist}.py, README.md, .github/workflows/build.yml, SPEC.md 附录 |
N(第三轮测试·文档·CI) |
SPEC.md 正文, src/registry.hpp |
冻结(集成方所有) |
测试约定:十三个测试文件为纯 assert 脚本(无第三方依赖,仅标准库 +
v8env),可独立运行,失败非零退出,结尾打印 N/N PASSED。
V8ENV_MOCK=1 用 tests/mock_v8env.py(纯 Python 契约模拟)跑结构组,
语义探针自动跳过——用于在没有 V8 的机器上自测测试代码本身。
第三轮七套不做 mock(mock 层未实现新功能),直接写真断言。
MIT。