Merge pull request '[agent/codex:gpt-5.3-codex-spark] Read docs/RFC.md fully. Find ONE feature described in the sp...' (#15) from main into dev

This commit is contained in:
Virgil 2026-04-03 19:27:31 +00:00
commit 8705a6be8b
3 changed files with 63 additions and 24 deletions

View file

@ -8,10 +8,10 @@ import (
// Buffer owns byte memory that can be passed safely to C.
//
// buffer := NewBuffer(16)
// defer buffer.Free()
// n := buffer.CopyFrom([]byte("payload"))
// _ = buffer.Bytes()[:n]
// buffer := NewBuffer(16)
// defer buffer.Free()
// n := buffer.CopyFrom([]byte("payload"))
// _ = buffer.Bytes()[:n]
type Buffer struct {
data []byte
length int
@ -21,7 +21,10 @@ type Buffer struct {
pinner runtime.Pinner
}
// NewBuffer allocates memory and pins it so Ptr can be used across C boundaries.
// NewBuffer allocates memory and pins it so Ptr can be safely shared with C.
//
// buffer := NewBuffer(32)
// defer buffer.Free()
func NewBuffer(size int) *Buffer {
if size < 0 {
panic("cgo.NewBuffer: size must be non-negative")
@ -43,6 +46,9 @@ func NewBuffer(size int) *Buffer {
}
// Free releases the pinned memory backing slice and marks the buffer as freed.
//
// buffer := NewBuffer(8)
// defer buffer.Free()
func (b *Buffer) Free() {
if b == nil {
return
@ -62,6 +68,9 @@ func (b *Buffer) Free() {
}
// CopyFrom copies bytes from src into the buffer and returns bytes copied.
//
// buffer := NewBuffer(3)
// buffer.CopyFrom([]byte("abc"))
func (b *Buffer) CopyFrom(src []byte) int {
b.assertNotFreed()
if len(src) == 0 || b.length == 0 {
@ -77,25 +86,38 @@ func (b *Buffer) CopyFrom(src []byte) int {
return copied
}
// Bytes returns a mutable byte slice backed by the buffer memory.
// Bytes returns the mutable byte slice backed by the buffer memory.
//
// buffer := NewBuffer(4)
// n := buffer.CopyFrom([]byte("go"))
// _ = buffer.Bytes()[:n]
func (b *Buffer) Bytes() []byte {
b.assertNotFreed()
return b.data
}
// Ptr returns the raw pointer to the buffer.
//
// buffer := NewBuffer(4)
// call := buffer.Ptr()
func (b *Buffer) Ptr() unsafe.Pointer {
b.assertNotFreed()
return b.pointer
}
// Len returns the current buffer length.
// Len returns the allocated byte length of the buffer.
//
// buffer := NewBuffer(4)
// if buffer.Len() == 4 { ... }
func (b *Buffer) Len() int {
b.assertNotFreed()
return b.length
}
// IsFreed reports whether Free has already been called.
//
// buffer := NewBuffer(4)
// if buffer.IsFreed() { ... }
func (b *Buffer) IsFreed() bool {
return b.freed.Load()
}

View file

@ -25,11 +25,16 @@ type Scope struct {
}
// NewScope creates a zero-value scope for grouped CGo allocations.
//
// scope := NewScope()
// defer scope.FreeAll()
func NewScope() *Scope {
return &Scope{}
}
// Buffer allocates a new managed buffer.
// Buffer allocates a managed buffer and registers it for scope cleanup.
//
// buffer := scope.Buffer(64)
func (s *Scope) Buffer(size int) *Buffer {
s.lock.Lock()
defer s.lock.Unlock()
@ -43,7 +48,9 @@ func (s *Scope) Buffer(size int) *Buffer {
return buffer
}
// CString allocates a managed C string.
// CString allocates a managed C string and registers it for scope cleanup.
//
// cString := scope.CString("hello")
func (s *Scope) CString(value string) *C.char {
s.lock.Lock()
defer s.lock.Unlock()
@ -58,6 +65,9 @@ func (s *Scope) CString(value string) *C.char {
}
// FreeAll releases every allocation created under this scope.
//
// scope := NewScope()
// defer scope.FreeAll()
func (s *Scope) FreeAll() {
if s == nil {
return
@ -86,6 +96,8 @@ func (s *Scope) FreeAll() {
}
// IsFreed reports whether FreeAll has been called.
//
// if scope.IsFreed() { return }
func (s *Scope) IsFreed() bool {
if s == nil {
return true
@ -94,6 +106,9 @@ func (s *Scope) IsFreed() bool {
}
// Close releases every allocation in the scope and implements io.Closer.
//
// scope := NewScope()
// defer scope.Close()
func (s *Scope) Close() error {
s.FreeAll()
return nil

View file

@ -139,10 +139,12 @@ func cIntBitSize() int {
return int(unsafe.Sizeof(C.int(0)) * 8)
}
// Call invokes a C function pointer and maps a non-zero return into a Go error using errno mapping.
// Call invokes a C function pointer and maps a non-zero return into a Go error.
//
// err := cgo.Call(unsafe.Pointer(C.some_function), cgo.SizeT(len(data)))
// err == nil indicates success.
// err := Call(unsafe.Pointer(C.some_function), buffer.Ptr(), SizeT(len(data)))
// if err != nil {
// return err
// }
func Call(function unsafe.Pointer, args ...interface{}) error {
if function == nil {
panic("cgo.Call: function pointer is nil")
@ -795,9 +797,9 @@ func toSyscallArg(value interface{}) (uintptr, bool) {
// GoString converts a null-terminated C string to a Go string.
//
// cStr := C.CString("example")
// result := cgo.GoString(cStr)
// cgo.Free(unsafe.Pointer(cStr))
// cString := CString("example")
// result := GoString(cString)
// Free(unsafe.Pointer(cString))
func GoString(cs *C.char) string {
if cs == nil {
return ""
@ -807,16 +809,16 @@ func GoString(cs *C.char) string {
// CString converts a Go string to a C string.
//
// cStr := cgo.CString("hello")
// defer cgo.Free(unsafe.Pointer(cStr))
// cString := CString("hello")
// defer Free(unsafe.Pointer(cString))
func CString(value string) *C.char {
return C.CString(value)
}
// Free releases memory previously returned by CString.
//
// cStr := cgo.CString("hello")
// cgo.Free(unsafe.Pointer(cStr))
// cString := CString("hello")
// Free(unsafe.Pointer(cString))
func Free(ptr unsafe.Pointer) {
if ptr == nil {
return
@ -826,17 +828,17 @@ func Free(ptr unsafe.Pointer) {
// Errno converts a C error number to a Go error.
//
// rc := cgo.Errno(-2)
func Errno(rc C.int) error {
if rc == 0 {
// resultCode := Errno(-2)
func Errno(resultCode C.int) error {
if resultCode == 0 {
return nil
}
return syscall.Errno(rc)
return syscall.Errno(resultCode)
}
// WithErrno runs a function that returns C.int and maps the result to Go error.
//
// result, err := cgo.WithErrno(func() C.int {
// resultCode, err := WithErrno(func() C.int {
// return C.my_function()
// })
func WithErrno(fn func() C.int) (int, error) {