feat(cmd): GOOS-aware headers, audit battery shapes and semicolon spacing
Test / test (push) Failing after 2m21s
Test / test (push) Failing after 2m21s
Assisted-by: GLM 5.3 Flash
This commit is contained in:
+34
-21
@@ -27,7 +27,10 @@ import (
|
||||
// GOROOT assembly includes it, and a standalone assembler has no compiler
|
||||
// to have produced it, so gasm generates the equivalent itself: the package
|
||||
// the .s file lives in is parsed and type-checked here, with the target
|
||||
// architecture's own sizes, and the same defines are written out.
|
||||
// architecture's own sizes, and the same defines are written out. The
|
||||
// type-checking GOOS is selected by the caller: a GOOS-specific file
|
||||
// (sys_darwin_arm64.s) needs its platform's defines, which a header from
|
||||
// the ambient GOOS silently omits.
|
||||
//
|
||||
// The emitter mirrors cmd/compile's dumpasmhdr exactly: constants come out
|
||||
// as "const_NAME", struct entries as "NAME__size" followed by the fields in
|
||||
@@ -67,11 +70,15 @@ func goAsmHeaderResolved(asmDir string, dirs []string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// generateGoAsmHeader type-checks the Go package in pkgDir for goarch,
|
||||
// writes its go_asm.h equivalent into dir, and returns dir. The caller
|
||||
// owns the directory and its removal.
|
||||
func generateGoAsmHeader(pkgDir, goarch, dir string) (string, error) {
|
||||
imp := newSourceImporter(goarch)
|
||||
// generateGoAsmHeader type-checks the Go package in pkgDir for goos and
|
||||
// goarch, writes its go_asm.h equivalent into dir, and returns dir. An
|
||||
// empty goos means the ambient one. The caller owns the directory and its
|
||||
// removal.
|
||||
func generateGoAsmHeader(pkgDir, goos, goarch, dir string) (string, error) {
|
||||
if goos == "" {
|
||||
goos = build.Default.GOOS
|
||||
}
|
||||
imp := newSourceImporter(goos, goarch)
|
||||
if imp.sizes == nil {
|
||||
return "", fmt.Errorf("go_asm.h: unknown GOARCH %q", goarch)
|
||||
}
|
||||
@@ -89,7 +96,7 @@ func generateGoAsmHeader(pkgDir, goarch, dir string) (string, error) {
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
fmt.Fprintf(&b, "// generated by gasm from package %s (GOARCH %s)\n\n", bp.Name, goarch)
|
||||
fmt.Fprintf(&b, "// generated by gasm from package %s (GOOS %s, GOARCH %s)\n\n", bp.Name, goos, goarch)
|
||||
// Files in the build's own order and declarations in source order: the
|
||||
// same walk the compiler's reader makes, so the header reads the same
|
||||
// way the toolchain's does. Order carries no meaning to the assembler
|
||||
@@ -203,13 +210,14 @@ type sourceImporter struct {
|
||||
pkgs map[string]*types.Package
|
||||
}
|
||||
|
||||
// newSourceImporter returns the importer for one target architecture.
|
||||
// newSourceImporter returns the importer for one target GOOS and GOARCH.
|
||||
// Cgo is disabled so the file set is deterministic and independent of the
|
||||
// host's C toolchain: cgo-tagged files drop out of the build exactly as
|
||||
// they do from a CGO_ENABLED=0 build, whose assembly is what gasm targets.
|
||||
func newSourceImporter(goarch string) *sourceImporter {
|
||||
func newSourceImporter(goos, goarch string) *sourceImporter {
|
||||
ctxt := new(build.Context)
|
||||
*ctxt = build.Default
|
||||
ctxt.GOOS = goos
|
||||
ctxt.GOARCH = goarch
|
||||
ctxt.CgoEnabled = false
|
||||
return &sourceImporter{
|
||||
@@ -291,7 +299,7 @@ func (im *sourceImporter) checkPackage(bp *build.Package, files []*ast.File) (*t
|
||||
// type-check must not be re-checked once per file.
|
||||
type asmhdrCache struct {
|
||||
root string
|
||||
dirs map[string]string // "pkgDir\x00goarch" -> directory holding go_asm.h
|
||||
dirs map[string]string // "pkgDir\x00goos\x00goarch" -> directory holding go_asm.h
|
||||
errs map[string]error
|
||||
}
|
||||
|
||||
@@ -304,17 +312,22 @@ func newAsmhdrCache() (*asmhdrCache, error) {
|
||||
}
|
||||
|
||||
// dirFor returns the directory holding the generated go_asm.h for pkgDir
|
||||
// and goarch, generating it on first use.
|
||||
func (c *asmhdrCache) dirFor(pkgDir, goarch string) (string, error) {
|
||||
key := pkgDir + "\x00" + goarch
|
||||
// under goos and goarch, generating it on first use. An empty goos means
|
||||
// the ambient one, resolved here so that one package cannot generate twice
|
||||
// under an explicit and an implicit spelling of the same GOOS.
|
||||
func (c *asmhdrCache) dirFor(pkgDir, goos, goarch string) (string, error) {
|
||||
if goos == "" {
|
||||
goos = build.Default.GOOS
|
||||
}
|
||||
key := pkgDir + "\x00" + goos + "\x00" + goarch
|
||||
if dir, ok := c.dirs[key]; ok {
|
||||
return dir, nil
|
||||
}
|
||||
if err, ok := c.errs[key]; ok {
|
||||
return "", err
|
||||
}
|
||||
dir := filepath.Join(c.root, fmt.Sprintf("h%d_%s", len(c.dirs), goarch))
|
||||
if _, err := generateGoAsmHeader(pkgDir, goarch, dir); err != nil {
|
||||
dir := filepath.Join(c.root, fmt.Sprintf("h%d_%s_%s", len(c.dirs), goos, goarch))
|
||||
if _, err := generateGoAsmHeader(pkgDir, goos, goarch, dir); err != nil {
|
||||
c.errs[key] = err
|
||||
return "", err
|
||||
}
|
||||
@@ -327,10 +340,10 @@ func (c *asmhdrCache) close() { os.RemoveAll(c.root) }
|
||||
|
||||
// ensureGoAsmHeader prepares the include directory a file that includes
|
||||
// go_asm.h needs: the generated header for the package in path's directory,
|
||||
// for the file's target architecture. It reports a usage error when the
|
||||
// architecture cannot be determined, and passes through the generator's
|
||||
// diagnostics, which name the package.
|
||||
func ensureGoAsmHeader(path string, target arch.Arch, cache *asmhdrCache) (string, func(), error) {
|
||||
// for the file's target GOOS and architecture. It reports a usage error
|
||||
// when the architecture cannot be determined, and passes through the
|
||||
// generator's diagnostics, which name the package.
|
||||
func ensureGoAsmHeader(path string, target arch.Arch, goos string, cache *asmhdrCache) (string, func(), error) {
|
||||
if path == "-" {
|
||||
return "", nil, errors.New("cannot generate go_asm.h for standard input (no package directory)")
|
||||
}
|
||||
@@ -338,14 +351,14 @@ func ensureGoAsmHeader(path string, target arch.Arch, cache *asmhdrCache) (strin
|
||||
return "", nil, errors.New("a file that includes go_asm.h needs a target architecture: name the file _<arch>.s or pass -GOARCH")
|
||||
}
|
||||
if cache != nil {
|
||||
dir, err := cache.dirFor(filepath.Dir(path), goarchName(target))
|
||||
dir, err := cache.dirFor(filepath.Dir(path), goos, goarchName(target))
|
||||
return dir, func() {}, err
|
||||
}
|
||||
root, err := os.MkdirTemp("", "gasm-asmhdr")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
dir, err := generateGoAsmHeader(filepath.Dir(path), goarchName(target), root)
|
||||
dir, err := generateGoAsmHeader(filepath.Dir(path), goos, goarchName(target), root)
|
||||
if err != nil {
|
||||
os.RemoveAll(root)
|
||||
return "", nil, err
|
||||
|
||||
Reference in New Issue
Block a user