Repository: tetratelabs/wazero
Pull request #2106 (2024-03-02 03:38:07)

api: reverts the uint32->uint64 breaking change for 2.0 release
This commit reverts the only/first ever breaking change we committed 
towards 2.0 release, #2085 and #2074.


These commits were made to fix a bug in our API which is described well in
https://github.com/tetratelabs/wazero/issues/1852 but the reality is that it will 
cause users to modify their existing code when they upgrade to 2.0 whose main
focus is to introduce the optimizing compiler just by updating wazero, not to fix
the bug. 

Note that this doesn't mean that we won't make any breaking change never, but this 
is more about dedicating 2.0 to the optimizing compiler, not fixing the bug which 
is highly likely that existing users will never encounter. 



mathetake: cc @ncruces 

Patch:
diff --git a/api/wasm.go b/api/wasm.go
index 6cb86e11..d6a0d796 100644
--- a/api/wasm.go
+++ b/api/wasm.go
@@ -563,7 +563,7 @@ type Memory interface {
 	// has 1 page: 65536
 	//
 	// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefsyntax-instr-memorymathsfmemorysize%E2%91%A0
-	Size() uint64
+	Size() uint32
 
 	// Grow increases memory by the delta in pages (65536 bytes per page).
 	// The return val is the previous memory size in pages, or false if the
@@ -635,7 +635,7 @@ type Memory interface {
 	// shared. Those who need a stable view must set Wasm memory min=max, or
 	// use wazero.RuntimeConfig WithMemoryCapacityPages to ensure max is always
 	// allocated.
-	Read(offset uint32, byteCount uint64) ([]byte, bool)
+	Read(offset, byteCount uint32) ([]byte, bool)
 
 	// WriteByte writes a single byte to the underlying buffer at the offset in or returns false if out of range.
 	WriteByte(offset uint32, v byte) bool
diff --git a/examples/allocation/rust/greet.go b/examples/allocation/rust/greet.go
index e416d6bd..3d19eec3 100644
--- a/examples/allocation/rust/greet.go
+++ b/examples/allocation/rust/greet.go
@@ -91,7 +91,7 @@ func main() {
 	defer deallocate.Call(ctx, uint64(greetingPtr), uint64(greetingSize))
 
 	// The pointer is a linear memory offset, which is where we write the name.
-	if bytes, ok := mod.Memory().Read(greetingPtr, uint64(greetingSize)); !ok {
+	if bytes, ok := mod.Memory().Read(greetingPtr, greetingSize); !ok {
 		log.Panicf("Memory.Read(%d, %d) out of range of memory size %d",
 			greetingPtr, greetingSize, mod.Memory().Size())
 	} else {
@@ -100,7 +100,7 @@ func main() {
 }
 
 func logString(ctx context.Context, m api.Module, offset, byteCount uint32) {
-	buf, ok := m.Memory().Read(offset, uint64(byteCount))
+	buf, ok := m.Memory().Read(offset, byteCount)
 	if !ok {
 		log.Panicf("Memory.Read(%d, %d) out of range", offset, byteCount)
 	}
diff --git a/examples/allocation/tinygo/greet.go b/examples/allocation/tinygo/greet.go
index fcebeb19..22d76d64 100644
--- a/examples/allocation/tinygo/greet.go
+++ b/examples/allocation/tinygo/greet.go
@@ -106,7 +106,7 @@ func main() {
 	}
 
 	// The pointer is a linear memory offset, which is where we write the name.
-	if bytes, ok := mod.Memory().Read(greetingPtr, uint64(greetingSize)); !ok {
+	if bytes, ok := mod.Memory().Read(greetingPtr, greetingSize); !ok {
 		log.Panicf("Memory.Read(%d, %d) out of range of memory size %d",
 			greetingPtr, greetingSize, mod.Memory().Size())
 	} else {
@@ -115,7 +115,7 @@ func main() {
 }
 
 func logString(_ context.Context, m api.Module, offset, byteCount uint32) {
-	buf, ok := m.Memory().Read(offset, uint64(byteCount))
+	buf, ok := m.Memory().Read(offset, byteCount)
 	if !ok {
 		log.Panicf("Memory.Read(%d, %d) out of range", offset, byteCount)
 	}
diff --git a/examples/allocation/zig/greet.go b/examples/allocation/zig/greet.go
index 7ed6bac5..467dc8e0 100644
--- a/examples/allocation/zig/greet.go
+++ b/examples/allocation/zig/greet.go
@@ -98,7 +98,7 @@ func run() error {
 	greetingPtr := uint32(ptrSize[0] >> 32)
 	greetingSize := uint32(ptrSize[0])
 	// The pointer is a linear memory offset, which is where we write the name.
-	if bytes, ok := mod.Memory().Read(greetingPtr, uint64(greetingSize)); !ok {
+	if bytes, ok := mod.Memory().Read(greetingPtr, greetingSize); !ok {
 		return fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d",
 			greetingPtr, greetingSize, mod.Memory().Size())
 	} else {
@@ -109,7 +109,7 @@ func run() error {
 }
 
 func logString(_ context.Context, m api.Module, offset, byteCount uint32) {
-	buf, ok := m.Memory().Read(offset, uint64(byteCount))
+	buf, ok := m.Memory().Read(offset, byteCount)
 	if !ok {
 		log.Panicf("Memory.Read(%d, %d) out of range", offset, byteCount)
 	}
diff --git a/imports/assemblyscript/assemblyscript.go b/imports/assemblyscript/assemblyscript.go
index 8f2ac445..5cbe605b 100644
--- a/imports/assemblyscript/assemblyscript.go
+++ b/imports/assemblyscript/assemblyscript.go
@@ -305,7 +305,7 @@ func readAssemblyScriptString(mem api.Memory, offset uint32) (string, bool) {
 	if !ok || byteCount%2 != 0 {
 		return "", false
 	}
-	buf, ok := mem.Read(offset, uint64(byteCount))
+	buf, ok := mem.Read(offset, byteCount)
 	if !ok {
 		return "", false
 	}
diff --git a/imports/wasi_snapshot_preview1/fs.go b/imports/wasi_snapshot_preview1/fs.go
index 7ae2aef9..384036a2 100644
--- a/imports/wasi_snapshot_preview1/fs.go
+++ b/imports/wasi_snapshot_preview1/fs.go
@@ -800,13 +800,13 @@ func fdReadOrPread(mod api.Module, params []uint64, isPread bool) experimentalsy
 
 func readv(mem api.Memory, iovs uint32, iovsCount uint32, reader func(buf []byte) (nread int, errno experimentalsys.Errno)) (uint32, experimentalsys.Errno) {
 	var nread uint32
-	iovsStop := uint64(iovsCount) * 8
+	iovsStop := iovsCount << 3 // iovsCount * 8
 	iovsBuf, ok := mem.Read(iovs, iovsStop)
 	if !ok {
 		return 0, experimentalsys.EFAULT
 	}
 
-	for iovsPos := uint64(0); iovsPos < iovsStop; iovsPos += 8 {
+	for iovsPos := uint32(0); iovsPos < iovsStop; iovsPos += 8 {
 		offset := le.Uint32(iovsBuf[iovsPos:])
 		l := le.Uint32(iovsBuf[iovsPos+4:])
 
@@ -814,7 +814,7 @@ func readv(mem api.Memory, iovs uint32, iovsCount uint32, reader func(buf []byte
 			continue
 		}
 
-		b, ok := mem.Read(offset, uint64(l))
+		b, ok := mem.Read(offset, l)
 		if !ok {
 			return 0, experimentalsys.EFAULT
 		}
@@ -917,7 +917,7 @@ func fdReaddirFn(_ context.Context, mod api.Module, params []uint64) experimenta
 		// ^^ yes this can overflow to negative, which means our implementation
 		// doesn't support writing greater than max int64 entries.
 
-		buf, ok := mem.Read(buf, uint64(bufToWrite))
+		buf, ok := mem.Read(buf, bufToWrite)
 		if !ok {
 			return experimentalsys.EFAULT
 		}
@@ -1284,17 +1284,17 @@ func fdWriteOrPwrite(mod api.Module, params []uint64, isPwrite bool) experimenta
 
 func writev(mem api.Memory, iovs uint32, iovsCount uint32, writer func(buf []byte) (n int, errno experimentalsys.Errno)) (uint32, experimentalsys.Errno) {
 	var nwritten uint32
-	iovsStop := uint64(iovsCount) * 8
+	iovsStop := iovsCount << 3 // iovsCount * 8
 	iovsBuf, ok := mem.Read(iovs, iovsStop)
 	if !ok {
 		return 0, experimentalsys.EFAULT
 	}
 
-	for iovsPos := uint64(0); iovsPos < iovsStop; iovsPos += 8 {
+	for iovsPos := uint32(0); iovsPos < iovsStop; iovsPos += 8 {
 		offset := le.Uint32(iovsBuf[iovsPos:])
 		l := le.Uint32(iovsBuf[iovsPos+4:])
 
-		b, ok := mem.Read(offset, uint64(l))
+		b, ok := mem.Read(offset, l)
 		if !ok {
 			return 0, experimentalsys.EFAULT
 		}
@@ -1645,7 +1645,7 @@ func pathOpenFn(_ context.Context, mod api.Module, params []uint64) experimental
 // See https://github.com/WebAssembly/wasi-libc/blob/659ff414560721b1660a19685110e484a081c3d4/libc-bottom-half/sources/at_fdcwd.c
 // See https://linux.die.net/man/2/openat
 func atPath(fsc *sys.FSContext, mem api.Memory, fd int32, p, pathLen uint32) (experimentalsys.FS, string, experimentalsys.Errno) {
-	b, ok := mem.Read(p, uint64(pathLen))
+	b, ok := mem.Read(p, pathLen)
 	if !ok {
 		return nil, "", experimentalsys.EFAULT
 	}
@@ -1946,12 +1946,12 @@ func pathSymlinkFn(_ context.Context, mod api.Module, params []uint64) experimen
 		return experimentalsys.EINVAL
 	}
 
-	oldPathBuf, ok := mem.Read(oldPath, uint64(oldPathLen))
+	oldPathBuf, ok := mem.Read(oldPath, oldPathLen)
 	if !ok {
 		return experimentalsys.EFAULT
 	}
 
-	newPathBuf, ok := mem.Read(newPath, uint64(newPathLen))
+	newPathBuf, ok := mem.Read(newPath, newPathLen)
 	if !ok {
 		return experimentalsys.EFAULT
 	}
diff --git a/imports/wasi_snapshot_preview1/poll.go b/imports/wasi_snapshot_preview1/poll.go
index 8c8839a5..d09f3024 100644
--- a/imports/wasi_snapshot_preview1/poll.go
+++ b/imports/wasi_snapshot_preview1/poll.go
@@ -62,11 +62,11 @@ func pollOneoffFn(_ context.Context, mod api.Module, params []uint64) sys.Errno
 	mem := mod.Memory()
 
 	// Ensure capacity prior to the read loop to reduce error handling.
-	inBuf, ok := mem.Read(in, uint64(nsubscriptions)*48)
+	inBuf, ok := mem.Read(in, nsubscriptions*48)
 	if !ok {
 		return sys.EFAULT
 	}
-	outBuf, ok := mem.Read(out, uint64(nsubscriptions)*32)
+	outBuf, ok := mem.Read(out, nsubscriptions*32)
 	// zero-out all buffer before writing
 	for i := range outBuf {
 		outBuf[i] = 0
diff --git a/imports/wasi_snapshot_preview1/random.go b/imports/wasi_snapshot_preview1/random.go
index 5c86968d..e4d7ccee 100644
--- a/imports/wasi_snapshot_preview1/random.go
+++ b/imports/wasi_snapshot_preview1/random.go
@@ -41,7 +41,7 @@ func randomGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
 	randSource := sysCtx.RandSource()
 	buf, bufLen := uint32(params[0]), uint32(params[1])
 
-	randomBytes, ok := mod.Memory().Read(buf, uint64(bufLen))
+	randomBytes, ok := mod.Memory().Read(buf, bufLen)
 	if !ok { // out-of-range
 		return sys.EFAULT
 	}
diff --git a/imports/wasi_snapshot_preview1/sock.go b/imports/wasi_snapshot_preview1/sock.go
index 291da486..756c0d39 100644
--- a/imports/wasi_snapshot_preview1/sock.go
+++ b/imports/wasi_snapshot_preview1/sock.go
@@ -85,7 +85,7 @@ func sockRecvFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
 		if !ok {
 			return sys.EINVAL
 		}
-		firstIovecBuf, ok := mem.Read(firstIovecBufAddr, uint64(firstIovecBufLen))
+		firstIovecBuf, ok := mem.Read(firstIovecBufAddr, firstIovecBufLen)
 		if !ok {
 			return sys.EINVAL
 		}
diff --git a/imports/wasi_snapshot_preview1/wasi.go b/imports/wasi_snapshot_preview1/wasi.go
index 564ddf4c..4ef41d50 100644
--- a/imports/wasi_snapshot_preview1/wasi.go
+++ b/imports/wasi_snapshot_preview1/wasi.go
@@ -233,12 +233,12 @@ func writeOffsetsAndNullTerminatedValues(mem api.Memory, values [][]byte, offset
 	// The caller may not place bytes directly after offsets, so we have to
 	// read them independently.
 	valuesLen := len(values)
-	offsetsLen := uint64(valuesLen) * 4
+	offsetsLen := uint32(valuesLen * 4) // uint32Le
 	offsetsBuf, ok := mem.Read(offsets, offsetsLen)
 	if !ok {
 		return sys.EFAULT
 	}
-	bytesBuf, ok := mem.Read(bytes, uint64(bytesLen))
+	bytesBuf, ok := mem.Read(bytes, bytesLen)
 	if !ok {
 		return sys.EFAULT
 	}
diff --git a/internal/engine/interpreter/interpreter.go b/internal/engine/interpreter/interpreter.go
index f9368be9..caecfee3 100644
--- a/internal/engine/interpreter/interpreter.go
+++ b/internal/engine/interpreter/interpreter.go
@@ -4024,7 +4024,7 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance
 				panic(wasmruntime.ErrRuntimeUnalignedAtomic)
 			}
 			// Just a bounds check
-			if int(offset) >= len(memoryInst.Buffer) {
+			if offset >= memoryInst.Size() {
 				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
 			}
 			res := memoryInst.Notify(offset, uint32(count))
diff --git a/internal/logging/logging.go b/internal/logging/logging.go
index 2e1da2d5..ecec61f7 100644
--- a/internal/logging/logging.go
+++ b/internal/logging/logging.go
@@ -263,7 +263,7 @@ func writeRef(_ context.Context, _ api.Module, w Writer, i uint32, vals []uint64
 
 func writeMemI32(_ context.Context, mod api.Module, w Writer, i uint32, vals []uint64) {
 	offset := uint32(vals[i])
-	byteCount := uint64(4)
+	byteCount := uint32(4)
 	if v, ok := mod.Memory().ReadUint32Le(offset); ok {
 		w.WriteString(strconv.FormatInt(int64(int32(v)), 10)) //nolint
 	} else { // log the positions that were out of memory
@@ -273,7 +273,7 @@ func writeMemI32(_ context.Context, mod api.Module, w Writer, i uint32, vals []u
 
 func writeMemH64(_ context.Context, mod api.Module, w Writer, i uint32, vals []uint64) {
 	offset := uint32(vals[i])
-	byteCount := uint64(8)
+	byteCount := uint32(8)
 	if s, ok := mod.Memory().Read(offset, byteCount); ok {
 		hex.NewEncoder(w).Write(s) //nolint
 	} else { // log the positions that were out of memory
@@ -283,10 +283,10 @@ func writeMemH64(_ context.Context, mod api.Module, w Writer, i uint32, vals []u
 
 func writeString(_ context.Context, mod api.Module, w Writer, i uint32, vals []uint64) {
 	offset, byteCount := uint32(vals[i]), uint32(vals[i+1])
-	WriteStringOrOOM(mod.Memory(), w, offset, uint64(byteCount))
+	WriteStringOrOOM(mod.Memory(), w, offset, byteCount)
 }
 
-func WriteStringOrOOM(mem api.Memory, w Writer, offset uint32, byteCount uint64) {
+func WriteStringOrOOM(mem api.Memory, w Writer, offset, byteCount uint32) {
 	if s, ok := mem.Read(offset, byteCount); ok {
 		w.Write(s) //nolint
 	} else { // log the positions that were out of memory
@@ -294,7 +294,7 @@ func WriteStringOrOOM(mem api.Memory, w Writer, offset uint32, byteCount uint64)
 	}
 }
 
-func WriteOOM(w Writer, offset uint32, byteCount uint64) {
+func WriteOOM(w Writer, offset uint32, byteCount uint32) {
 	w.WriteString("OOM(")                       //nolint
 	w.WriteString(strconv.Itoa(int(offset)))    //nolint
 	w.WriteByte(',')                            //nolint
diff --git a/internal/wasip1/logging/logging.go b/internal/wasip1/logging/logging.go
index 7881f5e8..d7341a09 100644
--- a/internal/wasip1/logging/logging.go
+++ b/internal/wasip1/logging/logging.go
@@ -260,7 +260,7 @@ func (i logMemI64) Log(_ context.Context, mod api.Module, w logging.Writer, para
 type logFilestat uint32
 
 func (i logFilestat) Log(_ context.Context, mod api.Module, w logging.Writer, params []uint64) {
-	offset, byteCount := uint32(params[i]), uint64(64)
+	offset, byteCount := uint32(params[i]), uint32(64)
 	if buf, ok := mod.Memory().Read(offset, byteCount); ok {
 		w.WriteString("{filetype=")          //nolint
 		w.WriteString(FiletypeName(buf[16])) //nolint
@@ -275,7 +275,7 @@ func (i logFilestat) Log(_ context.Context, mod api.Module, w logging.Writer, pa
 type logFdstat uint32
 
 func (i logFdstat) Log(_ context.Context, mod api.Module, w logging.Writer, params []uint64) {
-	offset, byteCount := uint32(params[i]), uint64(24)
+	offset, byteCount := uint32(params[i]), uint32(24)
 	if buf, ok := mod.Memory().Read(offset, byteCount); ok {
 		w.WriteString("{filetype=")                           //nolint
 		w.WriteString(FiletypeName(buf[0]))                   //nolint
@@ -293,7 +293,7 @@ type logString uint32
 
 func (i logString) Log(_ context.Context, mod api.Module, w logging.Writer, params []uint64) {
 	offset, byteCount := uint32(params[i]), uint32(params[i+1])
-	if s, ok := mod.Memory().Read(offset, uint64(byteCount)); ok {
+	if s, ok := mod.Memory().Read(offset, byteCount); ok {
 		w.Write(s) //nolint
 	}
 }
diff --git a/internal/wasm/memory.go b/internal/wasm/memory.go
index 5d549f8a..3a2c0ff4 100644
--- a/internal/wasm/memory.go
+++ b/internal/wasm/memory.go
@@ -130,13 +130,13 @@ func (m *MemoryInstance) Definition() api.MemoryDefinition {
 }
 
 // Size implements the same method as documented on api.Memory.
-func (m *MemoryInstance) Size() uint64 {
-	return uint64(m.size())
+func (m *MemoryInstance) Size() uint32 {
+	return m.size()
 }
 
 // ReadByte implements the same method as documented on api.Memory.
 func (m *MemoryInstance) ReadByte(offset uint32) (byte, bool) {
-	if int64(offset) >= int64(m.size()) {
+	if offset >= m.size() {
 		return 0, false
 	}
 	return m.Buffer[offset], true
@@ -179,16 +179,16 @@ func (m *MemoryInstance) ReadFloat64Le(offset uint32) (float64, bool) {
 }
 
 // Read implements the same method as documented on api.Memory.
-func (m *MemoryInstance) Read(offset uint32, byteCount uint64) ([]byte, bool) {
-	if !m.hasSize(offset, byteCount) {
+func (m *MemoryInstance) Read(offset, byteCount uint32) ([]byte, bool) {
+	if !m.hasSize(offset, uint64(byteCount)) {
 		return nil, false
 	}
-	return m.Buffer[offset : uint64(offset)+byteCount : uint64(offset)+byteCount], true
+	return m.Buffer[offset : offset+byteCount : offset+byteCount], true
 }
 
 // WriteByte implements the same method as documented on api.Memory.
 func (m *MemoryInstance) WriteByte(offset uint32, v byte) bool {
-	if int64(offset) >= m.size() {
+	if offset >= m.size() {
 		return false
 	}
 	m.Buffer[offset] = v
@@ -309,8 +309,8 @@ func memoryBytesNumToPages(bytesNum uint64) (pages uint32) {
 }
 
 // size returns the size in bytes of the buffer.
-func (m *MemoryInstance) size() int64 {
-	return int64(len(m.Buffer)) // We don't lock here because size can't become smaller.
+func (m *MemoryInstance) size() uint32 {
+	return uint32(len(m.Buffer)) // We don't lock here because size can't become smaller.
 }
 
 // hasSize returns true if Len is sufficient for byteCount at the given offset.


Test patch:
diff --git a/experimental/wazerotest/wazerotest.go b/experimental/wazerotest/wazerotest.go
index 252334b4..bfbddf78 100644
--- a/experimental/wazerotest/wazerotest.go
+++ b/experimental/wazerotest/wazerotest.go
@@ -507,8 +507,8 @@ func (m *Memory) Definition() api.MemoryDefinition {
 	return memoryDefinition{memory: m}
 }
 
-func (m *Memory) Size() uint64 {
-	return uint64(len(m.Bytes))
+func (m *Memory) Size() uint32 {
+	return uint32(len(m.Bytes))
 }
 
 func (m *Memory) Grow(deltaPages uint32) (previousPages uint32, ok bool) {
@@ -561,11 +561,11 @@ func (m *Memory) ReadFloat64Le(offset uint32) (float64, bool) {
 	return math.Float64frombits(v), ok
 }
 
-func (m *Memory) Read(offset uint32, length uint64) ([]byte, bool) {
+func (m *Memory) Read(offset, length uint32) ([]byte, bool) {
 	if m.isOutOfRange(offset, length) {
 		return nil, false
 	}
-	return m.Bytes[offset : uint64(offset)+length : uint64(offset)+length], true
+	return m.Bytes[offset : offset+length : offset+length], true
 }
 
 func (m *Memory) WriteByte(offset uint32, value byte) bool {
@@ -609,7 +609,7 @@ func (m *Memory) WriteFloat64Le(offset uint32, value float64) bool {
 }
 
 func (m *Memory) Write(offset uint32, value []byte) bool {
-	if m.isOutOfRange(offset, uint64(len(value))) {
+	if m.isOutOfRange(offset, uint32(len(value))) {
 		return false
 	}
 	copy(m.Bytes[offset:], value)
@@ -617,16 +617,15 @@ func (m *Memory) Write(offset uint32, value []byte) bool {
 }
 
 func (m *Memory) WriteString(offset uint32, value string) bool {
-	if m.isOutOfRange(offset, uint64(len(value))) {
+	if m.isOutOfRange(offset, uint32(len(value))) {
 		return false
 	}
 	copy(m.Bytes[offset:], value)
 	return true
 }
 
-func (m *Memory) isOutOfRange(_offset uint32, length uint64) bool {
+func (m *Memory) isOutOfRange(offset, length uint32) bool {
 	size := m.Size()
-	offset := uint64(_offset)
 	return offset >= size || length > size || offset > (size-length)
 }
 
diff --git a/imports/wasi_snapshot_preview1/args_test.go b/imports/wasi_snapshot_preview1/args_test.go
index bbc6b00b..fb30640f 100644
--- a/imports/wasi_snapshot_preview1/args_test.go
+++ b/imports/wasi_snapshot_preview1/args_test.go
@@ -32,7 +32,7 @@ func Test_argsGet(t *testing.T) {
 <== errno=ESUCCESS
 `, "\n"+log.String())
 
-	actual, ok := mod.Memory().Read(argvBuf-1, uint64(len(expectedMemory)))
+	actual, ok := mod.Memory().Read(argvBuf-1, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 }
@@ -41,7 +41,7 @@ func Test_argsGet_Errors(t *testing.T) {
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithArgs("a", "bc"))
 	defer r.Close(testCtx)
 
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 	validAddress := uint32(0) // arbitrary
 
 	tests := []struct {
@@ -124,7 +124,7 @@ func Test_argsSizesGet(t *testing.T) {
 <== errno=ESUCCESS
 `, "\n"+log.String())
 
-	actual, ok := mod.Memory().Read(resultArgc-1, uint64(len(expectedMemory)))
+	actual, ok := mod.Memory().Read(resultArgc-1, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 }
@@ -133,7 +133,7 @@ func Test_argsSizesGet_Errors(t *testing.T) {
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithArgs("a", "bc"))
 	defer r.Close(testCtx)
 
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 	validAddress := uint32(0) // arbitrary valid address as arguments to args_sizes_get. We chose 0 here.
 
 	tests := []struct {
diff --git a/imports/wasi_snapshot_preview1/clock_test.go b/imports/wasi_snapshot_preview1/clock_test.go
index dce231a0..87879da3 100644
--- a/imports/wasi_snapshot_preview1/clock_test.go
+++ b/imports/wasi_snapshot_preview1/clock_test.go
@@ -63,7 +63,7 @@ func Test_clockResGet(t *testing.T) {
 			requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.ClockResGetName, uint64(tc.clockID), uint64(resultResolution))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			actual, ok := mod.Memory().Read(uint32(resultResolution-1), uint64(len(tc.expectedMemory)))
+			actual, ok := mod.Memory().Read(uint32(resultResolution-1), uint32(len(tc.expectedMemory)))
 			require.True(t, ok)
 			require.Equal(t, tc.expectedMemory, actual)
 		})
@@ -170,7 +170,7 @@ func Test_clockTimeGet(t *testing.T) {
 			requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.ClockTimeGetName, uint64(tc.clockID), 0 /* TODO: precision */, uint64(resultTimestamp))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			actual, ok := mod.Memory().Read(uint32(resultTimestamp-1), uint64(len(tc.expectedMemory)))
+			actual, ok := mod.Memory().Read(uint32(resultTimestamp-1), uint32(len(tc.expectedMemory)))
 			require.True(t, ok)
 			require.Equal(t, tc.expectedMemory, actual)
 		})
@@ -259,7 +259,7 @@ func Test_clockTimeGet_Errors(t *testing.T) {
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig())
 	defer r.Close(testCtx)
 
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 
 	tests := []struct {
 		name                     string
diff --git a/imports/wasi_snapshot_preview1/environ_test.go b/imports/wasi_snapshot_preview1/environ_test.go
index 62a2d4c8..0ba8efae 100644
--- a/imports/wasi_snapshot_preview1/environ_test.go
+++ b/imports/wasi_snapshot_preview1/environ_test.go
@@ -34,7 +34,7 @@ func Test_environGet(t *testing.T) {
 <== errno=ESUCCESS
 `, "\n"+log.String())
 
-	actual, ok := mod.Memory().Read(resultEnvironBuf-1, uint64(len(expectedMemory)))
+	actual, ok := mod.Memory().Read(resultEnvironBuf-1, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 }
@@ -44,7 +44,7 @@ func Test_environGet_Errors(t *testing.T) {
 		WithEnv("a", "bc").WithEnv("b", "cd"))
 	defer r.Close(testCtx)
 
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 	validAddress := uint32(0) // arbitrary valid address as arguments to environ_get. We chose 0 here.
 
 	tests := []struct {
@@ -128,7 +128,7 @@ func Test_environSizesGet(t *testing.T) {
 <== errno=ESUCCESS
 `, "\n"+log.String())
 
-	actual, ok := mod.Memory().Read(resultEnvironc-1, uint64(len(expectedMemory)))
+	actual, ok := mod.Memory().Read(resultEnvironc-1, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 }
@@ -138,7 +138,7 @@ func Test_environSizesGet_Errors(t *testing.T) {
 		WithEnv("a", "b").WithEnv("b", "cd"))
 	defer r.Close(testCtx)
 
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 	validAddress := uint32(0) // arbitrary
 
 	tests := []struct {
diff --git a/imports/wasi_snapshot_preview1/fs_test.go b/imports/wasi_snapshot_preview1/fs_test.go
index 3d12f29d..04fe783c 100644
--- a/imports/wasi_snapshot_preview1/fs_test.go
+++ b/imports/wasi_snapshot_preview1/fs_test.go
@@ -233,7 +233,7 @@ func Test_fdFdstatGet(t *testing.T) {
 	file, dir := "animals.txt", "sub"
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFS(fstest.FS))
 	defer r.Close(testCtx)
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 
 	// open both paths without using WASI
 	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
@@ -380,7 +380,7 @@ func Test_fdFdstatGet(t *testing.T) {
 			requireErrnoResult(t, tc.expectedErrno, mod, wasip1.FdFdstatGetName, uint64(tc.fd), uint64(tc.resultFdstat))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			actual, ok := mod.Memory().Read(0, uint64(len(tc.expectedMemory)))
+			actual, ok := mod.Memory().Read(0, uint32(len(tc.expectedMemory)))
 			require.True(t, ok)
 			require.Equal(t, tc.expectedMemory, actual)
 		})
@@ -472,7 +472,7 @@ func Test_fdFdstatGet_StdioNonblock(t *testing.T) {
 			requireErrnoResult(t, tc.expectedErrno, mod, wasip1.FdFdstatGetName, uint64(tc.fd), uint64(tc.resultFdstat))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			actual, ok := mod.Memory().Read(0, uint64(len(tc.expectedMemory)))
+			actual, ok := mod.Memory().Read(0, uint32(len(tc.expectedMemory)))
 			require.True(t, ok)
 			require.Equal(t, tc.expectedMemory, actual)
 		})
@@ -659,7 +659,7 @@ func Test_fdFilestatGet(t *testing.T) {
 	file, dir := "animals.txt", "sub"
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFS(fstest.FS))
 	defer r.Close(testCtx)
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 
 	// open both paths without using WASI
 	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
@@ -822,7 +822,7 @@ func Test_fdFilestatGet(t *testing.T) {
 			requireErrnoResult(t, tc.expectedErrno, mod, wasip1.FdFilestatGetName, uint64(tc.fd), uint64(tc.resultFilestat))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			actual, ok := mod.Memory().Read(0, uint64(len(tc.expectedMemory)))
+			actual, ok := mod.Memory().Read(0, uint32(len(tc.expectedMemory)))
 			require.True(t, ok)
 			require.Equal(t, tc.expectedMemory, actual)
 		})
@@ -1160,7 +1160,7 @@ func Test_fdPread(t *testing.T) {
 			requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.FdPreadName, uint64(fd), uint64(iovs), uint64(iovsCount), uint64(tc.offset), uint64(resultNread))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			actual, ok := mod.Memory().Read(0, uint64(len(tc.expectedMemory)))
+			actual, ok := mod.Memory().Read(0, uint32(len(tc.expectedMemory)))
 			require.True(t, ok)
 			require.Equal(t, tc.expectedMemory, actual)
 		})
@@ -1200,7 +1200,7 @@ func Test_fdPread_offset(t *testing.T) {
 	require.True(t, ok)
 
 	requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.FdPreadName, uint64(fd), uint64(iovs), uint64(iovsCount), 2, uint64(resultNread))
-	actual, ok := mod.Memory().Read(0, uint64(len(expectedMemory)))
+	actual, ok := mod.Memory().Read(0, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 
@@ -1217,7 +1217,7 @@ func Test_fdPread_offset(t *testing.T) {
 	)
 
 	requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.FdReadName, uint64(fd), uint64(iovs), uint64(iovsCount), uint64(resultNread))
-	actual, ok = mod.Memory().Read(0, uint64(len(expectedMemory)))
+	actual, ok = mod.Memory().Read(0, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 
@@ -1388,7 +1388,7 @@ func Test_fdPrestatGet(t *testing.T) {
 <== (prestat={pr_name_len=1},errno=ESUCCESS)
 `, "\n"+log.String())
 
-	actual, ok := mod.Memory().Read(0, uint64(len(expectedMemory)))
+	actual, ok := mod.Memory().Read(0, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 }
@@ -1397,7 +1397,7 @@ func Test_fdPrestatGet_Errors(t *testing.T) {
 	mod, dirFD, log, r := requireOpenFile(t, t.TempDir(), "tmp", nil, true)
 	defer r.Close(testCtx)
 
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 	tests := []struct {
 		name          string
 		fd            int32
@@ -1468,7 +1468,7 @@ func Test_fdPrestatDirName(t *testing.T) {
 <== (path=,errno=ESUCCESS)
 `, "\n"+log.String())
 
-	actual, ok := mod.Memory().Read(0, uint64(len(expectedMemory)))
+	actual, ok := mod.Memory().Read(0, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 }
@@ -1477,7 +1477,7 @@ func Test_fdPrestatDirName_Errors(t *testing.T) {
 	mod, dirFD, log, r := requireOpenFile(t, t.TempDir(), "tmp", nil, true)
 	defer r.Close(testCtx)
 
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 	maskMemory(t, mod, 10)
 
 	validAddress := uint32(0) // Arbitrary valid address as arguments to fd_prestat_dir_name. We chose 0 here.
@@ -1634,7 +1634,7 @@ func Test_fdPwrite(t *testing.T) {
 			requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.FdPwriteName, uint64(fd), uint64(iovs), uint64(iovsCount), uint64(tc.offset), uint64(resultNwritten))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			actual, ok := mod.Memory().Read(0, uint64(len(tc.expectedMemory)))
+			actual, ok := mod.Memory().Read(0, uint32(len(tc.expectedMemory)))
 			require.True(t, ok)
 			require.Equal(t, tc.expectedMemory, actual)
 
@@ -1680,7 +1680,7 @@ func Test_fdPwrite_offset(t *testing.T) {
 
 	// Write the last half first, to offset 3
 	requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.FdPwriteName, uint64(fd), uint64(iovs), uint64(iovsCount), 3, uint64(resultNwritten))
-	actual, ok := mod.Memory().Read(0, uint64(len(expectedMemory)))
+	actual, ok := mod.Memory().Read(0, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 
@@ -1704,7 +1704,7 @@ func Test_fdPwrite_offset(t *testing.T) {
 	require.True(t, ok)
 
 	requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.FdWriteName, uint64(fd), uint64(iovs), uint64(iovsCount), uint64(resultNwritten))
-	actual, ok = mod.Memory().Read(0, uint64(len(expectedMemory)))
+	actual, ok = mod.Memory().Read(0, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 
@@ -1895,7 +1895,7 @@ func Test_fdRead(t *testing.T) {
 <== (nread=6,errno=ESUCCESS)
 `, "\n"+log.String())
 
-	actual, ok := mod.Memory().Read(0, uint64(len(expectedMemory)))
+	actual, ok := mod.Memory().Read(0, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 }
@@ -2238,7 +2238,7 @@ func Test_fdReaddir(t *testing.T) {
 			require.True(t, ok)
 			require.Equal(t, tc.expectedBufused, bufused)
 
-			mem, ok := mod.Memory().Read(buf, uint64(bufused))
+			mem, ok := mod.Memory().Read(buf, bufused)
 			require.True(t, ok)
 
 			if tc.expectedMem != nil {
@@ -2304,7 +2304,7 @@ func Test_fdReaddir_Rewind(t *testing.T) {
 func Test_fdReaddir_Errors(t *testing.T) {
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFS(fstest.FS))
 	defer r.Close(testCtx)
-	memLen := uint32(mod.Memory().Size())
+	memLen := mod.Memory().Size()
 
 	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	preopen := fsc.RootFS()
@@ -2621,7 +2621,7 @@ func Test_fdSeek(t *testing.T) {
 			requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.FdSeekName, uint64(fd), uint64(tc.offset), uint64(tc.whence), uint64(resultNewoffset))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			actual, ok := mod.Memory().Read(0, uint64(len(tc.expectedMemory)))
+			actual, ok := mod.Memory().Read(0, uint32(len(tc.expectedMemory)))
 			require.True(t, ok)
 			require.Equal(t, tc.expectedMemory, actual)
 
@@ -2640,7 +2640,7 @@ func Test_fdSeek_Errors(t *testing.T) {
 	require.Zero(t, fsc.RootFS().Mkdir("dir", 0o0777))
 	dirFD := requireOpenFD(t, mod, "dir")
 
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 
 	tests := []struct {
 		name                    string
@@ -2778,7 +2778,7 @@ func Test_fdTell(t *testing.T) {
 	requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.FdTellName, uint64(fd), uint64(resultNewoffset))
 	require.Equal(t, expectedLog, "\n"+log.String())
 
-	actual, ok := mod.Memory().Read(0, uint64(len(expectedMemory)))
+	actual, ok := mod.Memory().Read(0, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 
@@ -2791,7 +2791,7 @@ func Test_fdTell_Errors(t *testing.T) {
 	mod, fd, log, r := requireOpenFile(t, t.TempDir(), "test_path", []byte("wazero"), true)
 	defer r.Close(testCtx)
 
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 
 	tests := []struct {
 		name            string
@@ -2869,7 +2869,7 @@ func Test_fdWrite(t *testing.T) {
 <== (nwritten=6,errno=ESUCCESS)
 `, "\n"+log.String())
 
-	actual, ok := mod.Memory().Read(0, uint64(len(expectedMemory)))
+	actual, ok := mod.Memory().Read(0, uint32(len(expectedMemory)))
 	require.True(t, ok)
 	require.Equal(t, expectedMemory, actual)
 
@@ -2888,7 +2888,7 @@ func Test_fdWrite_Errors(t *testing.T) {
 
 	// Setup valid test memory
 	iovsCount := uint32(1)
-	memSize := uint32(mod.Memory().Size())
+	memSize := mod.Memory().Size()
 
 	tests := []struct {
 		name                 string
@@ -3058,7 +3058,7 @@ func Test_pathCreateDirectory_Errors(t *testing.T) {
 		{
 			name:          "out-of-memory reading path",
 			fd:            sys.FdPreopen,
-			path:          uint32(mod.Memory().Size()),
+			path:          mod.Memory().Size(),
 			pathLen:       1,
 			expectedErrno: wasip1.ErrnoFault,
 			expectedLog: `
@@ -3070,7 +3070,7 @@ func Test_pathCreateDirectory_Errors(t *testing.T) {
 			name:          "out-of-memory reading pathLen",
 			fd:            sys.FdPreopen,
 			path:          0,
-			pathLen:       uint32(mod.Memory().Size()) + 1, // path is in the valid memory range, but pathLen is OOM for path
+			pathLen:       mod.Memory().Size() + 1, // path is in the valid memory range, but pathLen is OOM for path
 			expectedErrno: wasip1.ErrnoFault,
 			expectedLog: `
 ==> wasi_snapshot_preview1.path_create_directory(fd=3,path=OOM(0,65537))
@@ -3126,7 +3126,7 @@ func Test_pathFilestatGet(t *testing.T) {
 
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFS(fstest.FS))
 	defer r.Close(testCtx)
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 
 	fileFD := requireOpenFD(t, mod, file)
 
@@ -3405,7 +3405,7 @@ func Test_pathFilestatGet(t *testing.T) {
 			requireErrnoResult(t, tc.expectedErrno, mod, wasip1.PathFilestatGetName, uint64(tc.fd), uint64(tc.flags), uint64(1), uint64(tc.pathLen), uint64(tc.resultFilestat))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			actual, ok := mod.Memory().Read(0, uint64(len(tc.expectedMemory)))
+			actual, ok := mod.Memory().Read(0, uint32(len(tc.expectedMemory)))
 			require.True(t, ok)
 			require.Equal(t, tc.expectedMemory, actual)
 		})
@@ -4078,7 +4078,7 @@ func Test_pathOpen_Errors(t *testing.T) {
 		{
 			name:          "out-of-memory reading path",
 			fd:            sys.FdPreopen,
-			path:          uint32(mod.Memory().Size()),
+			path:          mod.Memory().Size(),
 			pathLen:       uint32(len(file)),
 			expectedErrno: wasip1.ErrnoFault,
 			expectedLog: `
@@ -4090,7 +4090,7 @@ func Test_pathOpen_Errors(t *testing.T) {
 			name:          "out-of-memory reading pathLen",
 			fd:            sys.FdPreopen,
 			path:          0,
-			pathLen:       uint32(mod.Memory().Size()) + 1, // path is in the valid memory range, but pathLen is OOM for path
+			pathLen:       mod.Memory().Size() + 1, // path is in the valid memory range, but pathLen is OOM for path
 			expectedErrno: wasip1.ErrnoFault,
 			expectedLog: `
 ==> wasi_snapshot_preview1.path_open(fd=3,dirflags=,path=OOM(0,65537),oflags=,fs_rights_base=,fs_rights_inheriting=,fdflags=)
@@ -4163,7 +4163,7 @@ func Test_pathOpen_Errors(t *testing.T) {
 			pathName:       dir,
 			path:           0,
 			pathLen:        uint32(len(dir)),
-			resultOpenedFd: uint32(mod.Memory().Size()), // path and pathLen correctly point to the right path, but where to write the opened FD is outside memory.
+			resultOpenedFd: mod.Memory().Size(), // path and pathLen correctly point to the right path, but where to write the opened FD is outside memory.
 			expectedErrno:  wasip1.ErrnoFault,
 			expectedLog: `
 ==> wasi_snapshot_preview1.path_open(fd=3,dirflags=,path=dir,oflags=,fs_rights_base=,fs_rights_inheriting=,fdflags=)
@@ -4277,7 +4277,7 @@ func Test_pathReadlink(t *testing.T) {
 
 				size, ok := mem.ReadUint32Le(resultBufused)
 				require.True(t, ok)
-				actual, ok := mem.Read(buf, uint64(size))
+				actual, ok := mem.Read(buf, size)
 				require.True(t, ok)
 				require.Equal(t, tc.expectedBuf, string(actual))
 			})
@@ -4416,7 +4416,7 @@ func Test_pathRemoveDirectory_Errors(t *testing.T) {
 		{
 			name:          "out-of-memory reading path",
 			fd:            sys.FdPreopen,
-			path:          uint32(mod.Memory().Size()),
+			path:          mod.Memory().Size(),
 			pathLen:       1,
 			expectedErrno: wasip1.ErrnoFault,
 			expectedLog: `
@@ -4428,7 +4428,7 @@ func Test_pathRemoveDirectory_Errors(t *testing.T) {
 			name:          "out-of-memory reading pathLen",
 			fd:            sys.FdPreopen,
 			path:          0,
-			pathLen:       uint32(mod.Memory().Size()) + 1, // path is in the valid memory range, but pathLen is OOM for path
+			pathLen:       mod.Memory().Size() + 1, // path is in the valid memory range, but pathLen is OOM for path
 			expectedErrno: wasip1.ErrnoFault,
 			expectedLog: `
 ==> wasi_snapshot_preview1.path_remove_directory(fd=3,path=OOM(0,65537))
@@ -4682,7 +4682,7 @@ func Test_pathRename_Errors(t *testing.T) {
 			name:          "out-of-memory reading old path",
 			oldFd:         sys.FdPreopen,
 			newFd:         sys.FdPreopen,
-			oldPath:       uint32(mod.Memory().Size()),
+			oldPath:       mod.Memory().Size(),
 			oldPathLen:    1,
 			expectedErrno: wasip1.ErrnoFault,
 			expectedLog: `
@@ -4697,7 +4697,7 @@ func Test_pathRename_Errors(t *testing.T) {
 			oldPath:       0,
 			oldPathName:   "a",
 			oldPathLen:    1,
-			newPath:       uint32(mod.Memory().Size()),
+			newPath:       mod.Memory().Size(),
 			newPathLen:    1,
 			expectedErrno: wasip1.ErrnoFault,
 			expectedLog: `
@@ -4710,7 +4710,7 @@ func Test_pathRename_Errors(t *testing.T) {
 			oldFd:         sys.FdPreopen,
 			newFd:         sys.FdPreopen,
 			oldPath:       0,
-			oldPathLen:    uint32(mod.Memory().Size()) + 1, // path is in the valid memory range, but pathLen is OOM for path
+			oldPathLen:    mod.Memory().Size() + 1, // path is in the valid memory range, but pathLen is OOM for path
 			expectedErrno: wasip1.ErrnoFault,
 			expectedLog: `
 ==> wasi_snapshot_preview1.path_rename(fd=3,old_path=OOM(0,65537),new_fd=3,new_path=)
@@ -4724,7 +4724,7 @@ func Test_pathRename_Errors(t *testing.T) {
 			oldPathName:   file,
 			oldPathLen:    uint32(len(file)),
 			newPath:       0,
-			newPathLen:    uint32(mod.Memory().Size()) + 1, // path is in the valid memory range, but pathLen is OOM for path
+			newPathLen:    mod.Memory().Size() + 1, // path is in the valid memory range, but pathLen is OOM for path
 			expectedErrno: wasip1.ErrnoFault,
 			expectedLog: `
 ==> wasi_snapshot_preview1.path_rename(fd=3,old_path=file,new_fd=3,new_path=OOM(0,65537))
@@ -4853,7 +4853,7 @@ func Test_pathUnlinkFile_Errors(t *testing.T) {
 		{
 			name:          "out-of-memory reading path",
 			fd:            sys.FdPreopen,
-			path:          uint32(mod.Memory().Size()),
+			path:          mod.Memory().Size(),
 			pathLen:       1,
 			expectedErrno: wasip1.ErrnoFault,
 			expectedLog: `
@@ -4865,7 +4865,7 @@ func Test_pathUnlinkFile_Errors(t *testing.T) {
 			name:          "out-of-memory reading pathLen",
 			fd:            sys.FdPreopen,
 			path:          0,
-			pathLen:       uint32(mod.Memory().Size()) + 1, // path is in the valid memory range, but pathLen is OOM for path
+			pathLen:       mod.Memory().Size() + 1, // path is in the valid memory range, but pathLen is OOM for path
 			expectedErrno: wasip1.ErrnoFault,
 			expectedLog: `
 ==> wasi_snapshot_preview1.path_unlink_file(fd=3,path=OOM(0,65537))
@@ -4990,7 +4990,7 @@ func Test_fdReaddir_dotEntryHasARealInode(t *testing.T) {
 
 	used, _ := mem.ReadUint32Le(resultBufused)
 
-	results, _ := mem.Read(buf, uint64(used))
+	results, _ := mem.Read(buf, used)
 	require.Equal(t, dirents, results)
 }
 
@@ -5059,7 +5059,7 @@ func Test_fdReaddir_opened_file_written(t *testing.T) {
 
 	used, _ := mem.ReadUint32Le(resultBufused)
 
-	results, _ := mem.Read(buf, uint64(used))
+	results, _ := mem.Read(buf, used)
 	require.Equal(t, dirents, results)
 }
 
diff --git a/imports/wasi_snapshot_preview1/poll_test.go b/imports/wasi_snapshot_preview1/poll_test.go
index d2735c35..a5357e79 100644
--- a/imports/wasi_snapshot_preview1/poll_test.go
+++ b/imports/wasi_snapshot_preview1/poll_test.go
@@ -55,7 +55,7 @@ func Test_pollOneoff(t *testing.T) {
 <== (nevents=1,errno=ESUCCESS)
 `, "\n"+log.String())
 
-	outMem, ok := mod.Memory().Read(out, uint64(len(expectedMem)))
+	outMem, ok := mod.Memory().Read(out, uint32(len(expectedMem)))
 	require.True(t, ok)
 	require.Equal(t, expectedMem, outMem)
 
@@ -136,7 +136,7 @@ func Test_pollOneoff_Errors(t *testing.T) {
 				uint64(tc.nsubscriptions), uint64(tc.resultNevents))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			out, ok := mod.Memory().Read(tc.out, uint64(len(tc.expectedMem)))
+			out, ok := mod.Memory().Read(tc.out, uint32(len(tc.expectedMem)))
 			require.True(t, ok)
 			require.Equal(t, tc.expectedMem, out)
 
@@ -428,7 +428,7 @@ func Test_pollOneoff_Stdin(t *testing.T) {
 				uint64(tc.nsubscriptions), uint64(tc.resultNevents))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			out, ok := mod.Memory().Read(tc.out, uint64(len(tc.expectedMem)))
+			out, ok := mod.Memory().Read(tc.out, uint32(len(tc.expectedMem)))
 			require.True(t, ok)
 			require.Equal(t, tc.expectedMem, out)
 
@@ -492,7 +492,7 @@ func Test_pollOneoff_Zero(t *testing.T) {
 	requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.PollOneoffName, uint64(0), uint64(out),
 		uint64(nsubscriptions), uint64(resultNevents))
 
-	outMem, ok := mod.Memory().Read(out, uint64(len(expectedMem)))
+	outMem, ok := mod.Memory().Read(out, uint32(len(expectedMem)))
 	require.True(t, ok)
 	require.Equal(t, expectedMem, outMem)
 
@@ -529,7 +529,7 @@ func Test_pollOneoff_Zero(t *testing.T) {
 	requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.PollOneoffName, uint64(0), uint64(out),
 		uint64(nsubscriptions), uint64(resultNevents))
 
-	outMem, ok = mod.Memory().Read(out, uint64(len(expectedMem)))
+	outMem, ok = mod.Memory().Read(out, uint32(len(expectedMem)))
 	require.True(t, ok)
 	require.Equal(t, expectedMem, outMem)
 
diff --git a/imports/wasi_snapshot_preview1/random_test.go b/imports/wasi_snapshot_preview1/random_test.go
index d4364d60..46170a94 100644
--- a/imports/wasi_snapshot_preview1/random_test.go
+++ b/imports/wasi_snapshot_preview1/random_test.go
@@ -22,13 +22,13 @@ func Test_randomGet(t *testing.T) {
 		'?', // stopped after encoding
 	}
 
-	length := uint64(5) // arbitrary length,
-	offset := uint64(1) // offset,
+	length := uint32(5) // arbitrary length,
+	offset := uint32(1) // offset,
 
 	maskMemory(t, mod, len(expectedMemory))
 
 	// Invoke randomGet and check the memory side effects!
-	requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.RandomGetName, offset, length)
+	requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.RandomGetName, uint64(offset), uint64(length))
 	require.Equal(t, `
 ==> wasi_snapshot_preview1.random_get(buf=1,buf_len=5)
 <== errno=ESUCCESS
@@ -43,7 +43,7 @@ func Test_randomGet_Errors(t *testing.T) {
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig())
 	defer r.Close(testCtx)
 
-	memorySize := uint32(mod.Memory().Size())
+	memorySize := mod.Memory().Size()
 
 	tests := []struct {
 		name           string
diff --git a/imports/wasi_snapshot_preview1/sock_test.go b/imports/wasi_snapshot_preview1/sock_test.go
index b1d39183..2bafbd37 100644
--- a/imports/wasi_snapshot_preview1/sock_test.go
+++ b/imports/wasi_snapshot_preview1/sock_test.go
@@ -275,7 +275,7 @@ func Test_sockRecv(t *testing.T) {
 			requireErrnoResult(t, tc.expectedErrno, mod, wasip1.SockRecvName, uint64(connFd), uint64(iovs), tc.iovsCount, uint64(tc.flags), uint64(resultRoDatalen), uint64(resultRoDatalen+4))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			actual, ok := mod.Memory().Read(0, uint64(len(expectedMemory)))
+			actual, ok := mod.Memory().Read(0, uint32(len(expectedMemory)))
 			require.True(t, ok)
 			require.Equal(t, expectedMemory, actual)
 		})
@@ -352,7 +352,7 @@ func Test_sockSend(t *testing.T) {
 			requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.SockSendName, uint64(connFd), uint64(iovs), uint64(iovsCount), 0, uint64(resultSoDatalen))
 			require.Equal(t, tc.expectedLog, "\n"+log.String())
 
-			actual, ok := mod.Memory().Read(0, uint64(len(expectedMemory)))
+			actual, ok := mod.Memory().Read(0, uint32(len(expectedMemory)))
 			require.True(t, ok)
 			require.Equal(t, expectedMemory, actual)
 
diff --git a/internal/engine/wazevo/e2e_test.go b/internal/engine/wazevo/e2e_test.go
index 5a9a5f67..c0605a41 100644
--- a/internal/engine/wazevo/e2e_test.go
+++ b/internal/engine/wazevo/e2e_test.go
@@ -1049,7 +1049,7 @@ func TestE2E_stores(t *testing.T) {
 
 	f := inst.ExportedFunction(testcases.ExportedFunctionName)
 
-	mem, ok := inst.Memory().Read(0, uint64(wasm.MemoryPageSize))
+	mem, ok := inst.Memory().Read(0, wasm.MemoryPageSize)
 	require.True(t, ok)
 	for _, tc := range []struct {
 		i32 uint32
@@ -1144,7 +1144,7 @@ func TestE2E_reexported_memory(t *testing.T) {
 	mem := m1Inst.Memory()
 	require.Equal(t, mem, m3Inst.Memory())
 	require.Equal(t, mem, m2Inst.Memory())
-	require.Equal(t, uint64(11), mem.Size()/65536)
+	require.Equal(t, uint32(11), mem.Size()/65536)
 }
 
 func TestStackUnwind_panic_in_host(t *testing.T) {
diff --git a/internal/integration_test/engine/adhoc_test.go b/internal/integration_test/engine/adhoc_test.go
index 694adf22..53ca3ead 100644
--- a/internal/integration_test/engine/adhoc_test.go
+++ b/internal/integration_test/engine/adhoc_test.go
@@ -818,7 +818,7 @@ func testMemOps(t *testing.T, r wazero.Runtime) {
 	results, err = sizeFn.Call(testCtx)
 	require.NoError(t, err)
 	require.Equal(t, uint64(1), results[0])        // 1 page
-	require.Equal(t, uint64(65536), memory.Size()) // 64KB
+	require.Equal(t, uint32(65536), memory.Size()) // 64KB
 
 	// Grow again so that the memory size matches memory capacity.
 	results, err = growFn.Call(testCtx, 1)
@@ -1055,7 +1055,7 @@ func testCall(t *testing.T, r wazero.Runtime) {
 // * Wasm code calls wasm.OpcodeMemoryGrowName and this changes the capacity (by default, it will).
 func testModuleMemory(t *testing.T, r wazero.Runtime) {
 	wasmPhrase := "Well, that'll be the day when you say goodbye."
-	wasmPhraseSize := uint64(len(wasmPhrase))
+	wasmPhraseSize := uint32(len(wasmPhrase))
 
 	one := uint32(1)
 
@@ -1109,7 +1109,7 @@ func testModuleMemory(t *testing.T, r wazero.Runtime) {
 	require.Equal(t, wasmPhrase, string(buf))
 
 	hostPhrase := "Goodbye, cruel world. I'm off to join the circus." // Intentionally slightly longer.
-	hostPhraseSize := uint64(len(hostPhrase))
+	hostPhraseSize := uint32(len(hostPhrase))
 
 	// Copy over the buffer, which should stop at the current length.
 	copy(buf, hostPhrase)
diff --git a/internal/integration_test/vs/runtime.go b/internal/integration_test/vs/runtime.go
index 8964ee4b..2c2a7b4e 100644
--- a/internal/integration_test/vs/runtime.go
+++ b/internal/integration_test/vs/runtime.go
@@ -82,7 +82,7 @@ func (m *wazeroModule) Memory() []byte {
 func (r *wazeroRuntime) log(_ context.Context, mod api.Module, stack []uint64) {
 	offset, byteCount := uint32(stack[0]), uint32(stack[1])
 
-	buf, ok := mod.Memory().Read(offset, uint64(byteCount))
+	buf, ok := mod.Memory().Read(offset, byteCount)
 	if !ok {
 		panic("out of memory reading log buffer")
 	}
diff --git a/internal/wasm/memory_test.go b/internal/wasm/memory_test.go
index 82a848c0..3d975003 100644
--- a/internal/wasm/memory_test.go
+++ b/internal/wasm/memory_test.go
@@ -151,7 +151,7 @@ func TestMemoryInstance_HasSize(t *testing.T) {
 
 	tests := []struct {
 		name        string
-		offset      uint64
+		offset      uint32
 		sizeInBytes uint64
 		expected    bool
 	}{
@@ -197,7 +197,7 @@ func TestMemoryInstance_HasSize(t *testing.T) {
 		tc := tt
 
 		t.Run(tc.name, func(t *testing.T) {
-			require.Equal(t, tc.expected, memory.hasSize(uint32(tc.offset), tc.sizeInBytes))
+			require.Equal(t, tc.expected, memory.hasSize(tc.offset, tc.sizeInBytes))
 		})
 	}
 }
@@ -471,7 +471,7 @@ func TestMemoryInstance_WriteUint16Le(t *testing.T) {
 
 	tests := []struct {
 		name          string
-		offset        uint64
+		offset        uint32
 		v             uint16
 		expectedOk    bool
 		expectedBytes []byte
@@ -509,7 +509,7 @@ func TestMemoryInstance_WriteUint16Le(t *testing.T) {
 		tc := tt
 
 		t.Run(tc.name, func(t *testing.T) {
-			require.Equal(t, tc.expectedOk, memory.WriteUint16Le(uint32(tc.offset), tc.v))
+			require.Equal(t, tc.expectedOk, memory.WriteUint16Le(tc.offset, tc.v))
 			if tc.expectedOk {
 				require.Equal(t, tc.expectedBytes, memory.Buffer[tc.offset:tc.offset+2]) // 2 is the size of uint16
 			}
@@ -522,7 +522,7 @@ func TestMemoryInstance_WriteUint32Le(t *testing.T) {
 
 	tests := []struct {
 		name          string
-		offset        uint64
+		offset        uint32
 		v             uint32
 		expectedOk    bool
 		expectedBytes []byte
@@ -560,7 +560,7 @@ func TestMemoryInstance_WriteUint32Le(t *testing.T) {
 		tc := tt
 
 		t.Run(tc.name, func(t *testing.T) {
-			require.Equal(t, tc.expectedOk, memory.WriteUint32Le(uint32(tc.offset), tc.v))
+			require.Equal(t, tc.expectedOk, memory.WriteUint32Le(tc.offset, tc.v))
 			if tc.expectedOk {
 				require.Equal(t, tc.expectedBytes, memory.Buffer[tc.offset:tc.offset+4]) // 4 is the size of uint32
 			}
@@ -572,7 +572,7 @@ func TestMemoryInstance_WriteUint64Le(t *testing.T) {
 	memory := &MemoryInstance{Buffer: make([]byte, 100)}
 	tests := []struct {
 		name          string
-		offset        uint64
+		offset        uint32
 		v             uint64
 		expectedOk    bool
 		expectedBytes []byte
@@ -610,7 +610,7 @@ func TestMemoryInstance_WriteUint64Le(t *testing.T) {
 		tc := tt
 
 		t.Run(tc.name, func(t *testing.T) {
-			require.Equal(t, tc.expectedOk, memory.WriteUint64Le(uint32(tc.offset), tc.v))
+			require.Equal(t, tc.expectedOk, memory.WriteUint64Le(tc.offset, tc.v))
 			if tc.expectedOk {
 				require.Equal(t, tc.expectedBytes, memory.Buffer[tc.offset:tc.offset+8]) // 8 is the size of uint64
 			}
@@ -623,7 +623,7 @@ func TestMemoryInstance_WriteFloat32Le(t *testing.T) {
 
 	tests := []struct {
 		name          string
-		offset        uint64
+		offset        uint32
 		v             float32
 		expectedOk    bool
 		expectedBytes []byte
@@ -661,7 +661,7 @@ func TestMemoryInstance_WriteFloat32Le(t *testing.T) {
 		tc := tt
 
 		t.Run(tc.name, func(t *testing.T) {
-			require.Equal(t, tc.expectedOk, memory.WriteFloat32Le(uint32(tc.offset), tc.v))
+			require.Equal(t, tc.expectedOk, memory.WriteFloat32Le(tc.offset, tc.v))
 			if tc.expectedOk {
 				require.Equal(t, tc.expectedBytes, memory.Buffer[tc.offset:tc.offset+4]) // 4 is the size of float32
 			}
@@ -673,7 +673,7 @@ func TestMemoryInstance_WriteFloat64Le(t *testing.T) {
 	memory := &MemoryInstance{Buffer: make([]byte, 100)}
 	tests := []struct {
 		name          string
-		offset        uint64
+		offset        uint32
 		v             float64
 		expectedOk    bool
 		expectedBytes []byte
@@ -711,7 +711,7 @@ func TestMemoryInstance_WriteFloat64Le(t *testing.T) {
 		tc := tt
 
 		t.Run(tc.name, func(t *testing.T) {
-			require.Equal(t, tc.expectedOk, memory.WriteFloat64Le(uint32(tc.offset), tc.v))
+			require.Equal(t, tc.expectedOk, memory.WriteFloat64Le(tc.offset, tc.v))
 			if tc.expectedOk {
 				require.Equal(t, tc.expectedBytes, memory.Buffer[tc.offset:tc.offset+8]) // 8 is the size of float64
 			}
diff --git a/internal/wasm/store_test.go b/internal/wasm/store_test.go
index b8d3d45d..41fc4f17 100644
--- a/internal/wasm/store_test.go
+++ b/internal/wasm/store_test.go
@@ -23,7 +23,7 @@ func TestModuleInstance_Memory(t *testing.T) {
 		name        string
 		input       *Module
 		expected    bool
-		expectedLen uint64
+		expectedLen uint32
 	}{
 		{
 			name:  "no memory",
diff --git a/runtime_test.go b/runtime_test.go
index 0d7982be..b7fce389 100644
--- a/runtime_test.go
+++ b/runtime_test.go
@@ -192,7 +192,7 @@ func TestModule_Memory(t *testing.T) {
 		name        string
 		wasm        []byte
 		expected    bool
-		expectedLen uint64
+		expectedLen uint32
 	}{
 		{
 			name: "no memory",
@@ -226,7 +226,7 @@ func TestModule_Memory(t *testing.T) {
 				defs := module.ExportedMemoryDefinitions()
 				require.Equal(t, 1, len(defs))
 				def := defs["memory"]
-				require.Equal(t, tc.expectedLen>>16, uint64(def.Min()))
+				require.Equal(t, tc.expectedLen>>16, def.Min())
 			} else {
 				require.Nil(t, mem)
 				require.Zero(t, len(module.ExportedMemoryDefinitions()))