From e42987a17a5291a2128fdee36363d93b3da974fd Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Sun, 12 Mar 2023 22:52:01 -0700 Subject: [PATCH] Holds memory/func defs, and validated elements as values in wasm.Module (#1224) Signed-off-by: Takeshi Yoneda --- experimental/logging/log_listener_test.go | 6 +- internal/testing/enginetest/enginetest.go | 2 +- internal/wasm/function_definition.go | 37 ++++++------ internal/wasm/function_definition_test.go | 30 +++++----- internal/wasm/host.go | 2 +- internal/wasm/memory_definition.go | 15 +++-- internal/wasm/memory_definition_test.go | 8 +-- internal/wasm/module.go | 10 ++-- internal/wasm/module_test.go | 8 +-- internal/wasm/store_test.go | 18 +++--- internal/wasm/table.go | 11 ++-- internal/wasm/table_test.go | 68 +++++++++++------------ internal/wazeroir/compiler_test.go | 4 +- runtime.go | 2 +- 14 files changed, 115 insertions(+), 106 deletions(-) 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/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.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/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/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/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.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/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.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/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}, 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 }