Swift-SIL生成(包教但不保证会系列-updating...)

如何创建SIL项目

声明:

(一)⚠️⚠️⚠️目前的举例都是在Github里面可以下载的,🔗链接放在了项目地址(全文搜一下就知道了),大家到时候自己去看呀~

(二)⚠️⚠️⚠️创建常规项目也是没有问题的。你可以直接在你的项目文件目录下创建运行命令行

例如:你的项目目录可能是这样创建的

命令行

步骤一:

bash 复制代码
cd /Users/chill/Desktop/Github/SourceCodeAnalyse/Test-Swift-FuncDispatch/Test-Swift-FuncDispatch

步骤二:

swiftc -emit-silgen -O AClass.swift

既然我单独创建正常的项目没有问题,那我为什么还要创建一个单独的SIL项目。先解释一下为什么要单独要创建一个SIL的项目,因为我们就是怕其他的项目文件问题会对我当前的文件AClass.swift有影响(小心谨慎的❤️❤️❤️心态),那就我们按照我下面说的新建的步骤实现试一下,你可能心里更舒服。但是如果你觉得无所谓,我都会,那就可以退出了,已经没有什么值得看的了,哈哈哈。

开整!

1. 新建工程-步骤一
2. 新建工程-步骤二
2.1 main.swift详细的代码
swift 复制代码
class AClass {
    func test1() {
        
    }
    func test2() {
        
    }
}

extension AClass {
    func test3() {
        
    }
}
2.2 转换后的代码
swift 复制代码
chill@Chills-MacBook-Pro Test-CommonLineTool-Dispatch % swiftc main.swift 
chill@Chills-MacBook-Pro Test-CommonLineTool-Dispatch % swiftc -emit-sil main.swift 
sil_stage canonical

import Builtin
import Swift
import SwiftShims

import Foundation

class AClass {
  func test1()
  func test2()
  @objc deinit
  init()
}

extension AClass {
  func test3()
}

// main
sil @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
  %2 = integer_literal $Builtin.Int32, 0          // user: %3
  %3 = struct $Int32 (%2 : $Builtin.Int32)        // user: %4
  return %3 : $Int32                              // id: %4
} // end sil function 'main'

// AClass.test1()
sil hidden @$s4main6AClassC5test1yyF : $@convention(method) (@guaranteed AClass) -> () {
// %0 "self"                                      // user: %1
bb0(%0 : $AClass):
  debug_value %0 : $AClass, let, name "self", argno 1, implicit // id: %1
  %2 = tuple ()                                   // user: %3
  return %2 : $()                                 // id: %3
} // end sil function '$s4main6AClassC5test1yyF'

// AClass.test2()
sil hidden @$s4main6AClassC5test2yyF : $@convention(method) (@guaranteed AClass) -> () {
// %0 "self"                                      // user: %1
bb0(%0 : $AClass):
  debug_value %0 : $AClass, let, name "self", argno 1, implicit // id: %1
  %2 = tuple ()                                   // user: %3
  return %2 : $()                                 // id: %3
} // end sil function '$s4main6AClassC5test2yyF'

// AClass.deinit
sil hidden @$s4main6AClassCfd : $@convention(method) (@guaranteed AClass) -> @owned Builtin.NativeObject {
// %0 "self"                                      // users: %2, %1
bb0(%0 : $AClass):
  debug_value %0 : $AClass, let, name "self", argno 1, implicit // id: %1
  %2 = unchecked_ref_cast %0 : $AClass to $Builtin.NativeObject // user: %3
  return %2 : $Builtin.NativeObject               // id: %3
} // end sil function '$s4main6AClassCfd'

// AClass.__deallocating_deinit
sil hidden @$s4main6AClassCfD : $@convention(method) (@owned AClass) -> () {
// %0 "self"                                      // users: %3, %1
bb0(%0 : $AClass):
  debug_value %0 : $AClass, let, name "self", argno 1, implicit // id: %1
  // function_ref AClass.deinit
  %2 = function_ref @$s4main6AClassCfd : $@convention(method) (@guaranteed AClass) -> @owned Builtin.NativeObject // user: %3
  %3 = apply %2(%0) : $@convention(method) (@guaranteed AClass) -> @owned Builtin.NativeObject // user: %4
  %4 = unchecked_ref_cast %3 : $Builtin.NativeObject to $AClass // user: %5
  dealloc_ref %4 : $AClass                        // id: %5
  %6 = tuple ()                                   // user: %7
  return %6 : $()                                 // id: %7
} // end sil function '$s4main6AClassCfD'

// AClass.__allocating_init()
sil hidden [exact_self_class] @$s4main6AClassCACycfC : $@convention(method) (@thick AClass.Type) -> @owned AClass {
// %0 "$metatype"
bb0(%0 : $@thick AClass.Type):
  %1 = alloc_ref $AClass                          // user: %3
  // function_ref AClass.init()
  %2 = function_ref @$s4main6AClassCACycfc : $@convention(method) (@owned AClass) -> @owned AClass // user: %3
  %3 = apply %2(%1) : $@convention(method) (@owned AClass) -> @owned AClass // user: %4
  return %3 : $AClass                             // id: %4
} // end sil function '$s4main6AClassCACycfC'

// AClass.init()
sil hidden @$s4main6AClassCACycfc : $@convention(method) (@owned AClass) -> @owned AClass {
// %0 "self"                                      // users: %2, %1
bb0(%0 : $AClass):
  debug_value %0 : $AClass, let, name "self", argno 1, implicit // id: %1
  return %0 : $AClass                             // id: %2
} // end sil function '$s4main6AClassCACycfc'

// AClass.test3()
sil hidden @$s4main6AClassC5test3yyF : $@convention(method) (@guaranteed AClass) -> () {
// %0 "self"                                      // user: %1
bb0(%0 : $AClass):
  debug_value %0 : $AClass, let, name "self", argno 1, implicit // id: %1
  %2 = tuple ()                                   // user: %3
  return %2 : $()                                 // id: %3
} // end sil function '$s4main6AClassC5test3yyF'

sil_vtable AClass {
  #AClass.test1: (AClass) -> () -> () : @$s4main6AClassC5test1yyF	// AClass.test1()
  #AClass.test2: (AClass) -> () -> () : @$s4main6AClassC5test2yyF	// AClass.test2()
  #AClass.init!allocator: (AClass.Type) -> () -> AClass : @$s4main6AClassCACycfC	// AClass.__allocating_init()
  #AClass.deinit!deallocator: @$s4main6AClassCfD	// AClass.__deallocating_deinit
}

// Mappings from '#fileID' to '#filePath':
//   'main/main.swift' => 'main.swift'

看到上面生成的东西,我们可能会很费解s4main6AClassC5test1yyF是什么东西,细心的同学就会发现上面注释了AClass.test1(),但是我们可能还会有问题,这东西到底长啥样。那我们就来-名称重整。

3. 解决文件中的名称(名称重整)
命令行
swift 复制代码
xcrun swift-demangle
swift 复制代码
chill@Chills-MacBook-Pro Test-CommonLineTool-Dispatch % xcrun swift-demangle s4main6AClassC5test1yyF
$s4main6AClassC5test1yyF ---> main.AClass.test1() -> ()

💡💡💡

这个时候你就会说:那我也不能一个方法名一个方法名转换呀,我想要的是整体替换呀

3.1 名称重整后的代码
命令行
css 复制代码
swiftc -emit-sil main.swift | xcrun swift-demangle
swift 复制代码
chill@Chills-MacBook-Pro Test-CommonLineTool-Dispatch % swiftc -emit-sil main.swift | xcrun swift-demangle   
sil_stage canonical

import Builtin
import Swift
import SwiftShims

import Foundation

class AClass {
  func test1()
  func test2()
  @objc deinit
  init()
}

extension AClass {
  func test3()
}

// main
sil @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
  %2 = integer_literal $Builtin.Int32, 0          // user: %3
  %3 = struct $Int32 (%2 : $Builtin.Int32)        // user: %4
  return %3 : $Int32                              // id: %4
} // end sil function 'main'

// AClass.test1()
sil hidden @main.AClass.test1() -> () : $@convention(method) (@guaranteed AClass) -> () {
// %0 "self"                                      // user: %1
bb0(%0 : $AClass):
  debug_value %0 : $AClass, let, name "self", argno 1, implicit // id: %1
  %2 = tuple ()                                   // user: %3
  return %2 : $()                                 // id: %3
} // end sil function 'main.AClass.test1() -> ()'

// AClass.test2()
sil hidden @main.AClass.test2() -> () : $@convention(method) (@guaranteed AClass) -> () {
// %0 "self"                                      // user: %1
bb0(%0 : $AClass):
  debug_value %0 : $AClass, let, name "self", argno 1, implicit // id: %1
  %2 = tuple ()                                   // user: %3
  return %2 : $()                                 // id: %3
} // end sil function 'main.AClass.test2() -> ()'

// AClass.deinit
sil hidden @main.AClass.deinit : $@convention(method) (@guaranteed AClass) -> @owned Builtin.NativeObject {
// %0 "self"                                      // users: %2, %1
bb0(%0 : $AClass):
  debug_value %0 : $AClass, let, name "self", argno 1, implicit // id: %1
  %2 = unchecked_ref_cast %0 : $AClass to $Builtin.NativeObject // user: %3
  return %2 : $Builtin.NativeObject               // id: %3
} // end sil function 'main.AClass.deinit'

// AClass.__deallocating_deinit
sil hidden @main.AClass.__deallocating_deinit : $@convention(method) (@owned AClass) -> () {
// %0 "self"                                      // users: %3, %1
bb0(%0 : $AClass):
  debug_value %0 : $AClass, let, name "self", argno 1, implicit // id: %1
  // function_ref AClass.deinit
  %2 = function_ref @main.AClass.deinit : $@convention(method) (@guaranteed AClass) -> @owned Builtin.NativeObject // user: %3
  %3 = apply %2(%0) : $@convention(method) (@guaranteed AClass) -> @owned Builtin.NativeObject // user: %4
  %4 = unchecked_ref_cast %3 : $Builtin.NativeObject to $AClass // user: %5
  dealloc_ref %4 : $AClass                        // id: %5
  %6 = tuple ()                                   // user: %7
  return %6 : $()                                 // id: %7
} // end sil function 'main.AClass.__deallocating_deinit'

// AClass.__allocating_init()
sil hidden [exact_self_class] @main.AClass.__allocating_init() -> main.AClass : $@convention(method) (@thick AClass.Type) -> @owned AClass {
// %0 "$metatype"
bb0(%0 : $@thick AClass.Type):
  %1 = alloc_ref $AClass                          // user: %3
  // function_ref AClass.init()
  %2 = function_ref @main.AClass.init() -> main.AClass : $@convention(method) (@owned AClass) -> @owned AClass // user: %3
  %3 = apply %2(%1) : $@convention(method) (@owned AClass) -> @owned AClass // user: %4
  return %3 : $AClass                             // id: %4
} // end sil function 'main.AClass.__allocating_init() -> main.AClass'

// AClass.init()
sil hidden @main.AClass.init() -> main.AClass : $@convention(method) (@owned AClass) -> @owned AClass {
// %0 "self"                                      // users: %2, %1
bb0(%0 : $AClass):
  debug_value %0 : $AClass, let, name "self", argno 1, implicit // id: %1
  return %0 : $AClass                             // id: %2
} // end sil function 'main.AClass.init() -> main.AClass'

// AClass.test3()
sil hidden @main.AClass.test3() -> () : $@convention(method) (@guaranteed AClass) -> () {
// %0 "self"                                      // user: %1
bb0(%0 : $AClass):
  debug_value %0 : $AClass, let, name "self", argno 1, implicit // id: %1
  %2 = tuple ()                                   // user: %3
  return %2 : $()                                 // id: %3
} // end sil function 'main.AClass.test3() -> ()'

sil_vtable AClass {
  #AClass.test1: (AClass) -> () -> () : @main.AClass.test1() -> ()	// AClass.test1()
  #AClass.test2: (AClass) -> () -> () : @main.AClass.test2() -> ()	// AClass.test2()
  #AClass.init!allocator: (AClass.Type) -> () -> AClass : @main.AClass.__allocating_init() -> main.AClass	// AClass.__allocating_init()
  #AClass.deinit!deallocator: @main.AClass.__deallocating_deinit	// AClass.__deallocating_deinit
}

// Mappings from '#fileID' to '#filePath':
//   'main/main.swift' => 'main.swift'
4. 写入文件,方便查询记录
命令行
css 复制代码
swiftc -emit-sil main.swift | xcrun swift-demangle > ./main.sil
5. 如果你出现了UIKit的相关问题

例如我:

swift 复制代码
chill@Chills-MacBook-Pro Test-Swift-FuncDispatch % swiftc -emit-silgen -O ViewController.swift
ViewController.swift:8:8: error: no such module 'UIKit'

参考资料里面写的是

css 复制代码
swiftc -emit-sil -target x86_64-apple-ios15.3-simulator -sdk $(xcrun --show-sdk-path --sdk iphonesimulator) ViewController.swift > ViewController.sil

但是我实验过了,不起作用,还是会报错,等我研究下哈

vbnet 复制代码
xcrun: error: SDK "iphonesimulator" cannot be located
xcrun: error: SDK "iphonesimulator" cannot be located
xcrun: error: unable to lookup item 'Path' in SDK 'iphonesimulator'
<unknown>:0: error: no input files

还有一点是参考材料上说生成脚本,但我的报错了就没有跟下去。上面的问题不影响进度,我们继续,等回来的时候处理。

还有就是show me code,下面的项目名称和图上面的截屏是对的上的,您就学吧 项目地址:

参考资料:

上面的都学费了了吗?我们接下来准备干什么,我还是准备分析一下消息派发的机制能不能从SIL中看出来,但是可能还需要研究下... 如果感兴趣,不妨点个赞!收藏下! 我们改天继续...

相关推荐
王解2 小时前
Jest项目实战(4):将工具库顺利迁移到GitHub的完整指南
单元测试·github
油泼辣子多加2 小时前
2024年11月4日Github流行趋势
github
梓羽玩Python3 小时前
推荐一款用了5年的全能下载神器:Motrix!全平台支持,不限速下载网盘文件就靠它!
程序员·开源·github
小牛itbull9 小时前
ReactPress:重塑内容管理的未来
react.js·github·reactpress
鱼满满记17 小时前
1.6K+ Star!GenAIScript:一个可自动化的GenAI脚本环境
人工智能·ai·github
梦魇梦狸º19 小时前
腾讯轻量云服务器docker拉取不到镜像的问题:拉取超时
docker·容器·github
Huazie1 天前
一篇搞定 Hexo Diversity 主题接入!支持多主题自由切换!
javascript·github·hexo
草明2 天前
Nginx 做反向代理,一个服务优先被使用,当无法提供服务时才使用其他的备用服务
运维·nginx·github
马里嗷2 天前
Puppeteer - 掌控浏览器自动化的开源利器
后端·github