From bb88db68e0c1cb51f1cb8bb6e98ce72fffaa4bf1 Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Tue, 28 Jul 2015 16:28:21 +1000 Subject: [PATCH] OutMessage.Append --- internal/buffer/out_message.go | 14 ++++++++++++-- internal/buffer/runtime.go | 5 +++++ internal/buffer/runtime.s | 3 +++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/internal/buffer/out_message.go b/internal/buffer/out_message.go index f2dad9f..66099bf 100644 --- a/internal/buffer/out_message.go +++ b/internal/buffer/out_message.go @@ -15,7 +15,9 @@ package buffer import ( + "fmt" "log" + "reflect" "unsafe" "github.com/jacobsa/fuse/internal/fusekernel" @@ -87,8 +89,16 @@ func (b *OutMessage) GrowNoZero(size uintptr) (p unsafe.Pointer) { // Equivalent to growing by the length of p, then copying p over the new // segment. Panics if there is not enough room available. -func (b *OutMessage) Append(p []byte) { - panic("TODO") +func (b *OutMessage) Append(src []byte) { + p := b.GrowNoZero(uintptr(len(src))) + if p == nil { + panic(fmt.Sprintf("Can't grow %d bytes", len(src))) + } + + sh := (*reflect.SliceHeader)(unsafe.Pointer(&src)) + memmove(p, unsafe.Pointer(sh.Data), uintptr(sh.Len)) + + return } // Equivalent to growing by the length of s, then copying s over the new diff --git a/internal/buffer/runtime.go b/internal/buffer/runtime.go index 927032d..672c8a1 100644 --- a/internal/buffer/runtime.go +++ b/internal/buffer/runtime.go @@ -20,3 +20,8 @@ import "unsafe" // Zero the n bytes starting at p. func memclr(p unsafe.Pointer, n uintptr) + +//go:noescape + +// Copy from src to dst, allowing overlap. +func memmove(dst unsafe.Pointer, src unsafe.Pointer, n uintptr) diff --git a/internal/buffer/runtime.s b/internal/buffer/runtime.s index 9f65b4e..f39415a 100644 --- a/internal/buffer/runtime.s +++ b/internal/buffer/runtime.s @@ -31,3 +31,6 @@ TEXT ·memclr(SB),NOSPLIT,$0-16 JMP runtime·memclr(SB) + +TEXT ·memmove(SB),NOSPLIT,$0-24 + JMP runtime·memmove(SB)