Holds memory/func defs, and validated elements as values in wasm.Module (#1224)

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
This commit is contained in:
Takeshi Yoneda
2023-03-12 22:52:01 -07:00
committed by GitHub
parent a814cddcb6
commit e42987a17a
14 changed files with 115 additions and 106 deletions

View File

@@ -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{})

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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{},
},

View File

@@ -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 {

View File

@@ -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]

View File

@@ -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{"", ""},

View File

@@ -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
}

View File

@@ -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)
})
}

View File

@@ -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)},

View File

@@ -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 {

View File

@@ -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)}},
},
},

View File

@@ -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},

View File

@@ -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
}