SWIFT ABI 在哪里出现?

Where does SWIFT ABI come into picture?

标题可能不足以概述问题的上下文。所以这里是描述:

SWIFT编译过程 Swift 编译器经过以下步骤编译一个 Swift 文件

根据 Apple

IR generation (implemented in lib/IRGen) lowers SIL to LLVM IR, at which point LLVM can continue to optimize it and generate machine code.

查询号1 - 我们都知道编译器将我们的源代码转为汇编语言和汇编程序(主要嵌入OS,至少 Swift 编译器中没有汇编程序)将其转换为机器代码。因此,按照上面引用的语句,编译器中的 LLVM 将 LLVM IR 更改为机器代码。 那么,如果是这种情况,那么汇编程序将不会在 Swift 程序和执行中扮演任何角色?

查询编号 2 - Swift 中的 LLVM 将 LLVM IR 直接更改为机器代码。所以这意味着我编译的可执行二进制文件有机器代码,而不是汇编代码。根据我的理解,机器代码不需要像汇编语言那样的任何特定调用约定,而 ABI 就是关于调用约定、内存布局表示等,通过它们定义两个二进制文件之间的通信。 那么,由于二进制可执行文件已经具有机器代码,所以 ABI 在图片中出现在哪里?

那么是不是我遗漏了什么,或者 Apple 将其保持得相当抽象?

ABI Stability Manifesto 中对 ABI 的作用有很好的描述。

总而言之,ABI 是关于在链接和运行时编译的应用程序模块之间的通信层。例如应用程序和已编译的静态库。或者应用程序和标准库(Swift 运行时)。

ABI 回答如下问题:

  • 函数是如何存储的?名称是如何存储的?它的参数是如何存储的?默认参数值是如何存储的?如何存储属性(例如可用性)?如何存储泛型?您在哪里可以找到函数的机器指令?

  • 如何在开始执行函数机器指令之前将参数放入调用堆栈(即如何将参数和self传递给函数?)。这就是 调用约定 的含义。

如果您有两个版本的 Swift 编译器,并且每个版本都使用不同的格式,它们将无法相互调用,因为它们不知道如何解释文件中的信息。这就是需要 ABI 稳定性的原因。它稳定了代码的存储方式。请注意,机器指令是函数的主体,但所有其他元数据也必须存储。

程序集在 ABI 稳定性中没有作用。汇编只是 Swift 中未使用的另一种低级编程语言。