github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/asm/buffer_test.go (about)

     1  package asm_test
     2  
     3  import (
     4  	"testing"
     5  	"unsafe"
     6  
     7  	"github.com/wasilibs/wazerox/internal/asm"
     8  	"github.com/wasilibs/wazerox/internal/testing/require"
     9  )
    10  
    11  func TestCodeSegmentZeroValue(t *testing.T) {
    12  	withCodeSegment(t, func(code *asm.CodeSegment) {
    13  		require.Equal(t, uintptr(0), code.Addr())
    14  		require.Equal(t, uintptr(0), code.Size())
    15  		require.Equal(t, 0, code.Len())
    16  		require.Equal(t, ([]byte)(nil), code.Bytes())
    17  
    18  		buf := code.NextCodeSection()
    19  		require.Equal(t, 0, buf.Cap())
    20  		require.Equal(t, 0, buf.Len())
    21  		require.Equal(t, ([]byte)(nil), buf.Bytes())
    22  	})
    23  }
    24  
    25  func TestCodeSegmentMapUnmap(t *testing.T) {
    26  	withCodeSegment(t, func(code *asm.CodeSegment) {
    27  		const size = 4096
    28  		require.NoError(t, code.Map(size))
    29  		require.NotEqual(t, uintptr(0), code.Addr())
    30  		require.Equal(t, uintptr(size), code.Size())
    31  		require.Equal(t, size, code.Len())
    32  		require.NotEqual(t, ([]byte)(nil), code.Bytes())
    33  
    34  		for i := 0; i < 3; i++ {
    35  			require.NoError(t, code.Unmap())
    36  			require.Equal(t, uintptr(0), code.Addr())
    37  			require.Equal(t, uintptr(0), code.Size())
    38  			require.Equal(t, 0, code.Len())
    39  			require.Equal(t, ([]byte)(nil), code.Bytes())
    40  		}
    41  	})
    42  }
    43  
    44  func TestBufferAppendByte(t *testing.T) {
    45  	withBuffer(t, func(buf asm.Buffer) {
    46  		data := []byte("Hello World!")
    47  
    48  		for i, c := range data {
    49  			buf.AppendByte(c)
    50  			require.NotEqual(t, 0, buf.Cap())
    51  			require.Equal(t, i+1, buf.Len())
    52  			require.Equal(t, data[:i+1], buf.Bytes())
    53  		}
    54  	})
    55  }
    56  
    57  func TestBufferAppendBytes(t *testing.T) {
    58  	withBuffer(t, func(buf asm.Buffer) {
    59  		buf.AppendBytes([]byte("Hello World!"))
    60  		require.NotEqual(t, 0, buf.Cap())
    61  		require.Equal(t, 12, buf.Len())
    62  		require.Equal(t, []byte("Hello World!"), buf.Bytes())
    63  	})
    64  }
    65  
    66  func TestBufferAppendUint32(t *testing.T) {
    67  	withBuffer(t, func(buf asm.Buffer) {
    68  		values := []uint32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    69  		bytes := unsafe.Slice(*(**byte)(unsafe.Pointer(&values)), 4*len(values))
    70  
    71  		for i, v := range values {
    72  			buf.AppendUint32(v)
    73  			require.NotEqual(t, 0, buf.Cap())
    74  			require.Equal(t, 4*(i+1), buf.Len())
    75  			require.Equal(t, bytes[:4*(i+1)], buf.Bytes())
    76  		}
    77  	})
    78  }
    79  
    80  func TestBufferReset(t *testing.T) {
    81  	withBuffer(t, func(buf asm.Buffer) {
    82  		buf.AppendBytes([]byte("Hello World!"))
    83  		require.NotEqual(t, 0, buf.Cap())
    84  		require.Equal(t, 12, buf.Len())
    85  		require.Equal(t, []byte("Hello World!"), buf.Bytes())
    86  
    87  		buf.Reset()
    88  		require.Equal(t, 0, buf.Len())
    89  		require.Equal(t, []byte{}, buf.Bytes())
    90  	})
    91  }
    92  
    93  func TestBufferTruncate(t *testing.T) {
    94  	withBuffer(t, func(buf asm.Buffer) {
    95  		buf.AppendBytes([]byte("Hello World!"))
    96  		require.NotEqual(t, 0, buf.Cap())
    97  		require.Equal(t, 12, buf.Len())
    98  		require.Equal(t, []byte("Hello World!"), buf.Bytes())
    99  
   100  		buf.Truncate(5)
   101  		require.Equal(t, 5, buf.Len())
   102  		require.Equal(t, []byte("Hello"), buf.Bytes())
   103  	})
   104  }
   105  
   106  func withCodeSegment(t *testing.T, f func(*asm.CodeSegment)) {
   107  	code := asm.NewCodeSegment(nil)
   108  	defer func() { require.NoError(t, code.Unmap()) }()
   109  	f(code)
   110  }
   111  
   112  func withBuffer(t *testing.T, f func(asm.Buffer)) {
   113  	withCodeSegment(t, func(code *asm.CodeSegment) {
   114  		// Repeat the test multiple times to ensure that Next works as expected.
   115  		for i := 0; i < 10; i++ {
   116  			f(code.NextCodeSection())
   117  		}
   118  	})
   119  }