Documentation
¶
Overview ¶
Package runtime is the FFFI2 wire-protocol runtime — binary marshalling, channel I/O, deferred-block capture, and procedure dispatch. Forms the transport substrate beneath the typed wrappers in fffi2/typed/.
Index ¶
- Variables
- func GetBoolRetr[D UnmarshallReaderI, T ~bool](unmarshaller D) (r T)
- func GetBoolSliceRetr[D UnmarshallReaderI, T ~bool](unmarshaller D) (r []T)
- func GetBytesRetr[D UnmarshallReaderI, T byte](unmarshaller D) (r []byte)
- func GetComplex64Retr[D UnmarshallReaderI, T ~complex64](unmarshaller D) (r T)
- func GetComplex128Retr[D UnmarshallReaderI, T ~complex128](unmarshaller D) (r T)
- func GetFloat32Array2Retr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r [2]T)
- func GetFloat32Array3Retr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r [3]T)
- func GetFloat32Array4Retr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r [4]T)
- func GetFloat32Retr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r T)
- func GetFloat32SliceRetr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r []T)
- func GetFloat64Retr[D UnmarshallReaderI, T ~float64](unmarshaller D) (r T)
- func GetFloat64SliceRetr[D UnmarshallReaderI, T ~float64](unmarshaller D) (r []T)
- func GetInt8Retr[D UnmarshallReaderI, T ~int8](unmarshaller D) (r T)
- func GetInt8SliceRetr[D UnmarshallReaderI, T ~int8](unmarshaller D) (r []T)
- func GetInt16Retr[D UnmarshallReaderI, T ~int16](unmarshaller D) (r T)
- func GetInt16SliceRetr[D UnmarshallReaderI, T ~int16](unmarshaller D) (r []T)
- func GetInt32Retr[D UnmarshallReaderI, T ~int32](unmarshaller D) (r T)
- func GetInt32SliceRetr[D UnmarshallReaderI, T ~int32](unmarshaller D) (r []T)
- func GetInt64Retr[D UnmarshallReaderI, T ~int64](unmarshaller D) (r T)
- func GetInt64SliceRetr[D UnmarshallReaderI, T ~int64](unmarshaller D) (r []T)
- func GetStringRetr[D UnmarshallReaderI, T ~string](unmarshaller D) (r T)
- func GetStringRetrMostLikelyEmpty[D UnmarshallReaderI, T ~string](unmarshaller D) (r T)
- func GetUint8Retr[D UnmarshallReaderI, T ~uint8](unmarshaller D) (r T)
- func GetUint8SliceRetr[D UnmarshallReaderI, T ~uint8](unmarshaller D) (r []T)
- func GetUint16Retr[D UnmarshallReaderI, T ~uint16](unmarshaller D) (r T)
- func GetUint16SliceRetr[D UnmarshallReaderI, T ~uint16](unmarshaller D) (r []T)
- func GetUint32Retr[D UnmarshallReaderI, T ~uint32](unmarshaller D) (r T)
- func GetUint32SliceRetr[D UnmarshallReaderI, T ~uint32](unmarshaller D) (r []T)
- func GetUint64Retr[D UnmarshallReaderI, T ~uint64](unmarshaller D) (r T)
- func GetUint64SliceRetr[D UnmarshallReaderI, T ~uint64](unmarshaller D) (r []T)
- func GetUintptrRetr[D UnmarshallReaderI, T ~uintptr](unmarshaller D) (r T)
- func IterateFloat32SliceRetr[D UnmarshallReaderI, T ~float32](unmarshaller D) iter.Seq[T]
- func IterateFloat64SliceRetr[D UnmarshallReaderI, T ~float64](unmarshaller D) iter.Seq[T]
- func IterateInt64SliceRetr[D UnmarshallReaderI, T ~int64](unmarshaller D) iter.Seq[T]
- func IterateStringSliceRetr[D UnmarshallReaderI, T ~string](unmarshaller D) iter.Seq[T]
- func IterateUint32SliceRetr[D UnmarshallReaderI, T ~uint32](unmarshaller D) iter.Seq[T]
- func IterateUint64SliceRetr[D UnmarshallReaderI, T ~uint64](unmarshaller D) iter.Seq[T]
- func PutBoolArg[D MarshallWriterI, T ~bool](marshaller D, v T)
- func PutBoolSliceArg[D MarshallWriterI, T ~bool](marshaller D, vs []T)
- func PutBytesArg[D MarshallWriterI](marshaller D, v []byte)
- func PutComplex64Arg[D MarshallWriterI, T ~complex64](marshaller D, v T)
- func PutComplex64Array2Arg[D MarshallWriterI, T ~complex64](marshaller D, v [2]T)
- func PutComplex128Arg[D MarshallWriterI, T ~complex128](marshaller D, v T)
- func PutFloat32Arg[D MarshallWriterI, T ~float32](marshaller D, v T)
- func PutFloat32Array2Arg[D MarshallWriterI, T ~float32](marshaller D, v [2]T)
- func PutFloat32Array3Arg[D MarshallWriterI, T ~float32](marshaller D, v [3]T)
- func PutFloat32Array4Arg[D MarshallWriterI, T ~float32](marshaller D, v [4]T)
- func PutFloat32SliceArg[D MarshallWriterI, T ~float32](marshaller D, vs []T)
- func PutFloat64Arg[D MarshallWriterI, T ~float64](marshaller D, v T)
- func PutFloat64Array4Arg[D MarshallWriterI, T ~float64](marshaller D, v [4]T)
- func PutFloat64SliceArg[D MarshallWriterI, T ~float64](marshaller D, vs []T)
- func PutInt8Arg[D MarshallWriterI, T ~int8](marshaller D, v T)
- func PutInt8SliceArg[D MarshallWriterI, T ~int8](marshaller D, vs []T)
- func PutInt16Arg[D MarshallWriterI, T ~int16](marshaller D, v T)
- func PutInt16SliceArg[D MarshallWriterI, T ~int16](marshaller D, vs []T)
- func PutInt32Arg[D MarshallWriterI, T ~int32](marshaller D, v T)
- func PutInt32SliceArg[D MarshallWriterI, T ~int32](marshaller D, vs []T)
- func PutInt64Arg[D MarshallWriterI, T ~int64](marshaller D, v T)
- func PutInt64SliceArg[D MarshallWriterI, T ~int64](marshaller D, vs []T)
- func PutRuneArg[D MarshallWriterI, T ~rune](marshaller D, v T)
- func PutRuneSliceArg[D MarshallWriterI, T ~rune](marshaller D, vs []T)
- func PutStringArg[D MarshallWriterI, T ~string](marshaller D, v T)
- func PutStringSliceArg[D MarshallWriterI, T ~string](marshaller D, vs []T)
- func PutStringsArg[D MarshallWriterI, T ~string](marshaller D, vs []T)
- func PutUint8Arg[D MarshallWriterI, T ~uint8](marshaller D, v T)
- func PutUint8SliceArg[D MarshallWriterI, T ~uint8](marshaller D, vs []T)
- func PutUint16Arg[D MarshallWriterI, T ~uint16](marshaller D, v T)
- func PutUint16SliceArg[D MarshallWriterI, T ~uint16](marshaller D, vs []T)
- func PutUint32Arg[D MarshallWriterI, T ~uint32](marshaller D, v T)
- func PutUint32SliceArg[D MarshallWriterI, T ~uint32](marshaller D, vs []T)
- func PutUint64Arg[D MarshallWriterI, T ~uint64](marshaller D, v T)
- func PutUint64SliceArg[D MarshallWriterI, T ~uint64](marshaller D, vs []T)
- func PutUintptrArg[D MarshallWriterI, T ~uintptr](marshaller D, v T)
- func RegisterScopeHint(kind string) *atomic.Uint64
- type ByteOrderI
- type ChannelI
- type DeferredBlockScope
- func (inst *DeferredBlockScope) Begin(keyParts ...any)
- func (inst *DeferredBlockScope) BlockCount() uint32
- func (inst *DeferredBlockScope) End()
- func (inst *DeferredBlockScope) ReleaseWithHint()
- func (inst *DeferredBlockScope) Reset()
- func (inst *DeferredBlockScope) WriteToFixedKey(w *bytes.Buffer) (err error)
- type Fffi2
- func (inst *Fffi2[U]) AppendRawToCapture(raw []byte)
- func (inst *Fffi2[U]) BeginCapture(buf *bytes.Buffer, endianness binary.ByteOrder)
- func (inst *Fffi2[U]) CallFunctionMayThrow() (err error)
- func (inst *Fffi2[U]) CallFunctionNoThrow()
- func (inst *Fffi2[U]) EndCapture()
- func (inst *Fffi2[U]) IsCapturing() (capturing bool)
- func (inst *Fffi2[U]) PipelineProcedureNoThrow()
- func (inst *Fffi2[U]) ReceiveMsg() iter.Seq[U]
- func (inst *Fffi2[U]) SendIntermediate(buf []byte) (err error)
- func (inst *Fffi2[U]) SyncRetained(id uint64, buf []byte) (err error)
- type FffiCaptureI
- type FuncProcId
- type InlineIoChannel
- func (inst *InlineIoChannel[U]) FlushMessages()
- func (inst *InlineIoChannel[U]) Marshaller() *Marshaller
- func (inst *InlineIoChannel[U]) ReceiveMsg() iter.Seq[U]
- func (inst *InlineIoChannel[U]) SendSingleUseMsg(msg []byte)
- func (inst *InlineIoChannel[U]) SetInOut(in *bufio.Reader, out *bufio.Writer)
- func (inst *InlineIoChannel[U]) SyncMultiUseMsg(id uint64, msg []byte)
- type MarshallWriterI
- type Marshaller
- func (inst *Marshaller) GetWrittenBytes() int
- func (inst *Marshaller) ResetWrittenBytes()
- func (inst *Marshaller) WriteBool(v bool)
- func (inst *Marshaller) WriteBytes(v []byte)
- func (inst *Marshaller) WriteComplex64(v complex64)
- func (inst *Marshaller) WriteComplex128(v complex128)
- func (inst *Marshaller) WriteFloat32(v float32)
- func (inst *Marshaller) WriteFloat64(v float64)
- func (inst *Marshaller) WriteInt8(v int8)
- func (inst *Marshaller) WriteInt16(v int16)
- func (inst *Marshaller) WriteInt32(v int32)
- func (inst *Marshaller) WriteInt64(v int64)
- func (inst *Marshaller) WriteNilSlice()
- func (inst *Marshaller) WriteSliceLength(l int)
- func (inst *Marshaller) WriteString(v string)
- func (inst *Marshaller) WriteUint8(v uint8)
- func (inst *Marshaller) WriteUint16(v uint16)
- func (inst *Marshaller) WriteUint32(v uint32)
- func (inst *Marshaller) WriteUint64(v uint64)
- func (inst *Marshaller) WriteVerbatim(v []byte)
- type ScopeHintSnapshot
- type UnmarshallReaderI
- type Unmarshaller
- func (inst *Unmarshaller) ClearErr()
- func (inst *Unmarshaller) Err() (err error)
- func (inst *Unmarshaller) GetReadBytes() int
- func (inst *Unmarshaller) ReadBool() (v bool)
- func (inst *Unmarshaller) ReadBytes() (v []byte)
- func (inst *Unmarshaller) ReadComplex64() (v complex64)
- func (inst *Unmarshaller) ReadComplex128() (v complex128)
- func (inst *Unmarshaller) ReadFloat32() (v float32)
- func (inst *Unmarshaller) ReadFloat64() (v float64)
- func (inst *Unmarshaller) ReadInt8() (v int8)
- func (inst *Unmarshaller) ReadInt16() (v int16)
- func (inst *Unmarshaller) ReadInt32() (v int32)
- func (inst *Unmarshaller) ReadInt64() (v int64)
- func (inst *Unmarshaller) ReadSliceLength() (l int, isNil bool)
- func (inst *Unmarshaller) ReadString() (v string)
- func (inst *Unmarshaller) ReadStringMostLikelyEmpty() (v string)
- func (inst *Unmarshaller) ReadUInt8() (v uint8)
- func (inst *Unmarshaller) ReadUInt16() (v uint16)
- func (inst *Unmarshaller) ReadUInt32() (v uint32)
- func (inst *Unmarshaller) ReadUInt32MostLikelyZero() (v uint32)
- func (inst *Unmarshaller) ReadUInt64() (v uint64)
- func (inst *Unmarshaller) ReadUintptr() (v uintptr)
- func (inst *Unmarshaller) ResetReadBytes()
- func (inst *Unmarshaller) SetAllocateBufferFunc(f func(l uint32) []byte)
- func (inst *Unmarshaller) SetEndianness(endi binary.ByteOrder)
- func (inst *Unmarshaller) SetErrorHandler(f func(err error))
- func (inst *Unmarshaller) SetInput(r io.Reader)
Constants ¶
This section is empty.
Variables ¶
var DefaultErrorHandler = func(err error) { log.Error().Err(err).Msg("fffi2 channel error") }
var PackageProps = packageprops.Props{ WASMWASI: packageprops.WASMCompiles, WASMJS: packageprops.WASMCompiles, WASMFreestanding: packageprops.WASMCompiles, }
PackageProps records this package's curated properties (ADR-0080). Seeded by `wasmsurvey props generate`; curate by hand, then `wasmsurvey props verify`.
var StringAllocationError = errors.New("allocated string buffer does not have correct length")
Functions ¶
func GetBoolRetr ¶
func GetBoolRetr[D UnmarshallReaderI, T ~bool](unmarshaller D) (r T)
func GetBoolSliceRetr ¶
func GetBoolSliceRetr[D UnmarshallReaderI, T ~bool](unmarshaller D) (r []T)
func GetBytesRetr ¶
func GetBytesRetr[D UnmarshallReaderI, T byte](unmarshaller D) (r []byte)
func GetComplex64Retr ¶
func GetComplex64Retr[D UnmarshallReaderI, T ~complex64](unmarshaller D) (r T)
func GetComplex128Retr ¶
func GetComplex128Retr[D UnmarshallReaderI, T ~complex128](unmarshaller D) (r T)
func GetFloat32Array2Retr ¶
func GetFloat32Array2Retr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r [2]T)
func GetFloat32Array3Retr ¶
func GetFloat32Array3Retr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r [3]T)
func GetFloat32Array4Retr ¶
func GetFloat32Array4Retr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r [4]T)
func GetFloat32Retr ¶
func GetFloat32Retr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r T)
func GetFloat32SliceRetr ¶
func GetFloat32SliceRetr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r []T)
func GetFloat64Retr ¶
func GetFloat64Retr[D UnmarshallReaderI, T ~float64](unmarshaller D) (r T)
func GetFloat64SliceRetr ¶
func GetFloat64SliceRetr[D UnmarshallReaderI, T ~float64](unmarshaller D) (r []T)
func GetInt8Retr ¶
func GetInt8Retr[D UnmarshallReaderI, T ~int8](unmarshaller D) (r T)
func GetInt8SliceRetr ¶
func GetInt8SliceRetr[D UnmarshallReaderI, T ~int8](unmarshaller D) (r []T)
func GetInt16Retr ¶
func GetInt16Retr[D UnmarshallReaderI, T ~int16](unmarshaller D) (r T)
func GetInt16SliceRetr ¶
func GetInt16SliceRetr[D UnmarshallReaderI, T ~int16](unmarshaller D) (r []T)
func GetInt32Retr ¶
func GetInt32Retr[D UnmarshallReaderI, T ~int32](unmarshaller D) (r T)
func GetInt32SliceRetr ¶
func GetInt32SliceRetr[D UnmarshallReaderI, T ~int32](unmarshaller D) (r []T)
func GetInt64Retr ¶
func GetInt64Retr[D UnmarshallReaderI, T ~int64](unmarshaller D) (r T)
func GetInt64SliceRetr ¶
func GetInt64SliceRetr[D UnmarshallReaderI, T ~int64](unmarshaller D) (r []T)
func GetStringRetr ¶
func GetStringRetr[D UnmarshallReaderI, T ~string](unmarshaller D) (r T)
func GetStringRetrMostLikelyEmpty ¶
func GetStringRetrMostLikelyEmpty[D UnmarshallReaderI, T ~string](unmarshaller D) (r T)
func GetUint8Retr ¶
func GetUint8Retr[D UnmarshallReaderI, T ~uint8](unmarshaller D) (r T)
func GetUint8SliceRetr ¶
func GetUint8SliceRetr[D UnmarshallReaderI, T ~uint8](unmarshaller D) (r []T)
func GetUint16Retr ¶
func GetUint16Retr[D UnmarshallReaderI, T ~uint16](unmarshaller D) (r T)
func GetUint16SliceRetr ¶
func GetUint16SliceRetr[D UnmarshallReaderI, T ~uint16](unmarshaller D) (r []T)
func GetUint32Retr ¶
func GetUint32Retr[D UnmarshallReaderI, T ~uint32](unmarshaller D) (r T)
func GetUint32SliceRetr ¶
func GetUint32SliceRetr[D UnmarshallReaderI, T ~uint32](unmarshaller D) (r []T)
func GetUint64Retr ¶
func GetUint64Retr[D UnmarshallReaderI, T ~uint64](unmarshaller D) (r T)
func GetUint64SliceRetr ¶
func GetUint64SliceRetr[D UnmarshallReaderI, T ~uint64](unmarshaller D) (r []T)
func GetUintptrRetr ¶
func GetUintptrRetr[D UnmarshallReaderI, T ~uintptr](unmarshaller D) (r T)
func IterateFloat32SliceRetr ¶
func IterateFloat32SliceRetr[D UnmarshallReaderI, T ~float32](unmarshaller D) iter.Seq[T]
func IterateFloat64SliceRetr ¶
func IterateFloat64SliceRetr[D UnmarshallReaderI, T ~float64](unmarshaller D) iter.Seq[T]
func IterateInt64SliceRetr ¶
func IterateInt64SliceRetr[D UnmarshallReaderI, T ~int64](unmarshaller D) iter.Seq[T]
func IterateStringSliceRetr ¶
func IterateStringSliceRetr[D UnmarshallReaderI, T ~string](unmarshaller D) iter.Seq[T]
func IterateUint32SliceRetr ¶
func IterateUint32SliceRetr[D UnmarshallReaderI, T ~uint32](unmarshaller D) iter.Seq[T]
func IterateUint64SliceRetr ¶
func IterateUint64SliceRetr[D UnmarshallReaderI, T ~uint64](unmarshaller D) iter.Seq[T]
func PutBoolArg ¶
func PutBoolArg[D MarshallWriterI, T ~bool](marshaller D, v T)
func PutBoolSliceArg ¶
func PutBoolSliceArg[D MarshallWriterI, T ~bool](marshaller D, vs []T)
func PutBytesArg ¶
func PutBytesArg[D MarshallWriterI](marshaller D, v []byte)
func PutComplex64Arg ¶
func PutComplex64Arg[D MarshallWriterI, T ~complex64](marshaller D, v T)
func PutComplex64Array2Arg ¶
func PutComplex64Array2Arg[D MarshallWriterI, T ~complex64](marshaller D, v [2]T)
func PutComplex128Arg ¶
func PutComplex128Arg[D MarshallWriterI, T ~complex128](marshaller D, v T)
func PutFloat32Arg ¶
func PutFloat32Arg[D MarshallWriterI, T ~float32](marshaller D, v T)
func PutFloat32Array2Arg ¶
func PutFloat32Array2Arg[D MarshallWriterI, T ~float32](marshaller D, v [2]T)
func PutFloat32Array3Arg ¶
func PutFloat32Array3Arg[D MarshallWriterI, T ~float32](marshaller D, v [3]T)
func PutFloat32Array4Arg ¶
func PutFloat32Array4Arg[D MarshallWriterI, T ~float32](marshaller D, v [4]T)
func PutFloat32SliceArg ¶
func PutFloat32SliceArg[D MarshallWriterI, T ~float32](marshaller D, vs []T)
func PutFloat64Arg ¶
func PutFloat64Arg[D MarshallWriterI, T ~float64](marshaller D, v T)
func PutFloat64Array4Arg ¶
func PutFloat64Array4Arg[D MarshallWriterI, T ~float64](marshaller D, v [4]T)
func PutFloat64SliceArg ¶
func PutFloat64SliceArg[D MarshallWriterI, T ~float64](marshaller D, vs []T)
func PutInt8Arg ¶
func PutInt8Arg[D MarshallWriterI, T ~int8](marshaller D, v T)
func PutInt8SliceArg ¶
func PutInt8SliceArg[D MarshallWriterI, T ~int8](marshaller D, vs []T)
func PutInt16Arg ¶
func PutInt16Arg[D MarshallWriterI, T ~int16](marshaller D, v T)
func PutInt16SliceArg ¶
func PutInt16SliceArg[D MarshallWriterI, T ~int16](marshaller D, vs []T)
func PutInt32Arg ¶
func PutInt32Arg[D MarshallWriterI, T ~int32](marshaller D, v T)
func PutInt32SliceArg ¶
func PutInt32SliceArg[D MarshallWriterI, T ~int32](marshaller D, vs []T)
func PutInt64Arg ¶
func PutInt64Arg[D MarshallWriterI, T ~int64](marshaller D, v T)
func PutInt64SliceArg ¶
func PutInt64SliceArg[D MarshallWriterI, T ~int64](marshaller D, vs []T)
func PutRuneArg ¶
func PutRuneArg[D MarshallWriterI, T ~rune](marshaller D, v T)
func PutRuneSliceArg ¶
func PutRuneSliceArg[D MarshallWriterI, T ~rune](marshaller D, vs []T)
func PutStringArg ¶
func PutStringArg[D MarshallWriterI, T ~string](marshaller D, v T)
func PutStringSliceArg ¶
func PutStringSliceArg[D MarshallWriterI, T ~string](marshaller D, vs []T)
func PutStringsArg ¶
func PutStringsArg[D MarshallWriterI, T ~string](marshaller D, vs []T)
func PutUint8Arg ¶
func PutUint8Arg[D MarshallWriterI, T ~uint8](marshaller D, v T)
func PutUint8SliceArg ¶
func PutUint8SliceArg[D MarshallWriterI, T ~uint8](marshaller D, vs []T)
func PutUint16Arg ¶
func PutUint16Arg[D MarshallWriterI, T ~uint16](marshaller D, v T)
func PutUint16SliceArg ¶
func PutUint16SliceArg[D MarshallWriterI, T ~uint16](marshaller D, vs []T)
func PutUint32Arg ¶
func PutUint32Arg[D MarshallWriterI, T ~uint32](marshaller D, v T)
func PutUint32SliceArg ¶
func PutUint32SliceArg[D MarshallWriterI, T ~uint32](marshaller D, vs []T)
func PutUint64Arg ¶
func PutUint64Arg[D MarshallWriterI, T ~uint64](marshaller D, v T)
func PutUint64SliceArg ¶
func PutUint64SliceArg[D MarshallWriterI, T ~uint64](marshaller D, vs []T)
func PutUintptrArg ¶
func PutUintptrArg[D MarshallWriterI, T ~uintptr](marshaller D, v T)
func RegisterScopeHint ¶
RegisterScopeHint returns the singleton *atomic.Uint64 hint for the given scope-kind name, allocating it on first call. Idempotent: a second call with the same name returns the same pointer, so the codegen can wire `var hintCells = runtime.RegisterScopeHint("cells")` once per package and every scope instance of that kind reads/writes the shared atomic.
Concurrency: safe to call from any goroutine. Registration uses a short writer-lock; subsequent hint reads/writes from a scope's hot path go through the returned *atomic.Uint64 with no further synchronisation.
Types ¶
type ByteOrderI ¶
type ByteOrderI interface {
binary.ByteOrder
binary.AppendByteOrder
}
type DeferredBlockScope ¶
type DeferredBlockScope struct {
// contains filtered or unexported fields
}
DeferredBlockScope manages capture of deferred opcode blocks.
All block key bytes and opcode bytes are appended to a single contiguous slab (dataBuf). Individual blocks are tracked as offset+length pairs into the slab, eliminating per-cell allocations.
Lifecycle:
- scope := NewDeferredBlockScope(fffi, endianness) (or NewDeferredBlockScopeHinted)
- scope.Begin(key...) <- redirect Fffi2 to capture buffer
- ... widget.Send() ... <- messages go to capture buffer
- scope.End() <- restore Fffi2, store buffer
- scope.SpliceInto(r) <- write all blocks into RetainedFffiBuilder
- scope.ReleaseWithHint() <- (optional) fold high-water back into hint
func NewDeferredBlockScope ¶
func NewDeferredBlockScope( getFffi func() FffiCaptureI, endianness binary.ByteOrder, ) *DeferredBlockScope
NewDeferredBlockScope creates a new scope with a fixed-size initial dataBuf. Equivalent to NewDeferredBlockScopeHinted with a nil hint, retained for non-codegen callers and backward compatibility.
getFffi returns the current Fffi2 instance.
func NewDeferredBlockScopeHinted ¶
func NewDeferredBlockScopeHinted( getFffi func() FffiCaptureI, endianness binary.ByteOrder, dataHint *atomic.Uint64, ) *DeferredBlockScope
NewDeferredBlockScopeHinted creates a new scope whose dataBuf is pre-sized from the supplied hint (see RegisterScopeHint for the per-kind atomic). A nil hint behaves like NewDeferredBlockScope and falls back to the floor capacity.
Pre-sizing eliminates the per-doubling growSlice traffic that otherwise dominates the per-frame protocol marshalling cost on widgets like c.EndETable's cells block, where dataBuf reliably grows to a kind-specific high-water mark every frame. The hint is updated by DeferredBlockScope.ReleaseWithHint at the end of the scope's life. See ADR-0049 for the design rationale.
func (*DeferredBlockScope) Begin ¶
func (inst *DeferredBlockScope) Begin(keyParts ...any)
Begin starts capturing opcodes for the given key components.
Key components are serialized as their binary representations directly into the slab, avoiding binary.Write interface overhead:
- uint64 -> 8 bytes LE
- uint32 -> 4 bytes LE
- string -> 4 bytes LE length + UTF-8 bytes
func (*DeferredBlockScope) BlockCount ¶
func (inst *DeferredBlockScope) BlockCount() uint32
BlockCount returns the number of captured blocks.
func (*DeferredBlockScope) End ¶
func (inst *DeferredBlockScope) End()
End stops capturing and stores the block.
func (*DeferredBlockScope) ReleaseWithHint ¶
func (inst *DeferredBlockScope) ReleaseWithHint()
ReleaseWithHint finalises the scope and folds its observed dataBuf high-water mark back into the per-kind hint via a peak-ratchet + slow-decay CAS loop:
observed >= old : next = observed (ratchet up) observed < old : next = old - ((old - observed) >> N) (decay)
where N = deferredHintDecayShift (≈30-frame half-life at the default shift of 5). The buffers are released to GC; the scope must not be touched afterwards. Defensive: if [End] was forgotten (capturing == true), EndCapture is invoked to restore Fffi2 routing so the next frame does not write into a buffer that has been handed to GC.
Idempotent in the sense that calling on a scope without a hint (dataHint == nil) collapses to a no-op cleanup. See ADR-0049.
func (*DeferredBlockScope) Reset ¶
func (inst *DeferredBlockScope) Reset()
Reset clears all blocks for reuse across frames.
func (*DeferredBlockScope) WriteToFixedKey ¶
func (inst *DeferredBlockScope) WriteToFixedKey(w *bytes.Buffer) (err error)
WriteToFixedKey serializes the block map with a fixed key layout. Reads key and buffer data from the slab via offset+length.
Wire format:
u32: block_count for each block: [key_bytes] (fixed size, determined by KeyTypes) u32: block_byte_length [u8; block_byte_length]: framed opcode messages
type Fffi2 ¶
type Fffi2[U UnmarshallReaderI] struct { // contains filtered or unexported fields }
func NewFffi2 ¶
func NewFffi2[U UnmarshallReaderI](channel ChannelI[U]) *Fffi2[U]
func (*Fffi2[U]) AppendRawToCapture ¶
AppendRawToCapture writes raw bytes directly to the innermost capture buffer without adding a frame header. Use this only to re-emit bytes that were already captured with framing in a detached buffer — the DockArea iter wrapper uses it to flush buffered tab bodies into its deferred block scope at Send time.
func (*Fffi2[U]) BeginCapture ¶
BeginCapture redirects SendIntermediate to write into buf instead of the IPC pipe. Nested calls are supported — each Begin pushes a new capture frame; SendIntermediate writes to the innermost (top of stack), so an etable inside a dockArea tab body correctly nests its cell bodies inside the tab body bytes.
func (*Fffi2[U]) CallFunctionMayThrow ¶
func (*Fffi2[U]) CallFunctionNoThrow ¶
func (inst *Fffi2[U]) CallFunctionNoThrow()
func (*Fffi2[U]) EndCapture ¶
func (inst *Fffi2[U]) EndCapture()
EndCapture pops the innermost capture scope. After the outermost pop the stack is empty and SendIntermediate resumes sending to the pipe.
func (*Fffi2[U]) IsCapturing ¶
IsCapturing reports whether the current goroutine is inside a deferred-block capture scope — i.e. SendIntermediate is buffering into a capture frame rather than flushing to the IPC pipe. Read by Fetcher.invoke as a runtime guard: fetchers must not run inside captures (the fetch request would be buffered while the response read blocks on the pipe — mutual deadlock). See doc/skills/imzero2-fetchers/SKILLS.md.
func (*Fffi2[U]) PipelineProcedureNoThrow ¶
func (inst *Fffi2[U]) PipelineProcedureNoThrow()
func (*Fffi2[U]) ReceiveMsg ¶
func (*Fffi2[U]) SendIntermediate ¶
type FffiCaptureI ¶
type FffiCaptureI interface {
BeginCapture(buf *bytes.Buffer, endianness binary.ByteOrder)
EndCapture()
// AppendRawToCapture writes the given framed bytes directly into the
// innermost capture buffer WITHOUT adding a new frame header. Used when
// a caller has already captured framed messages into a detached buffer
// and wants to inject them into an active deferred-block capture scope
// (e.g. the DockArea iter wrapper, which captures each tab body ahead
// of Send and flushes all bodies in order at Send time).
AppendRawToCapture(raw []byte)
// IsCapturing reports whether a deferred-block capture frame is
// currently active. Used by callers (notably Fetcher.invoke) that
// must NOT run inside captures — synchronous fetcher requests would
// be buffered while the response read blocked on the empty pipe.
IsCapturing() bool
}
FffiCaptureI is the subset of Fffi2 needed for capture mode.
type FuncProcId ¶
type FuncProcId uint32
type InlineIoChannel ¶
type InlineIoChannel[U UnmarshallReaderI] struct { // contains filtered or unexported fields }
func NewInlineIoChannel ¶
func (*InlineIoChannel[U]) FlushMessages ¶
func (inst *InlineIoChannel[U]) FlushMessages()
func (*InlineIoChannel[U]) Marshaller ¶
func (inst *InlineIoChannel[U]) Marshaller() *Marshaller
func (*InlineIoChannel[U]) ReceiveMsg ¶
func (inst *InlineIoChannel[U]) ReceiveMsg() iter.Seq[U]
func (*InlineIoChannel[U]) SendSingleUseMsg ¶
func (inst *InlineIoChannel[U]) SendSingleUseMsg(msg []byte)
func (*InlineIoChannel[U]) SetInOut ¶
func (inst *InlineIoChannel[U]) SetInOut(in *bufio.Reader, out *bufio.Writer)
func (*InlineIoChannel[U]) SyncMultiUseMsg ¶
func (inst *InlineIoChannel[U]) SyncMultiUseMsg(id uint64, msg []byte)
type MarshallWriterI ¶
type MarshallWriterI interface {
WriteUint8(v uint8)
WriteBool(v bool)
WriteUint16(v uint16)
WriteUint32(v uint32)
WriteUint64(v uint64)
WriteInt8(v int8)
WriteInt16(v int16)
WriteInt32(v int32)
WriteInt64(v int64)
WriteFloat32(v float32)
WriteFloat64(v float64)
WriteComplex64(v complex64)
WriteComplex128(v complex128)
WriteString(v string)
WriteBytes(v []byte)
WriteSliceLength(l int)
WriteNilSlice()
}
type Marshaller ¶
type Marshaller struct {
// contains filtered or unexported fields
}
func NewMarshaller ¶
func (*Marshaller) GetWrittenBytes ¶
func (inst *Marshaller) GetWrittenBytes() int
func (*Marshaller) ResetWrittenBytes ¶
func (inst *Marshaller) ResetWrittenBytes()
func (*Marshaller) WriteBool ¶
func (inst *Marshaller) WriteBool(v bool)
func (*Marshaller) WriteBytes ¶
func (inst *Marshaller) WriteBytes(v []byte)
func (*Marshaller) WriteComplex64 ¶
func (inst *Marshaller) WriteComplex64(v complex64)
func (*Marshaller) WriteComplex128 ¶
func (inst *Marshaller) WriteComplex128(v complex128)
func (*Marshaller) WriteFloat32 ¶
func (inst *Marshaller) WriteFloat32(v float32)
func (*Marshaller) WriteFloat64 ¶
func (inst *Marshaller) WriteFloat64(v float64)
func (*Marshaller) WriteInt8 ¶
func (inst *Marshaller) WriteInt8(v int8)
func (*Marshaller) WriteInt16 ¶
func (inst *Marshaller) WriteInt16(v int16)
func (*Marshaller) WriteInt32 ¶
func (inst *Marshaller) WriteInt32(v int32)
func (*Marshaller) WriteInt64 ¶
func (inst *Marshaller) WriteInt64(v int64)
func (*Marshaller) WriteNilSlice ¶
func (inst *Marshaller) WriteNilSlice()
func (*Marshaller) WriteSliceLength ¶
func (inst *Marshaller) WriteSliceLength(l int)
func (*Marshaller) WriteString ¶
func (inst *Marshaller) WriteString(v string)
func (*Marshaller) WriteUint8 ¶
func (inst *Marshaller) WriteUint8(v uint8)
func (*Marshaller) WriteUint16 ¶
func (inst *Marshaller) WriteUint16(v uint16)
func (*Marshaller) WriteUint32 ¶
func (inst *Marshaller) WriteUint32(v uint32)
func (*Marshaller) WriteUint64 ¶
func (inst *Marshaller) WriteUint64(v uint64)
func (*Marshaller) WriteVerbatim ¶
func (inst *Marshaller) WriteVerbatim(v []byte)
type ScopeHintSnapshot ¶
type ScopeHintSnapshot struct {
// Kind is the IDL deferred-block name (e.g. "cells", "tabBody").
Kind string
// Bytes is the current hint value — the observed high-water mark
// for this kind, smoothed by the peak-and-slow-decay update rule
// applied at each [DeferredBlockScope.ReleaseWithHint] call.
Bytes uint64
}
ScopeHintSnapshot is one entry from ScopeHintsSnapshot.
func ScopeHintsSnapshot ¶
func ScopeHintsSnapshot() []ScopeHintSnapshot
ScopeHintsSnapshot returns the current per-kind wire-byte hints in kind-name order. Safe to call from any goroutine (e.g. a pprof HTTP handler, a slow-frame logger). The returned slice is owned by the caller; the underlying registry is not held across the call.
Per ADR-0049, the hint table doubles as a passive observability surface: each entry reports what a single scope of that kind cost the FFFI2 wire on its most-expensive recent frame, smoothed to damp one-off spikes.
type UnmarshallReaderI ¶
type UnmarshallReaderI interface {
SetInput(r io.Reader)
SetEndianness(endi binary.ByteOrder)
SetErrorHandler(f func(err error))
SetAllocateBufferFunc(f func(l uint32) []byte)
// Err reports the first read failure since the reader was last given a
// stream, or nil while it is intact. None of the Read methods below can
// signal failure themselves — each returns a zero value, which is
// indistinguishable from a zero the peer sent — so this is what
// separates decoded data from the wreckage of a broken stream.
Err() (err error)
ReadUInt8() (v uint8)
ReadUInt16() (v uint16)
ReadUInt32MostLikelyZero() (v uint32)
ReadUInt32() (v uint32)
ReadUInt64() (v uint64)
ReadInt8() (v int8)
ReadInt16() (v int16)
ReadInt32() (v int32)
ReadInt64() (v int64)
ReadFloat32() (v float32)
ReadFloat64() (v float64)
ReadComplex64() (v complex64)
ReadComplex128() (v complex128)
ReadUintptr() (v uintptr)
ReadString() (v string)
ReadStringMostLikelyEmpty() (v string)
ReadBytes() (v []byte)
ReadBool() (v bool)
ReadSliceLength() (l int, isNil bool)
}
type Unmarshaller ¶
type Unmarshaller struct {
// contains filtered or unexported fields
}
func NewUnmarshaller ¶
func (*Unmarshaller) ClearErr ¶ added in v0.0.17
func (inst *Unmarshaller) ClearErr()
ClearErr drops the sticky failure and re-arms reading. Only sound once the stream is known to be resynchronised, since a failed read leaves the position somewhere inside a frame. SetInput does this implicitly.
func (*Unmarshaller) Err ¶ added in v0.0.17
func (inst *Unmarshaller) Err() (err error)
Err returns the first read failure since the last SetInput or ClearErr, or nil while the stream is intact. Every Read* method returns a zero value on failure, so a caller that must trust what it decoded has to check this — typically once per frame rather than per field.
func (*Unmarshaller) GetReadBytes ¶
func (inst *Unmarshaller) GetReadBytes() int
func (*Unmarshaller) ReadBool ¶
func (inst *Unmarshaller) ReadBool() (v bool)
func (*Unmarshaller) ReadBytes ¶
func (inst *Unmarshaller) ReadBytes() (v []byte)
func (*Unmarshaller) ReadComplex64 ¶
func (inst *Unmarshaller) ReadComplex64() (v complex64)
func (*Unmarshaller) ReadComplex128 ¶
func (inst *Unmarshaller) ReadComplex128() (v complex128)
func (*Unmarshaller) ReadFloat32 ¶
func (inst *Unmarshaller) ReadFloat32() (v float32)
func (*Unmarshaller) ReadFloat64 ¶
func (inst *Unmarshaller) ReadFloat64() (v float64)
func (*Unmarshaller) ReadInt8 ¶
func (inst *Unmarshaller) ReadInt8() (v int8)
func (*Unmarshaller) ReadInt16 ¶
func (inst *Unmarshaller) ReadInt16() (v int16)
func (*Unmarshaller) ReadInt32 ¶
func (inst *Unmarshaller) ReadInt32() (v int32)
func (*Unmarshaller) ReadInt64 ¶
func (inst *Unmarshaller) ReadInt64() (v int64)
func (*Unmarshaller) ReadSliceLength ¶
func (inst *Unmarshaller) ReadSliceLength() (l int, isNil bool)
ReadSliceLength returns the element count, or isNil for the nil-slice sentinel. A failed read yields (0, false) — an empty, non-nil slice — which is a perfectly ordinary answer, so callers that must distinguish "the peer sent nothing" from "the stream died" have to consult Err.
func (*Unmarshaller) ReadString ¶
func (inst *Unmarshaller) ReadString() (v string)
func (*Unmarshaller) ReadStringMostLikelyEmpty ¶
func (inst *Unmarshaller) ReadStringMostLikelyEmpty() (v string)
func (*Unmarshaller) ReadUInt8 ¶
func (inst *Unmarshaller) ReadUInt8() (v uint8)
func (*Unmarshaller) ReadUInt16 ¶
func (inst *Unmarshaller) ReadUInt16() (v uint16)
func (*Unmarshaller) ReadUInt32 ¶
func (inst *Unmarshaller) ReadUInt32() (v uint32)
func (*Unmarshaller) ReadUInt32MostLikelyZero ¶
func (inst *Unmarshaller) ReadUInt32MostLikelyZero() (v uint32)
func (*Unmarshaller) ReadUInt64 ¶
func (inst *Unmarshaller) ReadUInt64() (v uint64)
func (*Unmarshaller) ReadUintptr ¶
func (inst *Unmarshaller) ReadUintptr() (v uintptr)
func (*Unmarshaller) ResetReadBytes ¶
func (inst *Unmarshaller) ResetReadBytes()
func (*Unmarshaller) SetAllocateBufferFunc ¶
func (inst *Unmarshaller) SetAllocateBufferFunc(f func(l uint32) []byte)
func (*Unmarshaller) SetEndianness ¶
func (inst *Unmarshaller) SetEndianness(endi binary.ByteOrder)
func (*Unmarshaller) SetErrorHandler ¶
func (inst *Unmarshaller) SetErrorHandler(f func(err error))
func (*Unmarshaller) SetInput ¶
func (inst *Unmarshaller) SetInput(r io.Reader)
SetInput attaches a new reader and re-arms reading: any previous failure described the stream being replaced.