MongoDB 中升级 SpiderMonkey WASM 引擎的完整操作指南
【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo
本指南以 spider-monkey/README.md 的官方升级流程为骨架,结合当前仓库中的 Bazel 仓库规则、版本校验文件与 WASI 构建脚本,完整讲解 MongoDB 如何从 Firefox/SpiderMonkey 上游源码升级 WASM 版 JavaScript 引擎。读完本文,你将掌握从修改版本号、运行 Evergreen CI 补丁构建、获取 S3 tarball 到更新 Bazel 依赖的端到端升级方法,并理解每一步背后仓库的校验与验证机制。
为什么 MongoDB 需要维护一个独立的 SpiderMonkey
MongoDB 使用 SpiderMonkey(Firefox 的 JavaScript 引擎)执行服务端 JavaScript 逻辑。在当前仓库中,这一组件位于 src/mongo/scripting/mozjs/wasm/,并且以WASM(WebAssembly)组件 + AOT 预编译的形式嵌入到 mongod/mongos 二进制中:
- 上游
mozjs_wasm_api.wasm组件从 S3 下载; - 构建期通过 wasmtime 做 AOT 编译,序列化为
.cwasm; - 再经 objcopy 转成 ELF
.o嵌入最终二进制,运行时用Component::deserialize()近瞬时加载(详见 wasm/README.md)。
由于 MongoDB 依赖的是 Firefox/SpiderMonkey 特定 ESR 版本标签,且下游还有 WASI Preview 2 构建链,因此升级流程必须走一条受控、可审计的路径,即本文介绍的 5 步流程。
升级前置:理解三个版本文件
升级的“入口”是 spider-monkey 目录下的三个纯文本文件,它们由 BUILD.bazel 通过exports_files暴露给 Bazel 仓库规则读取:
| 文件 | 当前内容 | 作用 |
|---|---|---|
| spider-monkey-version | FIREFOX_140_12_0esr_RELEASE | Firefox/SpiderMonkey 上游 release tag |
| spider-monkey-sha256sum | 3f3092578484cbba4f6e807a76928febdfc13acd6953d1dc4dcc8a49e09a85cb | 上游源码归档的 SHA-256 校验和 |
| spider-monkey-repository | https://github.com/mozilla-firefox/firefox | 上游仓库地址 |
这三个文件会被 spidermonkey_repo.bzl 中的spidermonkey_repository仓库规则读取:规则会拼接出归档 URL 形如https://github.com/mozilla-firefox/firefox/archive/refs/tags/<TAG>.tar.gz,以stripPrefix = "firefox-<TAG>"解压,并用 sha256 文件做完整性校验;若任一文件为空,构建会直接fail()。也就是说,版本号与校验和必须成对更新,否则无法通过 Bazel 的依赖解析。
5 步升级流程详解
第 1 步:更新版本与校验和文件
把 spider-monkey-version 改为新的 Firefox/SpiderMonkey release tag,例如升级到FIREFOX_141_0esr_RELEASE。
然后重新计算对应源码归档的 SHA-256(README 给出的命令):
curl -sL "https://github.com/mozilla-firefox/firefox/archive/refs/tags/<TAG>.tar.gz" | sha256sum将输出写入 spider-monkey-sha256sum。注意:<TAG>必须与 version 文件完全一致,否则 Bazel 下载时会因校验和失配而失败——这正是仓库把校验和单独成文件、强制人工更新的用意(参见 spidermonkey_repo.bzl 中对三个文件均非空的强制检查)。
第 2 步:在 Evergreen 补丁构建中运行 CI variant
把改动提交后创建 Evergreen patch,并运行名为spidermonkey-wasm-compile的 CI variant。该 variant 会:
- 构建
spidermonkey_wasip2_dist_release_from_source目标——即从第 1 步指定的上游源码出发,走 scripts/build_spidermonkey_wasip2.sh 的 WASI Preview 2 构建链; - 把产物打包成
spidermonkey-wasip2-release.tar.gz; - 上传到 S3,路径为
spidermonkey-wasm/<spidermonkey_version>/。
关于该 tarball 的构成,构建脚本头部注释明确列出:libjs_static.a(JS 引擎静态库)、公开与内部头文件(.h/.hpp)、libjsrust.a(如可用)、libmongo_wasip2_rust_shims.a(编码 shim)以及obj-extra/支持对象。同时脚本要求OUTPUT、SPIDER_MACH_PATH、RUST_SHIMS_LIB_RS、CARGO_TEMPLATE_PATH等环境变量,并支持通过WASI_SDK_BIN_FILES或WASI_SDK_PATH指定编译器发现方式。
第 3 步:获取新的 tarball URL
在 Evergreen UI 中打开该补丁构建的Files标签页,复制spidermonkey-wasip2-release.tar.gz对应的 S3 URL。这个 URL 即下游 Bazel 模块要引用的下载地址。
第 4 步:更新 spidermonkey_wasi 依赖
将spidermonkey_wasi模块的 URL 与 SHA-256 指向新上传的 tarball。该模块对应的仓库规则是 spidermonkey_wasi_repo.bzl,它下载并解压 tarball 后会自动生成 Bazel 目标:
headers:暴露include/**/*.h与include/**/*.hpp(排除与 MongoDB 自带 fmt 冲突的include/fmt/**),并强制MOZ_HAS_MOZGLUE宏;js_static:cc_import引入lib/libjs_static.a;jsrust(条件生成):仅当 tarball 中存在lib/libjsrust.a时才创建。
值得注意的是,该规则还会对include/js-confdefs.h做后处理:剔除所有#define FMT_*前缀定义,避免强制包含该头文件时与 MongoDB 自身的 fmt 头文件产生符号冲突。这意味着你上传到 S3 的 tarball 必须符合这些约定(目录结构、头文件布局),否则下游 Bazel 目标会解析失败。
第 5 步:提交 PR 并附上补丁构建链接
最后打开 PR,并在描述中链接产出该 tarball 的 patch build。这一步是审计与追溯的关键:评审者可以据此核对 tarball 确实来自可信的 CI 构建,而不是任何未经校验的第三方来源。
升级背后:从上游 tag 到二进制嵌入的完整链路
把 README 的 5 步流程放到整个 src/mongo/scripting/mozjs/wasm/ 体系中看,升级动作实际串联了三条链路:
- 源码获取链:
spider-monkey-version/-sha256sum/-repository→spidermonkey_repository(spidermonkey_repo.bzl)→ 上游 Firefox 源码; - WASI 构建链:上游源码 → scripts/build_spidermonkey_wasip2.sh →
spidermonkey-wasip2-release.tar.gz→ S3(由spidermonkey-wasm-compilevariant 驱动); - 嵌入链:S3 tarball →
spidermonkey_wasi_repo(spidermonkey_wasi_repo.bzl)→mozjs_wasm_api.wasm→ wasmtime AOT 编译 → objcopy 嵌入 → mongod/mongos(详见 wasm/README.md)。
整个链条中每个环节都有对应的 Bazel 目标与校验(sha256、fail()空文件检查、FMT_*过滤),这也解释了为什么 README 要求第 2 步必须走 CI variant 而非本地手工构建——只有spidermonkey-wasm-compile才能保证产物与仓库构建系统约定完全一致。
升级注意事项与常见问题
- 版本与校验和必须同步更新:
spidermonkey_repository会同时对 URL、tag、sha256 做强校验,任一缺失都会导致依赖解析失败; - tarball 结构有约定:下游
spidermonkey_wasi_repo依赖lib/、include/的标准布局,并期望可选的libjsrust.a按固定路径存在; - 头文件冲突是已知问题:
include/js-confdefs.h中FMT_*宏会被规则自动剥离,但如果你在 tarball 中引入了其他与 MongoDB 冲突的头文件,需要在生成 BUILD 时显式处理; - AOT 工具版本必须匹配:根据 wasm/README.md,AOT 编译工具必须与反序列化
.cwasm的二进制使用相同版本、相同引擎配置的 wasmtime 库,升级引擎时务必同步确认。
按照上述 5 步操作,即可在 MongoDB 仓库中完成一次受控、可审计的 SpiderMonkey 引擎升级;每一步产生的校验值与构建链接,都会成为后续排障与审计的可靠依据。
【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考