Ladybird 浏览器采用 Rust
Ladybird adopts Rust

原始链接: https://ladybird.org/posts/adopting-rust/

瓢虫,一个网页引擎,正在从C++过渡到Rust,以提高内存安全性和构建更强大的生态系统。 之前考虑过Swift,但由于互操作性问题和平台支持有限而受阻。 尽管最初担心Rust不适合网页平台的OOP风格,但其优势现在超过了这些缺点,这与Firefox和Chromium等项目的采用相呼应。 首次重大移植是LibJS,瓢虫的JavaScript引擎,在人工指导下,借助Claude和Codex等AI工具成功翻译,耗时约两周——手动操作估计需要数月。 这25,000行Rust代码与C++版本输出*字节对字节*完全相同,并且在广泛的测试套件(test262和瓢虫内部测试)和基准测试中未发现任何回归。 最初的重点是兼容性,因此Rust代码有意模仿C++模式。 未来的开发将涉及子系统的逐步移植,同时继续C++开发,由核心团队管理以确保高效集成。

## 瓢虫浏览器迁移至 Rust,并借助人工智能辅助 瓢虫浏览器项目已成功将其代码库从 C++ 移植到 Rust,整个过程在大约两周的时间内完成,并借助 Claude 和 Codex 等人工智能工具。然而,移植并非自主完成;开发者仔细地指导人工智能,决定翻译什么以及如何翻译,然后严格审查结果是否存在错误。目标是与原始 C++ 代码完全相同的字节级输出,并且验证确认没有回归。 虽然承认生成的 Rust 代码尚未完全符合惯用风格,但团队计划未来进行清理和简化。此次讨论强调了大型语言模型辅助迁移作为人工智能的一个有前景的应用案例,并探讨了这些工具对开发者热情和编程未来的影响。一些评论员对人工智能可能削弱人类程序员的作用表示担忧,而另一些人则认为它是一种自动化繁琐任务的宝贵工具。该项目致力于内部构建依赖项,而不是利用 Servo 等现有库,也值得注意。
相关文章

原文

We’ve been searching for a memory-safe programming language to replace C++ in Ladybird for a while now. We previously explored Swift, but the C++ interop never quite got there, and platform support outside the Apple ecosystem was limited. Rust is a different story. The ecosystem is far more mature for systems programming, and many of our contributors already know the language. Going forward, we are rewriting parts of Ladybird in Rust.

Why Rust?

When we originally evaluated Rust back in 2024, we rejected it because it’s not great at C++ style OOP. The web platform object model inherits a lot of 1990s OOP flavor, with garbage collection, deep inheritance hierarchies, and so on. Rust’s ownership model is not a natural fit for that.

But after another year of treading water, it’s time to make the pragmatic choice. Rust has the ecosystem and the safety guarantees we need. Both Firefox and Chromium have already begun introducing Rust into their codebases, and we think it’s the right choice for Ladybird too.

Porting LibJS

Our first target was LibJS , Ladybird’s JavaScript engine. The lexer, parser, AST, and bytecode generator are relatively self-contained and have extensive test coverage through test262, which made them a natural starting point.

I used Claude Code and Codex for the translation. This was human-directed, not autonomous code generation. I decided what to port, in what order, and what the Rust code should look like. It was hundreds of small prompts, steering the agents where things needed to go. After the initial translation, I ran multiple passes of adversarial review, asking different models to analyze the code for mistakes and bad patterns.

Results

The requirement from the start was byte-for-byte identical output from both pipelines. The result was about 25,000 lines of Rust, and the entire port took about two weeks. The same work would have taken me multiple months to do by hand. We’ve verified that every AST produced by the Rust parser is identical to the C++ one, and all bytecode generated by the Rust compiler is identical to the C++ compiler’s output. Zero regressions across the board:

Test suiteTestsRegressions
test26252,8980
Ladybird regression tests12,4610

No performance regressions on any of the JS benchmarks we track either.

Beyond the test suites, I’ve done extensive testing by browsing the web in a lockstep mode where both the C++ and Rust pipelines run simultaneously, verifying that output is identical for every piece of JavaScript that flows through them.

If you look at the code, you’ll notice it has a strong “translated from C++” vibe. That’s because it is translated from C++. The top priority for this first pass is compatibility with our C++ pipeline. The Rust code intentionally mimics things like the C++ register allocation patterns so that the two compilers produce identical bytecode. Correctness is a close second. We know the result isn’t idiomatic Rust, and there’s a lot that can be simplified once we’re comfortable retiring the C++ pipeline. That cleanup will come in time.

What’s next

This is not becoming the main focus of the project. We will continue developing the engine in C++, and porting subsystems to Rust will be a sidetrack that runs for a long time. New Rust code will coexist with existing C++ through well-defined interop boundaries.

We want to be deliberate about which parts get ported and in what order, so the porting effort is managed by the core team. Please coordinate with us before starting any porting work so nobody wastes their time on something we can’t merge.

I know this will be a controversial move, but I believe it’s the right decision for Ladybird’s future. :^)

Andreas Kling

Founder & President

联系我们 contact @ memedata.com