Repository: tetratelabs/wazero
Pull request #1224 (2023-03-13 04:31:56)

Holds memory/func defs, and validated elements as values in wasm.Module
```
$ benchstat old.txt new.txt
name                                    old time/op    new time/op    delta
Initialization/interpreter-32             39.2µs ± 4%    38.9µs ± 5%    ~     (p=0.375 n=17+19)
Initialization/interpreter-multiple-32    38.5µs ± 7%    38.1µs ± 6%    ~     (p=0.247 n=19+20)
Initialization/compiler-32                30.4µs ± 4%    30.3µs ± 2%    ~     (p=0.095 n=17+20)
Initialization/compiler-multiple-32       25.6µs ± 5%    25.4µs ± 4%    ~     (p=0.341 n=20+20)
Compilation/with_extern_cache-32           206µs ± 1%     204µs ± 1%  -1.17%  (p=0.000 n=20+20)
Compilation/without_extern_cache-32       6.12ms ± 1%    6.14ms ± 1%    ~     (p=0.127 n=19+20)

name                                    old alloc/op   new alloc/op   delta
Initialization/interpreter-32              136kB ± 0%     136kB ± 0%    ~     (p=0.547 n=20+20)
Initialization/interpreter-multiple-32     137kB ± 0%     137kB ± 0%    ~     (p=0.215 n=18+16)
Initialization/compiler-32                 137kB ± 0%     137kB ± 0%    ~     (all equal)
Initialization/compiler-multiple-32        142kB ± 0%     142kB ± 0%    ~     (p=0.978 n=18+17)
Compilation/with_extern_cache-32          55.6kB ± 0%    55.2kB ± 0%  -0.73%  (p=0.000 n=20+20)
Compilation/without_extern_cache-32       2.00MB ± 0%    2.00MB ± 0%  -0.02%  (p=0.000 n=20+20)

name                                    old allocs/op  new allocs/op  delta
Initialization/interpreter-32               38.0 ± 0%      38.0 ± 0%    ~     (all equal)
Initialization/interpreter-multiple-32      57.0 ± 0%      57.0 ± 0%    ~     (all equal)
Initialization/compiler-32                  38.0 ± 0%      38.0 ± 0%    ~     (all equal)
Initialization/compiler-multiple-32         47.0 ± 0%      47.0 ± 0%    ~     (all equal)
Compilation/with_extern_cache-32           1.08k ± 0%     1.03k ± 0%  -4.26%  (p=0.000 n=20+20)
Compilation/without_extern_cache-32        33.6k ± 0%     33.5k ± 0%  -0.14%  (p=0.000 n=20+20)


```


Patch:
diff --git a/imports/wasi_snapshot_preview1/fs.go b/imports/wasi_snapshot_preview1/fs.go
index 292a5023..d9a47aba 100644
--- a/imports/wasi_snapshot_preview1/fs.go
+++ b/imports/wasi_snapshot_preview1/fs.go
@@ -362,20 +362,24 @@ func fdFilestatGetFunc(mod api.Module, fd, resultBuf uint32) Errno {
 	return ErrnoSuccess
 }
 
-func getWasiFiletype(fileMode fs.FileMode) uint8 {
-	wasiFileType := FILETYPE_UNKNOWN
-	if fileMode&fs.ModeDevice != 0 {
-		wasiFileType = FILETYPE_BLOCK_DEVICE
-	} else if fileMode&fs.ModeCharDevice != 0 {
-		wasiFileType = FILETYPE_CHARACTER_DEVICE
-	} else if fileMode&fs.ModeDir != 0 {
-		wasiFileType = FILETYPE_DIRECTORY
-	} else if fileMode&fs.ModeType == 0 {
-		wasiFileType = FILETYPE_REGULAR_FILE
-	} else if fileMode&fs.ModeSymlink != 0 {
-		wasiFileType = FILETYPE_SYMBOLIC_LINK
-	}
-	return wasiFileType
+func getWasiFiletype(fm fs.FileMode) uint8 {
+	switch {
+	case fm.IsRegular():
+		return FILETYPE_REGULAR_FILE
+	case fm.IsDir():
+		return FILETYPE_DIRECTORY
+	case fm&fs.ModeSymlink != 0:
+		return FILETYPE_SYMBOLIC_LINK
+	case fm&fs.ModeDevice != 0:
+		// Unlike ModeDevice and ModeCharDevice, FILETYPE_CHARACTER_DEVICE and
+		// FILETYPE_BLOCK_DEVICE are set mutually exclusively.
+		if fm&fs.ModeCharDevice != 0 {
+			return FILETYPE_CHARACTER_DEVICE
+		}
+		return FILETYPE_BLOCK_DEVICE
+	default: // unknown
+		return FILETYPE_UNKNOWN
+	}
 }
 
 func writeFilestat(buf []byte, st *platform.Stat_t) (err error) {
diff --git a/internal/gojs/fs.go b/internal/gojs/fs.go
index e8fc592b..41bdbb83 100644
--- a/internal/gojs/fs.go
+++ b/internal/gojs/fs.go
@@ -204,50 +204,55 @@ func syscallFstat(fsc *internalsys.FSContext, fd uint32) (*jsSt, error) {
 	return newJsSt(&st), nil
 }
 
-func newJsSt(stat *platform.Stat_t) *jsSt {
+func newJsSt(st *platform.Stat_t) *jsSt {
 	ret := &jsSt{}
-	ret.isDir = stat.Mode.IsDir()
-	ret.dev = stat.Dev
-	ret.ino = stat.Ino
-	ret.mode = getJsMode(stat.Mode)
-	ret.nlink = uint32(stat.Nlink)
-	ret.size = stat.Size
-	ret.atimeMs = stat.Atim / 1e6
-	ret.mtimeMs = stat.Mtim / 1e6
-	ret.ctimeMs = stat.Ctim / 1e6
+	ret.isDir = st.Mode.IsDir()
+	ret.dev = st.Dev
+	ret.ino = st.Ino
+	ret.mode = getJsMode(st.Mode)
+	ret.nlink = uint32(st.Nlink)
+	ret.size = st.Size
+	ret.atimeMs = st.Atim / 1e6
+	ret.mtimeMs = st.Mtim / 1e6
+	ret.ctimeMs = st.Ctim / 1e6
 	return ret
 }
 
 // getJsMode is required because the mode property read in `GOOS=js` is
 // incompatible with normal go. Particularly the directory flag isn't the same.
-func getJsMode(mode fs.FileMode) (jsMode uint32) {
-	jsMode = uint32(mode & fs.ModePerm)
-	switch mode & fs.ModeType {
-	case 0:
-		jsMode |= S_IFREG
-	case fs.ModeDir:
-		jsMode |= S_IFDIR
-	case fs.ModeSymlink:
-		jsMode |= S_IFLNK
-	case fs.ModeNamedPipe:
-		jsMode |= S_IFIFO
-	case fs.ModeSocket:
-		jsMode |= S_IFSOCK
-	case fs.ModeDevice:
-		jsMode |= S_IFBLK
-	case fs.ModeCharDevice:
-		jsMode |= S_IFCHR
-	case fs.ModeIrregular:
-		// unmapped to js
+func getJsMode(fm fs.FileMode) (jsMode uint32) {
+	switch {
+	case fm.IsRegular():
+		jsMode = S_IFREG
+	case fm.IsDir():
+		jsMode = S_IFDIR
+	case fm&fs.ModeSymlink != 0:
+		jsMode = S_IFLNK
+	case fm&fs.ModeDevice != 0:
+		// Unlike ModeDevice and ModeCharDevice, S_IFCHR and S_IFBLK are set
+		// mutually exclusively.
+		if fm&fs.ModeCharDevice != 0 {
+			jsMode = S_IFCHR
+		} else {
+			jsMode = S_IFBLK
+		}
+	case fm&fs.ModeNamedPipe != 0:
+		jsMode = S_IFIFO
+	case fm&fs.ModeSocket != 0:
+		jsMode = S_IFSOCK
+	default: // unknown
+		jsMode = 0
 	}
 
-	if mode&fs.ModeSetgid != 0 {
+	jsMode |= uint32(fm & fs.ModePerm)
+
+	if fm&fs.ModeSetgid != 0 {
 		jsMode |= S_ISGID
 	}
-	if mode&fs.ModeSetuid != 0 {
+	if fm&fs.ModeSetuid != 0 {
 		jsMode |= S_ISUID
 	}
-	if mode&fs.ModeSticky != 0 {
+	if fm&fs.ModeSticky != 0 {
 		jsMode |= S_ISVTX
 	}
 	return
diff --git a/internal/wasm/function_definition.go b/internal/wasm/function_definition.go
index bd7b735c..3cf4646e 100644
--- a/internal/wasm/function_definition.go
+++ b/internal/wasm/function_definition.go
@@ -9,7 +9,8 @@ import (
 //
 // Note: Unlike ExportedFunctions, there is no unique constraint on imports.
 func (m *Module) ImportedFunctions() (ret []api.FunctionDefinition) {
-	for _, d := range m.FunctionDefinitionSection {
+	for i := range m.FunctionDefinitionSection {
+		d := &m.FunctionDefinitionSection[i]
 		if d.importDesc != nil {
 			ret = append(ret, d)
 		}
@@ -20,7 +21,8 @@ func (m *Module) ImportedFunctions() (ret []api.FunctionDefinition) {
 // ExportedFunctions returns the definitions of each exported function.
 func (m *Module) ExportedFunctions() map[string]api.FunctionDefinition {
 	ret := map[string]api.FunctionDefinition{}
-	for _, d := range m.FunctionDefinitionSection {
+	for i := range m.FunctionDefinitionSection {
+		d := &m.FunctionDefinitionSection[i]
 		for _, e := range d.exportNames {
 			ret[e] = d
 		}
@@ -49,7 +51,7 @@ func (m *Module) BuildFunctionDefinitions() {
 	}
 
 	importCount := m.ImportFuncCount()
-	m.FunctionDefinitionSection = make([]*FunctionDefinition, 0, importCount+uint32(len(m.FunctionSection)))
+	m.FunctionDefinitionSection = make([]FunctionDefinition, importCount+uint32(len(m.FunctionSection)))
 
 	importFuncIdx := Index(0)
 	for i := range m.ImportSection {
@@ -58,25 +60,25 @@ func (m *Module) BuildFunctionDefinitions() {
 			continue
 		}
 
-		m.FunctionDefinitionSection = append(m.FunctionDefinitionSection, &FunctionDefinition{
-			importDesc: &[2]string{imp.Module, imp.Name},
-			index:      importFuncIdx,
-			funcType:   m.TypeSection[imp.DescFunc],
-		})
+		def := &m.FunctionDefinitionSection[importFuncIdx]
+		def.importDesc = imp
+		def.index = importFuncIdx
+		def.funcType = m.TypeSection[imp.DescFunc]
 		importFuncIdx++
 	}
 
 	for codeIndex, typeIndex := range m.FunctionSection {
 		code := m.CodeSection[codeIndex]
-		m.FunctionDefinitionSection = append(m.FunctionDefinitionSection, &FunctionDefinition{
-			index:    Index(codeIndex) + importCount,
-			funcType: m.TypeSection[typeIndex],
-			goFunc:   code.GoFunc,
-		})
+		idx := importFuncIdx + Index(codeIndex)
+		def := &m.FunctionDefinitionSection[idx]
+		def.index = idx
+		def.funcType = m.TypeSection[typeIndex]
+		def.goFunc = code.GoFunc
 	}
 
 	n, nLen := 0, len(functionNames)
-	for _, d := range m.FunctionDefinitionSection {
+	for i := range m.FunctionDefinitionSection {
+		d := &m.FunctionDefinitionSection[i]
 		// The function name section begins with imports, but can be sparse.
 		// This keeps track of how far in the name section we've searched.
 		funcIdx := d.index
@@ -114,7 +116,7 @@ type FunctionDefinition struct {
 	debugName   string
 	goFunc      interface{}
 	funcType    *FunctionType
-	importDesc  *[2]string
+	importDesc  *Import
 	exportNames []string
 	paramNames  []string
 	resultNames []string
@@ -142,8 +144,9 @@ func (f *FunctionDefinition) DebugName() string {
 
 // Import implements the same method as documented on api.FunctionDefinition.
 func (f *FunctionDefinition) Import() (moduleName, name string, isImport bool) {
-	if importDesc := f.importDesc; importDesc != nil {
-		moduleName, name, isImport = importDesc[0], importDesc[1], true
+	if f.importDesc != nil {
+		importDesc := f.importDesc
+		moduleName, name, isImport = importDesc.Module, importDesc.Name, true
 	}
 	return
 }
diff --git a/internal/wasm/host.go b/internal/wasm/host.go
index 12f91856..15e542b6 100644
--- a/internal/wasm/host.go
+++ b/internal/wasm/host.go
@@ -180,7 +180,7 @@ func addFuncs(
 	m.NameSection.FunctionNames = make([]*NameAssoc, 0, funcCount)
 	m.FunctionSection = make([]Index, 0, funcCount)
 	m.CodeSection = make([]*Code, 0, funcCount)
-	m.FunctionDefinitionSection = make([]*FunctionDefinition, 0, funcCount)
+	m.FunctionDefinitionSection = make([]FunctionDefinition, 0, funcCount)
 
 	idx := Index(0)
 	for _, name := range funcNames {
diff --git a/internal/wasm/memory_definition.go b/internal/wasm/memory_definition.go
index 0f2d0dbc..be497bd7 100644
--- a/internal/wasm/memory_definition.go
+++ b/internal/wasm/memory_definition.go
@@ -4,7 +4,8 @@ import "github.com/tetratelabs/wazero/api"
 
 // ImportedMemories implements the same method as documented on wazero.CompiledModule.
 func (m *Module) ImportedMemories() (ret []api.MemoryDefinition) {
-	for _, d := range m.MemoryDefinitionSection {
+	for i := range m.MemoryDefinitionSection {
+		d := &m.MemoryDefinitionSection[i]
 		if d.importDesc != nil {
 			ret = append(ret, d)
 		}
@@ -15,7 +16,8 @@ func (m *Module) ImportedMemories() (ret []api.MemoryDefinition) {
 // ExportedMemories implements the same method as documented on wazero.CompiledModule.
 func (m *Module) ExportedMemories() map[string]api.MemoryDefinition {
 	ret := map[string]api.MemoryDefinition{}
-	for _, d := range m.MemoryDefinitionSection {
+	for i := range m.MemoryDefinitionSection {
+		d := &m.MemoryDefinitionSection[i]
 		for _, e := range d.exportNames {
 			ret[e] = d
 		}
@@ -42,7 +44,7 @@ func (m *Module) BuildMemoryDefinitions() {
 		return
 	}
 
-	m.MemoryDefinitionSection = make([]*MemoryDefinition, 0, memoryCount)
+	m.MemoryDefinitionSection = make([]MemoryDefinition, 0, memoryCount)
 	importMemIdx := Index(0)
 	for i := range m.ImportSection {
 		imp := &m.ImportSection[i]
@@ -50,7 +52,7 @@ func (m *Module) BuildMemoryDefinitions() {
 			continue
 		}
 
-		m.MemoryDefinitionSection = append(m.MemoryDefinitionSection, &MemoryDefinition{
+		m.MemoryDefinitionSection = append(m.MemoryDefinitionSection, MemoryDefinition{
 			importDesc: &[2]string{imp.Module, imp.Name},
 			index:      importMemIdx,
 			memory:     imp.DescMem,
@@ -59,13 +61,14 @@ func (m *Module) BuildMemoryDefinitions() {
 	}
 
 	if m.MemorySection != nil {
-		m.MemoryDefinitionSection = append(m.MemoryDefinitionSection, &MemoryDefinition{
+		m.MemoryDefinitionSection = append(m.MemoryDefinitionSection, MemoryDefinition{
 			index:  importMemIdx,
 			memory: m.MemorySection,
 		})
 	}
 
-	for _, d := range m.MemoryDefinitionSection {
+	for i := range m.MemoryDefinitionSection {
+		d := &m.MemoryDefinitionSection[i]
 		d.moduleName = moduleName
 		for i := range m.ExportSection {
 			e := &m.ExportSection[i]
diff --git a/internal/wasm/module.go b/internal/wasm/module.go
index 34039658..e19bc71d 100644
--- a/internal/wasm/module.go
+++ b/internal/wasm/module.go
@@ -168,7 +168,7 @@ type Module struct {
 	// consistent initialization result.
 	//
 	// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#table-instances%E2%91%A0
-	validatedActiveElementSegments []*validatedActiveElementSegment
+	validatedActiveElementSegments []validatedActiveElementSegment
 
 	// DataCountSection is the optional section and holds the number of data segments in the data section.
 	//
@@ -184,10 +184,10 @@ type Module struct {
 	IsHostModule bool
 
 	// FunctionDefinitionSection is a wazero-specific section built on Validate.
-	FunctionDefinitionSection []*FunctionDefinition
+	FunctionDefinitionSection []FunctionDefinition
 
 	// MemoryDefinitionSection is a wazero-specific section built on Validate.
-	MemoryDefinitionSection []*MemoryDefinition
+	MemoryDefinitionSection []MemoryDefinition
 
 	// DWARFLines is used to emit DWARF based stack trace. This is created from the multiple custom sections
 	// as described in https://yurydelendik.github.io/webassembly-dwarf/, though it is not specified in the Wasm
@@ -628,7 +628,7 @@ func (m *ModuleInstance) BuildFunctions(mod *Module, importedFunctions []*Functi
 	}
 	for i, section := range mod.FunctionSection {
 		offset := uint32(i) + importCount
-		d := mod.FunctionDefinitionSection[offset]
+		d := &mod.FunctionDefinitionSection[offset]
 		// This object is only referenced from a slice. Instead of creating a heap object
 		// here and storing a pointer, we store the struct directly in the slice. This
 		// reduces the number of heap objects which improves GC performance.
@@ -665,7 +665,7 @@ func (m *Module) buildMemory() (mem *MemoryInstance) {
 	memSec := m.MemorySection
 	if memSec != nil {
 		mem = NewMemoryInstance(memSec)
-		mem.definition = m.MemoryDefinitionSection[0]
+		mem.definition = &m.MemoryDefinitionSection[0]
 	}
 	return
 }
diff --git a/internal/wasm/table.go b/internal/wasm/table.go
index 78d98eaf..e7471710 100644
--- a/internal/wasm/table.go
+++ b/internal/wasm/table.go
@@ -140,7 +140,7 @@ type validatedActiveElementSegment struct {
 
 // validateTable ensures any ElementSegment is valid. This caches results via Module.validatedActiveElementSegments.
 // Note: limitsType are validated by decoders, so not re-validated here.
-func (m *Module) validateTable(enabledFeatures api.CoreFeatures, tables []Table, maximumTableIndex uint32) ([]*validatedActiveElementSegment, error) {
+func (m *Module) validateTable(enabledFeatures api.CoreFeatures, tables []Table, maximumTableIndex uint32) ([]validatedActiveElementSegment, error) {
 	if len(tables) > int(maximumTableIndex) {
 		return nil, fmt.Errorf("too many tables in a module: %d given with limit %d", len(tables), maximumTableIndex)
 	}
@@ -151,7 +151,7 @@ func (m *Module) validateTable(enabledFeatures api.CoreFeatures, tables []Table,
 
 	importedTableCount := m.ImportTableCount()
 
-	ret := make([]*validatedActiveElementSegment, 0, m.SectionElementCount(SectionIDElement))
+	ret := make([]validatedActiveElementSegment, 0, m.SectionElementCount(SectionIDElement))
 
 	// Create bounds checks as these can err prior to instantiation
 	funcCount := m.importCount(ExternTypeFunc) + m.SectionElementCount(SectionIDFunction)
@@ -204,7 +204,7 @@ func (m *Module) validateTable(enabledFeatures api.CoreFeatures, tables []Table,
 					continue // Per https://github.com/WebAssembly/spec/issues/1427 init can be no-op, but validate anyway!
 				}
 
-				ret = append(ret, &validatedActiveElementSegment{opcode: oc, arg: globalIdx, init: elem.Init, tableIndex: elem.TableIndex})
+				ret = append(ret, validatedActiveElementSegment{opcode: oc, arg: globalIdx, init: elem.Init, tableIndex: elem.TableIndex})
 			} else if oc == OpcodeI32Const {
 				// Treat constants as signed as their interpretation is not yet known per /RATIONALE.md
 				o, _, err := leb128.LoadInt32(elem.OffsetExpr.Data)
@@ -226,7 +226,7 @@ func (m *Module) validateTable(enabledFeatures api.CoreFeatures, tables []Table,
 					continue // Per https://github.com/WebAssembly/spec/issues/1427 init can be no-op, but validate anyway!
 				}
 
-				ret = append(ret, &validatedActiveElementSegment{opcode: oc, arg: offset, init: elem.Init, tableIndex: elem.TableIndex})
+				ret = append(ret, validatedActiveElementSegment{opcode: oc, arg: offset, init: elem.Init, tableIndex: elem.TableIndex})
 			} else {
 				return nil, fmt.Errorf("%s[%d] has an invalid const expression: %s", SectionIDName(SectionIDElement), idx, InstructionName(oc))
 			}
@@ -261,7 +261,8 @@ func (m *Module) buildTables(importedTables []*TableInstance, importedGlobals []
 		return
 	}
 
-	for elemI, elem := range elementSegments {
+	for elemI := range elementSegments { // Do not loop over the value since elementSegments is a slice of value.
+		elem := &elementSegments[elemI]
 		table := tables[elem.tableIndex]
 		var offset uint32
 		if elem.opcode == OpcodeGlobalGet {
diff --git a/runtime.go b/runtime.go
index edd4252f..c4a33e76 100644
--- a/runtime.go
+++ b/runtime.go
@@ -231,7 +231,7 @@ func buildListeners(ctx context.Context, internal *wasm.Module) ([]experimentala
 	importCount := internal.ImportFuncCount()
 	listeners := make([]experimentalapi.FunctionListener, len(internal.FunctionSection))
 	for i := 0; i < len(listeners); i++ {
-		listeners[i] = factory.NewListener(internal.FunctionDefinitionSection[uint32(i)+importCount])
+		listeners[i] = factory.NewListener(&internal.FunctionDefinitionSection[uint32(i)+importCount])
 	}
 	return listeners, nil
 }


Test patch:
diff --git a/experimental/logging/log_listener_test.go b/experimental/logging/log_listener_test.go
index 6cd5c117..d0271323 100644
--- a/experimental/logging/log_listener_test.go
+++ b/experimental/logging/log_listener_test.go
@@ -297,7 +297,7 @@ func Test_loggingListener(t *testing.T) {
 				m.CodeSection = []*wasm.Code{{Body: []byte{wasm.OpcodeEnd}}}
 			}
 			m.BuildFunctionDefinitions()
-			def := m.FunctionDefinitionSection[0]
+			def := &m.FunctionDefinitionSection[0]
 			l := lf.NewListener(def)
 
 			out.Reset()
@@ -332,9 +332,9 @@ func Test_loggingListener_indentation(t *testing.T) {
 		},
 	}
 	m.BuildFunctionDefinitions()
-	def1 := m.FunctionDefinitionSection[0]
+	def1 := &m.FunctionDefinitionSection[0]
 	l1 := lf.NewListener(def1)
-	def2 := m.FunctionDefinitionSection[1]
+	def2 := &m.FunctionDefinitionSection[1]
 	l2 := lf.NewListener(def2)
 
 	ctx := l1.Before(testCtx, nil, def1, []uint64{})
diff --git a/imports/wasi_snapshot_preview1/fs_unit_test.go b/imports/wasi_snapshot_preview1/fs_unit_test.go
index 096ded41..ab7bf51d 100644
--- a/imports/wasi_snapshot_preview1/fs_unit_test.go
+++ b/imports/wasi_snapshot_preview1/fs_unit_test.go
@@ -2,6 +2,7 @@ package wasi_snapshot_preview1
 
 import (
 	"io"
+	"os"
 	"syscall"
 	"testing"
 
@@ -422,3 +423,13 @@ func Test_openFlags(t *testing.T) {
 		})
 	}
 }
+
+func Test_getWasiFiletype_DevNull(t *testing.T) {
+	st, err := os.Stat(os.DevNull)
+	require.NoError(t, err)
+
+	ft := getWasiFiletype(st.Mode())
+
+	// Should be a character device, and not contain permissions
+	require.Equal(t, FILETYPE_CHARACTER_DEVICE, ft)
+}
diff --git a/internal/gojs/fs_unit_test.go b/internal/gojs/fs_unit_test.go
new file mode 100644
index 00000000..3ad7eb7b
--- /dev/null
+++ b/internal/gojs/fs_unit_test.go
@@ -0,0 +1,18 @@
+package gojs
+
+import (
+	"os"
+	"testing"
+
+	"github.com/tetratelabs/wazero/internal/testing/require"
+)
+
+func Test_getWasiFiletype_DevNull(t *testing.T) {
+	st, err := os.Stat(os.DevNull)
+	require.NoError(t, err)
+
+	fm := getJsMode(st.Mode())
+
+	// Should be a character device, and retain the permissions.
+	require.Equal(t, S_IFCHR|uint32(st.Mode().Perm()), fm)
+}
diff --git a/internal/testing/enginetest/enginetest.go b/internal/testing/enginetest/enginetest.go
index a54f2dee..83e8c84a 100644
--- a/internal/testing/enginetest/enginetest.go
+++ b/internal/testing/enginetest/enginetest.go
@@ -843,7 +843,7 @@ func buildListeners(factory experimental.FunctionListenerFactory, m *wasm.Module
 	listeners := make([]experimental.FunctionListener, len(m.FunctionSection))
 	importCount := m.ImportFuncCount()
 	for i := 0; i < len(listeners); i++ {
-		listeners[i] = factory.NewListener(m.FunctionDefinitionSection[uint32(i)+importCount])
+		listeners[i] = factory.NewListener(&m.FunctionDefinitionSection[uint32(i)+importCount])
 	}
 	return listeners
 }
diff --git a/internal/wasm/function_definition_test.go b/internal/wasm/function_definition_test.go
index d8fcb945..04456083 100644
--- a/internal/wasm/function_definition_test.go
+++ b/internal/wasm/function_definition_test.go
@@ -8,12 +8,17 @@ import (
 )
 
 func TestModule_BuildFunctionDefinitions(t *testing.T) {
+	imp := &Import{
+		Type:     ExternTypeFunc,
+		DescFunc: 2, // Index of type.
+	}
+
 	nopCode := &Code{Body: []byte{OpcodeEnd}}
 	fn := func(uint32) uint32 { return 1 }
 	tests := []struct {
 		name            string
 		m               *Module
-		expected        []*FunctionDefinition
+		expected        []FunctionDefinition
 		expectedImports []api.FunctionDefinition
 		expectedExports map[string]api.FunctionDefinition
 	}{
@@ -43,7 +48,7 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
 					ResultNames:   IndirectNameMap{{Index: Index(0), NameMap: NameMap{{Index: Index(0), Name: "y"}}}},
 				},
 			},
-			expected: []*FunctionDefinition{
+			expected: []FunctionDefinition{
 				{
 					index:       0,
 					name:        "fn",
@@ -79,7 +84,7 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
 					{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
 				},
 			},
-			expected: []*FunctionDefinition{
+			expected: []FunctionDefinition{
 				{
 					index:       0,
 					debugName:   ".$0",
@@ -123,10 +128,7 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
 		{
 			name: "with imports",
 			m: &Module{
-				ImportSection: []Import{{
-					Type:     ExternTypeFunc,
-					DescFunc: 2, // Index of type.
-				}},
+				ImportSection: []Import{*imp},
 				ExportSection: []Export{
 					{Name: "imported_function", Type: ExternTypeFunc, Index: 0},
 					{Name: "function_index=1", Type: ExternTypeFunc, Index: 1},
@@ -140,11 +142,11 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
 					{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
 				},
 			},
-			expected: []*FunctionDefinition{
+			expected: []FunctionDefinition{
 				{
 					index:       0,
 					debugName:   ".$0",
-					importDesc:  &[2]string{"", ""},
+					importDesc:  imp,
 					exportNames: []string{"imported_function"},
 					funcType:    &FunctionType{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
 				},
@@ -165,7 +167,7 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
 				&FunctionDefinition{
 					index:       0,
 					debugName:   ".$0",
-					importDesc:  &[2]string{"", ""},
+					importDesc:  imp,
 					exportNames: []string{"imported_function"},
 					funcType:    &FunctionType{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
 				},
@@ -174,7 +176,7 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
 				"imported_function": &FunctionDefinition{
 					index:       0,
 					debugName:   ".$0",
-					importDesc:  &[2]string{"", ""},
+					importDesc:  imp,
 					exportNames: []string{"imported_function"},
 					funcType:    &FunctionType{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
 				},
@@ -208,8 +210,8 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
 				FunctionSection: []Index{0, 0, 0, 0, 0},
 				CodeSection:     []*Code{nopCode, nopCode, nopCode, nopCode, nopCode},
 			},
-			expected: []*FunctionDefinition{
-				{moduleName: "module", index: 0, debugName: "module.$0", importDesc: &[2]string{"i", "f"}, funcType: v_v},
+			expected: []FunctionDefinition{
+				{moduleName: "module", index: 0, debugName: "module.$0", importDesc: &Import{Module: "i", Name: "f"}, funcType: v_v},
 				{moduleName: "module", index: 1, debugName: "module.$1", funcType: v_v},
 				{moduleName: "module", index: 2, debugName: "module.two", funcType: v_v, name: "two"},
 				{moduleName: "module", index: 3, debugName: "module.$3", funcType: v_v},
@@ -217,7 +219,7 @@ func TestModule_BuildFunctionDefinitions(t *testing.T) {
 				{moduleName: "module", index: 5, debugName: "module.five", funcType: v_v, name: "five"},
 			},
 			expectedImports: []api.FunctionDefinition{
-				&FunctionDefinition{moduleName: "module", index: 0, debugName: "module.$0", importDesc: &[2]string{"i", "f"}, funcType: v_v},
+				&FunctionDefinition{moduleName: "module", index: 0, debugName: "module.$0", importDesc: &Import{Module: "i", Name: "f"}, funcType: v_v},
 			},
 			expectedExports: map[string]api.FunctionDefinition{},
 		},
diff --git a/internal/wasm/memory_definition_test.go b/internal/wasm/memory_definition_test.go
index f6dc4f4e..38daeb11 100644
--- a/internal/wasm/memory_definition_test.go
+++ b/internal/wasm/memory_definition_test.go
@@ -11,7 +11,7 @@ func TestModule_BuildMemoryDefinitions(t *testing.T) {
 	tests := []struct {
 		name            string
 		m               *Module
-		expected        []*MemoryDefinition
+		expected        []MemoryDefinition
 		expectedImports []api.MemoryDefinition
 		expectedExports map[string]api.MemoryDefinition
 	}{
@@ -31,7 +31,7 @@ func TestModule_BuildMemoryDefinitions(t *testing.T) {
 		{
 			name:            "defines memory{0,}",
 			m:               &Module{MemorySection: &Memory{Min: 0}},
-			expected:        []*MemoryDefinition{{index: 0, memory: &Memory{Min: 0}}},
+			expected:        []MemoryDefinition{{index: 0, memory: &Memory{Min: 0}}},
 			expectedExports: map[string]api.MemoryDefinition{},
 		},
 		{
@@ -44,7 +44,7 @@ func TestModule_BuildMemoryDefinitions(t *testing.T) {
 				GlobalSection: []Global{{}},
 				MemorySection: &Memory{Min: 2, Max: 3, IsMaxEncoded: true},
 			},
-			expected: []*MemoryDefinition{
+			expected: []MemoryDefinition{
 				{
 					index:       0,
 					exportNames: []string{"memory_index=0"},
@@ -72,7 +72,7 @@ func TestModule_BuildMemoryDefinitions(t *testing.T) {
 				},
 				MemorySection: &Memory{Min: 2, Max: 3, IsMaxEncoded: true},
 			},
-			expected: []*MemoryDefinition{
+			expected: []MemoryDefinition{
 				{
 					index:       0,
 					importDesc:  &[2]string{"", ""},
diff --git a/internal/wasm/module_test.go b/internal/wasm/module_test.go
index a65787a9..3b1f2282 100644
--- a/internal/wasm/module_test.go
+++ b/internal/wasm/module_test.go
@@ -815,7 +815,7 @@ func TestModule_buildFunctions(t *testing.T) {
 		ImportSection:   []Import{{Type: ExternTypeFunc}},
 		FunctionSection: []Index{0, 0, 0, 0, 0},
 		CodeSection:     []*Code{nopCode, nopCode, nopCode, nopCode, nopCode},
-		FunctionDefinitionSection: []*FunctionDefinition{
+		FunctionDefinitionSection: []FunctionDefinition{
 			{index: 0, funcType: v_v},
 			{index: 1, funcType: v_v},
 			{index: 2, funcType: v_v, name: "two"},
@@ -842,15 +842,15 @@ func TestModule_buildMemoryInstance(t *testing.T) {
 	t.Run("non-nil", func(t *testing.T) {
 		min := uint32(1)
 		max := uint32(10)
-		mDef := &MemoryDefinition{moduleName: "foo"}
+		mDef := MemoryDefinition{moduleName: "foo"}
 		m := Module{
 			MemorySection:           &Memory{Min: min, Cap: min, Max: max},
-			MemoryDefinitionSection: []*MemoryDefinition{mDef},
+			MemoryDefinitionSection: []MemoryDefinition{mDef},
 		}
 		mem := m.buildMemory()
 		require.Equal(t, min, mem.Min)
 		require.Equal(t, max, mem.Max)
-		require.Equal(t, mDef, mem.definition)
+		require.Equal(t, &mDef, mem.definition)
 	})
 }
 
diff --git a/internal/wasm/store_test.go b/internal/wasm/store_test.go
index ca669412..da90c4d0 100644
--- a/internal/wasm/store_test.go
+++ b/internal/wasm/store_test.go
@@ -32,14 +32,14 @@ func TestModuleInstance_Memory(t *testing.T) {
 			name: "memory not exported, one page",
 			input: &Module{
 				MemorySection:           &Memory{Min: 1, Cap: 1},
-				MemoryDefinitionSection: []*MemoryDefinition{{}},
+				MemoryDefinitionSection: []MemoryDefinition{{}},
 			},
 		},
 		{
 			name: "memory exported, different name",
 			input: &Module{
 				MemorySection:           &Memory{Min: 1, Cap: 1},
-				MemoryDefinitionSection: []*MemoryDefinition{{}},
+				MemoryDefinitionSection: []MemoryDefinition{{}},
 				ExportSection:           []Export{{Type: ExternTypeMemory, Name: "momory", Index: 0}},
 			},
 		},
@@ -47,7 +47,7 @@ func TestModuleInstance_Memory(t *testing.T) {
 			name: "memory exported, but zero length",
 			input: &Module{
 				MemorySection:           &Memory{},
-				MemoryDefinitionSection: []*MemoryDefinition{{}},
+				MemoryDefinitionSection: []MemoryDefinition{{}},
 				ExportSection:           []Export{{Type: ExternTypeMemory, Name: "memory", Index: 0}},
 			},
 			expected: true,
@@ -56,7 +56,7 @@ func TestModuleInstance_Memory(t *testing.T) {
 			name: "memory exported, one page",
 			input: &Module{
 				MemorySection:           &Memory{Min: 1, Cap: 1},
-				MemoryDefinitionSection: []*MemoryDefinition{{}},
+				MemoryDefinitionSection: []MemoryDefinition{{}},
 				ExportSection:           []Export{{Type: ExternTypeMemory, Name: "memory", Index: 0}},
 			},
 			expected:    true,
@@ -66,7 +66,7 @@ func TestModuleInstance_Memory(t *testing.T) {
 			name: "memory exported, two pages",
 			input: &Module{
 				MemorySection:           &Memory{Min: 2, Cap: 2},
-				MemoryDefinitionSection: []*MemoryDefinition{{}},
+				MemoryDefinitionSection: []MemoryDefinition{{}},
 				ExportSection:           []Export{{Type: ExternTypeMemory, Name: "memory", Index: 0}},
 			},
 			expected:    true,
@@ -149,7 +149,7 @@ func TestStore_CloseWithExitCode(t *testing.T) {
 				FunctionSection:           []uint32{0},
 				CodeSection:               []*Code{{Body: []byte{OpcodeEnd}}},
 				ExportSection:             []Export{{Type: ExternTypeFunc, Index: 0, Name: "fn"}},
-				FunctionDefinitionSection: []*FunctionDefinition{{funcType: v_v}},
+				FunctionDefinitionSection: []FunctionDefinition{{funcType: v_v}},
 			}, importedModuleName, nil, []FunctionTypeID{0})
 			require.NoError(t, err)
 
@@ -157,7 +157,7 @@ func TestStore_CloseWithExitCode(t *testing.T) {
 				TypeSection:             []*FunctionType{v_v},
 				ImportSection:           []Import{{Type: ExternTypeFunc, Module: importedModuleName, Name: "fn", DescFunc: 0}},
 				MemorySection:           &Memory{Min: 1, Cap: 1},
-				MemoryDefinitionSection: []*MemoryDefinition{{}},
+				MemoryDefinitionSection: []MemoryDefinition{{}},
 				GlobalSection:           []Global{{Type: GlobalType{}, Init: ConstantExpression{Opcode: OpcodeI32Const, Data: const1}}},
 				TableSection:            []Table{{Min: 10}},
 			}, importingModuleName, nil, []FunctionTypeID{0})
@@ -198,7 +198,7 @@ func TestStore_hammer(t *testing.T) {
 		FunctionSection:         []uint32{0},
 		CodeSection:             []*Code{{Body: []byte{OpcodeEnd}}},
 		MemorySection:           &Memory{Min: 1, Cap: 1},
-		MemoryDefinitionSection: []*MemoryDefinition{{}},
+		MemoryDefinitionSection: []MemoryDefinition{{}},
 		GlobalSection: []Global{{
 			Type: GlobalType{ValType: ValueTypeI32},
 			Init: ConstantExpression{Opcode: OpcodeI32Const, Data: leb128.EncodeInt32(1)},
@@ -252,7 +252,7 @@ func TestStore_hammer_close(t *testing.T) {
 		FunctionSection:         []uint32{0},
 		CodeSection:             []*Code{{Body: []byte{OpcodeEnd}}},
 		MemorySection:           &Memory{Min: 1, Cap: 1},
-		MemoryDefinitionSection: []*MemoryDefinition{{}},
+		MemoryDefinitionSection: []MemoryDefinition{{}},
 		GlobalSection: []Global{{
 			Type: GlobalType{ValType: ValueTypeI32},
 			Init: ConstantExpression{Opcode: OpcodeI32Const, Data: leb128.EncodeInt32(1)},
diff --git a/internal/wasm/table_test.go b/internal/wasm/table_test.go
index 8c6352c1..171e2569 100644
--- a/internal/wasm/table_test.go
+++ b/internal/wasm/table_test.go
@@ -67,27 +67,27 @@ func TestModule_validateTable(t *testing.T) {
 	tests := []struct {
 		name     string
 		input    *Module
-		expected []*validatedActiveElementSegment
+		expected []validatedActiveElementSegment
 	}{
 		{
 			name:     "empty",
 			input:    &Module{},
-			expected: []*validatedActiveElementSegment{},
+			expected: []validatedActiveElementSegment{},
 		},
 		{
 			name:     "min zero",
 			input:    &Module{TableSection: []Table{{}}},
-			expected: []*validatedActiveElementSegment{},
+			expected: []validatedActiveElementSegment{},
 		},
 		{
 			name:     "maximum number of tables",
 			input:    &Module{TableSection: []Table{{}, {}, {}, {}, {}}},
-			expected: []*validatedActiveElementSegment{},
+			expected: []validatedActiveElementSegment{},
 		},
 		{
 			name:     "min/max",
 			input:    &Module{TableSection: []Table{{Min: 1, Max: &three}}},
-			expected: []*validatedActiveElementSegment{},
+			expected: []validatedActiveElementSegment{},
 		},
 		{ // See: https://github.com/WebAssembly/spec/issues/1427
 			name: "constant derived element offset=0 and no index",
@@ -103,7 +103,7 @@ func TestModule_validateTable(t *testing.T) {
 					},
 				},
 			},
-			expected: []*validatedActiveElementSegment{},
+			expected: []validatedActiveElementSegment{},
 		},
 		{
 			name: "constant derived element offset=0 and one index",
@@ -120,7 +120,7 @@ func TestModule_validateTable(t *testing.T) {
 					},
 				},
 			},
-			expected: []*validatedActiveElementSegment{
+			expected: []validatedActiveElementSegment{
 				{opcode: OpcodeI32Const, arg: 0, init: []*Index{uint32Ptr(0)}},
 			},
 		},
@@ -139,7 +139,7 @@ func TestModule_validateTable(t *testing.T) {
 					},
 				},
 			},
-			expected: []*validatedActiveElementSegment{
+			expected: []validatedActiveElementSegment{
 				{opcode: OpcodeI32Const, arg: 0, init: []*Index{uint32Ptr(0)}},
 			},
 		},
@@ -158,7 +158,7 @@ func TestModule_validateTable(t *testing.T) {
 					},
 				},
 			},
-			expected: []*validatedActiveElementSegment{
+			expected: []validatedActiveElementSegment{
 				{opcode: OpcodeI32Const, arg: 0, init: []*Index{uint32Ptr(0)}},
 			},
 		},
@@ -177,7 +177,7 @@ func TestModule_validateTable(t *testing.T) {
 					},
 				},
 			},
-			expected: []*validatedActiveElementSegment{
+			expected: []validatedActiveElementSegment{
 				{opcode: OpcodeI32Const, arg: 1, init: []*Index{uint32Ptr(0), uint32Ptr(2)}},
 			},
 		},
@@ -198,7 +198,7 @@ func TestModule_validateTable(t *testing.T) {
 					},
 				},
 			},
-			expected: []*validatedActiveElementSegment{},
+			expected: []validatedActiveElementSegment{},
 		},
 		{
 			name: "imported global derived element offset and one index",
@@ -218,7 +218,7 @@ func TestModule_validateTable(t *testing.T) {
 					},
 				},
 			},
-			expected: []*validatedActiveElementSegment{
+			expected: []validatedActiveElementSegment{
 				{opcode: OpcodeGlobalGet, arg: 0, init: []*Index{uint32Ptr(0)}},
 			},
 		},
@@ -240,7 +240,7 @@ func TestModule_validateTable(t *testing.T) {
 					},
 				},
 			},
-			expected: []*validatedActiveElementSegment{
+			expected: []validatedActiveElementSegment{
 				{opcode: OpcodeGlobalGet, arg: 0, init: []*Index{uint32Ptr(0)}},
 			},
 		},
@@ -262,7 +262,7 @@ func TestModule_validateTable(t *testing.T) {
 					},
 				},
 			},
-			expected: []*validatedActiveElementSegment{
+			expected: []validatedActiveElementSegment{
 				{opcode: OpcodeGlobalGet, arg: 0, init: []*Index{uint32Ptr(0)}},
 			},
 		},
@@ -285,7 +285,7 @@ func TestModule_validateTable(t *testing.T) {
 					},
 				},
 			},
-			expected: []*validatedActiveElementSegment{
+			expected: []validatedActiveElementSegment{
 				{opcode: OpcodeGlobalGet, arg: 1, init: []*Index{uint32Ptr(0), uint32Ptr(2)}},
 			},
 		},
@@ -313,7 +313,7 @@ func TestModule_validateTable(t *testing.T) {
 					},
 				},
 			},
-			expected: []*validatedActiveElementSegment{
+			expected: []validatedActiveElementSegment{
 				{opcode: OpcodeI32Const, arg: 1, init: []*Index{uint32Ptr(0), uint32Ptr(2)}},
 				{opcode: OpcodeGlobalGet, arg: 1, init: []*Index{uint32Ptr(1), uint32Ptr(2)}},
 			},
@@ -686,14 +686,14 @@ func TestModule_buildTables(t *testing.T) {
 		{
 			name: "empty",
 			module: &Module{
-				validatedActiveElementSegments: []*validatedActiveElementSegment{},
+				validatedActiveElementSegments: []validatedActiveElementSegment{},
 			},
 		},
 		{
 			name: "min zero",
 			module: &Module{
 				TableSection:                   []Table{{Type: RefTypeFuncref}},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{},
+				validatedActiveElementSegments: []validatedActiveElementSegment{},
 			},
 			expectedTables: []*TableInstance{{References: make([]Reference, 0), Min: 0, Type: RefTypeFuncref}},
 		},
@@ -701,7 +701,7 @@ func TestModule_buildTables(t *testing.T) {
 			name: "min/max",
 			module: &Module{
 				TableSection:                   []Table{{Min: 1, Max: &three}},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{},
+				validatedActiveElementSegments: []validatedActiveElementSegment{},
 			},
 			expectedTables: []*TableInstance{{References: make([]Reference, 1), Min: 1, Max: &three}},
 		},
@@ -712,7 +712,7 @@ func TestModule_buildTables(t *testing.T) {
 				TableSection:                   []Table{{Min: 1}},
 				FunctionSection:                []Index{0},
 				CodeSection:                    []*Code{codeEnd},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{},
+				validatedActiveElementSegments: []validatedActiveElementSegment{},
 			},
 			expectedTables: []*TableInstance{{References: make([]Reference, 1), Min: 1}},
 		},
@@ -720,7 +720,7 @@ func TestModule_buildTables(t *testing.T) {
 			name: "null extern refs",
 			module: &Module{
 				TableSection: []Table{{Min: 10, Type: RefTypeExternref}},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{opcode: OpcodeI32Const, arg: 5, init: []*Index{nil, nil, nil}}, // three null refs.
 				},
 			},
@@ -734,7 +734,7 @@ func TestModule_buildTables(t *testing.T) {
 				TableSection:    []Table{{Min: 1}},
 				FunctionSection: []Index{0},
 				CodeSection:     []*Code{codeEnd},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{opcode: OpcodeI32Const, arg: 0, init: []*Index{uint32Ptr(0)}},
 				},
 			},
@@ -747,7 +747,7 @@ func TestModule_buildTables(t *testing.T) {
 				TypeSection:     []*FunctionType{{}},
 				FunctionSection: []Index{0},
 				CodeSection:     []*Code{codeEnd},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{opcode: OpcodeI32Const, arg: 0, init: []*Index{uint32Ptr(0)}},
 				},
 			},
@@ -762,7 +762,7 @@ func TestModule_buildTables(t *testing.T) {
 				ImportSection:   []Import{{Type: ExternTypeTable, DescTable: Table{Min: 1}}},
 				FunctionSection: []Index{0},
 				CodeSection:     []*Code{codeEnd},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{opcode: OpcodeI32Const, arg: 0, init: []*Index{uint32Ptr(0)}},
 				},
 			},
@@ -777,7 +777,7 @@ func TestModule_buildTables(t *testing.T) {
 				TableSection:    []Table{{Min: 3}},
 				FunctionSection: []Index{0, 0, 0, 0},
 				CodeSection:     []*Code{codeEnd, codeEnd, codeEnd, codeEnd},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{opcode: OpcodeI32Const, arg: 1, init: []*Index{uint32Ptr(0), uint32Ptr(2)}},
 				},
 			},
@@ -794,7 +794,7 @@ func TestModule_buildTables(t *testing.T) {
 				TableSection:                   []Table{{Min: 1}},
 				FunctionSection:                []Index{0},
 				CodeSection:                    []*Code{codeEnd},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{},
+				validatedActiveElementSegments: []validatedActiveElementSegment{},
 			},
 			importedGlobals: []*GlobalInstance{{Type: GlobalType{ValType: ValueTypeI32}, Val: 1}},
 			expectedTables:  []*TableInstance{{References: make([]Reference, 1), Min: 1}},
@@ -809,7 +809,7 @@ func TestModule_buildTables(t *testing.T) {
 				TableSection:    []Table{{Min: 2}},
 				FunctionSection: []Index{0},
 				CodeSection:     []*Code{codeEnd},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{opcode: OpcodeGlobalGet, arg: 0, init: []*Index{uint32Ptr(0)}},
 				},
 			},
@@ -827,7 +827,7 @@ func TestModule_buildTables(t *testing.T) {
 				},
 				FunctionSection: []Index{0},
 				CodeSection:     []*Code{codeEnd},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{opcode: OpcodeGlobalGet, arg: 0, init: []*Index{uint32Ptr(0)}},
 				},
 			},
@@ -846,7 +846,7 @@ func TestModule_buildTables(t *testing.T) {
 				},
 				FunctionSection: []Index{0},
 				CodeSection:     []*Code{codeEnd},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{opcode: OpcodeGlobalGet, arg: 0, init: []*Index{uint32Ptr(0)}},
 				},
 			},
@@ -878,7 +878,7 @@ func TestModule_buildTables(t *testing.T) {
 						TableIndex: 0,
 					},
 				},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{tableIndex: 1, opcode: OpcodeGlobalGet, arg: 0, init: []*Index{nil, uint32Ptr(2)}},
 					{tableIndex: 0, opcode: OpcodeGlobalGet, arg: 1, init: []*Index{uint32Ptr(0), uint32Ptr(2)}},
 				},
@@ -907,7 +907,7 @@ func TestModule_buildTables(t *testing.T) {
 				TableSection:    []Table{{Min: 3}},
 				FunctionSection: []Index{0, 0, 0, 0},
 				CodeSection:     []*Code{codeEnd, codeEnd, codeEnd, codeEnd},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{opcode: OpcodeI32Const, arg: 1, init: []*Index{uint32Ptr(0), uint32Ptr(2)}},
 					{opcode: OpcodeGlobalGet, arg: 1, init: []*Index{uint32Ptr(1), uint32Ptr(2)}},
 				},
@@ -959,7 +959,7 @@ func TestModule_buildTable_Errors(t *testing.T) {
 						Init:       []*Index{uint32Ptr(0)},
 					},
 				},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{opcode: OpcodeI32Const, arg: 2, init: []*Index{uint32Ptr(0)}},
 				},
 			},
@@ -982,7 +982,7 @@ func TestModule_buildTable_Errors(t *testing.T) {
 						Init:       []*Index{uint32Ptr(0)},
 					},
 				},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{opcode: OpcodeGlobalGet, arg: 0, init: []*Index{uint32Ptr(0)}},
 				},
 			},
@@ -1006,7 +1006,7 @@ func TestModule_buildTable_Errors(t *testing.T) {
 						Init:       []*Index{uint32Ptr(0)},
 					},
 				},
-				validatedActiveElementSegments: []*validatedActiveElementSegment{
+				validatedActiveElementSegments: []validatedActiveElementSegment{
 					{opcode: OpcodeGlobalGet, arg: 0, init: []*Index{uint32Ptr(0)}},
 				},
 			},
diff --git a/internal/wazeroir/compiler_test.go b/internal/wazeroir/compiler_test.go
index 2b49a272..7b4cc4f6 100644
--- a/internal/wazeroir/compiler_test.go
+++ b/internal/wazeroir/compiler_test.go
@@ -2935,7 +2935,7 @@ func TestCompile_select_vectors(t *testing.T) {
 					wasm.OpcodeDrop,
 					wasm.OpcodeEnd,
 				}}},
-				FunctionDefinitionSection: []*wasm.FunctionDefinition{{}},
+				FunctionDefinitionSection: []wasm.FunctionDefinition{{}},
 			},
 			expected: []Operation{
 				OperationV128Const{Lo: 0x1, Hi: 0x2},
@@ -2961,7 +2961,7 @@ func TestCompile_select_vectors(t *testing.T) {
 					wasm.OpcodeDrop,
 					wasm.OpcodeEnd,
 				}}},
-				FunctionDefinitionSection: []*wasm.FunctionDefinition{{}},
+				FunctionDefinitionSection: []wasm.FunctionDefinition{{}},
 			},
 			expected: []Operation{
 				OperationV128Const{Lo: 0x1, Hi: 0x2},