Merge pull request #21 from Gaboose/fix-table-index-bug

Fix table index bug
This commit is contained in:
Takeshi Yoneda
2021-03-11 22:30:01 +09:00
committed by GitHub
2 changed files with 61 additions and 36 deletions

View File

@@ -121,43 +121,51 @@ func (m *Module) buildIndexSpaces(externModules map[string]*Module) error {
func (m *Module) resolveImports(externModules map[string]*Module) error {
for _, is := range m.SecImports {
em, ok := externModules[is.Module]
if !ok {
return fmt.Errorf("failed to resolve import of module name %s", is.Module)
}
es, ok := em.SecExports[is.Name]
if !ok {
return fmt.Errorf("%s not exported in module %s", is.Name, is.Module)
}
if is.Desc.Kind != es.Desc.Kind {
return fmt.Errorf("type mismatch on export: got %#x but want %#x", es.Desc.Kind, is.Desc.Kind)
}
switch is.Desc.Kind {
case 0x00: // function
if err := m.applyFunctionImport(is, em, es); err != nil {
return fmt.Errorf("applyFunctionImport failed: %w", err)
}
case 0x01: // table
if err := m.applyTableImport(em, es); err != nil {
return fmt.Errorf("applyTableImport failed: %w", err)
}
case 0x02: // mem
if err := m.applyMemoryImport(em, es); err != nil {
return fmt.Errorf("applyMemoryImport: %w", err)
}
case 0x03: // global
if err := m.applyGlobalImport(em, es); err != nil {
return fmt.Errorf("applyGlobalImport: %w", err)
}
default:
return fmt.Errorf("invalid kind of import: %#x", is.Desc.Kind)
if err := m.resolveImport(is, externModules); err != nil {
return fmt.Errorf("%s: %w", is.Name, err)
}
}
return nil
}
func (m *Module) resolveImport(is *ImportSegment, externModules map[string]*Module) error {
em, ok := externModules[is.Module]
if !ok {
return fmt.Errorf("failed to resolve import of module name %s", is.Module)
}
es, ok := em.SecExports[is.Name]
if !ok {
return fmt.Errorf("not exported in module %s", is.Module)
}
if is.Desc.Kind != es.Desc.Kind {
return fmt.Errorf("type mismatch on export: got %#x but want %#x", es.Desc.Kind, is.Desc.Kind)
}
switch is.Desc.Kind {
case 0x00: // function
if err := m.applyFunctionImport(is, em, es); err != nil {
return fmt.Errorf("applyFunctionImport failed: %w", err)
}
case 0x01: // table
if err := m.applyTableImport(em, es); err != nil {
return fmt.Errorf("applyTableImport failed: %w", err)
}
case 0x02: // mem
if err := m.applyMemoryImport(em, es); err != nil {
return fmt.Errorf("applyMemoryImport: %w", err)
}
case 0x03: // global
if err := m.applyGlobalImport(em, es); err != nil {
return fmt.Errorf("applyGlobalImport: %w", err)
}
default:
return fmt.Errorf("invalid kind of import: %#x", is.Desc.Kind)
}
return nil
}
func (m *Module) applyFunctionImport(is *ImportSegment, em *Module, es *ExportSegment) error {
if es.Desc.Index >= uint32(len(em.IndexSpace.Function)) {
return fmt.Errorf("exported index out of range")
@@ -318,13 +326,13 @@ func (m *Module) buildTableIndexSpace() error {
if size > len(table) {
next := make([]*uint32, size)
copy(next, table)
for i, b := range elem.Init {
next[i+offset] = &b
for i := range elem.Init {
next[i+offset] = &elem.Init[i]
}
m.IndexSpace.Table[elem.TableIndex] = next
} else {
for i, b := range elem.Init {
table[i+offset] = &b
for i := range elem.Init {
table[i+offset] = &elem.Init[i]
}
}
}

View File

@@ -506,6 +506,23 @@ func TestModule_buildTableIndexSpace(t *testing.T) {
},
exp: [][]*uint32{{nil, uint32Ptr(0x01), nil}},
},
{
m: &Module{
SecElements: []*ElementSegment{{
TableIndex: 0,
OffsetExpr: &ConstantExpression{
optCode: OptCodeI32Const,
data: []byte{0x0},
},
Init: []uint32{0x1, 0x2},
}},
SecTables: []*TableType{{Limit: &LimitsType{}}},
IndexSpace: &ModuleIndexSpace{
Table: [][]*uint32{{}},
},
},
exp: [][]*uint32{{uint32Ptr(0x01), uint32Ptr(0x02)}},
},
} {
require.NoError(t, c.m.buildTableIndexSpace())
require.Len(t, c.m.IndexSpace.Table, len(c.exp))