Swift-学习 sil swift中间语言

1,192 阅读3分钟

Swift语言和OC一样,也是构建在LLVM架构上的,标准的三段式设计

image.png 在OC中,我们可以通过Clang命令,生成C++文件来看底层原理,那么Swift呢?我们也可以通过swiftc命令生成Swift Intermediate Language来看底层原理 swiftc命令 swiftc是swift语言的编译工具,他可以把swift文件生成中间表示,也可以生成可执行文件,下面简单写下常用的命令:

生成可执行文件:swiftc -o main.out main.swift
生成抽象语法树的命令(AST):swiftc main.swift -dump-ast
生成中间语言(SIL):swiftc main.swift -emit-sil
LLVM中间表示层(LLVM IR):swiftc main.swift -emit -ir
生成汇编语言:swiftc main.swift -emit-assembly

其余的命令你可以通过swiftc -h获得帮助 生成Swift Intermediate Language 我们新建一个最简单的Demo,可以减少很多干扰项,打开Xcode,新建如下设置:

image.png 这样生成的项目只有一个main.swift文件,不会含有其他的干扰项。

image.png 我们添加一段简单的代码到main.swift import Foundation

class Teacher { var age: Int = 18 var name: String = "Tom" }

var person = Teacher() person.age = 6 复制代码 然后去终端进入main.swift所在的文件夹,输入如下指令: swiftc -emit-sil main.swift 复制代码 便可以在终端中看见Swift Intermediate Language

image.png 名字重整(Name Mangling) 我们可以从SIL中看到一些奇怪无规律的名字,例如:s4main6personAA7TeacherCvp。这其实是swift采用了名字重整技术,swift中的类名、方法名等会被重整,这样可以实现方法的重载,更好的实现多态设计。 其实这些名字并不是没有规律的,但我并不是很感兴趣,感兴趣的小伙伴可以参看这篇文章。 幸运的是,我们通过命令xcrun swift-demangle还原成原来的名字

image.png 这样,我们可以通过管道符将整个SIL中的名字还原回来 swiftc -emit-sil main.swift | xcrun swift-demangle 复制代码 可以对比一下:

image.png 名字很容易被还原回来了。 选择适合的编辑器 当然,在终端里面看很不方便,我们可以将它保存到文件,后缀名可以定义为.sil,添加如下命令输出: swiftc -emit-sil main.swift | xcrun swift-demangle > ./main.sil 复制代码 这样,在main.swift的同级目录下,可以看到main.sil,右键显示简介,可以调到你喜欢的编辑器软件打开,应用到所有该类文件就行了。 我用的是Sublime,你也可以用VSCode,看个人喜欢了。 脚本自动生成SIL文件并打开 由于你会频繁的修改代码并查看SIL文件,每次敲一遍命令会很烦(我是一个很懒的人啦),所以写一个简单的脚本插入到Xcode。 先在刚项目中新建一个Target,如下图:

image.png 新建一个脚本项:

image.png 在命令行内复制如下命令,需要注意的是,脚本的当前目录是xcodeproj同级目录,所以下面命令中的SwiftSIL改成你的项目名称,这样才可以找到文件 swiftc -emit-sil SwiftSIL/main.swift | xcrun swift-demangle > ./main.sil && open main.sil 复制代码 切换target运行,就能直接调出你的编译器看你生成的SIL文件了,是不是很方便? 其他

在SIL文件中,你会看到很多不懂的关键词,你可以查看GitHub上的官方文档查阅 如果你在iOS里生成SIL文件,难免会碰到UIKit之类的sdk,那么命令需要带参数了,模拟版本改成你当前的版本:

swiftc -emit-sil -target x86_64-apple-ios14.2-simulator -sdk $(xcrun --show-sdk-path --sdk iphonesimulator) ViewController.swift > ViewController.sil