diff options
| author | Ophestra <cat@gensokyo.uk> | 2026-07-23 16:21:20 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2026-07-23 16:39:34 +0900 |
| commit | 67dbb68818026f3d7a64e9519cf1aac36468b7c9 (patch) | |
| tree | 68f1e731242a9c8ef1912a195c2a6aefc53f6da5 /internal/pkg/ir.go | |
| parent | 0e689d9983dee9f742c4ed4b2e716fbcb1b84e99 (diff) | |
internal/pkg: implementation revisions
This enables changing the behaviour of an artifact implementation without changing its IR structure. Unfortunately this changes the IR header structure resulting in many rebuilds.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/pkg/ir.go')
| -rw-r--r-- | internal/pkg/ir.go | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/internal/pkg/ir.go b/internal/pkg/ir.go index 5a7e7f56..d5e6bbdb 100644 --- a/internal/pkg/ir.go +++ b/internal/pkg/ir.go @@ -278,10 +278,11 @@ func (ic *irCache) encode( return *a == *b }) - // kind uint64 | deps_sz uint64 - var buf [wordSize * 2]byte + // kind uint64 | rev uint64 | deps_sz uint64 + var buf [wordSize * 3]byte binary.LittleEndian.PutUint64(buf[:], uint64(a.Kind())) - binary.LittleEndian.PutUint64(buf[wordSize:], uint64(len(idents))) + binary.LittleEndian.PutUint64(buf[wordSize:], GetRevision(a)) + binary.LittleEndian.PutUint64(buf[wordSize*2:], uint64(len(idents))) if _, err = w.Write(buf[:]); err != nil { return } @@ -740,6 +741,15 @@ func (ir *IRReader) ReadString() string { return unsafe.String(unsafe.SliceData(p), len(p)) } +// A RevisionError describes the first [Artifact] in an IR stream claiming a +// revision not supported by the registered implementation. +type RevisionError [2]uint64 + +func (e RevisionError) Error() string { + return "claimed revision " + strconv.FormatUint(e[0], 10) + + " differs from implementation value " + strconv.FormatUint(e[1], 10) +} + // decode decodes the next [Artifact] in the IR stream and returns any buffer // originating from [Cache] before returning. decode returns [io.EOF] if and // only if the underlying [io.Reader] is already read to EOF. @@ -772,6 +782,9 @@ func (d *IRDecoder) decode() (a Artifact, err error) { return } + ir.mustRead(ir.buf[:]) + rev := binary.LittleEndian.Uint64(ir.buf[:]) + defer ir.putAll() ir.mustRead(ir.buf[:]) sz := binary.LittleEndian.Uint64(ir.buf[:]) @@ -792,6 +805,10 @@ func (d *IRDecoder) decode() (a Artifact, err error) { err = syscall.ENOTRECOVERABLE return } + if _rev := GetRevision(a); _rev != rev { + err = RevisionError{rev, _rev} + return + } if ir.count != -1 { err = ErrRemainingIR |
