compiler: Fix package dependency order calculation
The algorithm is now simpler and seems to work better.
Этот коммит содержится в:
родитель
88f143f3e6
коммит
db8b6c6900
1 изменённых файлов: 34 добавлений и 31 удалений
31
tgo.go
31
tgo.go
|
@ -124,7 +124,7 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error {
|
||||||
|
|
||||||
// TODO: pick the error of the first package, not a random package
|
// TODO: pick the error of the first package, not a random package
|
||||||
for _, pkgInfo := range lprogram.AllPackages {
|
for _, pkgInfo := range lprogram.AllPackages {
|
||||||
fmt.Println("package:", pkgInfo.Pkg.Name())
|
fmt.Println("package:", pkgInfo.Pkg.Path())
|
||||||
if len(pkgInfo.Errors) != 0 {
|
if len(pkgInfo.Errors) != 0 {
|
||||||
return pkgInfo.Errors[0]
|
return pkgInfo.Errors[0]
|
||||||
}
|
}
|
||||||
|
@ -136,23 +136,24 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error {
|
||||||
// Make a list of packages in import order.
|
// Make a list of packages in import order.
|
||||||
packageList := []*ssa.Package{}
|
packageList := []*ssa.Package{}
|
||||||
packageSet := map[string]struct{}{}
|
packageSet := map[string]struct{}{}
|
||||||
worklist := [][]string{{"runtime", mainPath}}
|
worklist := []string{"runtime", mainPath}
|
||||||
for len(worklist) != 0 {
|
for len(worklist) != 0 {
|
||||||
for _, pkgPath := range worklist[0] {
|
pkgPath := worklist[0]
|
||||||
pkg := program.ImportedPackage(pkgPath)
|
pkg := program.ImportedPackage(pkgPath)
|
||||||
if pkg == nil {
|
if pkg == nil {
|
||||||
|
// Non-SSA package (e.g. cgo).
|
||||||
packageSet[pkgPath] = struct{}{}
|
packageSet[pkgPath] = struct{}{}
|
||||||
continue // non-SSA package (e.g. cgo)
|
worklist = worklist[1:]
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := packageSet[pkgPath]; ok {
|
if _, ok := packageSet[pkgPath]; ok {
|
||||||
|
// Package already in the final package list.
|
||||||
|
worklist = worklist[1:]
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
unsatisfiedImports := make([]string, 0)
|
unsatisfiedImports := make([]string, 0)
|
||||||
imports := pkg.Pkg.Imports()
|
imports := pkg.Pkg.Imports()
|
||||||
if pkgPath != "runtime" && pkgPath != "unsafe" && pkgPath != "runtime/cgo" && pkgPath != "syscall" {
|
|
||||||
imports = append(imports, program.ImportedPackage("runtime").Pkg)
|
|
||||||
}
|
|
||||||
for _, pkg := range imports {
|
for _, pkg := range imports {
|
||||||
if _, ok := packageSet[pkg.Path()]; ok {
|
if _, ok := packageSet[pkg.Path()]; ok {
|
||||||
continue
|
continue
|
||||||
|
@ -160,15 +161,17 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error {
|
||||||
unsatisfiedImports = append(unsatisfiedImports, pkg.Path())
|
unsatisfiedImports = append(unsatisfiedImports, pkg.Path())
|
||||||
}
|
}
|
||||||
if len(unsatisfiedImports) == 0 {
|
if len(unsatisfiedImports) == 0 {
|
||||||
// all dependencies are in packageList inserted
|
// All dependencies of this package are satisfied, so add this
|
||||||
|
// package to the list.
|
||||||
packageList = append(packageList, pkg)
|
packageList = append(packageList, pkg)
|
||||||
packageSet[pkgPath] = struct{}{}
|
packageSet[pkgPath] = struct{}{}
|
||||||
} else {
|
|
||||||
unsatisfiedImports = append(unsatisfiedImports, pkgPath) // reconsider
|
|
||||||
worklist = append(worklist, unsatisfiedImports)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
worklist = worklist[1:]
|
worklist = worklist[1:]
|
||||||
|
} else {
|
||||||
|
// Prepend all dependencies to the worklist and reconsider this
|
||||||
|
// package (by not removing it from the worklist). At that point, it
|
||||||
|
// must be possible to add it to packageList.
|
||||||
|
worklist = append(unsatisfiedImports, worklist...)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform each package into LLVM IR.
|
// Transform each package into LLVM IR.
|
||||||
|
@ -309,7 +312,7 @@ func (c *Compiler) getFunctionName(fn *ssa.Function) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) parsePackage(program *ssa.Program, pkg *ssa.Package) error {
|
func (c *Compiler) parsePackage(program *ssa.Program, pkg *ssa.Package) error {
|
||||||
fmt.Println("package:", pkg.Pkg.Path())
|
fmt.Println("\npackage:", pkg.Pkg.Path())
|
||||||
|
|
||||||
// Make sure we're walking through all members in a constant order every
|
// Make sure we're walking through all members in a constant order every
|
||||||
// run.
|
// run.
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче