当前所在位置:首页 > 配资炒股哪家平台可靠

开发者“疯狂”整活:用纯 C 语言,从头编写一个 Rust 编译器

5394

2024-11-19 【 字体:

近日,一个项目在 HN 上引起了许多开发者的注意——一名富有创新精神的开发者正在尝试使用 C 语言来编写 Rust 编译器。这位开发者表示:为了引导 Rust 发展,无论付出什么代价都值得。

作者 | John Nunley 翻译 | 郑丽媛

细心的 Rust 爱好者可能已经注意到,我最近不太活跃。导致这种情况的原因有很多:最近我经历了一系列非常糟糕的事情,包括一位亲人的离世让我感到极其意外,同时我在工作中承担了更多责任,不再有很多时间和精力去贡献开源项目了。亦或许,我也失去了当初在大学时代、那种足以让我全身心投入开源世界的热情。

除此之外,还有另一个原因:我正忙于一个占据了我大部分业余时间的项目。这个项目是我在开源领域中创建的最大型的一个,如果我最后能完成它,那它一定会成为我的巅峰之作。

我正在用纯 C 语言编写一个 Rust 编译器:不用 C++,不用 flex 或 yacc,甚至不用 Makefile——仅仅用纯 C 语言。这个项目叫做 Dozer。

(CSDN 付费下载自视觉中国)

为什么要这么做?

想要理解我为何走上这条“疯狂”之路,你首先需要了解 Bootstrapping(引导法)以及它的重要性(所谓引导法,这是一种在编程中常见的技术,意为通过已有的基本代码或资源来构建更复杂的系统或工具)。

假设你用 Rust 写了一些代码,为了运行这些代码,你需要先编译它们。编译器是一种程序,它会解析你的代码,验证其正确性,然后将其转换为 CPU 可以理解的机器代码。

对于 Rust 来说,主要的编译器是 rustc——也就是你运行 cargo build 时所调用的底层程序。不得不说,rustc 是一个很棒的软件,甚至可以说是开源社区的瑰宝,其代码质量可以媲美 Linux 内核和 Quake III 源代码。

然而,rustc 本身也是一个程序,所以它也需要一个编译器将其从源代码编译为机器代码。那么问题来了:rustc 是用什么语言编写的呢?

这样来看,rustc 是一个用 Rust 编写的程序,其目的是为了编译 Rust 代码。但请仔细想想,如果 rustc 是用 Rust 编写的,而我们又需要用 rustc 来编译 Rust 代码,这意味着我们需要用 rustc 来编译 rustc……?

对于一般用户来说,这其实没什么问题,因为我们可以直接从网上下载 rustc 并使用它。但有个问题:第一个 rustc 是谁编译的,总得先有“鸡”才有“蛋”吧?这到底是从哪里开始的?

其实,这个问题并不复杂:每个新 rustc 版本都是由前一个版本的 rustc 编译出来的。也就是说,rustc 1.80.0 版本是用 rustc 1.79.0 版本编译的,rustc 1.79.0 版本又是由 rustc 1.78.0 版本编译的……以此类推,一直可以追溯到 rustc 0.7 版本。而那时,编译器是用 OCaml 写的,因此只需要一个 OCaml 编译器就能得到一个完整的 rustc 程序。

好了,问题解决了,我们已经搞清楚如何从头开始创建 rustc。但是,要让这一切都正常工作,我们仍需要一个 OCaml 编译器的版本。所以说,OCaml 编译器又是用什么语言编写的呢?

额……没事儿!有一个项目能成功用 Guile 编译 OCaml 编译器,而 Guile 是 Scheme 的众多变体之一,Scheme 又是 Lisp 的众多变体之一。另外,Guile 的解释器是用 C 编写的。

于是,这一切最终都指向了 C 语言。我们只需用 GCC 来编译它,一切就能顺利进行。那么我们只需要编译 GCC,而 GCC 是用……C++编写的?!

这个说法有点不准确。GCC 直到第 5 版之前都是用 C 语言编写的,这世上也并不缺少用 C 编写的 C 编译器……但这仍然没有回答我们的问题。第一个 C 编译器是用什么写的?汇编语言?那么第一个汇编器又是用什么写的呢?

原理介绍

这就是我要介绍 Bootstrappable Builds 项目的目的。在我看来,这就是开源社区中最有趣的项目之一,也基本上属于代码炼金术。

其 Linux 引导过程从一个 512 字节的二进制种子开始。这个种子包含了一个最简单的编译器:能接收十六进制数字并输出相应的原始字节。例如,以下为该编译器编译的部分“源代码”:

31 C0 # xor ax, ax8E D8 # mov ds, ax8E C0 # mov es, ax8E D0 # mov ss, axBC 00 77 # mov sp, 0x7700FC # cld ; clear direction flag88 16 15 7C # mov [boot_drive], dl

注意,井号后的所有内容都是注释,所有的空白字符也都被去掉了。坦白说,我甚至不确定这能否被称为编程语言。但严格来说,这确实是可分析、可剖析的源代码。

接下来,这个编译器就会编译一个非常简单的操作系统,一个简陋的 shell,以及一个稍微高级一点的编译器。那个编译器又编译了一个更高级一点的编译器。这样几步之后,你就有了类似汇编代码的东西。

DEFINE cmp_ebx,edx 39D3DEFINE je 0F84DEFINE sub_ebx, 81EB

:loop_optionscmp_ebx,edx # Check if we are doneje %loop_options_done # We are donesub_ebx, %2 # --options

说到这儿,你会觉得我把汇编代码当作比其他东西更高层次的语言,好像有点奇怪,对吧?

但这就足以得到一个非常基础的 C 语言子集,然后,利用这个子集编译一个稍微高级一点的 C 编译器。几步之后,就能编译 TinyCC 了。接着可以引导 yacc、基本 coreutils、Bash、autotools,并最终到达 GCC 和 Linux。

我这样讲,可能还是没法完全体现出这个过程的魅力,但这真的很引人入胜。总之,从“一个小到足以手动分析的二进制文件”开始,一步步到 Linux、GCC,再到基本上所有其他的东西,你基本上都经历过了。不过,我们还是从 TinyCC 开始再来一次吧。

目前,Rust 在这个过程中出现得非常晚。他们使用 mrustc,这是一种用 C++ 编写的 Rust 替代实现,可以编译 rustc 1.56 版本。在此基础上,他们再编译现代 Rust 代码。

这里的主要问题是,到引入 C++ 时,引导过程基本上已经结束了。因此,如果你想在引入 C++ 之前的任何时候使用 Rust,那是不可能的。

所以,对我来说,如果有一个 Rust 编译器能够从 C 开始引导,那就太好了。具体来说,就是一个可以从 TinyCC 开始引导的 Rust 编译器,同时假设系统中还没有可能有用的工具——这个编译器就是 Dozer。

未来计划

过去两个月中,我一直在忙于 Dozer 项目:把我那本就少得可怜的空闲时间,用来编写一种我有点讨厌的语言。

这个项目没有使用任何扩展功能,目前 TinyCC 和 cproc 都能顺利编译。我使用 QBE 作为后端。除此之外,我假设系统上没有其他工具,只有一个 C 编译器和一些非常基础的 shell 实现,再无其他。

在本文中,我不会深入探讨编写一个编译器的原始体验。但到目前为止,我已经完成了词法分析器,还完成了相当大一部分的语法解析器。宏/模块扩展我会尽量推迟,类型检查目前只支持 i32,而代码生成还稍显粗糙——但这已经是一个不错的开始了。

目前,我已可以成功编译以下代码:

fn rust_main -> i32 {(2 - 1) * 6 + 3}

那么,接下来怎么办呢?这是我的计划:

(1)慢慢推进 Dozer,直到它能够编译一些使用 libc 的基本示例代码,然后再编译 libcore,最后到 rustc。(顺便提一下,我计划编译 rustc 的 Cranelift 后端,这部分完全是用 Rust 编写的。由于我们假定还没有 C++,所以无法编译 LLVM。)

(2)创建一个等同于 cargo 的工具,可以用 Dozer 来编译 Rust 包。

(3)找出 rustc 中那些自动生成的代码源文件,并将它们剔除。根据 Bootstrappable 项目的规则,不允许使用自动生成的代码。

(4)创建一个可以用来编译 rustc 和 cargo 的过程,然后使用我们编译的 rustc/cargo 版本重新编译标准版本的 rustc/cargo。

毫无疑问,这是我迄今为止创建的最困难的项目,我也很怀疑自己到底能否完成它。但你知道吗?尝试过却失败了,总比从未尝试过要好。

阅读全文
相关推荐

连大鸽派也动摇了!美联储官员开始考虑更早加息的可能性 12月将一窥究竟

连大鸽派也动摇了!美联储官员开始考虑更早加息的可能性 12月将一窥究竟
美联储的政策制定者认为,随着通胀继续飙升、经济加速增长,美联储可能会比几个月前认...

揭秘“哈灵麻将干瞪眼到底有没有挂-太坑人了,曝光透视猫腻_游戏_玩家_封号

揭秘“哈灵麻将干瞪眼到底有没有挂-太坑人了,曝光透视猫腻_游戏_玩家_封号
哈灵麻将是一款广受欢迎的在线卡牌游戏,它以斗地主为游戏背景,结合了竞技、合作与社...

美一季度经济环比萎缩03%,英国央行暗示美元地位下降

美一季度经济环比萎缩03%,英国央行暗示美元地位下降
美国商务部4月30日公布最新数据显示,2025年第一季度美国国内生产总值(GDP...

“智慧金店”亮相上海

“智慧金店”亮相上海
  5月5日,在上海市普陀区一家商场内的“智慧金店”,人们观看黄金回收设备运行情...

民生加银康宁稳健养老目标一年持有期混合增聘刘欣

民生加银康宁稳健养老目标一年持有期混合增聘刘欣
@page{size:8.27in11.69in;margin-left:1.2...

4月21日香港周大福黄金价格37330港币两

4月21日香港周大福黄金价格37330港币两
4月21日,香港周大福黄金价格37330港币/两。(价格仅供参考,以门店实际为准...

2021年3月29日人民币NDF远期合约

2021年3月29日人民币NDF远期合约
NDF交易从1996年左右开始出现,新加坡和香港人民币NDF市场是亚洲最主要的离...

炒股杠杆软件:高风险高收益的双刃剑?

炒股杠杆软件:高风险高收益的双刃剑?
炒股杠杆软件:高风险高收益的双刃剑?元描述: 深入了解炒股杠杆软件的优...

股票配资选股:放大收益,也要谨慎风险!

股票配资选股:放大收益,也要谨慎风险!
股票配资选股:放大收益,也要谨慎风险!元描述: 股票配资放大收益,但风...

期货配资系统:撬动财富的杠杆,也可能是通往深渊的滑梯?

期货配资系统:撬动财富的杠杆,也可能是通往深渊的滑梯?
期货配资系统:撬动财富的杠杆,也可能是通往深渊的滑梯?元描述: 深入探...