首页 > 解决方案 > SWIFT ABI 在哪里发挥作用?

问题描述

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

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

Swift 编译步骤

根据苹果

IR 生成(在 lib/IRGen 中实现)将 SIL 降低到 LLVM IR,此时 LLVM 可以继续优化它并生成机器代码。

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

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

那么有什么我遗漏的东西,或者苹果公司一直把它保持得很抽象吗?

标签: iosswiftcompiler-constructionllvmabi

解决方案


在ABI Stability Manifesto中有一个很好的描述 ABI 的作用。

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

ABI 回答如下问题:

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

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

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

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


推荐阅读