Factor out reloc group logic

This commit is contained in:
gingerBill
2026-06-18 15:21:05 +01:00
parent 84e7e04816
commit 1060fd4c72
5 changed files with 30 additions and 53 deletions

View File

@@ -98,6 +98,8 @@ Module :: struct {
exports: []Export,
start: i64, // -1 if absent, else the start funcidx
reloc_groups: []Reloc_Group,
data: []u8, // borrowed reference to the whole file (body decode reads from it)
allocator: runtime.Allocator,

View File

@@ -196,6 +196,9 @@ parse :: proc(data: []u8, allocator := context.allocator) -> (m: Module, err: Re
build_functions(&m, func_typeidx, codes, allocator) or_return
apply_name_section(&m)
m.reloc_groups = parse_relocations(m, allocator) or_return
return
}
@@ -486,6 +489,8 @@ apply_name_section :: proc(m: ^Module) {
}
module_destroy :: proc(m: ^Module) {
relocations_destroy(m.reloc_groups, m.allocator)
for t in m.types {
delete(t.params, m.allocator)
delete(t.results, m.allocator)

View File

@@ -54,8 +54,6 @@ sbprint_module :: proc(sb: ^strings.Builder, m: Module) {
}
}
relocs_group, _ := parse_relocations(m, context.temp_allocator)
// sections
for sec in m.sections {
write_padded :: proc(sb: ^strings.Builder, s: string, width: int) {
@@ -133,14 +131,7 @@ sbprint_module :: proc(sb: ^strings.Builder, m: Module) {
}
fallthrough
case 0: // expr + bytes
relocs: []wasm.Relocation
for rg in relocs_group {
if rg.target_section == sec.id {
relocs = rg.relocs
break
}
}
relocs := relocations_from_section_id(m.reloc_groups, sec.id)
for r.off < u32(len(r.data)) {
inst, info, next := wasm.decode_one(r.data[r.off:], relocs=relocs, pc=0, targets_allocator=context.temp_allocator) or_break section_printing
r.off += next
@@ -211,13 +202,7 @@ sbprint_module :: proc(sb: ^strings.Builder, m: Module) {
// }
func_relocs: []wasm.Relocation
for rg in relocs_group {
if rg.target_section == .FUNCTION {
func_relocs = rg.relocs
break
}
}
func_relocs := relocations_from_section_id(m.reloc_groups, .FUNCTION)
for f in m.functions {
if f.exported {

View File

@@ -115,14 +115,7 @@ sbprint_wat :: proc(sb: ^strings.Builder, m: Module, opts := DEFAULT_WAT_OPTIONS
wat_write_imports(sb, m, unit)
relocs_group, _ := parse_relocations(m, context.temp_allocator)
func_relocs: []wasm.Relocation
for rg in relocs_group {
if rg.target_section == .FUNCTION {
func_relocs = rg.relocs
break
}
}
func_relocs := relocations_from_section_id(m.reloc_groups, .FUNCTION)
for f in m.functions {
if f.imported {
@@ -133,7 +126,7 @@ sbprint_wat :: proc(sb: ^strings.Builder, m: Module, opts := DEFAULT_WAT_OPTIONS
wat_write_tables (sb, m, unit)
wat_write_memories(sb, m, unit)
wat_write_globals (sb, m, relocs_group, unit)
wat_write_globals (sb, m, unit)
for e in m.exports {
fmt.sbprintf(sb, "%s(export %q (%s %d))\n", unit, e.name, external_kind_name(e.kind), e.index)
@@ -143,8 +136,8 @@ sbprint_wat :: proc(sb: ^strings.Builder, m: Module, opts := DEFAULT_WAT_OPTIONS
fmt.sbprintf(sb, "%s(start %d)\n", unit, m.start)
}
wat_write_elements(sb, m, relocs_group, unit)
wat_write_data (sb, m, relocs_group, unit)
wat_write_elements(sb, m, unit)
wat_write_data (sb, m, unit)
}
wat_write_functype :: proc(sb: ^strings.Builder, t: Func_Type) {
@@ -526,19 +519,13 @@ wat_write_memories :: proc(sb: ^strings.Builder, m: Module, unit: string) {
}
}
wat_write_globals :: proc(sb: ^strings.Builder, m: Module, relocs_group: []Reloc_Group, unit: string) {
wat_write_globals :: proc(sb: ^strings.Builder, m: Module, unit: string) {
idx := count_import_kind(m, .GLOBAL)
for sec in m.sections {
if sec.id != .GLOBAL {
continue
}
relocs: []wasm.Relocation
for rg in relocs_group {
if rg.target_section == sec.id {
relocs = rg.relocs
break
}
}
relocs := relocations_from_section_id(m.reloc_groups, sec.id)
r := reader(m.data, sec.offset)
count := rd_u32(&r) or_break
@@ -560,19 +547,14 @@ wat_write_globals :: proc(sb: ^strings.Builder, m: Module, relocs_group: []Reloc
}
}
wat_write_elements :: proc(sb: ^strings.Builder, m: Module, relocs_group: []Reloc_Group, unit: string) -> Parse_Error {
wat_write_elements :: proc(sb: ^strings.Builder, m: Module, unit: string) -> Parse_Error {
elem_idx := 0
for sec in m.sections {
if sec.id != .ELEMENT {
continue
}
relocs: []wasm.Relocation
for rg in relocs_group {
if rg.target_section == sec.id {
relocs = rg.relocs
break
}
}
relocs := relocations_from_section_id(m.reloc_groups, sec.id)
r := reader(m.data, sec.offset)
count := rd_u32(&r) or_break
@@ -599,7 +581,7 @@ wat_write_elements :: proc(sb: ^strings.Builder, m: Module, relocs_group: []Relo
return nil
}
wat_write_data :: proc(sb: ^strings.Builder, m: Module, relocs_group: []Reloc_Group, unit: string) -> Parse_Error {
wat_write_data :: proc(sb: ^strings.Builder, m: Module, unit: string) -> Parse_Error {
data_idx := 0
for sec in m.sections {
if sec.id != .DATA {
@@ -620,19 +602,12 @@ wat_write_data :: proc(sb: ^strings.Builder, m: Module, relocs_group: []Reloc_Gr
memidx, _ = rd_u32(&r)
fallthrough
case 0:
relocs: []wasm.Relocation
for rg in relocs_group {
if rg.target_section == sec.id {
relocs = rg.relocs
break
}
}
// expr + bytes
if memidx != 0 {
fmt.sbprintf(sb, " (memory %d)", memidx)
}
strings.write_byte(sb, ' ')
relocs := relocations_from_section_id(m.reloc_groups, sec.id)
wat_write_const_expr(sb, m, relocs, m.data, &r.off, unit, context.temp_allocator)
case 1:
// bytes

View File

@@ -57,6 +57,16 @@ relocations_destroy :: proc(groups: []Reloc_Group, allocator: runtime.Allocator)
delete(groups)
}
@(require_results)
relocations_from_section_id :: proc(reloc_groups: []Reloc_Group, sec_id: Section_Id) -> []wasm.Relocation {
for rg in reloc_groups {
if rg.target_section == sec_id {
return rg.relocs
}
}
return nil
}
@(require_results)
reloc_type_from_wire :: proc(code: u8) -> (wasm.Relocation_Type, bool) {
switch code {