一、 Go编译流程
二、过程说明
1. 词法解析
读取Go源文件,将字符序列转换为符号(token)序列,比如将“:=”转换为_Define
代码中的标识符、关键字、运算符和分隔符等字符串都将转化为对应的符号
2. 语法解析
根据Go语言规范对符号化的Go源文件进行解析,识别可能出现的语法错误,比如
1 package main 2 3 import \"fmt\" 4 5 func main() 6 { //这里不能单独一行 7 fmt.Println(\"Hello world!\") 8 } 9 10 # command-line-arguments 11 ./main.go:5:6: missing function body 12 ./main.go:6:1: syntax error: unexpected semicolon or newline before {
3. AST构建
AST,即抽象语法树(Abstract Syntax Tree)
4. 类型检查
a. 类型推断
b. 数组索引是否为正整数
c. 引用的结构体字段是否是大写可导出的
5. 变量捕获
主要针对闭包场景而言,闭包函数可能引用闭包外变量
变量捕获需要明确在闭包中通过值引用还是地址引用来捕获变量
6. 函数内联
函数内联是指将较小的函数直接组合进调用者的函数内
可以减少函数调用的开销
7. 逃逸分析
逃逸分析确定变量内存是分配在栈区还是堆区
8. 闭包重写
对闭包函数进行重写
9. 遍历函数
遍历函数中的声明和表达式,将操作函数替换为具体的执行函数,如map被替换为运行时mapaccess2_fast64函数
10. SSA生成
SSA,即静态单赋值(Static Single Assignment),可以理解为抽象语法树到机器码的中间代码
11. 机器码生成
a. 汇编
b. 链接
三、可执行文件
1. ELF
ELF,Executable and Linkable Format是类Unix操作系统下最常见的可执行且可链接的文件格式。
来源:https://www.cnblogs.com/amos01/p/16247118.html
本站部分图文来源于网络,如有侵权请联系删除。