前 Google 工程师、Mojo 核心贡献者 Evan Ovadia 近期完成了一项实验性工作,成功将 Rust 转化为其他编程语言可构建的库。该工作展示了一种在 Rust 与另一语言之间传递通用数据类型和函数的方法,突破了传统 C ABI(应用二进制接口)不支持泛型的限制。

Ovadia 在其解释性博客文章中将这项成果描述为“金”(Golden Spike)。这一方案使得丰富的 Rust 库功能能够通过稳定的高速通道输送至外部生态系统。这项工作源于 Ovadia 创建新语言 Valen 的努力——Valen 是早期项目 Vale 的一个分支,被定位为一种更快且更易于开发的 Rust 版本。
从头开始创建新语言面临的主要挑战在于无法直接复用现有的 Rust 库,尤其是高性能图形库 WGPU。目前,在其他语言编写的程序中使用特定语言库的常见方法是依赖 C ABI。C ABI 作为一个事实上的互操作性层,定义了编译代码之间传递数据和函数调用的规范。尽管 Rust 拥有自己的 ABI,但其不提供稳定性保证。在 C ABI 框架下,若 Rust 库通过 extern "C" 暴露函数,并通过 repr(C) 暴露类型,其他语言即可通过 FFI(外国函数接口)进行访问。
然而,Ovadia 遇到的核心障碍是 C ABI 不理解泛型(或数据类型的参数化),因为 C 语言本身不具备泛型概念。Rust 和 Valen 都广泛使用泛型,尽管实现方式不同。因此,关键问题在于如何实现跨语言的泛型支持。由于编译器通常是孤立的实体,让两个编译器协作极具挑战性。Ovadia 需要找到一种机制,使 Valen 能够调用 Rust 的通用函数,同时也允许 Rust 的通用函数被调用。
经过深入研究,Ovadia 提出了一个两部分解决方案:首先,将 Rust 编译器作为库运行。Rust 已经具备此功能(通过 rustc_driver),这允许 Valen 直接将 rustc 嵌入其内存空间。其次,对 Rust 进行修补,使其在遇到非 Rust 的 Valen 类型时,将控制权移交回 Valen 编译器处理相应部分,并等待编译结果。
Ovadia 承认,修补 Rust 编译器是整个过程中最具风险的部分。他写道:“老实说,这是整个努力中最危险的部分。”该补丁仅包含约 100 行代码,但存在漏洞,且假设 Rust 正在使用 LLVM 生成机器代码,而这一前提并不总是成立。他补充道:“它可以工作,但绝对不能上传。”
尽管如此,Ovadia 实现的跨语言双向泛型支持被视为编程语言互操作性的实质性进步。这一工作开辟了使用 Rust 启动新语言的可能性,这些新语言可以直接从 Rust 库中受益。虽然需要对 Rust 本身进行修改,但这种依赖 C ABI 之外的互操作模式未来可能会变得更加普遍。





