func Task() *ir.Name {
// Step 1: 处理 import 语句,按顺序查找出所有依赖包中的初始化任务
var deps []*obj.LSym
for _, pkg := range typecheck.Target.Imports {
n := typecheck.Resolve(ir.NewIdent(base.Pos, pkg.Lookup(".inittask")))
deps = append(deps, n.(*ir.Name).Linksym())
}
// Step 2: 处理全局变量赋值语句,函数 initOrder 用来确定初始化顺序,并且返回需要在运行时初始化的赋值语句
nf := initOrder(typecheck.Target.Decls)
var fns []*obj.LSym
if len(nf) > 0 {
// 如果有需要动态执行的赋值语句,则创建一个 init 函数,并将该函数的函数体设置为所有的动态赋值语句
// 该 init 函数在所有用户自定义的 init 函数之前
initializers := typecheck.Lookup("init")
fn := typecheck.DeclFunc(initializers, ir.NewFuncType(base.Pos, nil, nil, nil))
fn.Body = nf
typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
fns = append(fns, fn.Linksym())
}
// Step 3: 处理用户申明的 init 函数,按照顺序添加到 fns 中
for _, fn := range typecheck.Target.Inits {
// 代码优化,去除函数中的无效代码,如果优化之后函数体为空,则忽略该 init 函数
deadcode.Func(fn)
if len(fn.Body) == 1 {
if stmt := fn.Body[0]; stmt.Op() == ir.OBLOCK && len(stmt.(*ir.BlockStmt).List) == 0 {
continue
}
}
fns = append(fns, fn.Nname.Linksym())
}
// Step 4: 创建初始化任务 .inittask, 依次写入 deps 及 fns
sym := typecheck.Lookup(".inittask")
task := typecheck.NewName(sym)
task.Class = ir.PEXTERN
sym.Def = task
lsym := task.Linksym()
ot := 0
ot = objw.Uintptr(lsym, ot, 0) // state: not initialized yet
ot = objw.Uintptr(lsym, ot, uint64(len(deps)))
ot = objw.Uintptr(lsym, ot, uint64(len(fns)))
for _, d := range deps {
ot = objw.SymPtr(lsym, ot, d, 0)
}
for _, f := range fns {
ot = objw.SymPtr(lsym, ot, f, 0)
}
return task
}