Files
wazero/internal/asm/buffer_test.go
2023-05-19 07:06:30 +02:00

120 lines
3.1 KiB
Go

package asm_test
import (
"testing"
"unsafe"
"github.com/tetratelabs/wazero/internal/asm"
"github.com/tetratelabs/wazero/internal/testing/require"
)
func TestCodeSegmentZeroValue(t *testing.T) {
withCodeSegment(t, func(code *asm.CodeSegment) {
require.Equal(t, uintptr(0), code.Addr())
require.Equal(t, uintptr(0), code.Size())
require.Equal(t, 0, code.Len())
require.Equal(t, ([]byte)(nil), code.Bytes())
buf := code.NextCodeSection()
require.Equal(t, 0, buf.Cap())
require.Equal(t, 0, buf.Len())
require.Equal(t, ([]byte)(nil), buf.Bytes())
})
}
func TestCodeSegmentMapUnmap(t *testing.T) {
withCodeSegment(t, func(code *asm.CodeSegment) {
const size = 4096
require.NoError(t, code.Map(size))
require.NotEqual(t, uintptr(0), code.Addr())
require.Equal(t, uintptr(size), code.Size())
require.Equal(t, size, code.Len())
require.NotEqual(t, ([]byte)(nil), code.Bytes())
for i := 0; i < 3; i++ {
require.NoError(t, code.Unmap())
require.Equal(t, uintptr(0), code.Addr())
require.Equal(t, uintptr(0), code.Size())
require.Equal(t, 0, code.Len())
require.Equal(t, ([]byte)(nil), code.Bytes())
}
})
}
func TestBufferAppendByte(t *testing.T) {
withBuffer(t, func(buf asm.Buffer) {
data := []byte("Hello World!")
for i, c := range data {
buf.AppendByte(c)
require.NotEqual(t, 0, buf.Cap())
require.Equal(t, i+1, buf.Len())
require.Equal(t, data[:i+1], buf.Bytes())
}
})
}
func TestBufferAppendBytes(t *testing.T) {
withBuffer(t, func(buf asm.Buffer) {
buf.AppendBytes([]byte("Hello World!"))
require.NotEqual(t, 0, buf.Cap())
require.Equal(t, 12, buf.Len())
require.Equal(t, []byte("Hello World!"), buf.Bytes())
})
}
func TestBufferAppendUint32(t *testing.T) {
withBuffer(t, func(buf asm.Buffer) {
values := []uint32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
bytes := unsafe.Slice(*(**byte)(unsafe.Pointer(&values)), 4*len(values))
for i, v := range values {
buf.AppendUint32(v)
require.NotEqual(t, 0, buf.Cap())
require.Equal(t, 4*(i+1), buf.Len())
require.Equal(t, bytes[:4*(i+1)], buf.Bytes())
}
})
}
func TestBufferReset(t *testing.T) {
withBuffer(t, func(buf asm.Buffer) {
buf.AppendBytes([]byte("Hello World!"))
require.NotEqual(t, 0, buf.Cap())
require.Equal(t, 12, buf.Len())
require.Equal(t, []byte("Hello World!"), buf.Bytes())
buf.Reset()
require.Equal(t, 0, buf.Len())
require.Equal(t, []byte{}, buf.Bytes())
})
}
func TestBufferTruncate(t *testing.T) {
withBuffer(t, func(buf asm.Buffer) {
buf.AppendBytes([]byte("Hello World!"))
require.NotEqual(t, 0, buf.Cap())
require.Equal(t, 12, buf.Len())
require.Equal(t, []byte("Hello World!"), buf.Bytes())
buf.Truncate(5)
require.Equal(t, 5, buf.Len())
require.Equal(t, []byte("Hello"), buf.Bytes())
})
}
func withCodeSegment(t *testing.T, f func(*asm.CodeSegment)) {
code := asm.NewCodeSegment(nil)
defer func() { require.NoError(t, code.Unmap()) }()
f(code)
}
func withBuffer(t *testing.T, f func(asm.Buffer)) {
withCodeSegment(t, func(code *asm.CodeSegment) {
// Repeat the test multiple times to ensure that Next works as expected.
for i := 0; i < 10; i++ {
f(code.NextCodeSection())
}
})
}