「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」。
SIL分析
SIL(
Swift intermediate language):swift中间语言
调用swiftc -emit-sil LGPerson.swift >>. ./LGPerson.sil命令,生成LGPerson.sil文件。
用VSCode打开SIL文件
对main函数分析:
// main
sil @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
// 创建全局变量HTPerson
alloc_global @$s8HTPerson1tA2ACvp // id: %2
// 读取全局变量HTPerson地址,赋值给%3
%3 = global_addr @$s8HTPerson1tA2ACvp : $*HTPerson // user: %7
// metatype读取HTPerson的Type(Metadata),赋值给%4
%4 = metatype $@thick HTPerson.Type // user: %6
// 将HTPerson.__allocating_init() 函数地址给%5
%5 = function_ref @$s8HTPersonAACABycfC : $@convention(method) (@thick HTPerson.Type) -> @owned HTPerson // user: %6
// 调用%5函数,将返回值给%6
%6 = apply %5(%4) : $@convention(method) (@thick HTPerson.Type) -> @owned HTPerson // user: %7
// 将%6存储到%3 (%3是HTPerson类型)
store %6 to %3 : $*HTPerson // id: %7
// 构建Int并return
%8 = integer_literal $Builtin.Int32, 0 // user: %9
%9 = struct $Int32 (%8 : $Builtin.Int32) // user: %10
return %9 : $Int32 // id: %10
} // end sil function 'main'
- @main 这⾥标识我们当前 main.swift 的⼊⼝函数,SIL 中的标识符名称以 @ 作为前缀
- %0, %1... 在 SIL 也叫做寄存器,这⾥我们可以理解为我们⽇常开发中的常量,⼀旦赋值之后就不可 以再修改,如果 SIL 中还要继续使⽤,那么就不断的累加数字。 同时这⾥所说的寄存器是虚拟的,最 终运⾏到我们的机器上,会使⽤真的寄存器
- alloc_gobal :创建⼀个全局变量
- global_addr: 拿到全局变量的地址,赋值给 %3
- metatype 拿到 LGTeacher 的 Metadata 赋值给 %4 将 __allocating_init 的函数地址赋值给 %5
- __apply 调⽤ __allocating_init , 并把返回值给 %6
- 将 %6 的值存储到 %3(也就是我们刚刚创建的全局变量的地址) 构 建 Int , 并 return
- 构 建 Int , 并 return
LGPerson()实际调用分析:
// LGPerson.__allocating_init()
sil hidden [exact_self_class] @$s8 LGPerson AACABycfC : $@convention(method) (@thick LGPerson.Type) -> @owned LGPerson {
// %0 "$metatype"
bb0(%0 : $@thick LGPerson.Type):
// 读取LGPerson的`alloc_ref`方法地址,给%1
%1 = alloc_ref $LGPerson // user: %3
// 读取LGPerson.init()函数地址,给%2
%2 = function_ref @$s8 LGPerson AACABycfc : $@convention(method) (@owned LGPerson) -> @owned LGPerson // user: %3
// 调用`alloc_ref`创建一个LGPerson实例对象,给%3
%3 = apply %2(%1) : $@convention(method) (@owned LGPerson) -> @owned LGPerson // user: %4
// 返回%3(LGPerson类型)
return %3 : $LGPerson // id: %4
} // end sil function '$s8 LGPerson AACABycfC'