Add Memory.WriteString (#820)
Signed-off-by: Anuraag Agrawal <anuraaga@gmail.com>
This commit is contained in:
@@ -459,6 +459,9 @@ type Memory interface {
|
||||
|
||||
// Write writes the slice to the underlying buffer at the offset or returns false if out of range.
|
||||
Write(ctx context.Context, offset uint32, v []byte) bool
|
||||
|
||||
// WriteString writes the string to the underlying buffer at the offset or returns false if out of range.
|
||||
WriteString(ctx context.Context, offset uint32, v string) bool
|
||||
}
|
||||
|
||||
// EncodeExternref encodes the input as a ValueTypeExternref.
|
||||
|
||||
@@ -162,6 +162,15 @@ func (m *MemoryInstance) Write(_ context.Context, offset uint32, val []byte) boo
|
||||
return true
|
||||
}
|
||||
|
||||
// WriteString implements the same method as documented on api.Memory.
|
||||
func (m *MemoryInstance) WriteString(_ context.Context, offset uint32, val string) bool {
|
||||
if !m.hasSize(offset, uint32(len(val))) {
|
||||
return false
|
||||
}
|
||||
copy(m.Buffer[offset:], val)
|
||||
return true
|
||||
}
|
||||
|
||||
// MemoryPagesToBytesNum converts the given pages into the number of bytes contained in these pages.
|
||||
func MemoryPagesToBytesNum(pages uint32) (bytesNum uint64) {
|
||||
return uint64(pages) << MemoryPageSizeInBits
|
||||
|
||||
@@ -3,8 +3,10 @@ package wasm
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/internal/testing/require"
|
||||
)
|
||||
|
||||
@@ -763,3 +765,49 @@ func TestMemoryInstance_Write(t *testing.T) {
|
||||
require.False(t, ok)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMemoryInstance_WriteString(t *testing.T) {
|
||||
for _, ctx := range []context.Context{nil, testCtx} { // Ensure it doesn't crash on nil!
|
||||
var mem = &MemoryInstance{Buffer: []byte{0, 0, 0, 0, 16, 0, 0, 0}, Min: 1}
|
||||
|
||||
s := "bear"
|
||||
require.True(t, mem.WriteString(ctx, 4, s))
|
||||
require.Equal(t, []byte{0, 0, 0, 0, 'b', 'e', 'a', 'r'}, mem.Buffer)
|
||||
|
||||
ok := mem.WriteString(ctx, 5, s)
|
||||
require.False(t, ok)
|
||||
|
||||
ok = mem.WriteString(ctx, 9, s)
|
||||
require.False(t, ok)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkWriteString(b *testing.B) {
|
||||
tests := []string{
|
||||
"",
|
||||
"bear",
|
||||
"hello world",
|
||||
strings.Repeat("hello ", 10),
|
||||
}
|
||||
// nolint intentionally testing interface access
|
||||
var mem api.Memory
|
||||
mem = &MemoryInstance{Buffer: make([]byte, 1000), Min: 1}
|
||||
for _, tt := range tests {
|
||||
b.Run("", func(b *testing.B) {
|
||||
b.Run("Write", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
if !mem.Write(testCtx, 0, []byte(tt)) {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
b.Run("WriteString", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
if !mem.WriteString(testCtx, 0, tt) {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user