diff --git a/cmd/gasm/audit.go b/cmd/gasm/audit.go index 08c99d2..7a77407 100644 --- a/cmd/gasm/audit.go +++ b/cmd/gasm/audit.go @@ -10,7 +10,8 @@ import ( "path/filepath" "regexp" "runtime" - "sort" + "slices" + "strconv" "strings" "sourcedock.dev/petrbalvin/gasm-devkit/arch" @@ -80,9 +81,9 @@ mnemonic, so the audit tracks whatever toolchain `+"`go env GOROOT`"+` names. // GO-ONLY is not enumerable by probing: Go's table is only visible // through names we already know, so nothing can be reported there. - sort.Strings(superset) - sort.Strings(backlog) - sort.Strings(shared) + slices.Sort(superset) + slices.Sort(backlog) + slices.Sort(shared) w := os.Stdout fmt.Fprintf(w, "gasm table (amd64, families excluded): %d mnemonics\n", len(names)) @@ -176,8 +177,10 @@ func probeGoAsm(names []string) (map[string]bool, error) { if m == nil { continue } - var lineNo int - fmt.Sscanf(m[1], "%d", &lineNo) + lineNo, err := strconv.Atoi(m[1]) + if err != nil { + continue + } if name, ok := lineMnemonic[lineNo]; ok && unrecognizedRe.MatchString(l) { result[name] = false } diff --git a/cmd/gasm/scaffold.go b/cmd/gasm/scaffold.go index da3dd67..2ec6386 100644 --- a/cmd/gasm/scaffold.go +++ b/cmd/gasm/scaffold.go @@ -80,7 +80,7 @@ bodies, place the file in the kernel's package, and run it in CI. fmt.Fprintf(&out, "func Test%sDifferential(t *testing.T) {\n", strings.ToUpper(name[:1])+name[1:]) fmt.Fprintf(&out, "\trng := rand.New(rand.NewSource(1))\n") - fmt.Fprintf(&out, "\tfor iter := 0; iter < 1000; iter++ {\n") + fmt.Fprintf(&out, "\tfor range 1000 {\n") // Seed two independent argument sets per iteration: the kernel runs // on set A, the portable reference on set B, so in-place writes // through pointer/slice arguments cannot contaminate the other side. @@ -97,11 +97,11 @@ bodies, place the file in the kernel's package, and run it in CI. fmt.Fprintf(&out, "\t\tgot := %s(%s)\n", name, strings.Join(aArgs, ", ")) fmt.Fprintf(&out, "\t\twant := %sPortable(%s)\n", name, strings.Join(bArgs, ", ")) fmt.Fprintf(&out, "\t\tif !bytes.Equal(outputBytes(got), outputBytes(want)) {\n") - fmt.Fprintf(&out, "\t\t\tt.Fatalf(\"iter %%d: kernel diverges from the portable spec\", iter)\n") + fmt.Fprintf(&out, "\t\t\tt.Fatalf(\"kernel diverges from the portable spec (seed 1, deterministic)\")\n") fmt.Fprintf(&out, "\t\t}\n") for _, s := range sliceNames { fmt.Fprintf(&out, "\t\tif !bytes.Equal(outputBytes(%sA), outputBytes(%sB)) {\n", s, s) - fmt.Fprintf(&out, "\t\t\tt.Fatalf(\"iter %%d: kernel mutated %%s differently\", iter, %q)\n", s) + fmt.Fprintf(&out, "\t\t\tt.Fatalf(\"kernel mutated %%q differently (seed 1, deterministic)\", %q)\n", s) fmt.Fprintf(&out, "\t\t}\n") } fmt.Fprintf(&out, "\t}\n}\n\n") @@ -334,7 +334,7 @@ func outputBytes(v any) []byte { return b case int: b := make([]byte, 8) - for i := 0; i < 8; i++ { + for i := range 8 { b[i] = byte(uint64(t) >> (8 * i)) } return b diff --git a/verify/buffers.go b/verify/buffers.go index 1b094f0..af6b7b4 100644 --- a/verify/buffers.go +++ b/verify/buffers.go @@ -7,6 +7,7 @@ import ( "encoding/binary" "encoding/hex" "fmt" + "strconv" "strings" "unsafe" ) @@ -200,21 +201,13 @@ func ParseScalarArgs(spec string) (map[string]uint64, error) { } func splitScalar(part string) (string, uint64, error) { - eq := strings.Index(part, "=") - if eq <= 0 { + name, valStr, ok := strings.Cut(part, "=") + if !ok || strings.TrimSpace(name) == "" { return "", 0, fmt.Errorf("scalar arg spec %q: want name=value", part) } - name := strings.TrimSpace(part[:eq]) - valStr := strings.TrimSpace(part[eq+1:]) - var val uint64 - var err error - if strings.HasPrefix(valStr, "0x") || strings.HasPrefix(valStr, "0X") { - _, err = fmt.Sscanf(valStr, "0x%x", &val) - } else { - _, err = fmt.Sscanf(valStr, "%d", &val) - } - if err != nil || name == "" { + val, err := strconv.ParseUint(strings.TrimSpace(valStr), 0, 64) + if err != nil { return "", 0, fmt.Errorf("scalar arg spec %q: bad value", part) } - return name, val, nil + return strings.TrimSpace(name), val, nil }