Repository: tetratelabs/wazero
Pull request #1280 (2023-03-24 04:25:00)

Deletes wasm.CallCtx
`wasm.CallCtx` was introduced in the past bound to "function call" as the doc says, 
but it is no longer the case. In fact, it is just a thin wrapper over `*wasm.ModuleInstance`,
and unnecessary and confusing internal data structure now.
This removes the type and implements api.Module directly over `*wasm.ModuleInstance`.
As a result, we can clean up the internal and reduce the allocation.
```
goos: linux
goarch: amd64
pkg: github.com/tetratelabs/wazero/internal/integration_test/bench
cpu: AMD Ryzen 9 3950X 16-Core Processor
                                       │   old.txt   │              new.txt               │
                                       │   sec/op    │   sec/op     vs base               │
Initialization/interpreter-32            33.25µ ± 1%   32.75µ ± 0%  -1.52% (p=0.000 n=30)
Initialization/interpreter-multiple-32   14.16µ ± 0%   14.25µ ± 1%  +0.64% (p=0.020 n=30)
Initialization/compiler-32               38.60µ ± 1%   37.93µ ± 0%  -1.73% (p=0.000 n=30)
Initialization/compiler-multiple-32      13.65µ ± 1%   13.65µ ± 1%       ~ (p=0.117 n=30)
Compilation/with_extern_cache-32         292.4µ ± 1%   289.8µ ± 1%       ~ (p=0.100 n=30)
Compilation/without_extern_cache-32      10.61m ± 1%   10.46m ± 1%  -1.33% (p=0.000 n=30)
geomean                                  95.72µ        94.95µ       -0.80%

                                       │   old.txt    │               new.txt               │
                                       │     B/op     │     B/op      vs base               │
Initialization/interpreter-32            132.4Ki ± 0%   132.4Ki ± 0%  -0.02% (p=0.000 n=30)
Initialization/interpreter-multiple-32   132.9Ki ± 0%   132.8Ki ± 0%  -0.02% (p=0.000 n=30)
Initialization/compiler-32               133.1Ki ± 0%   133.1Ki ± 0%  -0.02% (p=0.000 n=30)
Initialization/compiler-multiple-32      137.4Ki ± 0%   137.4Ki ± 0%  -0.02% (p=0.000 n=30)
Compilation/with_extern_cache-32         53.76Ki ± 0%   53.78Ki ± 0%  +0.05% (p=0.000 n=30)
Compilation/without_extern_cache-32      1.907Mi ± 0%   1.907Mi ± 0%  -0.03% (p=0.000 n=30)
geomean                                  179.8Ki        179.8Ki       -0.01%

                                       │   old.txt   │              new.txt               │
                                       │  allocs/op  │  allocs/op   vs base               │
Initialization/interpreter-32             29.00 ± 0%    28.00 ± 0%  -3.45% (p=0.000 n=30)
Initialization/interpreter-multiple-32    42.00 ± 0%    41.00 ± 0%  -2.38% (p=0.000 n=30)
Initialization/compiler-32                29.00 ± 0%    28.00 ± 0%  -3.45% (p=0.000 n=30)
Initialization/compiler-multiple-32       32.00 ± 0%    31.00 ± 0%  -3.12% (p=0.000 n=30)
Compilation/with_extern_cache-32          986.0 ± 0%    986.0 ± 0%       ~ (p=0.313 n=30)
Compilation/without_extern_cache-32      32.62k ± 0%   32.62k ± 0%   0.00% (p=0.017 n=30)
geomean                                   182.0         178.2       -2.08%

```

mathetake: I won't mark this ready until 1.0 is released

Patch:
diff --git a/imports/assemblyscript/assemblyscript.go b/imports/assemblyscript/assemblyscript.go
index 78103f67..92226ce6 100644
--- a/imports/assemblyscript/assemblyscript.go
+++ b/imports/assemblyscript/assemblyscript.go
@@ -149,7 +149,7 @@ var abortMessageDisabled = abortMessageEnabled.WithGoModuleFunc(abort)
 
 // abortWithMessage implements AbortName
 func abortWithMessage(ctx context.Context, mod api.Module, stack []uint64) {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	mem := mod.Memory()
 
 	message := uint32(stack[0])
@@ -191,7 +191,7 @@ var traceStdout = &wasm.HostFunc{
 	ParamNames:  []string{"message", "nArgs", "arg0", "arg1", "arg2", "arg3", "arg4"},
 	Code: wasm.Code{
 		GoFunc: api.GoModuleFunc(func(_ context.Context, mod api.Module, stack []uint64) {
-			fsc := mod.(*wasm.CallContext).Sys.FS()
+			fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 			traceTo(mod, stack, internalsys.WriterForFile(fsc, internalsys.FdStdout))
 		}),
 	},
@@ -199,7 +199,7 @@ var traceStdout = &wasm.HostFunc{
 
 // traceStderr implements trace to the configured Stderr.
 var traceStderr = traceStdout.WithGoModuleFunc(func(_ context.Context, mod api.Module, stack []uint64) {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	traceTo(mod, stack, internalsys.WriterForFile(fsc, internalsys.FdStderr))
 })
 
@@ -276,7 +276,7 @@ var seed = &wasm.HostFunc{
 	ResultNames: []string{"rand"},
 	Code: wasm.Code{
 		GoFunc: api.GoModuleFunc(func(ctx context.Context, mod api.Module, stack []uint64) {
-			r := mod.(*wasm.CallContext).Sys.RandSource()
+			r := mod.(*wasm.ModuleInstance).Sys.RandSource()
 			buf := make([]byte, 8)
 			_, err := io.ReadFull(r, buf)
 			if err != nil {
diff --git a/imports/emscripten/emscripten.go b/imports/emscripten/emscripten.go
index b7160e7a..6bd480da 100644
--- a/imports/emscripten/emscripten.go
+++ b/imports/emscripten/emscripten.go
@@ -143,7 +143,7 @@ var invokeI = &wasm.HostFunc{
 }
 
 func invokeIFn(ctx context.Context, mod api.Module, stack []uint64) {
-	ret, err := callDynamic(ctx, mod.(*wasm.CallContext), wasm.PreAllocatedTypeID_v_i32, wasm.Index(stack[0]), nil)
+	ret, err := callDynamic(ctx, mod.(*wasm.ModuleInstance), wasm.PreAllocatedTypeID_v_i32, wasm.Index(stack[0]), nil)
 	if err != nil {
 		panic(err)
 	}
@@ -160,7 +160,7 @@ var invokeIi = &wasm.HostFunc{
 }
 
 func invokeIiFn(ctx context.Context, mod api.Module, stack []uint64) {
-	ret, err := callDynamic(ctx, mod.(*wasm.CallContext), wasm.PreAllocatedTypeID_i32_i32, wasm.Index(stack[0]), stack[1:])
+	ret, err := callDynamic(ctx, mod.(*wasm.ModuleInstance), wasm.PreAllocatedTypeID_i32_i32, wasm.Index(stack[0]), stack[1:])
 	if err != nil {
 		panic(err)
 	}
@@ -177,7 +177,7 @@ var invokeIii = &wasm.HostFunc{
 }
 
 func invokeIiiFn(ctx context.Context, mod api.Module, stack []uint64) {
-	ret, err := callDynamic(ctx, mod.(*wasm.CallContext), wasm.PreAllocatedTypeID_i32i32_i32, wasm.Index(stack[0]), stack[1:])
+	ret, err := callDynamic(ctx, mod.(*wasm.ModuleInstance), wasm.PreAllocatedTypeID_i32i32_i32, wasm.Index(stack[0]), stack[1:])
 	if err != nil {
 		panic(err)
 	}
@@ -194,7 +194,7 @@ var invokeIiii = &wasm.HostFunc{
 }
 
 func invokeIiiiFn(ctx context.Context, mod api.Module, stack []uint64) {
-	ret, err := callDynamic(ctx, mod.(*wasm.CallContext), wasm.PreAllocatedTypeID_i32i32i32_i32, wasm.Index(stack[0]), stack[1:])
+	ret, err := callDynamic(ctx, mod.(*wasm.ModuleInstance), wasm.PreAllocatedTypeID_i32i32i32_i32, wasm.Index(stack[0]), stack[1:])
 	if err != nil {
 		panic(err)
 	}
@@ -211,7 +211,7 @@ var invokeIiiii = &wasm.HostFunc{
 }
 
 func invokeIiiiiFn(ctx context.Context, mod api.Module, stack []uint64) {
-	ret, err := callDynamic(ctx, mod.(*wasm.CallContext), wasm.PreAllocatedTypeID_i32i32i32i32_i32, wasm.Index(stack[0]), stack[1:])
+	ret, err := callDynamic(ctx, mod.(*wasm.ModuleInstance), wasm.PreAllocatedTypeID_i32i32i32i32_i32, wasm.Index(stack[0]), stack[1:])
 	if err != nil {
 		panic(err)
 	}
@@ -228,7 +228,7 @@ var invokeV = &wasm.HostFunc{
 }
 
 func invokeVFn(ctx context.Context, mod api.Module, stack []uint64) {
-	_, err := callDynamic(ctx, mod.(*wasm.CallContext), wasm.PreAllocatedTypeID_v_v, wasm.Index(stack[0]), nil)
+	_, err := callDynamic(ctx, mod.(*wasm.ModuleInstance), wasm.PreAllocatedTypeID_v_v, wasm.Index(stack[0]), nil)
 	if err != nil {
 		panic(err)
 	}
@@ -244,7 +244,7 @@ var invokeVi = &wasm.HostFunc{
 }
 
 func invokeViFn(ctx context.Context, mod api.Module, stack []uint64) {
-	_, err := callDynamic(ctx, mod.(*wasm.CallContext), wasm.PreAllocatedTypeID_i32_v, wasm.Index(stack[0]), stack[1:])
+	_, err := callDynamic(ctx, mod.(*wasm.ModuleInstance), wasm.PreAllocatedTypeID_i32_v, wasm.Index(stack[0]), stack[1:])
 	if err != nil {
 		panic(err)
 	}
@@ -260,7 +260,7 @@ var invokeVii = &wasm.HostFunc{
 }
 
 func invokeViiFn(ctx context.Context, mod api.Module, stack []uint64) {
-	_, err := callDynamic(ctx, mod.(*wasm.CallContext), wasm.PreAllocatedTypeID_i32i32_v, wasm.Index(stack[0]), stack[1:])
+	_, err := callDynamic(ctx, mod.(*wasm.ModuleInstance), wasm.PreAllocatedTypeID_i32i32_v, wasm.Index(stack[0]), stack[1:])
 	if err != nil {
 		panic(err)
 	}
@@ -276,7 +276,7 @@ var invokeViii = &wasm.HostFunc{
 }
 
 func invokeViiiFn(ctx context.Context, mod api.Module, stack []uint64) {
-	_, err := callDynamic(ctx, mod.(*wasm.CallContext), wasm.PreAllocatedTypeID_i32i32i32_v, wasm.Index(stack[0]), stack[1:])
+	_, err := callDynamic(ctx, mod.(*wasm.ModuleInstance), wasm.PreAllocatedTypeID_i32i32i32_v, wasm.Index(stack[0]), stack[1:])
 	if err != nil {
 		panic(err)
 	}
@@ -292,7 +292,7 @@ var invokeViiii = &wasm.HostFunc{
 }
 
 func invokeViiiiFn(ctx context.Context, mod api.Module, stack []uint64) {
-	_, err := callDynamic(ctx, mod.(*wasm.CallContext), wasm.PreAllocatedTypeID_i32i32i32i32_v, wasm.Index(stack[0]), stack[1:])
+	_, err := callDynamic(ctx, mod.(*wasm.ModuleInstance), wasm.PreAllocatedTypeID_i32i32i32i32_v, wasm.Index(stack[0]), stack[1:])
 	if err != nil {
 		panic(err)
 	}
@@ -304,17 +304,15 @@ func invokeViiiiFn(ctx context.Context, mod api.Module, stack []uint64) {
 // # Parameters
 //
 //   - ctx: the propagated go context.
-//   - callCtx: the incoming context of the `invoke_` function.
+//   - m: the incoming module instance of the `invoke_` function.
 //   - typeID: used to type check on indirect calls.
 //   - tableOffset: position in the module's only table
 //   - params: parameters to the funcref
-func callDynamic(ctx context.Context, callCtx *wasm.CallContext, typeID wasm.FunctionTypeID, tableOffset wasm.Index, params []uint64) (results []uint64, err error) {
-	m := callCtx.Module()
-
+func callDynamic(ctx context.Context, m *wasm.ModuleInstance, typeID wasm.FunctionTypeID, tableOffset wasm.Index, params []uint64) (results []uint64, err error) {
 	t := m.Tables[0] // Emscripten doesn't use multiple tables
 	idx, err := m.Engine.LookupFunction(t, typeID, tableOffset)
 	if err != nil {
 		return nil, err
 	}
-	return callCtx.Function(idx).Call(ctx, params...)
+	return m.Function(idx).Call(ctx, params...)
 }
diff --git a/imports/wasi_snapshot_preview1/args.go b/imports/wasi_snapshot_preview1/args.go
index 273f79f0..71b2c411 100644
--- a/imports/wasi_snapshot_preview1/args.go
+++ b/imports/wasi_snapshot_preview1/args.go
@@ -44,7 +44,7 @@ import (
 var argsGet = newHostFunc(wasip1.ArgsGetName, argsGetFn, []api.ValueType{i32, i32}, "argv", "argv_buf")
 
 func argsGetFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	sysCtx := mod.(*wasm.CallContext).Sys
+	sysCtx := mod.(*wasm.ModuleInstance).Sys
 	argv, argvBuf := uint32(params[0]), uint32(params[1])
 	return writeOffsetsAndNullTerminatedValues(mod.Memory(), sysCtx.Args(), argv, argvBuf, sysCtx.ArgsSize())
 }
@@ -81,7 +81,7 @@ func argsGetFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno
 var argsSizesGet = newHostFunc(wasip1.ArgsSizesGetName, argsSizesGetFn, []api.ValueType{i32, i32}, "result.argc", "result.argv_len")
 
 func argsSizesGetFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	sysCtx := mod.(*wasm.CallContext).Sys
+	sysCtx := mod.(*wasm.ModuleInstance).Sys
 	mem := mod.Memory()
 	resultArgc, resultArgvLen := uint32(params[0]), uint32(params[1])
 
diff --git a/imports/wasi_snapshot_preview1/clock.go b/imports/wasi_snapshot_preview1/clock.go
index 59b0d73c..6e732a06 100644
--- a/imports/wasi_snapshot_preview1/clock.go
+++ b/imports/wasi_snapshot_preview1/clock.go
@@ -40,7 +40,7 @@ import (
 var clockResGet = newHostFunc(wasip1.ClockResGetName, clockResGetFn, []api.ValueType{i32, i32}, "id", "result.resolution")
 
 func clockResGetFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	sysCtx := mod.(*wasm.CallContext).Sys
+	sysCtx := mod.(*wasm.ModuleInstance).Sys
 	id, resultResolution := uint32(params[0]), uint32(params[1])
 
 	var resolution uint64 // ns
@@ -93,7 +93,7 @@ func clockResGetFn(_ context.Context, mod api.Module, params []uint64) syscall.E
 var clockTimeGet = newHostFunc(wasip1.ClockTimeGetName, clockTimeGetFn, []api.ValueType{i32, i64, i32}, "id", "precision", "result.timestamp")
 
 func clockTimeGetFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	sysCtx := mod.(*wasm.CallContext).Sys
+	sysCtx := mod.(*wasm.ModuleInstance).Sys
 	id := uint32(params[0])
 	// TODO: precision is currently ignored.
 	// precision = params[1]
diff --git a/imports/wasi_snapshot_preview1/environ.go b/imports/wasi_snapshot_preview1/environ.go
index ba8cd48d..995f82f2 100644
--- a/imports/wasi_snapshot_preview1/environ.go
+++ b/imports/wasi_snapshot_preview1/environ.go
@@ -44,7 +44,7 @@ import (
 var environGet = newHostFunc(wasip1.EnvironGetName, environGetFn, []api.ValueType{i32, i32}, "environ", "environ_buf")
 
 func environGetFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	sysCtx := mod.(*wasm.CallContext).Sys
+	sysCtx := mod.(*wasm.ModuleInstance).Sys
 	environ, environBuf := uint32(params[0]), uint32(params[1])
 
 	return writeOffsetsAndNullTerminatedValues(mod.Memory(), sysCtx.Environ(), environ, environBuf, sysCtx.EnvironSize())
@@ -84,7 +84,7 @@ func environGetFn(_ context.Context, mod api.Module, params []uint64) syscall.Er
 var environSizesGet = newHostFunc(wasip1.EnvironSizesGetName, environSizesGetFn, []api.ValueType{i32, i32}, "result.environc", "result.environv_len")
 
 func environSizesGetFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	sysCtx := mod.(*wasm.CallContext).Sys
+	sysCtx := mod.(*wasm.ModuleInstance).Sys
 	mem := mod.Memory()
 	resultEnvironc, resultEnvironvLen := uint32(params[0]), uint32(params[1])
 
diff --git a/imports/wasi_snapshot_preview1/fs.go b/imports/wasi_snapshot_preview1/fs.go
index 1fb20808..7ca64331 100644
--- a/imports/wasi_snapshot_preview1/fs.go
+++ b/imports/wasi_snapshot_preview1/fs.go
@@ -43,7 +43,7 @@ func fdAdviseFn(_ context.Context, mod api.Module, params []uint64) syscall.Errn
 	_ = params[1]
 	_ = params[2]
 	advice := byte(params[3])
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	_, ok := fsc.LookupFile(fd)
 	if !ok {
@@ -86,7 +86,7 @@ func fdAllocateFn(_ context.Context, mod api.Module, params []uint64) syscall.Er
 	offset := params[1]
 	length := params[2]
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	f, ok := fsc.LookupFile(fd)
 	if !ok {
 		return syscall.EBADF
@@ -134,7 +134,7 @@ func fdAllocateFn(_ context.Context, mod api.Module, params []uint64) syscall.Er
 var fdClose = newHostFunc(wasip1.FdCloseName, fdCloseFn, []api.ValueType{i32}, "fd")
 
 func fdCloseFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	fd := uint32(params[0])
 
 	return fsc.CloseFile(fd)
@@ -147,7 +147,7 @@ func fdCloseFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno
 var fdDatasync = newHostFunc(wasip1.FdDatasyncName, fdDatasyncFn, []api.ValueType{i32}, "fd")
 
 func fdDatasyncFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	fd := uint32(params[0])
 
 	// Check to see if the file descriptor is available
@@ -200,7 +200,7 @@ var fdFdstatGet = newHostFunc(wasip1.FdFdstatGetName, fdFdstatGetFn, []api.Value
 // fdFdstatGetFn cannot currently use proxyResultParams because fdstat is larger
 // than api.ValueTypeI64 (i64 == 8 bytes, but fdstat is 24).
 func fdFdstatGetFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd, resultFdstat := uint32(params[0]), uint32(params[1])
 
@@ -248,7 +248,7 @@ var fdFdstatSetFlags = newHostFunc(wasip1.FdFdstatSetFlagsName, fdFdstatSetFlags
 
 func fdFdstatSetFlagsFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
 	fd, wasiFlag := uint32(params[0]), uint16(params[1])
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	// We can only support APPEND flag.
 	if wasip1.FD_DSYNC&wasiFlag != 0 || wasip1.FD_NONBLOCK&wasiFlag != 0 || wasip1.FD_RSYNC&wasiFlag != 0 || wasip1.FD_SYNC&wasiFlag != 0 {
@@ -328,7 +328,7 @@ func fdFilestatGetFn(_ context.Context, mod api.Module, params []uint64) syscall
 }
 
 func fdFilestatGetFunc(mod api.Module, fd, resultBuf uint32) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	// Ensure we can write the filestat
 	buf, ok := mod.Memory().Read(resultBuf, 64)
@@ -391,7 +391,7 @@ func fdFilestatSetSizeFn(_ context.Context, mod api.Module, params []uint64) sys
 	fd := uint32(params[0])
 	size := uint32(params[1])
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	// Check to see if the file descriptor is available
 	if f, ok := fsc.LookupFile(fd); !ok {
@@ -420,7 +420,7 @@ func fdFilestatSetTimesFn(_ context.Context, mod api.Module, params []uint64) sy
 	mtim := int64(params[2])
 	fstFlags := uint16(params[3])
 
-	sys := mod.(*wasm.CallContext).Sys
+	sys := mod.(*wasm.ModuleInstance).Sys
 	fsc := sys.FS()
 
 	f, ok := fsc.LookupFile(fd)
@@ -524,7 +524,7 @@ func fdPreadFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno
 var fdPrestatGet = newHostFunc(wasip1.FdPrestatGetName, fdPrestatGetFn, []api.ValueType{i32, i32}, "fd", "result.prestat")
 
 func fdPrestatGetFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	fd, resultPrestat := uint32(params[0]), uint32(params[1])
 
 	name, errno := preopenPath(fsc, fd)
@@ -578,7 +578,7 @@ var fdPrestatDirName = newHostFunc(
 )
 
 func fdPrestatDirNameFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	fd, path, pathLen := uint32(params[0]), uint32(params[1]), uint32(params[2])
 
 	name, errno := preopenPath(fsc, fd)
@@ -674,7 +674,7 @@ func fdReadFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno
 
 func fdReadOrPread(mod api.Module, params []uint64, isPread bool) syscall.Errno {
 	mem := mod.Memory()
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd := uint32(params[0])
 
@@ -759,7 +759,7 @@ var fdReaddir = newHostFunc(
 
 func fdReaddirFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
 	mem := mod.Memory()
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd := uint32(params[0])
 	buf := uint32(params[1])
@@ -1067,7 +1067,7 @@ func openedDir(fsc *sys.FSContext, fd uint32) (fs.File, *sys.ReadDir, syscall.Er
 var fdRenumber = newHostFunc(wasip1.FdRenumberName, fdRenumberFn, []wasm.ValueType{i32, i32}, "fd", "to")
 
 func fdRenumberFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	from := uint32(params[0])
 	to := uint32(params[1])
@@ -1122,7 +1122,7 @@ var fdSeek = newHostFunc(
 )
 
 func fdSeekFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	fd := uint32(params[0])
 	offset := params[1]
 	whence := uint32(params[2])
@@ -1163,7 +1163,7 @@ func fdSeekFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno
 var fdSync = newHostFunc(wasip1.FdSyncName, fdSyncFn, []api.ValueType{i32}, "fd")
 
 func fdSyncFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	fd := uint32(params[0])
 
 	// Check to see if the file descriptor is available
@@ -1263,7 +1263,7 @@ func fdWriteFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno
 
 func fdWriteOrPwrite(mod api.Module, params []uint64, isPwrite bool) syscall.Errno {
 	mem := mod.Memory()
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd := uint32(params[0])
 	iovs := uint32(params[1])
@@ -1345,7 +1345,7 @@ var pathCreateDirectory = newHostFunc(
 )
 
 func pathCreateDirectoryFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd := uint32(params[0])
 	path := uint32(params[1])
@@ -1398,7 +1398,7 @@ var pathFilestatGet = newHostFunc(
 )
 
 func pathFilestatGetFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd := uint32(params[0])
 	flags := uint16(params[1])
@@ -1458,7 +1458,7 @@ func pathFilestatSetTimesFn(_ context.Context, mod api.Module, params []uint64)
 	mtim := int64(params[5])
 	fstFlags := uint16(params[6])
 
-	sys := mod.(*wasm.CallContext).Sys
+	sys := mod.(*wasm.ModuleInstance).Sys
 	fsc := sys.FS()
 
 	times, errno := toTimes(atim, mtim, fstFlags)
@@ -1487,7 +1487,7 @@ var pathLink = newHostFunc(
 
 func pathLinkFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
 	mem := mod.Memory()
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	oldFd := uint32(params[0])
 	// TODO: use old_flags?
@@ -1576,7 +1576,7 @@ var pathOpen = newHostFunc(
 )
 
 func pathOpenFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	preopenFD := uint32(params[0])
 
@@ -1742,7 +1742,7 @@ var pathReadlink = newHostFunc(
 )
 
 func pathReadlinkFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd := uint32(params[0])
 	path := uint32(params[1])
@@ -1805,7 +1805,7 @@ var pathRemoveDirectory = newHostFunc(
 )
 
 func pathRemoveDirectoryFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd := uint32(params[0])
 	path := uint32(params[1])
@@ -1851,7 +1851,7 @@ var pathRename = newHostFunc(
 )
 
 func pathRenameFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd := uint32(params[0])
 	oldPath := uint32(params[1])
@@ -1889,7 +1889,7 @@ var pathSymlink = newHostFunc(
 )
 
 func pathSymlinkFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	oldPath := uint32(params[0])
 	oldPathLen := uint32(params[1])
@@ -1967,7 +1967,7 @@ var pathUnlinkFile = newHostFunc(
 )
 
 func pathUnlinkFileFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd := uint32(params[0])
 	path := uint32(params[1])
diff --git a/imports/wasi_snapshot_preview1/poll.go b/imports/wasi_snapshot_preview1/poll.go
index 2c1c0a60..2ccc29b1 100644
--- a/imports/wasi_snapshot_preview1/poll.go
+++ b/imports/wasi_snapshot_preview1/poll.go
@@ -127,7 +127,7 @@ func processClockEvent(_ context.Context, mod api.Module, inBuf []byte) syscall.
 	// unaffected. Since this function only supports relative timeout, we can
 	// skip name ID validation and use a single sleep function.
 
-	sysCtx := mod.(*wasm.CallContext).Sys
+	sysCtx := mod.(*wasm.ModuleInstance).Sys
 	sysCtx.Nanosleep(int64(timeout))
 	return 0
 }
@@ -136,7 +136,7 @@ func processClockEvent(_ context.Context, mod api.Module, inBuf []byte) syscall.
 // subscriptions are not yet supported.
 func processFDEvent(mod api.Module, eventType byte, inBuf []byte) syscall.Errno {
 	fd := le.Uint32(inBuf)
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	// Choose the best error, which falls back to unsupported, until we support
 	// files.
diff --git a/imports/wasi_snapshot_preview1/random.go b/imports/wasi_snapshot_preview1/random.go
index 32a919f5..dc94bf7d 100644
--- a/imports/wasi_snapshot_preview1/random.go
+++ b/imports/wasi_snapshot_preview1/random.go
@@ -37,7 +37,7 @@ import (
 var randomGet = newHostFunc(wasip1.RandomGetName, randomGetFn, []api.ValueType{i32, i32}, "buf", "buf_len")
 
 func randomGetFn(_ context.Context, mod api.Module, params []uint64) syscall.Errno {
-	sysCtx := mod.(*wasm.CallContext).Sys
+	sysCtx := mod.(*wasm.ModuleInstance).Sys
 	randSource := sysCtx.RandSource()
 	buf, bufLen := uint32(params[0]), uint32(params[1])
 
diff --git a/imports/wasi_snapshot_preview1/sched.go b/imports/wasi_snapshot_preview1/sched.go
index 16901bbc..b6dbf190 100644
--- a/imports/wasi_snapshot_preview1/sched.go
+++ b/imports/wasi_snapshot_preview1/sched.go
@@ -16,7 +16,7 @@ import (
 var schedYield = newHostFunc(wasip1.SchedYieldName, schedYieldFn, nil)
 
 func schedYieldFn(_ context.Context, mod api.Module, _ []uint64) syscall.Errno {
-	sysCtx := mod.(*wasm.CallContext).Sys
+	sysCtx := mod.(*wasm.ModuleInstance).Sys
 	sysCtx.Osyield()
 	return 0
 }
diff --git a/internal/engine/compiler/engine.go b/internal/engine/compiler/engine.go
index f3b10382..d21db5c8 100644
--- a/internal/engine/compiler/engine.go
+++ b/internal/engine/compiler/engine.go
@@ -346,10 +346,10 @@ const (
 	moduleInstanceGlobalsOffset          = 48
 	moduleInstanceMemoryOffset           = 72
 	moduleInstanceTablesOffset           = 80
-	moduleInstanceEngineOffset           = 112
-	moduleInstanceTypeIDsOffset          = 128
-	moduleInstanceDataInstancesOffset    = 152
-	moduleInstanceElementInstancesOffset = 176
+	moduleInstanceEngineOffset           = 104
+	moduleInstanceTypeIDsOffset          = 120
+	moduleInstanceDataInstancesOffset    = 144
+	moduleInstanceElementInstancesOffset = 168
 
 	// Offsets for wasm.TableInstance.
 	tableInstanceTableOffset    = 0
@@ -592,7 +592,7 @@ func (e *moduleEngine) FunctionInstanceReference(funcIndex wasm.Index) wasm.Refe
 	return uintptr(unsafe.Pointer(&e.functions[funcIndex]))
 }
 
-func (e *moduleEngine) NewCallEngine(_ *wasm.CallContext, f *wasm.FunctionInstance) (ce wasm.CallEngine, err error) {
+func (e *moduleEngine) NewCallEngine(_ *wasm.ModuleInstance, f *wasm.FunctionInstance) (ce wasm.CallEngine, err error) {
 	// Note: The input parameters are pre-validated, so a compiled function is only absent on close. Updates to
 	// code on close aren't locked, neither is this read.
 	compiled := &e.functions[f.Definition.Index()]
@@ -639,14 +639,14 @@ func functionFromUintptr(ptr uintptr) *function {
 }
 
 // Call implements the same method as documented on wasm.ModuleEngine.
-func (ce *callEngine) Call(ctx context.Context, callCtx *wasm.CallContext, params []uint64) (results []uint64, err error) {
+func (ce *callEngine) Call(ctx context.Context, m *wasm.ModuleInstance, params []uint64) (results []uint64, err error) {
 	if ce.fn.parent.withEnsureTermination {
 		select {
 		case <-ctx.Done():
 			// If the provided context is already done, close the call context
 			// and return the error.
-			callCtx.CloseWithCtxErr(ctx)
-			return nil, callCtx.FailIfClosed()
+			m.CloseWithCtxErr(ctx)
+			return nil, m.FailIfClosed()
 		default:
 		}
 	}
@@ -666,18 +666,18 @@ func (ce *callEngine) Call(ctx context.Context, callCtx *wasm.CallContext, param
 		err = ce.deferredOnCall(recover())
 		if err == nil {
 			// If the module closed during the call, and the call didn't err for another reason, set an ExitError.
-			err = callCtx.FailIfClosed()
+			err = m.FailIfClosed()
 		}
 	}()
 
 	ce.initializeStack(tp, params)
 
 	if ce.fn.parent.withEnsureTermination {
-		done := callCtx.CloseModuleOnCanceledOrTimeout(ctx)
+		done := m.CloseModuleOnCanceledOrTimeout(ctx)
 		defer done()
 	}
 
-	ce.execWasmFunction(ctx, callCtx)
+	ce.execWasmFunction(ctx, m)
 
 	// This returns a safe copy of the results, instead of a slice view. If we
 	// returned a re-slice, the caller could accidentally or purposefully
@@ -900,7 +900,7 @@ const (
 	builtinFunctionIndexBreakPoint
 )
 
-func (ce *callEngine) execWasmFunction(ctx context.Context, callCtx *wasm.CallContext) {
+func (ce *callEngine) execWasmFunction(ctx context.Context, m *wasm.ModuleInstance) {
 	codeAddr := ce.initialFn.codeInitialAddress
 	modAddr := ce.initialFn.moduleInstanceAddress
 	ce.ctx = ctx
@@ -929,7 +929,7 @@ entry:
 			fn := calleeHostFunction.parent.goFunc
 			switch fn := fn.(type) {
 			case api.GoModuleFunction:
-				fn.Call(ce.ctx, ce.callerFunctionInstance.Module.CallCtx, stack)
+				fn.Call(ce.ctx, ce.callerFunctionInstance.Module, stack)
 			case api.GoFunction:
 				fn.Call(ce.ctx, stack)
 			}
@@ -940,20 +940,20 @@ entry:
 			caller := ce.moduleContext.fn
 			switch ce.exitContext.builtinFunctionCallIndex {
 			case builtinFunctionIndexMemoryGrow:
-				ce.builtinFunctionMemoryGrow(caller.source.Module.Memory)
+				ce.builtinFunctionMemoryGrow(caller.source.Module.MemoryInstance)
 			case builtinFunctionIndexGrowStack:
 				ce.builtinFunctionGrowStack(caller.parent.stackPointerCeil)
 			case builtinFunctionIndexTableGrow:
 				ce.builtinFunctionTableGrow(caller.source.Module.Tables)
 			case builtinFunctionIndexFunctionListenerBefore:
-				ce.builtinFunctionFunctionListenerBefore(ce.ctx, callCtx, caller)
+				ce.builtinFunctionFunctionListenerBefore(ce.ctx, m, caller)
 			case builtinFunctionIndexFunctionListenerAfter:
-				ce.builtinFunctionFunctionListenerAfter(ce.ctx, callCtx, caller)
+				ce.builtinFunctionFunctionListenerAfter(ce.ctx, m, caller)
 			case builtinFunctionIndexCheckExitCode:
 				// Note: this operation must be done in Go, not native code. The reason is that
 				// native code cannot be preempted and that means it can block forever if there are not
 				// enough OS threads (which we don't have control over).
-				if err := callCtx.FailIfClosed(); err != nil {
+				if err := m.FailIfClosed(); err != nil {
 					panic(err)
 				}
 			}
diff --git a/internal/engine/interpreter/interpreter.go b/internal/engine/interpreter/interpreter.go
index 44fe922a..2eb8a2c1 100644
--- a/internal/engine/interpreter/interpreter.go
+++ b/internal/engine/interpreter/interpreter.go
@@ -740,7 +740,7 @@ func (e *moduleEngine) FunctionInstanceReference(funcIndex wasm.Index) wasm.Refe
 }
 
 // NewCallEngine implements the same method as documented on wasm.ModuleEngine.
-func (e *moduleEngine) NewCallEngine(_ *wasm.CallContext, f *wasm.FunctionInstance) (ce wasm.CallEngine, err error) {
+func (e *moduleEngine) NewCallEngine(_ *wasm.ModuleInstance, f *wasm.FunctionInstance) (ce wasm.CallEngine, err error) {
 	// Note: The input parameters are pre-validated, so a compiled function is only absent on close. Updates to
 	// code on close aren't locked, neither is this read.
 	compiled := &e.functions[f.Definition.Index()]
@@ -770,18 +770,18 @@ func (e *moduleEngine) LookupFunction(t *wasm.TableInstance, typeId wasm.Functio
 }
 
 // Call implements the same method as documented on wasm.CallEngine.
-func (ce *callEngine) Call(ctx context.Context, m *wasm.CallContext, params []uint64) (results []uint64, err error) {
+func (ce *callEngine) Call(ctx context.Context, m *wasm.ModuleInstance, params []uint64) (results []uint64, err error) {
 	return ce.call(ctx, m, ce.compiled, params)
 }
 
-func (ce *callEngine) call(ctx context.Context, callCtx *wasm.CallContext, tf *function, params []uint64) (results []uint64, err error) {
+func (ce *callEngine) call(ctx context.Context, m *wasm.ModuleInstance, tf *function, params []uint64) (results []uint64, err error) {
 	if ce.compiled.parent.ensureTermination {
 		select {
 		case <-ctx.Done():
 			// If the provided context is already done, close the call context
 			// and return the error.
-			callCtx.CloseWithCtxErr(ctx)
-			return nil, callCtx.FailIfClosed()
+			m.CloseWithCtxErr(ctx)
+			return nil, m.FailIfClosed()
 		default:
 		}
 	}
@@ -796,7 +796,7 @@ func (ce *callEngine) call(ctx context.Context, callCtx *wasm.CallContext, tf *f
 	defer func() {
 		// If the module closed during the call, and the call didn't err for another reason, set an ExitError.
 		if err == nil {
-			err = callCtx.FailIfClosed()
+			err = m.FailIfClosed()
 		}
 		// TODO: ^^ Will not fail if the function was imported from a closed module.
 
@@ -810,11 +810,11 @@ func (ce *callEngine) call(ctx context.Context, callCtx *wasm.CallContext, tf *f
 	}
 
 	if ce.compiled.parent.ensureTermination {
-		done := callCtx.CloseModuleOnCanceledOrTimeout(ctx)
+		done := m.CloseModuleOnCanceledOrTimeout(ctx)
 		defer done()
 	}
 
-	ce.callFunction(ctx, callCtx, tf)
+	ce.callFunction(ctx, m, tf)
 
 	// This returns a safe copy of the results, instead of a slice view. If we
 	// returned a re-slice, the caller could accidentally or purposefully
@@ -845,21 +845,21 @@ func (ce *callEngine) recoverOnCall(v interface{}) (err error) {
 	return
 }
 
-func (ce *callEngine) callFunction(ctx context.Context, callCtx *wasm.CallContext, f *function) {
+func (ce *callEngine) callFunction(ctx context.Context, m *wasm.ModuleInstance, f *function) {
 	if f.parent.hostFn != nil {
-		ce.callGoFuncWithStack(ctx, callCtx, f)
+		ce.callGoFuncWithStack(ctx, m, f)
 	} else if lsn := f.parent.listener; lsn != nil {
-		ce.callNativeFuncWithListener(ctx, callCtx, f, lsn)
+		ce.callNativeFuncWithListener(ctx, m, f, lsn)
 	} else {
-		ce.callNativeFunc(ctx, callCtx, f)
+		ce.callNativeFunc(ctx, m, f)
 	}
 }
 
-func (ce *callEngine) callGoFunc(ctx context.Context, callCtx *wasm.CallContext, f *function, stack []uint64) {
+func (ce *callEngine) callGoFunc(ctx context.Context, m *wasm.ModuleInstance, f *function, stack []uint64) {
 	lsn := f.parent.listener
 	if lsn != nil {
 		params := stack[:f.source.Type.ParamNumInUint64]
-		ctx = lsn.Before(ctx, callCtx, f.source.Definition, params)
+		ctx = lsn.Before(ctx, m, f.source.Definition, params)
 	}
 	frame := &callFrame{f: f}
 	ce.pushFrame(frame)
@@ -867,7 +867,7 @@ func (ce *callEngine) callGoFunc(ctx context.Context, callCtx *wasm.CallContext,
 	fn := f.parent.hostFn
 	switch fn := fn.(type) {
 	case api.GoModuleFunction:
-		fn.Call(ctx, callCtx, stack)
+		fn.Call(ctx, m, stack)
 	case api.GoFunction:
 		fn.Call(ctx, stack)
 	}
@@ -876,11 +876,11 @@ func (ce *callEngine) callGoFunc(ctx context.Context, callCtx *wasm.CallContext,
 	if lsn != nil {
 		// TODO: This doesn't get the error due to use of panic to propagate them.
 		results := stack[:f.source.Type.ResultNumInUint64]
-		lsn.After(ctx, callCtx, f.source.Definition, nil, results)
+		lsn.After(ctx, m, f.source.Definition, nil, results)
 	}
 }
 
-func (ce *callEngine) callNativeFunc(ctx context.Context, callCtx *wasm.CallContext, f *function) {
+func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance, f *function) {
 	frame := &callFrame{f: f}
 	moduleInst := f.source.Module
 	functions := moduleInst.Engine.(*moduleEngine).functions
@@ -888,7 +888,7 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, callCtx *wasm.CallCont
 	if f.parent.hostFn != nil {
 		memoryInst = ce.callerMemory()
 	} else {
-		memoryInst = moduleInst.Memory
+		memoryInst = moduleInst.MemoryInstance
 	}
 	globals := moduleInst.Globals
 	tables := moduleInst.Tables
@@ -905,7 +905,7 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, callCtx *wasm.CallCont
 		// how the stack is modified, etc.
 		switch op.kind {
 		case wazeroir.OperationKindBuiltinFunctionCheckExitCode:
-			if err := callCtx.FailIfClosed(); err != nil {
+			if err := m.FailIfClosed(); err != nil {
 				panic(err)
 			}
 			frame.pc++
@@ -931,7 +931,7 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, callCtx *wasm.CallCont
 				frame.pc = op.us[0]
 			}
 		case wazeroir.OperationKindCall:
-			ce.callFunction(ctx, f.source.Module.CallCtx, &functions[op.us[0]])
+			ce.callFunction(ctx, f.source.Module, &functions[op.us[0]])
 			frame.pc++
 		case wazeroir.OperationKindCallIndirect:
 			offset := ce.popValue()
@@ -949,7 +949,7 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, callCtx *wasm.CallCont
 				panic(wasmruntime.ErrRuntimeIndirectCallTypeMismatch)
 			}
 
-			ce.callFunction(ctx, f.source.Module.CallCtx, tf)
+			ce.callFunction(ctx, f.source.Module, tf)
 			frame.pc++
 		case wazeroir.OperationKindDrop:
 			ce.drop(op.rs[0])
@@ -4158,7 +4158,7 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, callCtx *wasm.CallCont
 
 // callerMemory returns the caller context memory.
 func (ce *callEngine) callerMemory() *wasm.MemoryInstance {
-	return ce.frames[len(ce.frames)-1].f.source.Module.Memory
+	return ce.frames[len(ce.frames)-1].f.source.Module.MemoryInstance
 }
 
 func WasmCompatMax32bits(v1, v2 uint32) uint64 {
@@ -4357,11 +4357,11 @@ func i32Abs(v uint32) uint32 {
 	}
 }
 
-func (ce *callEngine) callNativeFuncWithListener(ctx context.Context, callCtx *wasm.CallContext, f *function, fnl experimental.FunctionListener) context.Context {
-	ctx = fnl.Before(ctx, callCtx, f.source.Definition, ce.peekValues(len(f.source.Type.Params)))
-	ce.callNativeFunc(ctx, callCtx, f)
+func (ce *callEngine) callNativeFuncWithListener(ctx context.Context, m *wasm.ModuleInstance, f *function, fnl experimental.FunctionListener) context.Context {
+	ctx = fnl.Before(ctx, m, f.source.Definition, ce.peekValues(len(f.source.Type.Params)))
+	ce.callNativeFunc(ctx, m, f)
 	// TODO: This doesn't get the error due to use of panic to propagate them.
-	fnl.After(ctx, callCtx, f.source.Definition, nil, ce.peekValues(len(f.source.Type.Results)))
+	fnl.After(ctx, m, f.source.Definition, nil, ce.peekValues(len(f.source.Type.Results)))
 	return ctx
 }
 
@@ -4376,7 +4376,7 @@ func (ce *callEngine) popMemoryOffset(op *interpreterOp) uint32 {
 	return uint32(offset)
 }
 
-func (ce *callEngine) callGoFuncWithStack(ctx context.Context, callCtx *wasm.CallContext, f *function) {
+func (ce *callEngine) callGoFuncWithStack(ctx context.Context, m *wasm.ModuleInstance, f *function) {
 	paramLen := f.source.Type.ParamNumInUint64
 	resultLen := f.source.Type.ResultNumInUint64
 	stackLen := paramLen
@@ -4392,7 +4392,7 @@ func (ce *callEngine) callGoFuncWithStack(ctx context.Context, callCtx *wasm.Cal
 
 	// Pass the stack elements to the go function.
 	stack := ce.stack[len(ce.stack)-stackLen:]
-	ce.callGoFunc(ctx, callCtx, f, stack)
+	ce.callGoFunc(ctx, m, f, stack)
 
 	// Shrink the stack when there were more parameters than results.
 	if shrinkLen := paramLen - resultLen; shrinkLen > 0 {
diff --git a/internal/gojs/argsenv.go b/internal/gojs/argsenv.go
index 4be4bf7c..f41a5b16 100644
--- a/internal/gojs/argsenv.go
+++ b/internal/gojs/argsenv.go
@@ -22,7 +22,7 @@ var le = binary.LittleEndian
 // they can be read by main, Go compiles as the function export "run".
 func WriteArgsAndEnviron(mod api.Module) (argc, argv uint32, err error) {
 	mem := mod.Memory()
-	sysCtx := mod.(*wasm.CallContext).Sys
+	sysCtx := mod.(*wasm.ModuleInstance).Sys
 	args := sysCtx.Args()
 	environ := sysCtx.Environ()
 
diff --git a/internal/gojs/crypto.go b/internal/gojs/crypto.go
index d69da3fe..7b528da3 100644
--- a/internal/gojs/crypto.go
+++ b/internal/gojs/crypto.go
@@ -23,7 +23,7 @@ var jsCrypto = newJsVal(goos.RefJsCrypto, custom.NameCrypto).
 type cryptoGetRandomValues struct{}
 
 func (cryptoGetRandomValues) invoke(_ context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
-	randSource := mod.(*wasm.CallContext).Sys.RandSource()
+	randSource := mod.(*wasm.ModuleInstance).Sys.RandSource()
 
 	r := args[0].(*goos.ByteArray)
 	n, err := randSource.Read(r.Unwrap())
diff --git a/internal/gojs/fs.go b/internal/gojs/fs.go
index 1737c7c0..3a81a610 100644
--- a/internal/gojs/fs.go
+++ b/internal/gojs/fs.go
@@ -108,7 +108,7 @@ func (o *jsfsOpen) invoke(ctx context.Context, mod api.Module, args ...interface
 	perm := custom.FromJsMode(goos.ValueToUint32(args[2]), o.proc.umask)
 	callback := args[3].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd, errno := fsc.OpenFile(fsc.RootFS(), path, int(flags), perm)
 
@@ -132,7 +132,7 @@ func (s *jsfsStat) invoke(ctx context.Context, mod api.Module, args ...interface
 
 // syscallStat is like syscall.Stat
 func syscallStat(mod api.Module, path string) (*jsSt, error) {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	if st, errno := fsc.RootFS().Stat(path); errno != 0 {
 		return nil, errno
@@ -159,7 +159,7 @@ func (l *jsfsLstat) invoke(ctx context.Context, mod api.Module, args ...interfac
 
 // syscallLstat is like syscall.Lstat
 func syscallLstat(mod api.Module, path string) (*jsSt, error) {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	if st, errno := fsc.RootFS().Lstat(path); errno != 0 {
 		return nil, errno
@@ -174,7 +174,7 @@ func syscallLstat(mod api.Module, path string) (*jsSt, error) {
 type jsfsFstat struct{}
 
 func (jsfsFstat) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd := goos.ValueToUint32(args[0])
 	callback := args[1].(funcWrapper)
@@ -217,7 +217,7 @@ func newJsSt(st platform.Stat_t) *jsSt {
 type jsfsClose struct{}
 
 func (jsfsClose) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd := goos.ValueToUint32(args[0])
 	callback := args[1].(funcWrapper)
@@ -250,7 +250,7 @@ func (jsfsRead) invoke(ctx context.Context, mod api.Module, args ...interface{})
 
 // syscallRead is like syscall.Read
 func syscallRead(mod api.Module, fd uint32, offset interface{}, p []byte) (n uint32, err error) {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	f, ok := fsc.LookupFile(fd)
 	if !ok {
@@ -300,7 +300,7 @@ func (jsfsWrite) invoke(ctx context.Context, mod api.Module, args ...interface{}
 
 // syscallWrite is like syscall.Write
 func syscallWrite(mod api.Module, fd uint32, offset interface{}, p []byte) (n uint32, err error) {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	var writer io.Writer
 	if f, ok := fsc.LookupFile(fd); !ok {
@@ -342,7 +342,7 @@ func (r *jsfsReaddir) invoke(ctx context.Context, mod api.Module, args ...interf
 }
 
 func syscallReaddir(_ context.Context, mod api.Module, name string) (*objectArray, error) {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	// don't allocate a file descriptor
 	f, errno := fsc.RootFS().OpenFile(name, os.O_RDONLY, 0)
@@ -374,7 +374,7 @@ func (m *jsfsMkdir) invoke(ctx context.Context, mod api.Module, args ...interfac
 	perm := custom.FromJsMode(goos.ValueToUint32(args[1]), m.proc.umask)
 	callback := args[2].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	root := fsc.RootFS()
 
 	var fd uint32
@@ -401,7 +401,7 @@ func (r *jsfsRmdir) invoke(ctx context.Context, mod api.Module, args ...interfac
 	path := util.ResolvePath(r.proc.cwd, args[0].(string))
 	callback := args[1].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	errno := fsc.RootFS().Rmdir(path)
 
 	return jsfsInvoke(ctx, mod, callback, errno)
@@ -420,7 +420,7 @@ func (r *jsfsRename) invoke(ctx context.Context, mod api.Module, args ...interfa
 	to := util.ResolvePath(cwd, args[1].(string))
 	callback := args[2].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	errno := fsc.RootFS().Rename(from, to)
 
 	return jsfsInvoke(ctx, mod, callback, errno)
@@ -437,7 +437,7 @@ func (u *jsfsUnlink) invoke(ctx context.Context, mod api.Module, args ...interfa
 	path := util.ResolvePath(u.proc.cwd, args[0].(string))
 	callback := args[1].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	errno := fsc.RootFS().Unlink(path)
 
 	return jsfsInvoke(ctx, mod, callback, errno)
@@ -456,7 +456,7 @@ func (u *jsfsUtimes) invoke(ctx context.Context, mod api.Module, args ...interfa
 	mtimeSec := toInt64(args[2])
 	callback := args[3].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	times := [2]syscall.Timespec{
 		syscall.NsecToTimespec(atimeSec * 1e9), syscall.NsecToTimespec(mtimeSec * 1e9),
 	}
@@ -477,7 +477,7 @@ func (c *jsfsChmod) invoke(ctx context.Context, mod api.Module, args ...interfac
 	mode := custom.FromJsMode(goos.ValueToUint32(args[1]), 0)
 	callback := args[2].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	errno := fsc.RootFS().Chmod(path, mode)
 
 	return jsfsInvoke(ctx, mod, callback, errno)
@@ -494,7 +494,7 @@ func (jsfsFchmod) invoke(ctx context.Context, mod api.Module, args ...interface{
 	callback := args[2].(funcWrapper)
 
 	// Check to see if the file descriptor is available
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	var errno syscall.Errno
 	if f, ok := fsc.LookupFile(fd); !ok {
 		errno = syscall.EBADF
@@ -520,7 +520,7 @@ func (c *jsfsChown) invoke(ctx context.Context, mod api.Module, args ...interfac
 	gid := goos.ValueToInt32(args[2])
 	callback := args[3].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	errno := fsc.RootFS().Chown(path, int(uid), int(gid))
 
 	return jsfsInvoke(ctx, mod, callback, errno)
@@ -538,7 +538,7 @@ func (jsfsFchown) invoke(ctx context.Context, mod api.Module, args ...interface{
 	callback := args[3].(funcWrapper)
 
 	// Check to see if the file descriptor is available
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	var errno syscall.Errno
 	if f, ok := fsc.LookupFile(fd); !ok {
 		errno = syscall.EBADF
@@ -562,7 +562,7 @@ func (l *jsfsLchown) invoke(ctx context.Context, mod api.Module, args ...interfa
 	gid := goos.ValueToUint32(args[2])
 	callback := args[3].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	errno := fsc.RootFS().Lchown(path, int(uid), int(gid))
 
 	return jsfsInvoke(ctx, mod, callback, errno)
@@ -580,7 +580,7 @@ func (t *jsfsTruncate) invoke(ctx context.Context, mod api.Module, args ...inter
 	length := toInt64(args[1])
 	callback := args[2].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	errno := fsc.RootFS().Truncate(path, length)
 
 	return jsfsInvoke(ctx, mod, callback, errno)
@@ -597,7 +597,7 @@ func (jsfsFtruncate) invoke(ctx context.Context, mod api.Module, args ...interfa
 	callback := args[2].(funcWrapper)
 
 	// Check to see if the file descriptor is available
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	var errno syscall.Errno
 	if f, ok := fsc.LookupFile(fd); !ok {
 		errno = syscall.EBADF
@@ -621,7 +621,7 @@ func (r *jsfsReadlink) invoke(ctx context.Context, mod api.Module, args ...inter
 	path := util.ResolvePath(r.proc.cwd, args[0].(string))
 	callback := args[1].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	dst, errno := fsc.RootFS().Readlink(path)
 
 	return callback.invoke(ctx, mod, goos.RefJsfs, maybeError(errno), dst) // note: error first
@@ -640,7 +640,7 @@ func (l *jsfsLink) invoke(ctx context.Context, mod api.Module, args ...interface
 	link := util.ResolvePath(cwd, args[1].(string))
 	callback := args[2].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	errno := fsc.RootFS().Link(path, link)
 
 	return jsfsInvoke(ctx, mod, callback, errno)
@@ -658,7 +658,7 @@ func (s *jsfsSymlink) invoke(ctx context.Context, mod api.Module, args ...interf
 	link := util.ResolvePath(s.proc.cwd, args[1].(string))
 	callback := args[2].(funcWrapper)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	errno := fsc.RootFS().Symlink(dst, link)
 
 	return jsfsInvoke(ctx, mod, callback, errno)
@@ -674,7 +674,7 @@ func (jsfsFsync) invoke(ctx context.Context, mod api.Module, args ...interface{}
 	callback := args[1].(funcWrapper)
 
 	// Check to see if the file descriptor is available
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	var errno syscall.Errno
 	if f, ok := fsc.LookupFile(fd); !ok {
 		errno = syscall.EBADF
diff --git a/internal/gojs/goarch/wasm.go b/internal/gojs/goarch/wasm.go
index 350b6806..dab0a333 100644
--- a/internal/gojs/goarch/wasm.go
+++ b/internal/gojs/goarch/wasm.go
@@ -152,7 +152,7 @@ func (s *stack) SetResultUint32(i int, v uint32) {
 func GetSP(mod api.Module) uint32 {
 	// Cheat by reading global[0] directly instead of through a function proxy.
 	// https://github.com/golang/go/blob/go1.20/src/runtime/rt0_js_wasm.s#L87-L90
-	return uint32(mod.(*wasm.CallContext).GlobalVal(0))
+	return uint32(mod.(*wasm.ModuleInstance).GlobalVal(0))
 }
 
 func NewFunc(name string, goFunc Func) *wasm.HostFunc {
diff --git a/internal/gojs/runtime.go b/internal/gojs/runtime.go
index b86e9ff9..68fc5f36 100644
--- a/internal/gojs/runtime.go
+++ b/internal/gojs/runtime.go
@@ -41,7 +41,7 @@ func wasmWrite(_ context.Context, mod api.Module, stack goarch.Stack) {
 	fd := stack.ParamUint32(0)
 	p := stack.ParamBytes(mod.Memory(), 1 /*, 2 */)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	if writer := internalsys.WriterForFile(fsc, fd); writer == nil {
 		panic(fmt.Errorf("fd %d invalid", fd))
 	} else if _, err := writer.Write(p); err != nil {
@@ -67,7 +67,7 @@ func resetMemoryDataView(context.Context, api.Module, goarch.Stack) {
 var Nanotime1 = goarch.NewFunc(custom.NameRuntimeNanotime1, nanotime1)
 
 func nanotime1(_ context.Context, mod api.Module, stack goarch.Stack) {
-	nsec := mod.(*wasm.CallContext).Sys.Nanotime()
+	nsec := mod.(*wasm.ModuleInstance).Sys.Nanotime()
 
 	stack.SetResultI64(0, nsec)
 }
@@ -78,7 +78,7 @@ func nanotime1(_ context.Context, mod api.Module, stack goarch.Stack) {
 var Walltime = goarch.NewFunc(custom.NameRuntimeWalltime, walltime)
 
 func walltime(_ context.Context, mod api.Module, stack goarch.Stack) {
-	sec, nsec := mod.(*wasm.CallContext).Sys.Walltime()
+	sec, nsec := mod.(*wasm.ModuleInstance).Sys.Walltime()
 
 	stack.SetResultI64(0, sec)
 	stack.SetResultI32(1, nsec)
@@ -144,7 +144,7 @@ var GetRandomData = goarch.NewFunc(custom.NameRuntimeGetRandomData, getRandomDat
 func getRandomData(_ context.Context, mod api.Module, stack goarch.Stack) {
 	r := stack.ParamBytes(mod.Memory(), 0 /*, 1 */)
 
-	randSource := mod.(*wasm.CallContext).Sys.RandSource()
+	randSource := mod.(*wasm.ModuleInstance).Sys.RandSource()
 
 	bufLen := len(r)
 	if n, err := randSource.Read(r); err != nil {
diff --git a/internal/wasm/engine.go b/internal/wasm/engine.go
index c536922a..a34858af 100644
--- a/internal/wasm/engine.go
+++ b/internal/wasm/engine.go
@@ -40,7 +40,7 @@ type ModuleEngine interface {
 	Name() string
 
 	// NewCallEngine returns a CallEngine for the given FunctionInstance.
-	NewCallEngine(callCtx *CallContext, f *FunctionInstance) (CallEngine, error)
+	NewCallEngine(m *ModuleInstance, f *FunctionInstance) (CallEngine, error)
 
 	// LookupFunction returns the index of the function in the function table.
 	LookupFunction(t *TableInstance, typeId FunctionTypeID, tableOffset Index) (Index, error)
@@ -54,5 +54,5 @@ type ModuleEngine interface {
 // internally, and shouldn't be used concurrently.
 type CallEngine interface {
 	// Call invokes a function instance f with given parameters.
-	Call(ctx context.Context, m *CallContext, params []uint64) (results []uint64, err error)
+	Call(ctx context.Context, m *ModuleInstance, params []uint64) (results []uint64, err error)
 }
diff --git a/internal/wasm/module.go b/internal/wasm/module.go
index c55e93b0..7b5cf376 100644
--- a/internal/wasm/module.go
+++ b/internal/wasm/module.go
@@ -637,8 +637,8 @@ func paramNames(localNames IndirectNameMap, funcIdx uint32, paramLen int) []stri
 func (m *ModuleInstance) buildMemory(module *Module) {
 	memSec := module.MemorySection
 	if memSec != nil {
-		m.Memory = NewMemoryInstance(memSec)
-		m.Memory.definition = &module.MemoryDefinitionSection[0]
+		m.MemoryInstance = NewMemoryInstance(memSec)
+		m.MemoryInstance.definition = &module.MemoryDefinitionSection[0]
 	}
 }
 
diff --git a/internal/wasm/call_context.go b/internal/wasm/module_instance.go
similarity index 55%
rename from internal/wasm/call_context.go
rename to internal/wasm/module_instance.go
index e868dd39..ee68d2d1 100644
--- a/internal/wasm/call_context.go
+++ b/internal/wasm/module_instance.go
@@ -7,59 +7,11 @@ import (
 	"sync/atomic"
 
 	"github.com/tetratelabs/wazero/api"
-	internalsys "github.com/tetratelabs/wazero/internal/sys"
 	"github.com/tetratelabs/wazero/sys"
 )
 
-// compile time check to ensure CallContext implements api.Module
-var _ api.Module = &CallContext{}
-
-func NewCallContext(s *Store, instance *ModuleInstance, sys *internalsys.Context) *CallContext {
-	return &CallContext{memory: instance.Memory, module: instance, s: s, Sys: sys, Closed: 0}
-}
-
-// CallContext is a function call context bound to a module. This is important as one module's functions can call
-// imported functions, but all need to effect the same memory.
-//
-// Note: This does not include the context.Context because doing so risks caching the wrong context which can break
-// functionality like trace propagation.
-// Note: this also implements api.Module in order to simplify usage as a host function parameter.
-type CallContext struct {
-	// TODO: We've never found a great name for this. It is only used for function calls, hence CallContext, but it
-	// moves on a different axis than, for example, the context.Context. context.Context is the same root for the whole
-	// call stack, where the CallContext can change depending on where memory is defined and who defines the calling
-	// function. When we rename this again, we should try to capture as many key points possible on the docs.
-
-	module *ModuleInstance
-	// memory is returned by Memory and overridden WithMemory
-	memory api.Memory
-	s      *Store
-
-	// Sys is exposed for use in special imports such as WASI, assemblyscript
-	// and gojs.
-	//
-	// # Notes
-	//
-	//   - This is a part of CallContext so that scope and Close is coherent.
-	//   - This is not exposed outside this repository (as a host function
-	//	  parameter) because we haven't thought through capabilities based
-	//	  security implications.
-	Sys *internalsys.Context
-
-	// closed is the pointer used both to guard moduleEngine.CloseWithExitCode and to store the exit code.
-	//
-	// The update value is closedType + exitCode << 32. This ensures an exit code of zero isn't mistaken for never closed.
-	//
-	// Note: Exclusively reading and updating this with atomics guarantees cross-goroutine observations.
-	// See /RATIONALE.md
-	Closed uint64
-
-	// CodeCloser is non-nil when the code should be closed after this module.
-	CodeCloser api.Closer
-}
-
 // FailIfClosed returns a sys.ExitError if CloseWithExitCode was called.
-func (m *CallContext) FailIfClosed() (err error) {
+func (m *ModuleInstance) FailIfClosed() (err error) {
 	if closed := atomic.LoadUint64(&m.Closed); closed != 0 {
 		return sys.NewExitError(uint32(closed >> 32)) // Unpack the high order bits as the exit code.
 	}
@@ -71,7 +23,7 @@ func (m *CallContext) FailIfClosed() (err error) {
 // one of the conditions, it sets the appropriate exit code.
 //
 // Callers of this function must invoke the returned context.CancelFunc to release the spawned Goroutine.
-func (m *CallContext) CloseModuleOnCanceledOrTimeout(ctx context.Context) context.CancelFunc {
+func (m *ModuleInstance) CloseModuleOnCanceledOrTimeout(ctx context.Context) context.CancelFunc {
 	// Creating an empty channel in this case is a bit more efficient than
 	// creating a context.Context and canceling it with the same effect. We
 	// really just need to be notified when to stop listening to the users
@@ -83,7 +35,7 @@ func (m *CallContext) CloseModuleOnCanceledOrTimeout(ctx context.Context) contex
 }
 
 // closeModuleOnCanceledOrTimeout is extracted from CloseModuleOnCanceledOrTimeout for testing.
-func (m *CallContext) closeModuleOnCanceledOrTimeout(ctx context.Context, cancelChan <-chan struct{}) {
+func (m *ModuleInstance) closeModuleOnCanceledOrTimeout(ctx context.Context, cancelChan <-chan struct{}) {
 	select {
 	case <-ctx.Done():
 		select {
@@ -103,7 +55,7 @@ func (m *CallContext) closeModuleOnCanceledOrTimeout(ctx context.Context, cancel
 // error reported by the context.
 //
 // If the context's error is unknown or nil, the module does not close.
-func (m *CallContext) CloseWithCtxErr(ctx context.Context) {
+func (m *ModuleInstance) CloseWithCtxErr(ctx context.Context) {
 	switch {
 	case errors.Is(ctx.Err(), context.Canceled):
 		// TODO: figure out how to report error here.
@@ -115,45 +67,45 @@ func (m *CallContext) CloseWithCtxErr(ctx context.Context) {
 }
 
 // Name implements the same method as documented on api.Module
-func (m *CallContext) Name() string {
-	return m.module.Name
+func (m *ModuleInstance) Name() string {
+	return m.ModuleName
 }
 
 // String implements the same method as documented on api.Module
-func (m *CallContext) String() string {
+func (m *ModuleInstance) String() string {
 	return fmt.Sprintf("Module[%s]", m.Name())
 }
 
 // Close implements the same method as documented on api.Module.
-func (m *CallContext) Close(ctx context.Context) (err error) {
+func (m *ModuleInstance) Close(ctx context.Context) (err error) {
 	return m.CloseWithExitCode(ctx, 0)
 }
 
 // CloseWithExitCode implements the same method as documented on api.Module.
-func (m *CallContext) CloseWithExitCode(ctx context.Context, exitCode uint32) (err error) {
+func (m *ModuleInstance) CloseWithExitCode(ctx context.Context, exitCode uint32) (err error) {
 	if !m.setExitCode(exitCode) {
 		return nil // not an error to have already closed
 	}
-	_ = m.s.deleteModule(m.module.moduleListNode)
+	_ = m.s.deleteModule(m.moduleListNode)
 	return m.ensureResourcesClosed(ctx)
 }
 
 // closeWithExitCode is the same as CloseWithExitCode besides this doesn't delete it from Store.moduleList.
-func (m *CallContext) closeWithExitCode(ctx context.Context, exitCode uint32) (err error) {
+func (m *ModuleInstance) closeWithExitCode(ctx context.Context, exitCode uint32) (err error) {
 	if !m.setExitCode(exitCode) {
 		return nil // not an error to have already closed
 	}
 	return m.ensureResourcesClosed(ctx)
 }
 
-func (m *CallContext) setExitCode(exitCode uint32) bool {
+func (m *ModuleInstance) setExitCode(exitCode uint32) bool {
 	closed := uint64(1) + uint64(exitCode)<<32 // Store exitCode as high-order bits.
 	return atomic.CompareAndSwapUint64(&m.Closed, 0, closed)
 }
 
 // ensureResourcesClosed ensures that resources assigned to CallContext is released.
 // Multiple calls to this function is safe.
-func (m *CallContext) ensureResourcesClosed(ctx context.Context) (err error) {
+func (m *ModuleInstance) ensureResourcesClosed(ctx context.Context) (err error) {
 	if sysCtx := m.Sys; sysCtx != nil { // nil if from HostModuleBuilder
 		if err = sysCtx.FS().Close(ctx); err != nil {
 			return err
@@ -172,27 +124,27 @@ func (m *CallContext) ensureResourcesClosed(ctx context.Context) (err error) {
 }
 
 // Memory implements the same method as documented on api.Module.
-func (m *CallContext) Memory() api.Memory {
-	return m.module.Memory
+func (m *ModuleInstance) Memory() api.Memory {
+	return m.MemoryInstance
 }
 
 // ExportedMemory implements the same method as documented on api.Module.
-func (m *CallContext) ExportedMemory(name string) api.Memory {
-	_, err := m.module.getExport(name, ExternTypeMemory)
+func (m *ModuleInstance) ExportedMemory(name string) api.Memory {
+	_, err := m.getExport(name, ExternTypeMemory)
 	if err != nil {
 		return nil
 	}
 	// We Assume that we have at most one memory.
-	return m.memory
+	return m.MemoryInstance
 }
 
 // ExportedMemoryDefinitions implements the same method as documented on
 // api.Module.
-func (m *CallContext) ExportedMemoryDefinitions() map[string]api.MemoryDefinition {
+func (m *ModuleInstance) ExportedMemoryDefinitions() map[string]api.MemoryDefinition {
 	// Special case as we currently only support one memory.
-	if mem := m.module.Memory; mem != nil {
+	if mem := m.MemoryInstance; mem != nil {
 		// Now, find out if it is exported
-		for name, exp := range m.module.Exports {
+		for name, exp := range m.Exports {
 			if exp.Type == ExternTypeMemory {
 				return map[string]api.MemoryDefinition{name: mem.definition}
 			}
@@ -202,40 +154,35 @@ func (m *CallContext) ExportedMemoryDefinitions() map[string]api.MemoryDefinitio
 }
 
 // ExportedFunction implements the same method as documented on api.Module.
-func (m *CallContext) ExportedFunction(name string) api.Function {
-	exp, err := m.module.getExport(name, ExternTypeFunc)
+func (m *ModuleInstance) ExportedFunction(name string) api.Function {
+	exp, err := m.getExport(name, ExternTypeFunc)
 	if err != nil {
 		return nil
 	}
 
-	return m.function(&m.module.Functions[exp.Index])
+	return m.function(&m.Functions[exp.Index])
 }
 
 // ExportedFunctionDefinitions implements the same method as documented on
 // api.Module.
-func (m *CallContext) ExportedFunctionDefinitions() map[string]api.FunctionDefinition {
+func (m *ModuleInstance) ExportedFunctionDefinitions() map[string]api.FunctionDefinition {
 	result := map[string]api.FunctionDefinition{}
-	for name, exp := range m.module.Exports {
+	for name, exp := range m.Exports {
 		if exp.Type == ExternTypeFunc {
-			result[name] = m.module.Functions[exp.Index].Definition
+			result[name] = m.Functions[exp.Index].Definition
 		}
 	}
 	return result
 }
 
-// Module is exposed for emscripten.
-func (m *CallContext) Module() *ModuleInstance {
-	return m.module
-}
-
-func (m *CallContext) Function(funcIdx Index) api.Function {
-	if uint32(len(m.module.Functions)) < funcIdx {
+func (m *ModuleInstance) Function(funcIdx Index) api.Function {
+	if uint32(len(m.Functions)) < funcIdx {
 		return nil
 	}
-	return m.function(&m.module.Functions[funcIdx])
+	return m.function(&m.Functions[funcIdx])
 }
 
-func (m *CallContext) function(f *FunctionInstance) api.Function {
+func (m *ModuleInstance) function(f *FunctionInstance) api.Function {
 	ce, err := f.Module.Engine.NewCallEngine(m, f)
 	if err != nil {
 		return nil
@@ -257,21 +204,21 @@ func (f *function) Definition() api.FunctionDefinition {
 
 // Call implements the same method as documented on api.Function.
 func (f *function) Call(ctx context.Context, params ...uint64) (ret []uint64, err error) {
-	return f.ce.Call(ctx, f.fi.Module.CallCtx, params)
+	return f.ce.Call(ctx, f.fi.Module, params)
 }
 
 // GlobalVal is an internal hack to get the lower 64 bits of a global.
-func (m *CallContext) GlobalVal(idx Index) uint64 {
-	return m.module.Globals[idx].Val
+func (m *ModuleInstance) GlobalVal(idx Index) uint64 {
+	return m.Globals[idx].Val
 }
 
 // ExportedGlobal implements the same method as documented on api.Module.
-func (m *CallContext) ExportedGlobal(name string) api.Global {
-	exp, err := m.module.getExport(name, ExternTypeGlobal)
+func (m *ModuleInstance) ExportedGlobal(name string) api.Global {
+	exp, err := m.getExport(name, ExternTypeGlobal)
 	if err != nil {
 		return nil
 	}
-	g := m.module.Globals[exp.Index]
+	g := m.Globals[exp.Index]
 	if g.Type.Mutable {
 		return &mutableGlobal{g}
 	}
diff --git a/internal/wasm/store.go b/internal/wasm/store.go
index 59e04c56..2ca03ce3 100644
--- a/internal/wasm/store.go
+++ b/internal/wasm/store.go
@@ -55,17 +55,15 @@ type (
 	// to the instances, rather than "addresses" (i.e. index to Store.Functions, Globals, etc) for convenience.
 	//
 	// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#syntax-moduleinst
+	//
+	// This implements api.Module.
 	ModuleInstance struct {
-		Name      string
-		Exports   map[string]*Export
-		Functions []FunctionInstance
-		Globals   []*GlobalInstance
-		// Memory is set when Module.MemorySection had a memory, regardless of whether it was exported.
-		Memory *MemoryInstance
-		Tables []*TableInstance
-
-		// CallCtx holds default function call context from this function instance.
-		CallCtx *CallContext
+		ModuleName     string
+		Exports        map[string]*Export
+		Functions      []FunctionInstance
+		Globals        []*GlobalInstance
+		MemoryInstance *MemoryInstance
+		Tables         []*TableInstance
 
 		// Engine implements function calls for this module.
 		Engine ModuleEngine
@@ -85,6 +83,30 @@ type (
 		ElementInstances []ElementInstance
 
 		moduleListNode *moduleListNode
+
+		// Sys is exposed for use in special imports such as WASI, assemblyscript
+		// and gojs.
+		//
+		// # Notes
+		//
+		//   - This is a part of CallContext so that scope and Close is coherent.
+		//   - This is not exposed outside this repository (as a host function
+		//	  parameter) because we haven't thought through capabilities based
+		//	  security implications.
+		Sys *internalsys.Context
+
+		// closed is the pointer used both to guard moduleEngine.CloseWithExitCode and to store the exit code.
+		//
+		// The update value is closedType + exitCode << 32. This ensures an exit code of zero isn't mistaken for never closed.
+		//
+		// Note: Exclusively reading and updating this with atomics guarantees cross-goroutine observations.
+		// See /RATIONALE.md
+		Closed uint64
+
+		// CodeCloser is non-nil when the code should be closed after this module.
+		CodeCloser api.Closer
+
+		s *Store
 	}
 
 	// DataInstance holds bytes corresponding to the data segment in a module.
@@ -195,7 +217,7 @@ func (m *ModuleInstance) validateData(data []DataSegment) (err error) {
 		if !d.IsPassive() {
 			offset := int(executeConstExpressionI32(m.Globals, &d.OffsetExpression))
 			ceil := offset + len(d.Init)
-			if offset < 0 || ceil > len(m.Memory.Buffer) {
+			if offset < 0 || ceil > len(m.MemoryInstance.Buffer) {
 				return fmt.Errorf("%s[%d]: out of bounds memory access", SectionIDName(SectionIDData), i)
 			}
 		}
@@ -213,10 +235,10 @@ func (m *ModuleInstance) applyData(data []DataSegment) error {
 		m.DataInstances[i] = d.Init
 		if !d.IsPassive() {
 			offset := executeConstExpressionI32(m.Globals, &d.OffsetExpression)
-			if offset < 0 || int(offset)+len(d.Init) > len(m.Memory.Buffer) {
+			if offset < 0 || int(offset)+len(d.Init) > len(m.MemoryInstance.Buffer) {
 				return fmt.Errorf("%s[%d]: out of bounds memory access", SectionIDName(SectionIDData), i)
 			}
-			copy(m.Memory.Buffer[offset:], d.Init)
+			copy(m.MemoryInstance.Buffer[offset:], d.Init)
 		}
 	}
 	return nil
@@ -226,10 +248,10 @@ func (m *ModuleInstance) applyData(data []DataSegment) error {
 func (m *ModuleInstance) getExport(name string, et ExternType) (*Export, error) {
 	exp, ok := m.Exports[name]
 	if !ok {
-		return nil, fmt.Errorf("%q is not exported in module %q", name, m.Name)
+		return nil, fmt.Errorf("%q is not exported in module %q", name, m.ModuleName)
 	}
 	if exp.Type != et {
-		return nil, fmt.Errorf("export %q in module %q is a %s, not a %s", name, m.Name, ExternTypeName(exp.Type), ExternTypeName(et))
+		return nil, fmt.Errorf("export %q in module %q is a %s, not a %s", name, m.ModuleName, ExternTypeName(exp.Type), ExternTypeName(et))
 	}
 	return exp, nil
 }
@@ -262,7 +284,7 @@ func (s *Store) Instantiate(
 	name string,
 	sys *internalsys.Context,
 	typeIDs []FunctionTypeID,
-) (*CallContext, error) {
+) (*ModuleInstance, error) {
 	// Collect any imported modules to avoid locking the store too long.
 	importedModuleNames := map[string]struct{}{}
 	for i := range module.ImportSection {
@@ -288,23 +310,23 @@ func (s *Store) Instantiate(
 	}
 
 	// Instantiate the module and add it to the store so that other modules can import it.
-	callCtx, err := s.instantiate(ctx, module, name, sys, importedModules, typeIDs)
+	m, err := s.instantiate(ctx, module, name, sys, importedModules, typeIDs)
 	if err != nil {
 		_ = s.deleteModule(listNode)
 		return nil, err
 	}
 
-	callCtx.module.moduleListNode = listNode
+	m.moduleListNode = listNode
 
 	if name != "" {
 		// Now that the instantiation is complete without error, add it.
 		// This makes the module visible for import, and ensures it is closed when the store is.
-		if err := s.setModule(callCtx.module); err != nil {
-			callCtx.Close(ctx)
+		if err := s.setModule(m); err != nil {
+			m.Close(ctx)
 			return nil, err
 		}
 	}
-	return callCtx, nil
+	return m, nil
 }
 
 func (s *Store) instantiate(
@@ -314,8 +336,8 @@ func (s *Store) instantiate(
 	sysCtx *internalsys.Context,
 	modules map[string]*ModuleInstance,
 	typeIDs []FunctionTypeID,
-) (*CallContext, error) {
-	m := &ModuleInstance{Name: name, TypeIDs: typeIDs}
+) (*ModuleInstance, error) {
+	m := &ModuleInstance{ModuleName: name, TypeIDs: typeIDs, Sys: sysCtx, s: s}
 
 	m.Functions = make([]FunctionInstance, int(module.ImportFunctionCount)+len(module.FunctionSection))
 	m.Tables = make([]*TableInstance, int(module.ImportTableCount)+len(module.TableSection))
@@ -363,22 +385,18 @@ func (s *Store) instantiate(
 
 	m.applyElements(module.validatedActiveElementSegments)
 
-	// Compile the default context for calls to this module.
-	callCtx := NewCallContext(s, m, sysCtx)
-	m.CallCtx = callCtx
-
 	// Execute the start function.
 	if module.StartSection != nil {
 		funcIdx := *module.StartSection
 		f := &m.Functions[funcIdx]
 
-		ce, err := f.Module.Engine.NewCallEngine(callCtx, f)
+		ce, err := f.Module.Engine.NewCallEngine(m, f)
 		if err != nil {
 			return nil, fmt.Errorf("create call engine for start function[%s]: %v",
 				module.funcDesc(SectionIDFunction, funcIdx), err)
 		}
 
-		_, err = ce.Call(ctx, callCtx, nil)
+		_, err = ce.Call(ctx, m, nil)
 		if exitErr, ok := err.(*sys.ExitError); ok { // Don't wrap an exit error!
 			return nil, exitErr
 		} else if err != nil {
@@ -386,7 +404,7 @@ func (s *Store) instantiate(
 		}
 	}
 
-	return m.CallCtx, nil
+	return m, nil
 }
 
 func (m *ModuleInstance) resolveImports(module *Module, importedModules map[string]*ModuleInstance) (err error) {
@@ -445,7 +463,7 @@ func (m *ModuleInstance) resolveImports(module *Module, importedModules map[stri
 			tables++
 		case ExternTypeMemory:
 			expected := i.DescMem
-			importedMemory := importedModule.Memory
+			importedMemory := importedModule.MemoryInstance
 
 			if expected.Min > memoryBytesNumToPages(uint64(len(importedMemory.Buffer))) {
 				err = errorMinSizeMismatch(i, idx, expected.Min, importedMemory.Min)
@@ -456,7 +474,7 @@ func (m *ModuleInstance) resolveImports(module *Module, importedModules map[stri
 				err = errorMaxSizeMismatch(i, idx, expected.Max, importedMemory.Max)
 				return
 			}
-			m.Memory = importedMemory
+			m.MemoryInstance = importedMemory
 		case ExternTypeGlobal:
 			expected := i.DescGlobal
 			importedGlobal := importedModule.Globals[imported.Index]
@@ -641,7 +659,7 @@ func (s *Store) CloseWithExitCode(ctx context.Context, exitCode uint32) (err err
 	for node := s.moduleList; node != nil; node = node.next {
 		// If closing this module errs, proceed anyway to close the others.
 		if m := node.module; m != nil {
-			if e := m.CallCtx.closeWithExitCode(ctx, exitCode); e != nil && err == nil {
+			if e := m.closeWithExitCode(ctx, exitCode); e != nil && err == nil {
 				// TODO: use multiple errors handling in Go 1.20.
 				err = e // first error
 			}
diff --git a/internal/wasm/store_module_list.go b/internal/wasm/store_module_list.go
index 7466af8d..3291198a 100644
--- a/internal/wasm/store_module_list.go
+++ b/internal/wasm/store_module_list.go
@@ -18,9 +18,9 @@ func (s *Store) setModule(m *ModuleInstance) error {
 	s.mux.Lock()
 	defer s.mux.Unlock()
 
-	node, ok := s.nameToNode[m.Name]
+	node, ok := s.nameToNode[m.ModuleName]
 	if !ok {
-		return fmt.Errorf("module[%s] name has not been required", m.Name)
+		return fmt.Errorf("module[%s] name has not been required", m.ModuleName)
 	}
 
 	node.module = m
@@ -143,5 +143,5 @@ func (s *Store) Module(moduleName string) api.Module {
 	if err != nil {
 		return nil
 	}
-	return m.CallCtx
+	return m
 }
diff --git a/runtime.go b/runtime.go
index 47895061..34bc51f7 100644
--- a/runtime.go
+++ b/runtime.go
@@ -313,7 +313,7 @@ func (r *runtime) InstantiateModule(
 
 	// Attach the code closer so that anything afterwards closes the compiled code when closing the module.
 	if code.closeWithModule {
-		mod.(*wasm.CallContext).CodeCloser = code
+		mod.(*wasm.ModuleInstance).CodeCloser = code
 	}
 
 	// Now, invoke any start functions, failing at first error.


Test patch:
diff --git a/imports/wasi_snapshot_preview1/fs_test.go b/imports/wasi_snapshot_preview1/fs_test.go
index fd38dbbc..ad1e494b 100644
--- a/imports/wasi_snapshot_preview1/fs_test.go
+++ b/imports/wasi_snapshot_preview1/fs_test.go
@@ -53,7 +53,7 @@ func Test_fdAllocate(t *testing.T) {
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFSConfig(
 		wazero.NewFSConfig().WithDirMount(tmpDir, "/"),
 	))
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	preopen := fsc.RootFS()
 	defer r.Close(testCtx)
 
@@ -132,7 +132,7 @@ func Test_fdClose(t *testing.T) {
 	defer r.Close(testCtx)
 
 	// open both paths without using WASI
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	preopen := fsc.RootFS()
 
 	fdToClose, errno := fsc.OpenFile(preopen, path1, os.O_RDONLY, 0)
@@ -225,7 +225,7 @@ func Test_fdFdstatGet(t *testing.T) {
 	memorySize := mod.Memory().Size()
 
 	// open both paths without using WASI
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	preopen := fsc.RootFS()
 
 	fileFD, errno := fsc.OpenFile(preopen, file, os.O_RDONLY, 0)
@@ -374,7 +374,7 @@ func Test_fdFdstatSetFlags(t *testing.T) {
 
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFSConfig(wazero.NewFSConfig().
 		WithDirMount(tmpDir, "/")))
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	preopen := fsc.RootFS()
 	defer r.Close(testCtx)
 
@@ -470,7 +470,7 @@ func Test_fdFilestatGet(t *testing.T) {
 	memorySize := mod.Memory().Size()
 
 	// open both paths without using WASI
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	preopen := fsc.RootFS()
 
 	fileFD, errno := fsc.OpenFile(preopen, file, os.O_RDONLY, 0)
@@ -839,7 +839,7 @@ func Test_fdFilestatSetTimes(t *testing.T) {
 			mod, fd, log, r := requireOpenFile(t, tmpDir, filepath, []byte("anything"), false)
 			defer r.Close(testCtx)
 
-			sys := mod.(*wasm.CallContext).Sys
+			sys := mod.(*wasm.ModuleInstance).Sys
 			fsc := sys.FS()
 
 			paramFd := fd
@@ -1882,7 +1882,7 @@ func Test_fdReaddir(t *testing.T) {
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFS(fstest.FS))
 	defer r.Close(testCtx)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	preopen := fsc.RootFS()
 
 	fd, errno := fsc.OpenFile(preopen, "dir", os.O_RDONLY, 0)
@@ -2188,7 +2188,7 @@ func Test_fdReaddir_Rewind(t *testing.T) {
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFS(fstest.FS))
 	defer r.Close(testCtx)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 
 	fd, errno := fsc.OpenFile(fsc.RootFS(), "dir", os.O_RDONLY, 0)
 	require.Zero(t, errno)
@@ -2251,7 +2251,7 @@ func Test_fdReaddir_Errors(t *testing.T) {
 	defer r.Close(testCtx)
 	memLen := mod.Memory().Size()
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	preopen := fsc.RootFS()
 
 	fileFD, errno := fsc.OpenFile(preopen, "animals.txt", os.O_RDONLY, 0)
@@ -2450,7 +2450,7 @@ func Test_fdRenumber(t *testing.T) {
 			mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFS(fstest.FS))
 			defer r.Close(testCtx)
 
-			fsc := mod.(*wasm.CallContext).Sys.FS()
+			fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 			preopen := fsc.RootFS()
 
 			// Sanity check of the file descriptor assignment.
@@ -2537,7 +2537,7 @@ func Test_fdSeek(t *testing.T) {
 			maskMemory(t, mod, len(tc.expectedMemory))
 
 			// Since we initialized this file, we know it is a seeker (because it is a MapFile)
-			fsc := mod.(*wasm.CallContext).Sys.FS()
+			fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 			f, ok := fsc.LookupFile(fd)
 			require.True(t, ok)
 			seeker := f.File.(io.Seeker)
@@ -2565,7 +2565,7 @@ func Test_fdSeek_Errors(t *testing.T) {
 	mod, fileFD, log, r := requireOpenFile(t, t.TempDir(), "test_path", []byte("wazero"), false)
 	defer r.Close(testCtx)
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	require.Zero(t, fsc.RootFS().Mkdir("dir", 0o0700))
 	dirFD := requireOpenFD(t, mod, "dir")
 
@@ -2695,7 +2695,7 @@ func Test_fdTell(t *testing.T) {
 	maskMemory(t, mod, len(expectedMemory))
 
 	// Since we initialized this file, we know it is a seeker (because it is a MapFile)
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	f, ok := fsc.LookupFile(fd)
 	require.True(t, ok)
 	seeker := f.File.(io.Seeker)
@@ -3548,7 +3548,7 @@ func Test_pathFilestatSetTimes(t *testing.T) {
 			path := 0
 			pathLen := uint32(len(pathName))
 
-			sys := mod.(*wasm.CallContext).Sys
+			sys := mod.(*wasm.ModuleInstance).Sys
 			fsc := sys.FS()
 
 			var oldSt platform.Stat_t
@@ -3604,7 +3604,7 @@ func Test_pathLink(t *testing.T) {
 	newDirName := "my-new-dir/sub"
 	newDirPath := joinPath(tmpDir, newDirName)
 	require.NoError(t, os.MkdirAll(joinPath(tmpDir, newDirName), 0o700))
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	newFd, errno := fsc.OpenFile(fsc.RootFS(), newDirName, 0o600, 0)
 	require.Zero(t, errno)
 
@@ -3949,14 +3949,14 @@ func Test_pathOpen(t *testing.T) {
 				require.True(t, ok)
 				require.Equal(t, expectedOpenedFd, openedFd)
 
-				tc.expected(t, mod.(*wasm.CallContext).Sys.FS())
+				tc.expected(t, mod.(*wasm.ModuleInstance).Sys.FS())
 			}
 		})
 	}
 }
 
 func requireOpenFD(t *testing.T, mod api.Module, path string) uint32 {
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	preopen := fsc.RootFS()
 
 	fd, errno := fsc.OpenFile(preopen, path, os.O_RDONLY, 0)
@@ -4892,7 +4892,7 @@ func requireOpenFile(t *testing.T, tmpDir string, pathName string, data []byte,
 	}
 
 	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFSConfig(fsConfig))
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	preopen := fsc.RootFS()
 
 	fd, errno := fsc.OpenFile(preopen, pathName, oflags, 0)
@@ -4915,7 +4915,7 @@ func Test_fdReaddir_dotEntriesHaveRealInodes(t *testing.T) {
 
 	mem := mod.Memory()
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	preopen := fsc.RootFS()
 
 	readDirTarget := "dir"
@@ -4973,7 +4973,7 @@ func Test_fdReaddir_opened_file_written(t *testing.T) {
 
 	mem := mod.Memory()
 
-	fsc := mod.(*wasm.CallContext).Sys.FS()
+	fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 	preopen := fsc.RootFS()
 
 	dirName := "dir"
diff --git a/imports/wasi_snapshot_preview1/wasi_bench_test.go b/imports/wasi_snapshot_preview1/wasi_bench_test.go
index 0f36d1dc..64081e0d 100644
--- a/imports/wasi_snapshot_preview1/wasi_bench_test.go
+++ b/imports/wasi_snapshot_preview1/wasi_bench_test.go
@@ -191,7 +191,7 @@ func Benchmark_fdReaddir(b *testing.B) {
 			fn := mod.ExportedFunction(wasip1.FdReaddirName)
 
 			// Open the root directory as a file-descriptor.
-			fsc := mod.(*wasm.CallContext).Sys.FS()
+			fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 			fd, errno := fsc.OpenFile(fsc.RootFS(), ".", os.O_RDONLY, 0)
 			if errno != 0 {
 				b.Fatal(errno)
@@ -317,7 +317,7 @@ func Benchmark_pathFilestat(b *testing.B) {
 			// under a pre-determined directory: zig
 			fd := sys.FdPreopen
 			if bc.fd != sys.FdPreopen {
-				fsc := mod.(*wasm.CallContext).Sys.FS()
+				fsc := mod.(*wasm.ModuleInstance).Sys.FS()
 				fd, errno := fsc.OpenFile(fsc.RootFS(), "zig", os.O_RDONLY, 0)
 				if errno != 0 {
 					b.Fatal(errno)
diff --git a/internal/engine/compiler/compiler_initialization_test.go b/internal/engine/compiler/compiler_initialization_test.go
index da580f1f..e11c649f 100644
--- a/internal/engine/compiler/compiler_initialization_test.go
+++ b/internal/engine/compiler/compiler_initialization_test.go
@@ -19,8 +19,8 @@ func TestCompiler_compileModuleContextInitialization(t *testing.T) {
 		{
 			name: "no nil",
 			moduleInstance: &wasm.ModuleInstance{
-				Globals: []*wasm.GlobalInstance{{Val: 100}},
-				Memory:  &wasm.MemoryInstance{Buffer: make([]byte, 10)},
+				Globals:        []*wasm.GlobalInstance{{Val: 100}},
+				MemoryInstance: &wasm.MemoryInstance{Buffer: make([]byte, 10)},
 				Tables: []*wasm.TableInstance{
 					{References: make([]wasm.Reference, 20)},
 					{References: make([]wasm.Reference, 10)},
@@ -34,7 +34,7 @@ func TestCompiler_compileModuleContextInitialization(t *testing.T) {
 			name: "element instances nil",
 			moduleInstance: &wasm.ModuleInstance{
 				Globals:          []*wasm.GlobalInstance{{Val: 100}},
-				Memory:           &wasm.MemoryInstance{Buffer: make([]byte, 10)},
+				MemoryInstance:   &wasm.MemoryInstance{Buffer: make([]byte, 10)},
 				Tables:           []*wasm.TableInstance{{References: make([]wasm.Reference, 20)}},
 				TypeIDs:          make([]wasm.FunctionTypeID, 10),
 				DataInstances:    make([][]byte, 10),
@@ -45,7 +45,7 @@ func TestCompiler_compileModuleContextInitialization(t *testing.T) {
 			name: "data instances nil",
 			moduleInstance: &wasm.ModuleInstance{
 				Globals:          []*wasm.GlobalInstance{{Val: 100}},
-				Memory:           &wasm.MemoryInstance{Buffer: make([]byte, 10)},
+				MemoryInstance:   &wasm.MemoryInstance{Buffer: make([]byte, 10)},
 				Tables:           []*wasm.TableInstance{{References: make([]wasm.Reference, 20)}},
 				TypeIDs:          make([]wasm.FunctionTypeID, 10),
 				DataInstances:    nil,
@@ -55,7 +55,7 @@ func TestCompiler_compileModuleContextInitialization(t *testing.T) {
 		{
 			name: "globals nil",
 			moduleInstance: &wasm.ModuleInstance{
-				Memory:           &wasm.MemoryInstance{Buffer: make([]byte, 10)},
+				MemoryInstance:   &wasm.MemoryInstance{Buffer: make([]byte, 10)},
 				Tables:           []*wasm.TableInstance{{References: make([]wasm.Reference, 20)}},
 				TypeIDs:          make([]wasm.FunctionTypeID, 10),
 				DataInstances:    make([][]byte, 10),
@@ -75,7 +75,7 @@ func TestCompiler_compileModuleContextInitialization(t *testing.T) {
 		{
 			name: "table nil",
 			moduleInstance: &wasm.ModuleInstance{
-				Memory:           &wasm.MemoryInstance{Buffer: make([]byte, 10)},
+				MemoryInstance:   &wasm.MemoryInstance{Buffer: make([]byte, 10)},
 				Tables:           []*wasm.TableInstance{{References: nil}},
 				TypeIDs:          make([]wasm.FunctionTypeID, 10),
 				DataInstances:    make([][]byte, 10),
@@ -94,7 +94,7 @@ func TestCompiler_compileModuleContextInitialization(t *testing.T) {
 		{
 			name: "memory zero length",
 			moduleInstance: &wasm.ModuleInstance{
-				Memory: &wasm.MemoryInstance{Buffer: make([]byte, 0)},
+				MemoryInstance: &wasm.MemoryInstance{Buffer: make([]byte, 0)},
 			},
 		},
 		{
@@ -111,7 +111,7 @@ func TestCompiler_compileModuleContextInitialization(t *testing.T) {
 			ce := env.callEngine()
 
 			ir := &wazeroir.CompilationResult{
-				HasMemory:           tc.moduleInstance.Memory != nil,
+				HasMemory:           tc.moduleInstance.MemoryInstance != nil,
 				HasTable:            len(tc.moduleInstance.Tables) > 0,
 				HasDataInstances:    len(tc.moduleInstance.DataInstances) > 0,
 				HasElementInstances: len(tc.moduleInstance.ElementInstances) > 0,
@@ -142,11 +142,11 @@ func TestCompiler_compileModuleContextInitialization(t *testing.T) {
 			bufSliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&tc.moduleInstance.Globals))
 			require.Equal(t, bufSliceHeader.Data, ce.moduleContext.globalElement0Address)
 
-			if tc.moduleInstance.Memory != nil {
-				bufSliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&tc.moduleInstance.Memory.Buffer))
+			if tc.moduleInstance.MemoryInstance != nil {
+				bufSliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&tc.moduleInstance.MemoryInstance.Buffer))
 				require.Equal(t, uint64(bufSliceHeader.Len), ce.moduleContext.memorySliceLen)
 				require.Equal(t, bufSliceHeader.Data, ce.moduleContext.memoryElement0Address)
-				require.Equal(t, tc.moduleInstance.Memory, ce.moduleContext.memoryInstance)
+				require.Equal(t, tc.moduleInstance.MemoryInstance, ce.moduleContext.memoryInstance)
 			}
 
 			if len(tc.moduleInstance.Tables) > 0 {
diff --git a/internal/engine/compiler/compiler_test.go b/internal/engine/compiler/compiler_test.go
index cd09eeb0..41db0615 100644
--- a/internal/engine/compiler/compiler_test.go
+++ b/internal/engine/compiler/compiler_test.go
@@ -74,7 +74,7 @@ func init() {
 	// Offsets for wasm.ModuleInstance.
 	var moduleInstance wasm.ModuleInstance
 	requireEqual(int(unsafe.Offsetof(moduleInstance.Globals)), moduleInstanceGlobalsOffset, "moduleInstanceGlobalsOffset")
-	requireEqual(int(unsafe.Offsetof(moduleInstance.Memory)), moduleInstanceMemoryOffset, "moduleInstanceMemoryOffset")
+	requireEqual(int(unsafe.Offsetof(moduleInstance.MemoryInstance)), moduleInstanceMemoryOffset, "moduleInstanceMemoryOffset")
 	requireEqual(int(unsafe.Offsetof(moduleInstance.Tables)), moduleInstanceTablesOffset, "moduleInstanceTablesOffset")
 	requireEqual(int(unsafe.Offsetof(moduleInstance.Engine)), moduleInstanceEngineOffset, "moduleInstanceEngineOffset")
 	requireEqual(int(unsafe.Offsetof(moduleInstance.TypeIDs)), moduleInstanceTypeIDsOffset, "moduleInstanceTypeIDsOffset")
@@ -147,7 +147,7 @@ func (j *compilerEnv) stackTopAsV128() (lo uint64, hi uint64) {
 }
 
 func (j *compilerEnv) memory() []byte {
-	return j.moduleInstance.Memory.Buffer
+	return j.moduleInstance.MemoryInstance.Buffer
 }
 
 func (j *compilerEnv) stack() []uint64 {
@@ -267,10 +267,10 @@ func newCompilerEnvironment() *compilerEnv {
 	return &compilerEnv{
 		me: me,
 		moduleInstance: &wasm.ModuleInstance{
-			Memory:  &wasm.MemoryInstance{Buffer: make([]byte, wasm.MemoryPageSize*defaultMemoryPageNumInTest)},
-			Tables:  []*wasm.TableInstance{},
-			Globals: []*wasm.GlobalInstance{},
-			Engine:  me,
+			MemoryInstance: &wasm.MemoryInstance{Buffer: make([]byte, wasm.MemoryPageSize*defaultMemoryPageNumInTest)},
+			Tables:         []*wasm.TableInstance{},
+			Globals:        []*wasm.GlobalInstance{},
+			Engine:         me,
 		},
 		ce: me.newCallEngine(initialStackSize, nil),
 	}
diff --git a/internal/engine/compiler/engine_test.go b/internal/engine/compiler/engine_test.go
index 39421f7c..5b321c3a 100644
--- a/internal/engine/compiler/engine_test.go
+++ b/internal/engine/compiler/engine_test.go
@@ -606,7 +606,7 @@ func TestCallEngine_builtinFunctionFunctionListenerBefore(t *testing.T) {
 		stackContext: stackContext{stackBasePointerInBytes: 16},
 		contextStack: &contextStack{self: prevContext},
 	}
-	ce.builtinFunctionFunctionListenerBefore(ce.ctx, &wasm.CallContext{}, f)
+	ce.builtinFunctionFunctionListenerBefore(ce.ctx, &wasm.ModuleInstance{}, f)
 
 	// Contexts must be stacked.
 	require.Equal(t, currentContext, ce.contextStack.self)
@@ -635,7 +635,7 @@ func TestCallEngine_builtinFunctionFunctionListenerAfter(t *testing.T) {
 		stackContext: stackContext{stackBasePointerInBytes: 40},
 		contextStack: &contextStack{self: prevContext},
 	}
-	ce.builtinFunctionFunctionListenerAfter(ce.ctx, &wasm.CallContext{}, f)
+	ce.builtinFunctionFunctionListenerAfter(ce.ctx, &wasm.ModuleInstance{}, f)
 
 	// Contexts must be popped.
 	require.Nil(t, ce.contextStack)
diff --git a/internal/engine/interpreter/interpreter_test.go b/internal/engine/interpreter/interpreter_test.go
index d2b4d762..6ed14805 100644
--- a/internal/engine/interpreter/interpreter_test.go
+++ b/internal/engine/interpreter/interpreter_test.go
@@ -367,7 +367,7 @@ func TestInterpreter_NonTrappingFloatToIntConversion(t *testing.T) {
 						source: &wasm.FunctionInstance{Module: &wasm.ModuleInstance{Engine: &moduleEngine{}}},
 						parent: &code{body: body},
 					}
-					ce.callNativeFunc(testCtx, &wasm.CallContext{}, f)
+					ce.callNativeFunc(testCtx, &wasm.ModuleInstance{}, f)
 
 					if len(tc.expected32bit) > 0 {
 						require.Equal(t, tc.expected32bit[i], int32(uint32(ce.popValue())))
@@ -434,7 +434,7 @@ func TestInterpreter_CallEngine_callNativeFunc_signExtend(t *testing.T) {
 						{kind: wazeroir.OperationKindBr, us: []uint64{math.MaxUint64}},
 					}},
 				}
-				ce.callNativeFunc(testCtx, &wasm.CallContext{}, f)
+				ce.callNativeFunc(testCtx, &wasm.ModuleInstance{}, f)
 				require.Equal(t, tc.expected, int32(uint32(ce.popValue())))
 			})
 		}
@@ -488,7 +488,7 @@ func TestInterpreter_CallEngine_callNativeFunc_signExtend(t *testing.T) {
 						{kind: wazeroir.OperationKindBr, us: []uint64{math.MaxUint64}},
 					}},
 				}
-				ce.callNativeFunc(testCtx, &wasm.CallContext{}, f)
+				ce.callNativeFunc(testCtx, &wasm.ModuleInstance{}, f)
 				require.Equal(t, tc.expected, int64(ce.popValue()))
 			})
 		}
diff --git a/internal/integration_test/bench/hostfunc_bench_test.go b/internal/integration_test/bench/hostfunc_bench_test.go
index 4c6c76bc..04c9e43e 100644
--- a/internal/integration_test/bench/hostfunc_bench_test.go
+++ b/internal/integration_test/bench/hostfunc_bench_test.go
@@ -40,7 +40,7 @@ func BenchmarkHostFunctionCall(b *testing.B) {
 	const offset = uint64(100)
 	const val = float32(1.1234)
 
-	binary.LittleEndian.PutUint32(m.Memory.Buffer[offset:], math.Float32bits(val))
+	binary.LittleEndian.PutUint32(m.MemoryInstance.Buffer[offset:], math.Float32bits(val))
 
 	for _, fn := range []string{callGoReflectHostName, callGoHostName} {
 		fn := fn
@@ -53,7 +53,7 @@ func BenchmarkHostFunctionCall(b *testing.B) {
 
 			b.ResetTimer()
 			for i := 0; i < b.N; i++ {
-				res, err := ce.Call(testCtx, m.CallCtx, []uint64{offset})
+				res, err := ce.Call(testCtx, m, []uint64{offset})
 				if err != nil {
 					b.Fatal(err)
 				}
@@ -92,7 +92,7 @@ func TestBenchmarkFunctionCall(t *testing.T) {
 		{offset: wasm.MemoryPageSize - 4, val: 1.12314},
 	}
 
-	mem := m.Memory.Buffer
+	mem := m.MemoryInstance.Buffer
 
 	for _, f := range []struct {
 		name string
@@ -105,7 +105,7 @@ func TestBenchmarkFunctionCall(t *testing.T) {
 		t.Run(f.name, func(t *testing.T) {
 			for _, tc := range tests {
 				binary.LittleEndian.PutUint32(mem[tc.offset:], math.Float32bits(tc.val))
-				res, err := f.ce.Call(context.Background(), m.CallCtx, []uint64{uint64(tc.offset)})
+				res, err := f.ce.Call(context.Background(), m, []uint64{uint64(tc.offset)})
 				require.NoError(t, err)
 				require.Equal(t, math.Float32bits(tc.val), uint32(res[0]))
 			}
@@ -121,7 +121,7 @@ func getCallEngine(m *wasm.ModuleInstance, name string) (ce wasm.CallEngine, err
 		return
 	}
 
-	ce, err = m.Engine.NewCallEngine(m.CallCtx, f)
+	ce, err = m.Engine.NewCallEngine(m, f)
 	return
 }
 
@@ -171,7 +171,7 @@ func setupHostCallBench(requireNoError func(error)) *wasm.ModuleInstance {
 	hostModule.BuildFunctionDefinitions()
 
 	host := &wasm.ModuleInstance{
-		Name: "host", TypeIDs: []wasm.FunctionTypeID{0},
+		ModuleName: "host", TypeIDs: []wasm.FunctionTypeID{0},
 		Functions: make([]wasm.FunctionInstance, len(hostModule.CodeSection)),
 	}
 	host.BuildFunctions(hostModule)
@@ -182,7 +182,7 @@ func setupHostCallBench(requireNoError func(error)) *wasm.ModuleInstance {
 	err := eng.CompileModule(testCtx, hostModule, nil, false)
 	requireNoError(err)
 
-	hostME, err := eng.NewModuleEngine(host.Name, hostModule, host.Functions)
+	hostME, err := eng.NewModuleEngine(host.ModuleName, hostModule, host.Functions)
 	requireNoError(err)
 	linkModuleToEngine(host, hostME)
 
@@ -224,15 +224,14 @@ func setupHostCallBench(requireNoError func(error)) *wasm.ModuleInstance {
 	importing.BuildFunctions(importingModule)
 	importing.Exports = importingModule.Exports
 
-	importingMe, err := eng.NewModuleEngine(importing.Name, importingModule, importing.Functions)
+	importingMe, err := eng.NewModuleEngine(importing.ModuleName, importingModule, importing.Functions)
 	requireNoError(err)
 	linkModuleToEngine(importing, importingMe)
 
-	importing.Memory = &wasm.MemoryInstance{Buffer: make([]byte, wasm.MemoryPageSize), Min: 1, Cap: 1, Max: 1}
+	importing.MemoryInstance = &wasm.MemoryInstance{Buffer: make([]byte, wasm.MemoryPageSize), Min: 1, Cap: 1, Max: 1}
 	return importing
 }
 
 func linkModuleToEngine(module *wasm.ModuleInstance, me wasm.ModuleEngine) {
 	module.Engine = me
-	module.CallCtx = wasm.NewCallContext(nil, module, nil)
 }
diff --git a/internal/testing/enginetest/enginetest.go b/internal/testing/enginetest/enginetest.go
index fe266be8..09dac228 100644
--- a/internal/testing/enginetest/enginetest.go
+++ b/internal/testing/enginetest/enginetest.go
@@ -166,39 +166,39 @@ func RunTestModuleEngine_Call(t *testing.T, et EngineTester) {
 
 	// To use the function, we first need to add it to a module.
 	module := &wasm.ModuleInstance{
-		Name: t.Name(), TypeIDs: []wasm.FunctionTypeID{0},
+		ModuleName: t.Name(), TypeIDs: []wasm.FunctionTypeID{0},
 		Functions: make([]wasm.FunctionInstance, len(m.FunctionSection)),
 	}
 	module.BuildFunctions(m)
 
 	// Compile the module
-	me, err := e.NewModuleEngine(module.Name, m, module.Functions)
+	me, err := e.NewModuleEngine(module.ModuleName, m, module.Functions)
 	require.NoError(t, err)
 	linkModuleToEngine(module, me)
 
 	// Ensure the base case doesn't fail: A single parameter should work as that matches the function signature.
 	fn := &module.Functions[0]
 
-	ce, err := me.NewCallEngine(module.CallCtx, fn)
+	ce, err := me.NewCallEngine(module, fn)
 	require.NoError(t, err)
 
-	results, err := ce.Call(testCtx, module.CallCtx, []uint64{1, 2})
+	results, err := ce.Call(testCtx, module, []uint64{1, 2})
 	require.NoError(t, err)
 	require.Equal(t, []uint64{1, 2}, results)
 
 	t.Run("errs when not enough parameters", func(t *testing.T) {
-		ce, err := me.NewCallEngine(module.CallCtx, fn)
+		ce, err := me.NewCallEngine(module, fn)
 		require.NoError(t, err)
 
-		_, err = ce.Call(testCtx, module.CallCtx, nil)
+		_, err = ce.Call(testCtx, module, nil)
 		require.EqualError(t, err, "expected 2 params, but passed 0")
 	})
 
 	t.Run("errs when too many parameters", func(t *testing.T) {
-		ce, err := me.NewCallEngine(module.CallCtx, fn)
+		ce, err := me.NewCallEngine(module, fn)
 		require.NoError(t, err)
 
-		_, err = ce.Call(testCtx, module.CallCtx, []uint64{1, 2, 3})
+		_, err = ce.Call(testCtx, module, []uint64{1, 2, 3})
 		require.EqualError(t, err, "expected 2 params, but passed 3")
 	})
 }
@@ -230,7 +230,7 @@ func RunTestModuleEngine_LookupFunction(t *testing.T, et EngineTester) {
 	}
 	m.BuildFunctions(mod)
 
-	me, err := e.NewModuleEngine(m.Name, mod, m.Functions)
+	me, err := e.NewModuleEngine(m.ModuleName, mod, m.Functions)
 	require.NoError(t, err)
 	linkModuleToEngine(m, me)
 
@@ -288,7 +288,7 @@ func runTestModuleEngine_Call_HostFn_Mem(t *testing.T, et EngineTester, readMem
 	defer done()
 
 	importingMemoryVal := uint64(6)
-	importing.Memory = &wasm.MemoryInstance{Buffer: u64.LeBytes(importingMemoryVal), Min: 1, Cap: 1, Max: 1}
+	importing.MemoryInstance = &wasm.MemoryInstance{Buffer: u64.LeBytes(importingMemoryVal), Min: 1, Cap: 1, Max: 1}
 
 	tests := []struct {
 		name     string
@@ -305,10 +305,10 @@ func runTestModuleEngine_Call_HostFn_Mem(t *testing.T, et EngineTester, readMem
 		tc := tt
 
 		t.Run(tc.name, func(t *testing.T) {
-			ce, err := tc.fn.Module.Engine.NewCallEngine(tc.fn.Module.CallCtx, tc.fn)
+			ce, err := tc.fn.Module.Engine.NewCallEngine(tc.fn.Module, tc.fn)
 			require.NoError(t, err)
 
-			results, err := ce.Call(testCtx, importing.CallCtx, nil)
+			results, err := ce.Call(testCtx, importing, nil)
 			require.NoError(t, err)
 			require.Equal(t, tc.expected, results[0])
 		})
@@ -334,22 +334,22 @@ func runTestModuleEngine_Call_HostFn(t *testing.T, et EngineTester, hostDivBy *w
 	// Ensure the base case doesn't fail: A single parameter should work as that matches the function signature.
 	tests := []struct {
 		name   string
-		module *wasm.CallContext
+		module *wasm.ModuleInstance
 		fn     *wasm.FunctionInstance
 	}{
 		{
 			name:   divByWasmName,
-			module: imported.CallCtx,
+			module: imported,
 			fn:     &imported.Functions[imported.Exports[divByWasmName].Index],
 		},
 		{
 			name:   callDivByGoName,
-			module: imported.CallCtx,
+			module: imported,
 			fn:     &imported.Functions[imported.Exports[callDivByGoName].Index],
 		},
 		{
 			name:   callImportCallDivByGoName,
-			module: importing.CallCtx,
+			module: importing,
 			fn:     &importing.Functions[importing.Exports[callImportCallDivByGoName].Index],
 		},
 	}
@@ -386,7 +386,7 @@ func RunTestModuleEngine_Call_Errors(t *testing.T, et EngineTester) {
 
 	tests := []struct {
 		name        string
-		module      *wasm.CallContext
+		module      *wasm.ModuleInstance
 		fn          *wasm.FunctionInstance
 		input       []uint64
 		expectedErr string
@@ -394,21 +394,21 @@ func RunTestModuleEngine_Call_Errors(t *testing.T, et EngineTester) {
 		{
 			name:        "wasm function not enough parameters",
 			input:       []uint64{},
-			module:      imported.CallCtx,
+			module:      imported,
 			fn:          &imported.Functions[imported.Exports[divByWasmName].Index],
 			expectedErr: `expected 1 params, but passed 0`,
 		},
 		{
 			name:        "wasm function too many parameters",
 			input:       []uint64{1, 2},
-			module:      imported.CallCtx,
+			module:      imported,
 			fn:          &imported.Functions[imported.Exports[divByWasmName].Index],
 			expectedErr: `expected 1 params, but passed 2`,
 		},
 		{
 			name:   "wasm function panics with wasmruntime.Error",
 			input:  []uint64{0},
-			module: imported.CallCtx,
+			module: imported,
 			fn:     &imported.Functions[imported.Exports[divByWasmName].Index],
 			expectedErr: `wasm error: integer divide by zero
 wasm stack trace:
@@ -417,7 +417,7 @@ wasm stack trace:
 		{
 			name:   "wasm calls host function that panics",
 			input:  []uint64{math.MaxUint32},
-			module: imported.CallCtx,
+			module: imported,
 			fn:     &imported.Functions[imported.Exports[callDivByGoName].Index],
 			expectedErr: `host-function panic (recovered by wazero)
 wasm stack trace:
@@ -427,7 +427,7 @@ wasm stack trace:
 		{
 			name:   "wasm calls imported wasm that calls host function panics with runtime.Error",
 			input:  []uint64{0},
-			module: importing.CallCtx,
+			module: importing,
 			fn:     &importing.Functions[importing.Exports[callImportCallDivByGoName].Index],
 			expectedErr: `runtime error: integer divide by zero (recovered by wazero)
 wasm stack trace:
@@ -438,7 +438,7 @@ wasm stack trace:
 		{
 			name:   "wasm calls imported wasm that calls host function that panics",
 			input:  []uint64{math.MaxUint32},
-			module: importing.CallCtx,
+			module: importing,
 			fn:     &importing.Functions[importing.Exports[callImportCallDivByGoName].Index],
 			expectedErr: `host-function panic (recovered by wazero)
 wasm stack trace:
@@ -449,7 +449,7 @@ wasm stack trace:
 		{
 			name:   "wasm calls imported wasm calls host function panics with runtime.Error",
 			input:  []uint64{0},
-			module: importing.CallCtx,
+			module: importing,
 			fn:     &importing.Functions[importing.Exports[callImportCallDivByGoName].Index],
 			expectedErr: `runtime error: integer divide by zero (recovered by wazero)
 wasm stack trace:
@@ -532,13 +532,13 @@ func RunTestModuleEngine_Memory(t *testing.T, et EngineTester) {
 
 	// Assign memory to the module instance
 	module := &wasm.ModuleInstance{
-		Name:          t.Name(),
-		Memory:        wasm.NewMemoryInstance(m.MemorySection),
-		DataInstances: []wasm.DataInstance{m.DataSection[0].Init},
-		TypeIDs:       []wasm.FunctionTypeID{0, 1},
-		Functions:     make([]wasm.FunctionInstance, len(m.FunctionSection)),
+		ModuleName:     t.Name(),
+		MemoryInstance: wasm.NewMemoryInstance(m.MemorySection),
+		DataInstances:  []wasm.DataInstance{m.DataSection[0].Init},
+		TypeIDs:        []wasm.FunctionTypeID{0, 1},
+		Functions:      make([]wasm.FunctionInstance, len(m.FunctionSection)),
 	}
-	var memory api.Memory = module.Memory
+	var memory api.Memory = module.MemoryInstance
 
 	// To use functions, we need to instantiate them (associate them with a ModuleInstance).
 	module.BuildFunctions(m)
@@ -546,7 +546,7 @@ func RunTestModuleEngine_Memory(t *testing.T, et EngineTester) {
 	grow, init := &module.Functions[0], &module.Functions[1]
 
 	// Compile the module
-	me, err := e.NewModuleEngine(module.Name, m, module.Functions)
+	me, err := e.NewModuleEngine(module.ModuleName, m, module.Functions)
 	require.NoError(t, err)
 	linkModuleToEngine(module, me)
 
@@ -555,9 +555,9 @@ func RunTestModuleEngine_Memory(t *testing.T, et EngineTester) {
 	require.Equal(t, make([]byte, wasmPhraseSize), buf)
 
 	// Initialize the memory using Wasm. This copies the test phrase.
-	initCallEngine, err := me.NewCallEngine(module.CallCtx, init)
+	initCallEngine, err := me.NewCallEngine(module, init)
 	require.NoError(t, err)
-	_, err = initCallEngine.Call(testCtx, module.CallCtx, nil)
+	_, err = initCallEngine.Call(testCtx, module, nil)
 	require.NoError(t, err)
 
 	// We expect the same []byte read earlier to now include the phrase in wasm.
@@ -587,18 +587,18 @@ func RunTestModuleEngine_Memory(t *testing.T, et EngineTester) {
 	require.Equal(t, hostPhraseTruncated, string(buf2))
 
 	// Now, we need to prove the other direction, that when Wasm changes the capacity, the host's buffer is unaffected.
-	growCallEngine, err := me.NewCallEngine(module.CallCtx, grow)
+	growCallEngine, err := me.NewCallEngine(module, grow)
 	require.NoError(t, err)
-	_, err = growCallEngine.Call(testCtx, module.CallCtx, []uint64{1})
+	_, err = growCallEngine.Call(testCtx, module, []uint64{1})
 	require.NoError(t, err)
 
 	// The host buffer should still contain the same bytes as before grow
 	require.Equal(t, hostPhraseTruncated, string(buf2))
 
 	// Re-initialize the memory in wasm, which overwrites the region.
-	initCallEngine2, err := me.NewCallEngine(module.CallCtx, init)
+	initCallEngine2, err := me.NewCallEngine(module, init)
 	require.NoError(t, err)
-	_, err = initCallEngine2.Call(testCtx, module.CallCtx, nil)
+	_, err = initCallEngine2.Call(testCtx, module, nil)
 	require.NoError(t, err)
 
 	// The host was not affected because it is a different slice due to "memory.grow" affecting the underlying memory.
@@ -665,14 +665,14 @@ func setupCallTests(t *testing.T, e wasm.Engine, divBy *wasm.Code, fnlf experime
 	err := e.CompileModule(testCtx, hostModule, lns, false)
 	require.NoError(t, err)
 	host := &wasm.ModuleInstance{
-		Name: hostModule.NameSection.ModuleName, TypeIDs: []wasm.FunctionTypeID{0},
+		ModuleName: hostModule.NameSection.ModuleName, TypeIDs: []wasm.FunctionTypeID{0},
 		Functions: make([]wasm.FunctionInstance, len(hostModule.FunctionSection)),
 	}
 	host.BuildFunctions(hostModule)
 	host.Exports = exportMap(hostModule)
 	hostFn := &host.Functions[host.Exports[divByGoName].Index]
 
-	hostME, err := e.NewModuleEngine(host.Name, hostModule, host.Functions)
+	hostME, err := e.NewModuleEngine(host.ModuleName, hostModule, host.Functions)
 	require.NoError(t, err)
 	linkModuleToEngine(host, hostME)
 
@@ -705,7 +705,7 @@ func setupCallTests(t *testing.T, e wasm.Engine, divBy *wasm.Code, fnlf experime
 	require.NoError(t, err)
 
 	imported := &wasm.ModuleInstance{
-		Name: importedModule.NameSection.ModuleName, TypeIDs: []wasm.FunctionTypeID{0},
+		ModuleName: importedModule.NameSection.ModuleName, TypeIDs: []wasm.FunctionTypeID{0},
 		Functions: []wasm.FunctionInstance{*hostFn, {}, {}},
 	}
 	imported.BuildFunctions(importedModule)
@@ -713,7 +713,7 @@ func setupCallTests(t *testing.T, e wasm.Engine, divBy *wasm.Code, fnlf experime
 	callHostFn := &imported.Functions[imported.Exports[callDivByGoName].Index]
 
 	// Compile the imported module
-	importedMe, err := e.NewModuleEngine(imported.Name, importedModule, imported.Functions)
+	importedMe, err := e.NewModuleEngine(imported.ModuleName, importedModule, imported.Functions)
 	require.NoError(t, err)
 	linkModuleToEngine(imported, importedMe)
 
@@ -742,14 +742,14 @@ func setupCallTests(t *testing.T, e wasm.Engine, divBy *wasm.Code, fnlf experime
 
 	// Add the exported function.
 	importing := &wasm.ModuleInstance{
-		Name: importingModule.NameSection.ModuleName, TypeIDs: []wasm.FunctionTypeID{0},
+		ModuleName: importingModule.NameSection.ModuleName, TypeIDs: []wasm.FunctionTypeID{0},
 		Functions: []wasm.FunctionInstance{*callHostFn, {}},
 	}
 	importing.BuildFunctions(importingModule)
 	importing.Exports = exportMap(importingModule)
 
 	// Compile the importing module
-	importingMe, err := e.NewModuleEngine(importing.Name, importingModule, importing.Functions)
+	importingMe, err := e.NewModuleEngine(importing.ModuleName, importingModule, importing.Functions)
 	require.NoError(t, err)
 	linkModuleToEngine(importing, importingMe)
 
@@ -780,14 +780,14 @@ func setupCallMemTests(t *testing.T, e wasm.Engine, readMem *wasm.Code, fnlf exp
 	err := e.CompileModule(testCtx, hostModule, nil, false)
 	require.NoError(t, err)
 	host := &wasm.ModuleInstance{
-		Name: hostModule.NameSection.ModuleName, TypeIDs: []wasm.FunctionTypeID{0},
+		ModuleName: hostModule.NameSection.ModuleName, TypeIDs: []wasm.FunctionTypeID{0},
 		Functions: make([]wasm.FunctionInstance, len(hostModule.FunctionSection)),
 	}
 	host.BuildFunctions(hostModule)
 	host.Exports = exportMap(hostModule)
 	readMemFn := &host.Functions[host.Exports[readMemName].Index]
 
-	hostME, err := e.NewModuleEngine(host.Name, hostModule, host.Functions)
+	hostME, err := e.NewModuleEngine(host.ModuleName, hostModule, host.Functions)
 	require.NoError(t, err)
 	linkModuleToEngine(host, hostME)
 
@@ -821,7 +821,7 @@ func setupCallMemTests(t *testing.T, e wasm.Engine, readMem *wasm.Code, fnlf exp
 
 	// Add the exported function.
 	importing := &wasm.ModuleInstance{
-		Name: importingModule.NameSection.ModuleName, TypeIDs: []wasm.FunctionTypeID{0},
+		ModuleName: importingModule.NameSection.ModuleName, TypeIDs: []wasm.FunctionTypeID{0},
 		Functions: []wasm.FunctionInstance{*readMemFn, {}},
 	}
 	importing.BuildFunctions(importingModule)
@@ -829,7 +829,7 @@ func setupCallMemTests(t *testing.T, e wasm.Engine, readMem *wasm.Code, fnlf exp
 	importing.Exports = exportMap(importingModule)
 
 	// Compile the importing module
-	importingMe, err := e.NewModuleEngine(importing.Name, importingModule, importing.Functions)
+	importingMe, err := e.NewModuleEngine(importing.ModuleName, importingModule, importing.Functions)
 	require.NoError(t, err)
 	linkModuleToEngine(importing, importingMe)
 
@@ -848,8 +848,6 @@ func setupCallMemTests(t *testing.T, e wasm.Engine, readMem *wasm.Code, fnlf exp
 // wasm.Store: store isn't used here for unit test precision.
 func linkModuleToEngine(module *wasm.ModuleInstance, me wasm.ModuleEngine) {
 	module.Engine = me // for Compiler, links the module to the module-engine compiled from it (moduleInstanceEngineOffset).
-	// callEngineModuleContextModuleInstanceAddressOffset
-	module.CallCtx = wasm.NewCallContext(nil, module, nil)
 }
 
 func buildListeners(factory experimental.FunctionListenerFactory, m *wasm.Module) []experimental.FunctionListener {
diff --git a/internal/wasm/gofunc_test.go b/internal/wasm/gofunc_test.go
index 07fc2e58..64269bf8 100644
--- a/internal/wasm/gofunc_test.go
+++ b/internal/wasm/gofunc_test.go
@@ -175,7 +175,7 @@ func TestPopValues(t *testing.T) {
 
 func Test_callGoFunc(t *testing.T) {
 	tPtr := uintptr(unsafe.Pointer(t))
-	callCtx := &CallContext{}
+	inst := &ModuleInstance{}
 
 	tests := []struct {
 		name                         string
@@ -196,7 +196,7 @@ func Test_callGoFunc(t *testing.T) {
 			name: "(ctx, mod) -> ()",
 			input: func(ctx context.Context, m api.Module) {
 				require.Equal(t, testCtx, ctx)
-				require.Equal(t, callCtx, m)
+				require.Equal(t, inst, m)
 			},
 		},
 		{
@@ -242,7 +242,7 @@ func Test_callGoFunc(t *testing.T) {
 			name: "all supported params and i32 result - (ctx, mod)",
 			input: func(ctx context.Context, m api.Module, v uintptr, w uint32, x uint64, y float32, z float64) uint32 {
 				require.Equal(t, testCtx, ctx)
-				require.Equal(t, callCtx, m)
+				require.Equal(t, inst, m)
 				require.Equal(t, tPtr, v)
 				require.Equal(t, uint32(math.MaxUint32), w)
 				require.Equal(t, uint64(math.MaxUint64), x)
@@ -279,7 +279,7 @@ func Test_callGoFunc(t *testing.T) {
 			case api.GoFunction:
 				code.GoFunc.(api.GoFunction).Call(testCtx, stack)
 			case api.GoModuleFunction:
-				code.GoFunc.(api.GoModuleFunction).Call(testCtx, callCtx, stack)
+				code.GoFunc.(api.GoModuleFunction).Call(testCtx, inst, stack)
 			default:
 				t.Fatal("unexpected type.")
 			}
diff --git a/internal/wasm/call_context_test.go b/internal/wasm/module_instance_test.go
similarity index 89%
rename from internal/wasm/call_context_test.go
rename to internal/wasm/module_instance_test.go
index 79c9f23d..9e848364 100644
--- a/internal/wasm/call_context_test.go
+++ b/internal/wasm/module_instance_test.go
@@ -62,19 +62,19 @@ func TestCallContext_Close(t *testing.T) {
 
 	tests := []struct {
 		name           string
-		closer         func(context.Context, *CallContext) error
+		closer         func(context.Context, *ModuleInstance) error
 		expectedClosed uint64
 	}{
 		{
 			name: "Close()",
-			closer: func(ctx context.Context, callContext *CallContext) error {
+			closer: func(ctx context.Context, callContext *ModuleInstance) error {
 				return callContext.Close(ctx)
 			},
 			expectedClosed: uint64(1),
 		},
 		{
 			name: "CloseWithExitCode(255)",
-			closer: func(ctx context.Context, callContext *CallContext) error {
+			closer: func(ctx context.Context, callContext *ModuleInstance) error {
 				return callContext.CloseWithExitCode(ctx, 255)
 			},
 			expectedClosed: uint64(255)<<32 + 1,
@@ -166,19 +166,19 @@ func TestCallContext_CallDynamic(t *testing.T) {
 
 	tests := []struct {
 		name           string
-		closer         func(context.Context, *CallContext) error
+		closer         func(context.Context, *ModuleInstance) error
 		expectedClosed uint64
 	}{
 		{
 			name: "Close()",
-			closer: func(ctx context.Context, callContext *CallContext) error {
+			closer: func(ctx context.Context, callContext *ModuleInstance) error {
 				return callContext.Close(ctx)
 			},
 			expectedClosed: uint64(1),
 		},
 		{
 			name: "CloseWithExitCode(255)",
-			closer: func(ctx context.Context, callContext *CallContext) error {
+			closer: func(ctx context.Context, callContext *ModuleInstance) error {
 				return callContext.CloseWithExitCode(ctx, 255)
 			},
 			expectedClosed: uint64(255)<<32 + 1,
@@ -262,7 +262,7 @@ func TestCallContext_CallDynamic(t *testing.T) {
 func TestCallContext_CloseModuleOnCanceledOrTimeout(t *testing.T) {
 	s := newStore()
 	t.Run("timeout", func(t *testing.T) {
-		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &ModuleInstance{Closed: 0, ModuleName: "test", s: s}
 		const duration = time.Second
 		ctx, cancel := context.WithTimeout(context.Background(), duration)
 		defer cancel()
@@ -275,7 +275,7 @@ func TestCallContext_CloseModuleOnCanceledOrTimeout(t *testing.T) {
 	})
 
 	t.Run("cancel", func(t *testing.T) {
-		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &ModuleInstance{Closed: 0, ModuleName: "test", s: s}
 		ctx, cancel := context.WithCancel(context.Background())
 		done := cc.CloseModuleOnCanceledOrTimeout(context.WithValue(ctx, struct{}{}, 1)) // Wrapping arbitrary context.
 		cancel()
@@ -290,7 +290,7 @@ func TestCallContext_CloseModuleOnCanceledOrTimeout(t *testing.T) {
 	})
 
 	t.Run("timeout over cancel", func(t *testing.T) {
-		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &ModuleInstance{Closed: 0, ModuleName: "test", s: s}
 		const duration = time.Second
 		ctx, cancel := context.WithCancel(context.Background())
 		defer cancel()
@@ -303,7 +303,7 @@ func TestCallContext_CloseModuleOnCanceledOrTimeout(t *testing.T) {
 	})
 
 	t.Run("cancel over timeout", func(t *testing.T) {
-		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &ModuleInstance{Closed: 0, ModuleName: "test", s: s}
 		ctx, cancel := context.WithCancel(context.Background())
 		// Wrap the timeout context by cancel context.
 		var timeoutDone context.CancelFunc
@@ -320,7 +320,7 @@ func TestCallContext_CloseModuleOnCanceledOrTimeout(t *testing.T) {
 	})
 
 	t.Run("cancel works", func(t *testing.T) {
-		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &ModuleInstance{Closed: 0, ModuleName: "test", s: s}
 		cancelChan := make(chan struct{})
 		var wg sync.WaitGroup
 		wg.Add(1)
@@ -335,7 +335,7 @@ func TestCallContext_CloseModuleOnCanceledOrTimeout(t *testing.T) {
 	})
 
 	t.Run("no close on all resources canceled", func(t *testing.T) {
-		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &ModuleInstance{Closed: 0, ModuleName: "test", s: s}
 		cancelChan := make(chan struct{})
 		close(cancelChan)
 		ctx, cancel := context.WithCancel(context.Background())
@@ -352,7 +352,7 @@ func TestCallContext_CloseWithCtxErr(t *testing.T) {
 	s := newStore()
 
 	t.Run("context canceled", func(t *testing.T) {
-		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &ModuleInstance{Closed: 0, ModuleName: "test", s: s}
 		ctx, cancel := context.WithCancel(context.Background())
 		cancel()
 
@@ -363,7 +363,7 @@ func TestCallContext_CloseWithCtxErr(t *testing.T) {
 	})
 
 	t.Run("context timeout", func(t *testing.T) {
-		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &ModuleInstance{Closed: 0, ModuleName: "test", s: s}
 		duration := time.Second
 		ctx, cancel := context.WithTimeout(context.Background(), duration)
 		defer cancel()
@@ -377,7 +377,7 @@ func TestCallContext_CloseWithCtxErr(t *testing.T) {
 	})
 
 	t.Run("no error", func(t *testing.T) {
-		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &ModuleInstance{Closed: 0, ModuleName: "test", s: s}
 
 		cc.CloseWithCtxErr(context.Background())
 
@@ -398,11 +398,11 @@ func TestCallContext_ensureResourcesClosed(t *testing.T) {
 
 	for _, tc := range []struct {
 		name string
-		m    *CallContext
+		m    *ModuleInstance
 	}{
-		{m: &CallContext{CodeCloser: closer}},
-		{m: &CallContext{Sys: internalsys.DefaultContext(nil)}},
-		{m: &CallContext{Sys: internalsys.DefaultContext(nil), CodeCloser: closer}},
+		{m: &ModuleInstance{CodeCloser: closer}},
+		{m: &ModuleInstance{Sys: internalsys.DefaultContext(nil)}},
+		{m: &ModuleInstance{Sys: internalsys.DefaultContext(nil), CodeCloser: closer}},
 	} {
 		err := tc.m.ensureResourcesClosed(context.Background())
 		require.NoError(t, err)
diff --git a/internal/wasm/module_test.go b/internal/wasm/module_test.go
index 380aba88..1e249cdb 100644
--- a/internal/wasm/module_test.go
+++ b/internal/wasm/module_test.go
@@ -852,7 +852,7 @@ func TestModule_buildFunctions(t *testing.T) {
 
 	// Note: This only returns module-defined functions, not imported ones. That's why the index starts with 1, not 0.
 	instance := &ModuleInstance{
-		Name: "counter", TypeIDs: []FunctionTypeID{0},
+		ModuleName: "counter", TypeIDs: []FunctionTypeID{0},
 		Functions: make([]FunctionInstance, len(m.ImportSection)+len(m.FunctionSection)),
 	}
 	instance.BuildFunctions(m)
@@ -865,7 +865,7 @@ func TestModule_buildMemoryInstance(t *testing.T) {
 	t.Run("nil", func(t *testing.T) {
 		m := ModuleInstance{}
 		m.buildMemory(&Module{})
-		require.Nil(t, m.Memory)
+		require.Nil(t, m.MemoryInstance)
 	})
 	t.Run("non-nil", func(t *testing.T) {
 		min := uint32(1)
@@ -876,7 +876,7 @@ func TestModule_buildMemoryInstance(t *testing.T) {
 			MemorySection:           &Memory{Min: min, Cap: min, Max: max},
 			MemoryDefinitionSection: []MemoryDefinition{mDef},
 		})
-		mem := m.Memory
+		mem := m.MemoryInstance
 		require.Equal(t, min, mem.Min)
 		require.Equal(t, max, mem.Max)
 		require.Equal(t, &mDef, mem.definition)
diff --git a/internal/wasm/store_module_list_test.go b/internal/wasm/store_module_list_test.go
index d85ccdd5..e2858cdc 100644
--- a/internal/wasm/store_module_list_test.go
+++ b/internal/wasm/store_module_list_test.go
@@ -9,16 +9,16 @@ import (
 
 func TestStore_setModule(t *testing.T) {
 	s := newStore()
-	m1 := &ModuleInstance{Name: "m1"}
+	m1 := &ModuleInstance{ModuleName: "m1"}
 
 	t.Run("errors if not required", func(t *testing.T) {
 		require.Error(t, s.setModule(m1))
 	})
 
 	t.Run("adds module", func(t *testing.T) {
-		s.nameToNode[m1.Name] = &moduleListNode{name: m1.Name}
+		s.nameToNode[m1.ModuleName] = &moduleListNode{name: m1.ModuleName}
 		require.NoError(t, s.setModule(m1))
-		require.Equal(t, map[string]*moduleListNode{m1.Name: {name: m1.Name, module: m1}}, s.nameToNode)
+		require.Equal(t, map[string]*moduleListNode{m1.ModuleName: {name: m1.ModuleName, module: m1}}, s.nameToNode)
 
 		// Doesn't affect module names
 		require.Nil(t, s.moduleList)
@@ -26,17 +26,17 @@ func TestStore_setModule(t *testing.T) {
 
 	t.Run("redundant ok", func(t *testing.T) {
 		require.NoError(t, s.setModule(m1))
-		require.Equal(t, map[string]*moduleListNode{m1.Name: {name: m1.Name, module: m1}}, s.nameToNode)
+		require.Equal(t, map[string]*moduleListNode{m1.ModuleName: {name: m1.ModuleName, module: m1}}, s.nameToNode)
 
 		// Doesn't affect module names
 		require.Nil(t, s.moduleList)
 	})
 
 	t.Run("adds second module", func(t *testing.T) {
-		m2 := &ModuleInstance{Name: "m2"}
-		s.nameToNode[m2.Name] = &moduleListNode{name: m2.Name}
+		m2 := &ModuleInstance{ModuleName: "m2"}
+		s.nameToNode[m2.ModuleName] = &moduleListNode{name: m2.ModuleName}
 		require.NoError(t, s.setModule(m2))
-		require.Equal(t, map[string]*moduleListNode{m1.Name: {name: m1.Name, module: m1}, m2.Name: {name: m2.Name, module: m2}}, s.nameToNode)
+		require.Equal(t, map[string]*moduleListNode{m1.ModuleName: {name: m1.ModuleName, module: m1}, m2.ModuleName: {name: m2.ModuleName, module: m2}}, s.nameToNode)
 
 		// Doesn't affect module names
 		require.Nil(t, s.moduleList)
@@ -55,8 +55,8 @@ func TestStore_deleteModule(t *testing.T) {
 		require.NoError(t, s.deleteModule(m2.moduleListNode))
 
 		// Leaves the other module alone
-		m1Node := &moduleListNode{name: m1.Name, module: m1}
-		require.Equal(t, map[string]*moduleListNode{m1.Name: m1Node}, s.nameToNode)
+		m1Node := &moduleListNode{name: m1.ModuleName, module: m1}
+		require.Equal(t, map[string]*moduleListNode{m1.ModuleName: m1Node}, s.nameToNode)
 		require.Equal(t, m1Node, s.moduleList)
 	})
 
@@ -76,7 +76,7 @@ func TestStore_module(t *testing.T) {
 	s, m1, _ := newTestStore()
 
 	t.Run("ok", func(t *testing.T) {
-		got, err := s.module(m1.Name)
+		got, err := s.module(m1.ModuleName)
 		require.NoError(t, err)
 		require.Equal(t, m1, got)
 	})
@@ -96,7 +96,7 @@ func TestStore_module(t *testing.T) {
 
 	t.Run("store closed", func(t *testing.T) {
 		require.NoError(t, s.CloseWithExitCode(context.Background(), 0))
-		got, err := s.module(m1.Name)
+		got, err := s.module(m1.ModuleName)
 		require.Error(t, err)
 		require.Nil(t, got)
 	})
@@ -106,9 +106,9 @@ func TestStore_requireModules(t *testing.T) {
 	t.Run("ok", func(t *testing.T) {
 		s, m1, _ := newTestStore()
 
-		modules, err := s.requireModules(map[string]struct{}{m1.Name: {}})
+		modules, err := s.requireModules(map[string]struct{}{m1.ModuleName: {}})
 		require.NoError(t, err)
-		require.Equal(t, map[string]*ModuleInstance{m1.Name: m1}, modules)
+		require.Equal(t, map[string]*ModuleInstance{m1.ModuleName: m1}, modules)
 	})
 	t.Run("module not instantiated", func(t *testing.T) {
 		s, _, _ := newTestStore()
@@ -156,8 +156,8 @@ func TestStore_requireModuleName(t *testing.T) {
 func TestStore_AliasModule(t *testing.T) {
 	s := newStore()
 
-	m1 := &ModuleInstance{Name: "m1"}
-	s.nameToNode[m1.Name] = &moduleListNode{name: m1.Name, module: m1}
+	m1 := &ModuleInstance{ModuleName: "m1"}
+	s.nameToNode[m1.ModuleName] = &moduleListNode{name: m1.ModuleName, module: m1}
 
 	t.Run("alias module", func(t *testing.T) {
 		require.NoError(t, s.AliasModule("m1", "m2"))
@@ -172,7 +172,7 @@ func TestStore_Module(t *testing.T) {
 	s, m1, _ := newTestStore()
 
 	t.Run("ok", func(t *testing.T) {
-		require.Equal(t, m1.CallCtx, s.Module(m1.Name))
+		require.Equal(t, m1, s.Module(m1.ModuleName))
 	})
 
 	t.Run("unknown", func(t *testing.T) {
@@ -183,16 +183,13 @@ func TestStore_Module(t *testing.T) {
 // newTestStore sets up a new Store without adding test coverage its functions.
 func newTestStore() (*Store, *ModuleInstance, *ModuleInstance) {
 	s := newStore()
-	m1 := &ModuleInstance{Name: "m1"}
-	m1.CallCtx = NewCallContext(s, m1, nil)
+	m1 := &ModuleInstance{ModuleName: "m1"}
+	m2 := &ModuleInstance{ModuleName: "m2"}
 
-	m2 := &ModuleInstance{Name: "m2"}
-	m2.CallCtx = NewCallContext(s, m2, nil)
-
-	node1 := &moduleListNode{name: m1.Name, module: m1}
-	node2 := &moduleListNode{name: m2.Name, module: m2, next: node1}
+	node1 := &moduleListNode{name: m1.ModuleName, module: m1}
+	node2 := &moduleListNode{name: m2.ModuleName, module: m2, next: node1}
 	node1.prev = node2
-	s.nameToNode = map[string]*moduleListNode{m1.Name: node1, m2.Name: node2}
+	s.nameToNode = map[string]*moduleListNode{m1.ModuleName: node1, m2.ModuleName: node2}
 	s.moduleList = node2
 
 	m1.moduleListNode = node1
diff --git a/internal/wasm/store_test.go b/internal/wasm/store_test.go
index a6640b5d..6424e062 100644
--- a/internal/wasm/store_test.go
+++ b/internal/wasm/store_test.go
@@ -114,8 +114,8 @@ func TestStore_Instantiate(t *testing.T) {
 	defer mod.Close(testCtx)
 
 	t.Run("CallContext defaults", func(t *testing.T) {
-		require.Equal(t, s.nameToNode["bar"].module, mod.module)
-		require.Equal(t, s.nameToNode["bar"].module.Memory, mod.memory)
+		require.Equal(t, s.nameToNode["bar"].module, mod)
+		require.Equal(t, s.nameToNode["bar"].module.MemoryInstance, mod.MemoryInstance)
 		require.Equal(t, s, mod.s)
 		require.Equal(t, sysCtx, mod.Sys)
 	})
@@ -446,7 +446,7 @@ func (e *mockModuleEngine) FunctionInstanceReference(i Index) Reference {
 }
 
 // NewCallEngine implements the same method as documented on wasm.ModuleEngine.
-func (e *mockModuleEngine) NewCallEngine(callCtx *CallContext, f *FunctionInstance) (CallEngine, error) {
+func (e *mockModuleEngine) NewCallEngine(_ *ModuleInstance, f *FunctionInstance) (CallEngine, error) {
 	return &mockCallEngine{f: f, callFailIndex: e.callFailIndex}, nil
 }
 
@@ -463,7 +463,7 @@ func (e *mockModuleEngine) Close(context.Context) {
 }
 
 // Call implements the same method as documented on wasm.ModuleEngine.
-func (ce *mockCallEngine) Call(ctx context.Context, callCtx *CallContext, _ []uint64) (results []uint64, err error) {
+func (ce *mockCallEngine) Call(_ context.Context, _ *ModuleInstance, _ []uint64) (results []uint64, err error) {
 	if ce.callFailIndex >= 0 && ce.f.Definition.Index() == Index(ce.callFailIndex) {
 		err = errors.New("call failed")
 		return
@@ -651,7 +651,7 @@ func Test_resolveImports(t *testing.T) {
 	})
 	t.Run("export instance not found", func(t *testing.T) {
 		modules := map[string]*ModuleInstance{
-			moduleName: {Exports: map[string]*Export{}, Name: moduleName},
+			moduleName: {Exports: map[string]*Export{}, ModuleName: moduleName},
 		}
 		m := &ModuleInstance{}
 		err := m.resolveImports(&Module{ImportSection: []Import{{Module: moduleName, Name: "unknown"}}}, modules)
@@ -669,7 +669,7 @@ func Test_resolveImports(t *testing.T) {
 					name: {Type: ExternTypeFunc, Index: 0},
 					"":   {Type: ExternTypeFunc, Index: 1},
 				},
-				Name: moduleName,
+				ModuleName: moduleName,
 			}
 			importedModules := map[string]*ModuleInstance{
 				moduleName: externMod,
@@ -695,7 +695,7 @@ func Test_resolveImports(t *testing.T) {
 				Exports: map[string]*Export{
 					name: {Type: ExternTypeFunc, Index: 0},
 				},
-				Name: moduleName,
+				ModuleName: moduleName,
 			}
 			module := &Module{
 				TypeSection:   []FunctionType{{Results: []ValueType{ValueTypeF32}}},
@@ -716,7 +716,7 @@ func Test_resolveImports(t *testing.T) {
 				map[string]*ModuleInstance{
 					moduleName: {
 						Globals: []*GlobalInstance{g},
-						Exports: map[string]*Export{name: {Type: ExternTypeGlobal, Index: 0}}, Name: moduleName,
+						Exports: map[string]*Export{name: {Type: ExternTypeGlobal, Index: 0}}, ModuleName: moduleName,
 					},
 				},
 			)
@@ -731,7 +731,7 @@ func Test_resolveImports(t *testing.T) {
 						Type:  ExternTypeGlobal,
 						Index: 0,
 					}},
-					Name: moduleName,
+					ModuleName: moduleName,
 				},
 			}
 			m := &ModuleInstance{Globals: make([]*GlobalInstance, 1)}
@@ -746,7 +746,7 @@ func Test_resolveImports(t *testing.T) {
 						Type:  ExternTypeGlobal,
 						Index: 0,
 					}},
-					Name: moduleName,
+					ModuleName: moduleName,
 				},
 			}
 			m := &ModuleInstance{Globals: make([]*GlobalInstance, 1)}
@@ -760,27 +760,27 @@ func Test_resolveImports(t *testing.T) {
 			memoryInst := &MemoryInstance{Max: max}
 			importedModules := map[string]*ModuleInstance{
 				moduleName: {
-					Memory: memoryInst,
+					MemoryInstance: memoryInst,
 					Exports: map[string]*Export{name: {
 						Type: ExternTypeMemory,
 					}},
-					Name: moduleName,
+					ModuleName: moduleName,
 				},
 			}
 			m := &ModuleInstance{}
 			err := m.resolveImports(&Module{ImportSection: []Import{{Module: moduleName, Name: name, Type: ExternTypeMemory, DescMem: &Memory{Max: max}}}}, importedModules)
 			require.NoError(t, err)
-			require.Equal(t, m.Memory, memoryInst)
+			require.Equal(t, m.MemoryInstance, memoryInst)
 		})
 		t.Run("minimum size mismatch", func(t *testing.T) {
 			importMemoryType := &Memory{Min: 2, Cap: 2}
 			importedModules := map[string]*ModuleInstance{
 				moduleName: {
-					Memory: &MemoryInstance{Min: importMemoryType.Min - 1, Cap: 2},
+					MemoryInstance: &MemoryInstance{Min: importMemoryType.Min - 1, Cap: 2},
 					Exports: map[string]*Export{name: {
 						Type: ExternTypeMemory,
 					}},
-					Name: moduleName,
+					ModuleName: moduleName,
 				},
 			}
 			m := &ModuleInstance{}
@@ -792,11 +792,11 @@ func Test_resolveImports(t *testing.T) {
 			importMemoryType := &Memory{Max: max}
 			modules := map[string]*ModuleInstance{
 				moduleName: {
-					Memory: &MemoryInstance{Max: MemoryLimitPages},
+					MemoryInstance: &MemoryInstance{Max: MemoryLimitPages},
 					Exports: map[string]*Export{name: {
 						Type: ExternTypeMemory,
 					}},
-					Name: moduleName,
+					ModuleName: moduleName,
 				},
 			}
 			m := &ModuleInstance{}
@@ -807,7 +807,7 @@ func Test_resolveImports(t *testing.T) {
 }
 
 func TestModuleInstance_validateData(t *testing.T) {
-	m := &ModuleInstance{Memory: &MemoryInstance{Buffer: make([]byte, 5)}}
+	m := &ModuleInstance{MemoryInstance: &MemoryInstance{Buffer: make([]byte, 5)}}
 	tests := []struct {
 		name   string
 		data   []DataSegment
@@ -852,17 +852,17 @@ func TestModuleInstance_validateData(t *testing.T) {
 
 func TestModuleInstance_applyData(t *testing.T) {
 	t.Run("ok", func(t *testing.T) {
-		m := &ModuleInstance{Memory: &MemoryInstance{Buffer: make([]byte, 10)}}
+		m := &ModuleInstance{MemoryInstance: &MemoryInstance{Buffer: make([]byte, 10)}}
 		err := m.applyData([]DataSegment{
 			{OffsetExpression: ConstantExpression{Opcode: OpcodeI32Const, Data: const0}, Init: []byte{0xa, 0xf}},
 			{OffsetExpression: ConstantExpression{Opcode: OpcodeI32Const, Data: leb128.EncodeUint32(8)}, Init: []byte{0x1, 0x5}},
 		})
 		require.NoError(t, err)
-		require.Equal(t, []byte{0xa, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x5}, m.Memory.Buffer)
+		require.Equal(t, []byte{0xa, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x5}, m.MemoryInstance.Buffer)
 		require.Equal(t, [][]byte{{0xa, 0xf}, {0x1, 0x5}}, m.DataInstances)
 	})
 	t.Run("error", func(t *testing.T) {
-		m := &ModuleInstance{Memory: &MemoryInstance{Buffer: make([]byte, 5)}}
+		m := &ModuleInstance{MemoryInstance: &MemoryInstance{Buffer: make([]byte, 5)}}
 		err := m.applyData([]DataSegment{
 			{OffsetExpression: ConstantExpression{Opcode: OpcodeI32Const, Data: leb128.EncodeUint32(8)}, Init: []byte{}},
 		})
diff --git a/internal/wasm/table_test.go b/internal/wasm/table_test.go
index 7e921474..f4601923 100644
--- a/internal/wasm/table_test.go
+++ b/internal/wasm/table_test.go
@@ -24,9 +24,9 @@ func Test_resolveImports_table(t *testing.T) {
 		tableInst := &TableInstance{Max: &max}
 		importedModules := map[string]*ModuleInstance{
 			moduleName: {
-				Tables:  []*TableInstance{tableInst},
-				Exports: map[string]*Export{name: {Type: ExternTypeTable, Index: 0}},
-				Name:    moduleName,
+				Tables:     []*TableInstance{tableInst},
+				Exports:    map[string]*Export{name: {Type: ExternTypeTable, Index: 0}},
+				ModuleName: moduleName,
 			},
 		}
 		m := &ModuleInstance{Tables: make([]*TableInstance, 1)}
@@ -38,9 +38,9 @@ func Test_resolveImports_table(t *testing.T) {
 		importTableType := Table{Min: 2}
 		importedModules := map[string]*ModuleInstance{
 			moduleName: {
-				Tables:  []*TableInstance{{Min: importTableType.Min - 1}},
-				Exports: map[string]*Export{name: {Type: ExternTypeTable}},
-				Name:    moduleName,
+				Tables:     []*TableInstance{{Min: importTableType.Min - 1}},
+				Exports:    map[string]*Export{name: {Type: ExternTypeTable}},
+				ModuleName: moduleName,
 			},
 		}
 		m := &ModuleInstance{Tables: make([]*TableInstance, 1)}
@@ -52,9 +52,9 @@ func Test_resolveImports_table(t *testing.T) {
 		importTableType := Table{Max: &max}
 		importedModules := map[string]*ModuleInstance{
 			moduleName: {
-				Tables:  []*TableInstance{{Min: importTableType.Min - 1}},
-				Exports: map[string]*Export{name: {Type: ExternTypeTable}},
-				Name:    moduleName,
+				Tables:     []*TableInstance{{Min: importTableType.Min - 1}},
+				Exports:    map[string]*Export{name: {Type: ExternTypeTable}},
+				ModuleName: moduleName,
 			},
 		}
 		m := &ModuleInstance{Tables: make([]*TableInstance, 1)}
@@ -64,9 +64,9 @@ func Test_resolveImports_table(t *testing.T) {
 	t.Run("type mismatch", func(t *testing.T) {
 		importedModules := map[string]*ModuleInstance{
 			moduleName: {
-				Tables:  []*TableInstance{{Type: RefTypeFuncref}},
-				Exports: map[string]*Export{name: {Type: ExternTypeTable}},
-				Name:    moduleName,
+				Tables:     []*TableInstance{{Type: RefTypeFuncref}},
+				Exports:    map[string]*Export{name: {Type: ExternTypeTable}},
+				ModuleName: moduleName,
 			},
 		}
 		m := &ModuleInstance{Tables: make([]*TableInstance, 1)}