feat(parser): macro expansion, conditionals and include splicing with -I
Assisted-by: GLM 5.3 Flash
This commit is contained in:
+30
-7
@@ -37,7 +37,7 @@ import (
|
||||
// construction and are excluded from the diff; the other architectures list
|
||||
// their conditional branches outright.
|
||||
func cmdAuditInstructions(args []string) error {
|
||||
fs := newCommand("audit-instructions", "gasm audit-instructions [--corpus [dir]] [amd64|arm64|riscv64|loong64]", `
|
||||
fs := newCommand("audit-instructions", "gasm audit-instructions [--corpus [dir]] [-I dir] [amd64|arm64|riscv64|loong64]", `
|
||||
Compare the gasm encoder for the given architecture (default amd64) against
|
||||
go tool asm and print the diff: superset encodings (gasm-only, shippable via
|
||||
gasm asm --format goobj) and known-but-unencodable names (the backlog). The
|
||||
@@ -57,11 +57,13 @@ per-architecture pass rates and the most common failure reasons, which drive
|
||||
the encodability backlog by frequency rather than by table order.
|
||||
`)
|
||||
corpus := fs.Bool("corpus", false, "assemble a corpus of .s files and report pass rates and failure reasons")
|
||||
var dirs includeDirs
|
||||
fs.Var(&dirs, "I", "directory to search for #include files (may be repeated)")
|
||||
if err := fs.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
if *corpus {
|
||||
return cmdAuditCorpus(fs.Args())
|
||||
return cmdAuditCorpus(fs.Args(), dirs)
|
||||
}
|
||||
archName := "amd64"
|
||||
switch n := len(fs.Args()); {
|
||||
@@ -395,8 +397,11 @@ func (t *corpusTally) fail(path, reason string) {
|
||||
}
|
||||
}
|
||||
|
||||
// cmdAuditCorpus implements audit-instructions --corpus.
|
||||
func cmdAuditCorpus(args []string) error {
|
||||
// cmdAuditCorpus implements audit-instructions --corpus. The include
|
||||
// directories carry #include resolution over a corpus whose files refer to
|
||||
// headers such as GOROOT/pkg/include, the same -I a toolchain comparison
|
||||
// needs.
|
||||
func cmdAuditCorpus(args []string, dirs includeDirs) error {
|
||||
if len(args) > 1 {
|
||||
return &usageError{fmt.Errorf("audit-instructions --corpus takes at most one directory argument")}
|
||||
}
|
||||
@@ -410,7 +415,25 @@ func cmdAuditCorpus(args []string) error {
|
||||
}
|
||||
root = filepath.Join(strings.TrimSpace(string(out)), "src")
|
||||
}
|
||||
stats, err := runCorpusAudit(root)
|
||||
// The toolchain's shipped headers (funcdata.h and friends) define the
|
||||
// macros GOROOT files include; a corpus audit measures those files, so
|
||||
// the header directory joins the search path automatically. go_asm.h
|
||||
// is compiler-generated per package and stays unresolvable on purpose.
|
||||
if out, err := exec.Command("go", "env", "GOROOT").Output(); err == nil {
|
||||
pkgInclude := filepath.Join(strings.TrimSpace(string(out)), "pkg", "include")
|
||||
if fi, err := os.Stat(pkgInclude); err == nil && fi.IsDir() {
|
||||
seen := false
|
||||
for _, d := range dirs {
|
||||
if d == pkgInclude {
|
||||
seen = true
|
||||
}
|
||||
}
|
||||
if !seen {
|
||||
dirs = append(dirs, pkgInclude)
|
||||
}
|
||||
}
|
||||
}
|
||||
stats, err := runCorpusAudit(root, dirs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -454,7 +477,7 @@ func otherPortFile(path string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func runCorpusAudit(root string) (*corpusStats, error) {
|
||||
func runCorpusAudit(root string, dirs includeDirs) (*corpusStats, error) {
|
||||
files, err := asmFiles(root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -479,7 +502,7 @@ func runCorpusAudit(root string) (*corpusStats, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f, errs := parser.Parse(path, src)
|
||||
f, errs := parser.ParseWithOptions(path, src, parser.Options{Expand: true, IncludeDirs: dirs})
|
||||
|
||||
var wanted []int // indexes into targets
|
||||
if a := arch.FromFilename(path); a != arch.Unknown {
|
||||
|
||||
Reference in New Issue
Block a user