mem.go

  1package util
  2
  3import (
  4	"bytes"
  5	"math"
  6
  7	"github.com/tetratelabs/wazero/api"
  8)
  9
 10const (
 11	PtrLen = 4
 12	IntLen = 4
 13)
 14
 15type (
 16	i8  interface{ ~int8 | ~uint8 }
 17	i32 interface{ ~int32 | ~uint32 }
 18	i64 interface{ ~int64 | ~uint64 }
 19
 20	Stk_t = uint64
 21	Ptr_t uint32
 22	Res_t int32
 23)
 24
 25func View(mod api.Module, ptr Ptr_t, size int64) []byte {
 26	if ptr == 0 {
 27		panic(NilErr)
 28	}
 29	if uint64(size) > math.MaxUint32 {
 30		panic(RangeErr)
 31	}
 32	buf, ok := mod.Memory().Read(uint32(ptr), uint32(size))
 33	if !ok {
 34		panic(RangeErr)
 35	}
 36	return buf
 37}
 38
 39func Read[T i8](mod api.Module, ptr Ptr_t) T {
 40	if ptr == 0 {
 41		panic(NilErr)
 42	}
 43	v, ok := mod.Memory().ReadByte(uint32(ptr))
 44	if !ok {
 45		panic(RangeErr)
 46	}
 47	return T(v)
 48}
 49
 50func Write[T i8](mod api.Module, ptr Ptr_t, v T) {
 51	if ptr == 0 {
 52		panic(NilErr)
 53	}
 54	ok := mod.Memory().WriteByte(uint32(ptr), uint8(v))
 55	if !ok {
 56		panic(RangeErr)
 57	}
 58}
 59
 60func Read32[T i32](mod api.Module, ptr Ptr_t) T {
 61	if ptr == 0 {
 62		panic(NilErr)
 63	}
 64	v, ok := mod.Memory().ReadUint32Le(uint32(ptr))
 65	if !ok {
 66		panic(RangeErr)
 67	}
 68	return T(v)
 69}
 70
 71func Write32[T i32](mod api.Module, ptr Ptr_t, v T) {
 72	if ptr == 0 {
 73		panic(NilErr)
 74	}
 75	ok := mod.Memory().WriteUint32Le(uint32(ptr), uint32(v))
 76	if !ok {
 77		panic(RangeErr)
 78	}
 79}
 80
 81func Read64[T i64](mod api.Module, ptr Ptr_t) T {
 82	if ptr == 0 {
 83		panic(NilErr)
 84	}
 85	v, ok := mod.Memory().ReadUint64Le(uint32(ptr))
 86	if !ok {
 87		panic(RangeErr)
 88	}
 89	return T(v)
 90}
 91
 92func Write64[T i64](mod api.Module, ptr Ptr_t, v T) {
 93	if ptr == 0 {
 94		panic(NilErr)
 95	}
 96	ok := mod.Memory().WriteUint64Le(uint32(ptr), uint64(v))
 97	if !ok {
 98		panic(RangeErr)
 99	}
100}
101
102func ReadFloat64(mod api.Module, ptr Ptr_t) float64 {
103	return math.Float64frombits(Read64[uint64](mod, ptr))
104}
105
106func WriteFloat64(mod api.Module, ptr Ptr_t, v float64) {
107	Write64(mod, ptr, math.Float64bits(v))
108}
109
110func ReadBool(mod api.Module, ptr Ptr_t) bool {
111	return Read32[int32](mod, ptr) != 0
112}
113
114func WriteBool(mod api.Module, ptr Ptr_t, v bool) {
115	var i int32
116	if v {
117		i = 1
118	}
119	Write32(mod, ptr, i)
120}
121
122func ReadString(mod api.Module, ptr Ptr_t, maxlen int64) string {
123	if ptr == 0 {
124		panic(NilErr)
125	}
126	if maxlen <= 0 {
127		return ""
128	}
129	mem := mod.Memory()
130	maxlen = min(maxlen, math.MaxInt32-1) + 1
131	buf, ok := mem.Read(uint32(ptr), uint32(maxlen))
132	if !ok {
133		buf, ok = mem.Read(uint32(ptr), mem.Size()-uint32(ptr))
134		if !ok {
135			panic(RangeErr)
136		}
137	}
138	if i := bytes.IndexByte(buf, 0); i >= 0 {
139		return string(buf[:i])
140	}
141	panic(NoNulErr)
142}
143
144func WriteBytes(mod api.Module, ptr Ptr_t, b []byte) {
145	buf := View(mod, ptr, int64(len(b)))
146	copy(buf, b)
147}
148
149func WriteString(mod api.Module, ptr Ptr_t, s string) {
150	buf := View(mod, ptr, int64(len(s))+1)
151	buf[len(s)] = 0
152	copy(buf, s)
153}