diff --git a/core/rexcode/ir/wasm/print_wat.odin b/core/rexcode/ir/wasm/print_wat.odin index 4244d5cec..920bca99c 100644 --- a/core/rexcode/ir/wasm/print_wat.odin +++ b/core/rexcode/ir/wasm/print_wat.odin @@ -97,7 +97,7 @@ sbprint_wat :: proc(sb: ^strings.Builder, m: Module, opts := DEFAULT_WAT_OPTIONS defer strings.write_string(sb, ")\n") if name, ok := module_name(m); ok { - if wat_ident_ok(name) { + if ident_ok(name) { strings.write_string(sb, " $") strings.write_string(sb, name) } else { @@ -201,7 +201,7 @@ wat_write_imports :: proc(sb: ^strings.Builder, m: Module, unit: string) -> Pars if int(fi) < len(m.functions) { name = m.functions[fi].name } - wat_write_id_or_comment(sb, name, Id(fi)) + write_id_or_comment(sb, name, Id(fi)) fmt.sbprintf(sb, " (type %d)", tidx) fi += 1 case .TABLE: @@ -240,7 +240,7 @@ wat_write_function :: proc(sb: ^strings.Builder, m: Module, func_relocs: []Reloc strings.write_string(sb, unit) strings.write_string(sb, "(func") defer strings.write_string(sb, ")\n") - wat_write_id_or_comment(sb, f.name, f.id) + write_id_or_comment(sb, f.name, f.id) fmt.sbprintf(sb, " (type %d)", f.signature) type := &m.func_types[f.signature] @@ -273,11 +273,13 @@ wat_write_function :: proc(sb: ^strings.Builder, m: Module, func_relocs: []Reloc } strings.write_byte(sb, '\n') + m := m + opts := DEFAULT_PRINT_OPTIONS opts.indent = " " assert(len(f.blocks) <= 1) - level := 0 for blk in f.blocks { + level := 0 for &op, i in blk.ops { opcode := Opcode(op.opcode) #partial switch opcode { @@ -286,10 +288,8 @@ wat_write_function :: proc(sb: ^strings.Builder, m: Module, func_relocs: []Reloc } level = max(level, 0) - for _ in 0.. bool { - if len(s) == 0 { - return false - } - #no_bounds_check for i in 0..', '?', '@', '\\', '^', '_', '`', '|', - '~': - // okay - case: - return false - } - } - return true -} wat_write_quoted_string :: proc(sb: ^strings.Builder, bytes: []u8) { @(rodata, static) diff --git a/core/rexcode/ir/wasm/printer.odin b/core/rexcode/ir/wasm/printer.odin index c2f2d30a1..6a9ce672c 100644 --- a/core/rexcode/ir/wasm/printer.odin +++ b/core/rexcode/ir/wasm/printer.odin @@ -3,6 +3,7 @@ package rexcode_wasm +import "core:fmt" import "core:strings" import "core:strconv" @@ -40,6 +41,7 @@ import "core:strconv" // print: disassemble `m` into the caller-owned builder `sb`. The canonical ir // print verb; `sbprint` / `tprint` below are thin convenience sinks over it. print :: proc(m: Module, sb: ^strings.Builder, options: ^Print_Options = nil) { + m := m opts := DEFAULT_PRINT_OPTIONS if options != nil { opts = options^ } @@ -52,7 +54,7 @@ print :: proc(m: Module, sb: ^strings.Builder, options: ^Print_Options = nil) { } for blk in fn.blocks { for &op in blk.ops { - write_operation(sb, &op, &opts) + write_operation(sb, &op, &opts, &m) strings.write_string(sb, opts.separator) } } @@ -66,7 +68,7 @@ sbprint :: proc(sb: ^strings.Builder, ops: []Operation, options: ^Print_Options opts := DEFAULT_PRINT_OPTIONS if options != nil { opts = options^ } for &op in ops { - write_operation(sb, &op, &opts) + write_operation(sb, &op, &opts, nil) strings.write_string(sb, opts.separator) } } @@ -98,7 +100,7 @@ mnemonic_to_string :: proc(op: Opcode, uppercase := false, allocator := context. // Per-operation writer // ============================================================================= -write_operation :: proc(sb: ^strings.Builder, op: ^Operation, opts: ^Print_Options) { +write_operation :: proc(sb: ^strings.Builder, op: ^Operation, opts: ^Print_Options, module: Maybe(^Module)) { strings.write_string(sb, opts.indent) opcode := Opcode(op.opcode) @@ -138,6 +140,20 @@ write_operation :: proc(sb: ^strings.Builder, op: ^Operation, opts: ^Print_Optio } } + case .CALL: + if m, ok := module.?; ok { + assert(len(op.operands) == 1) + o := op.operands[0] + if o.kind == .REF { + if o.imm < i64(len(m.functions)) { + name := m.functions[o.imm].name + write_name_or_id(sb, name, Id(o.imm)) + break + } + + } + } + fallthrough case: for &o in op.operands { write_operand(sb, &o, opcode, opts) @@ -145,6 +161,46 @@ write_operation :: proc(sb: ^strings.Builder, op: ^Operation, opts: ^Print_Optio } } +@(private, require_results) +ident_ok :: proc(s: string) -> bool { + if len(s) == 0 { + return false + } + #no_bounds_check for i in 0..', '?', '@', '\\', '^', '_', '`', '|', + '~': + // okay + case: + return false + } + } + return true +} + +write_name_or_id :: proc(sb: ^strings.Builder, name: string, index: Id) { + if name != "" && ident_ok(name) { + strings.write_string(sb, " $") + strings.write_string(sb, name) + } else { + fmt.sbprintf(sb, " %d", index) + } +} + + +write_id_or_comment :: proc(sb: ^strings.Builder, name: string, index: Id) { + if name != "" && ident_ok(name) { + strings.write_string(sb, " $") + strings.write_string(sb, name) + } else { + fmt.sbprintf(sb, " (;%d;)", index) + } +} + // ============================================================================= // Internal writers // =============================================================================