diff options
| author | Ophestra <cat@gensokyo.uk> | 2026-08-25 13:57:38 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2026-08-25 14:00:42 +0900 |
| commit | ac7abbbe3fa2eea01defb670abc7dc1dc336cf21 (patch) | |
| tree | cb8c451110acbd394667e94ae66c53dc422398b8 /internal | |
| parent | 7ee5d5368de5494350e7766a595c2bdc8f01ce80 (diff) | |
internal/rosa: read-only access to built-ins
This removes potential footguns caused by mutable builtins without requiring unnecessary clones.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/rosa/builtins.go | 42 | ||||
| -rw-r--r-- | internal/rosa/go.go | 2 | ||||
| -rw-r--r-- | internal/rosa/llvm.go | 4 | ||||
| -rw-r--r-- | internal/rosa/llvm_test.go | 2 | ||||
| -rw-r--r-- | internal/rosa/report.go | 4 | ||||
| -rw-r--r-- | internal/rosa/rosa.go | 16 | ||||
| -rw-r--r-- | internal/rosa/rosa_test.go | 7 | ||||
| -rw-r--r-- | internal/rosa/state.go | 34 | ||||
| -rw-r--r-- | internal/rosa/state_test.go | 6 |
9 files changed, 74 insertions, 43 deletions
diff --git a/internal/rosa/builtins.go b/internal/rosa/builtins.go index 8c46779f..6d457dbd 100644 --- a/internal/rosa/builtins.go +++ b/internal/rosa/builtins.go @@ -25,7 +25,7 @@ const ( loadFlagE = `"-l$` + pkg.EnvLoad + `"` ) -// newTar wraps [pkg.NewHTTPGetTar] with a simpler function signature. +// newTar is a helper for downloading compressed tarballs. func newTar(url, checksum string, compress uint32) pkg.Artifact { return pkg.NewTar( pkg.NewDecompress( @@ -114,3 +114,43 @@ func skipGNUTests(tests ...int64) string { } return buf.String() } + +// builtin contains native and embedded [Artifact] registrations. +var builtin S + +// New returns the address of a newly populated [S] derived from built-ins. +func New() *S { return builtin.Clone() } + +// Collect returns all built-in non-excluded [ArtifactH]. +func Collect() (handles P) { return builtin.Collect() } + +// CollectAll returns all built-in [ArtifactH]. +func CollectAll() (handles P) { return builtin.CollectAll() } + +// builtinStd is the [Std] toolchain stage on builtin. +var builtinStd = builtin.Std() + +// Load satisfies an [Artifact] referred to by an [ArtifactH]. +func Load(handle ArtifactH) (*Metadata, pkg.Artifact) { + return builtinStd.Load(handle) +} + +// LoadAt satisfies an [Artifact] referred to by an [ArtifactH] at the +// specified stage. +func LoadAt(stage Stage, handle ArtifactH) (*Metadata, pkg.Artifact) { + return builtin.New(stage).Load(handle) +} + +// MustLoad is like Load, but panics if the named [Artifact] is not registered. +func MustLoad(handle ArtifactH) (*Metadata, pkg.Artifact) { + return builtinStd.MustLoad(handle) +} + +// MustLoadAt is like LoadAt, but panics if the named [Artifact] is not +// registered. +func MustLoadAt(stage Stage, handle ArtifactH) (*Metadata, pkg.Artifact) { + return builtin.New(stage).MustLoad(handle) +} + +// HasStageEarly returns whether a stage0 distribution is available. +func HasStageEarly() (ok bool) { return builtin.HasStageEarly() } diff --git a/internal/rosa/go.go b/internal/rosa/go.go index 6cebd08f..69d5eb73 100644 --- a/internal/rosa/go.go +++ b/internal/rosa/go.go @@ -66,7 +66,7 @@ func init() { Version: version, Exclude: true, } - native.MustRegister(meta.Name, func(t Toolchain) (*Metadata, pkg.Artifact) { + builtin.MustRegister(meta.Name, func(t Toolchain) (*Metadata, pkg.Artifact) { var ( bootstrapEnv []string bootstrapEarly []pkg.Artifact diff --git a/internal/rosa/llvm.go b/internal/rosa/llvm.go index 8a844268..85f4292d 100644 --- a/internal/rosa/llvm.go +++ b/internal/rosa/llvm.go @@ -48,7 +48,7 @@ func litArgs(verbose bool, skipChecks ...string) string { } func init() { - native.MustRegister("llvm", func(t Toolchain) (*Metadata, pkg.Artifact) { + builtin.MustRegister("llvm", func(t Toolchain) (*Metadata, pkg.Artifact) { meta := Metadata{ Name: "llvm", Description: "a collection of modular and reusable compiler and toolchain technologies", @@ -168,7 +168,7 @@ func init() { ) } - if t.opts&OptLLVMNoLTO == 0 { + if t.opts&OptToolchainLTO != 0 { cache = append(cache, []KV{ // very expensive {"LLVM_ENABLE_LTO", "Thin"}, diff --git a/internal/rosa/llvm_test.go b/internal/rosa/llvm_test.go index 2b1d2e7d..42b0b540 100644 --- a/internal/rosa/llvm_test.go +++ b/internal/rosa/llvm_test.go @@ -10,7 +10,7 @@ import ( func TestLLVMInputs(t *testing.T) { const wantInputCount = 470 - _, llvm := rosa.Native().Std().MustLoad(rosa.H("llvm")) + _, llvm := rosa.MustLoad(rosa.H("llvm")) var n int for range pkg.Inputs(llvm) { n++ diff --git a/internal/rosa/report.go b/internal/rosa/report.go index a97ff8e8..7792d9e9 100644 --- a/internal/rosa/report.go +++ b/internal/rosa/report.go @@ -42,8 +42,8 @@ func WriteReport(msg message.Msg, w io.Writer, c *pkg.Cache) error { zero [wordSize]byte buf [len(pkg.ID{}) + wordSize]byte ) - t := native.Std() - for _, p := range native.Collect() { + t := builtin.Std() + for _, p := range builtin.Collect() { meta, a := t.MustLoad(p) if meta == nil { return errors.New("artifact " + p.String() + " in inconsistent state") diff --git a/internal/rosa/rosa.go b/internal/rosa/rosa.go index 32c1bd00..1089ffa1 100644 --- a/internal/rosa/rosa.go +++ b/internal/rosa/rosa.go @@ -624,33 +624,25 @@ func (attr *GenericHelper) script(t Toolchain, _ string) string { return script } -// native contains natively-implemented and built-in azalea-based [Artifact]. -// It is generally recommended to clone this instance for custom [Artifact] -// registrations. -var native S - -// Native returns the global [S]. -func Native() *S { return &native } - // parseTime is the duration of early parsing of built-in azalea expressions. var parseTime time.Duration // ParseTime returns the time taken by early parsing of built-in azalea expressions. func ParseTime() time.Duration { return parseTime } -// nativeB is the backing directory of built-in azalea-based [Artifact] +// builtinAzalea is the backing directory of built-in azalea-based [Artifact] // implementations. // //go:embed package -var nativeB embed.FS +var builtinAzalea embed.FS func init() { - sub, err := fs.Sub(nativeB, "package") + sub, err := fs.Sub(builtinAzalea, "package") if err != nil { panic(err) } t := time.Now() - if err = native.RegisterFS(sub); err != nil { + if err = builtin.RegisterFS(sub); err != nil { println(err.Error()) os.Exit(1) } diff --git a/internal/rosa/rosa_test.go b/internal/rosa/rosa_test.go index 8d0917bb..86468ea4 100644 --- a/internal/rosa/rosa_test.go +++ b/internal/rosa/rosa_test.go @@ -28,7 +28,6 @@ var ( ) func TestMain(m *testing.M) { - rosa.Native().DropCaches("", rosa.OptLLVMNoLTO) container.TryArgv0(nil) code := m.Run() @@ -79,8 +78,8 @@ func TestCureAll(t *testing.T) { cache := getCache(t) t.Parallel() - for _, p := range rosa.Native().CollectAll() { - _, a := rosa.Native().Std().MustLoad(p) + for _, p := range rosa.CollectAll() { + _, a := rosa.MustLoad(p) t.Run(p.String(), func(t *testing.T) { t.Parallel() @@ -94,7 +93,7 @@ func TestCureAll(t *testing.T) { } func BenchmarkStage3(b *testing.B) { - t := rosa.Native().Clone().Std() + t := rosa.New().Std() llvm := rosa.H("llvm") for b.Loop() { diff --git a/internal/rosa/state.go b/internal/rosa/state.go index ab1868f4..85ad5476 100644 --- a/internal/rosa/state.go +++ b/internal/rosa/state.go @@ -184,16 +184,16 @@ type cachedArtifact struct { const ( // OptSkipCheck skips running all test suites. OptSkipCheck = 1 << iota - // OptLLVMNoLTO disables LTO in all [LLVM] stages. - OptLLVMNoLTO + // OptToolchainLTO enables LTO in all LLVM stages. + OptToolchainLTO ) // S holds a set of [Artifact]. type S struct { // [ArtifactH] to [Artifact]. - artifacts sync.Map - // Size of artifacts. - artifactCount atomic.Uint64 + p sync.Map + // Size of p. + len atomic.Uint64 // Target architecture. arch string @@ -220,9 +220,9 @@ type S struct { // Clone returns a copy of s. func (s *S) Clone() *S { v := S{arch: s.arch, opts: s.opts} - s.artifacts.Range(func(key, value any) bool { - v.artifacts.Store(key, value) - v.artifactCount.Add(1) + s.p.Range(func(key, value any) bool { + v.p.Store(key, value) + v.len.Add(1) return true }) return &v @@ -304,7 +304,7 @@ func (s *S) DropCaches(targetArch string, flags int) { // get returns the named [Artifact]. func (s *S) get(handle ArtifactH) (f Artifact) { s.wantsArch() - v, ok := s.artifacts.Load(handle) + v, ok := s.p.Load(handle) if ok { f = v.(Artifact) } @@ -393,9 +393,9 @@ func (s *S) Register(name string, f Artifact) bool { return false } p := ArtifactH(unique.Make(name)) - _, ok := s.artifacts.LoadOrStore(p, f) + _, ok := s.p.LoadOrStore(p, f) if !ok { - s.artifactCount.Add(1) + s.len.Add(1) } return !ok } @@ -418,15 +418,15 @@ func (s *S) MustRegister(name string, f Artifact) { } } -// count returns the number of [Artifact] registered to s. +// count returns the number of [Artifact] registered to r. func (s *S) count() int { - return int(s.artifactCount.Load()) + return int(s.len.Load()) } // CollectAll returns all [ArtifactH] registered to s. func (s *S) CollectAll() (handles P) { handles = make(P, 0, s.count()) - s.artifacts.Range(func(key, _ any) bool { + s.p.Range(func(key, _ any) bool { handles = append(handles, key.(ArtifactH)) return true }) @@ -439,7 +439,7 @@ func (s *S) CollectAll() (handles P) { // Collect returns all non-excluded [ArtifactH] registered to s. func (s *S) Collect() (handles P) { handles = make(P, 0, s.count()) - s.artifacts.Range(func(key, _ any) bool { + s.p.Range(func(key, _ any) bool { h := key.(ArtifactH) meta, _ := s.Std().MustLoad(h) if !meta.Exclude { @@ -453,7 +453,7 @@ func (s *S) Collect() (handles P) { return } -// deferredGit is a call to Toolchain.newTagRemote from azalea. +// deferredGit is a call to [Toolchain.NewViaGit] from azalea. type deferredGit struct { url string tag string @@ -1375,7 +1375,7 @@ func (s *S) SetSource(fsys fs.FS) error { const name = "hakurei-source" a := pkg.NewFile("hakurei-src-current.tar.gz", buf.Bytes()) - s.artifacts.Store( + s.p.Store( H(name), Artifact(func(t Toolchain) (*Metadata, pkg.Artifact) { return &Metadata{ diff --git a/internal/rosa/state_test.go b/internal/rosa/state_test.go index ea4b7bf8..ad16bc26 100644 --- a/internal/rosa/state_test.go +++ b/internal/rosa/state_test.go @@ -9,17 +9,17 @@ import ( func TestLoad(t *testing.T) { t.Parallel() - for _, p := range rosa.Native().Collect() { + for _, p := range rosa.Collect() { t.Run(p.String(), func(t *testing.T) { t.Parallel() - rosa.Native().Std().MustLoad(p) + rosa.MustLoad(p) }) } } func BenchmarkAll(b *testing.B) { - t := rosa.Native().Clone().Std() + t := rosa.New().Std() for b.Loop() { for _, p := range t.Collect() { |
