wa-lang.org/wazero@v1.0.2/internal/wazeroir/format.go (about) 1 package wazeroir 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "strings" 8 ) 9 10 const EntrypointLabel = ".entrypoint" 11 12 func Format(ops []Operation) string { 13 buf := bytes.NewBuffer(nil) 14 15 _, _ = buf.WriteString(EntrypointLabel + "\n") 16 for _, op := range ops { 17 formatOperation(buf, op) 18 } 19 20 return buf.String() 21 } 22 23 func formatOperation(w io.StringWriter, b Operation) { 24 var str string 25 var isLabel bool 26 switch o := b.(type) { 27 case *OperationUnreachable: 28 str = "unreachable" 29 case *OperationLabel: 30 isLabel = true 31 str = fmt.Sprintf("%s:", o.Label.asBranchTarget()) 32 case *OperationBr: 33 str = fmt.Sprintf("br %s", o.Target.String()) 34 case *OperationBrIf: 35 str = fmt.Sprintf("br_if %s, %s", o.Then, o.Else) 36 case *OperationBrTable: 37 targets := make([]string, len(o.Targets)) 38 for i, t := range o.Targets { 39 targets[i] = t.String() 40 } 41 str = fmt.Sprintf("br_table [%s] %s", strings.Join(targets, ","), o.Default) 42 case *OperationCall: 43 str = fmt.Sprintf("call %d", o.FunctionIndex) 44 case *OperationCallIndirect: 45 str = fmt.Sprintf("call_indirect: type=%d, table=%d", o.TypeIndex, o.TableIndex) 46 case *OperationDrop: 47 str = fmt.Sprintf("drop %d..%d", o.Depth.Start, o.Depth.End) 48 case *OperationSelect: 49 str = "select" 50 case *OperationPick: 51 str = fmt.Sprintf("pick %d (is_vector=%v)", o.Depth, o.IsTargetVector) 52 case *OperationSet: 53 str = fmt.Sprintf("swap %d (is_vector=%v)", o.Depth, o.IsTargetVector) 54 case *OperationGlobalGet: 55 str = fmt.Sprintf("global.get %d", o.Index) 56 case *OperationGlobalSet: 57 str = fmt.Sprintf("global.set %d", o.Index) 58 case *OperationLoad: 59 str = fmt.Sprintf("%s.load (align=%d, offset=%d)", o.Type, o.Arg.Alignment, o.Arg.Offset) 60 case *OperationLoad8: 61 str = fmt.Sprintf("%s.load8 (align=%d, offset=%d)", o.Type, o.Arg.Alignment, o.Arg.Offset) 62 case *OperationLoad16: 63 str = fmt.Sprintf("%s.load16 (align=%d, offset=%d)", o.Type, o.Arg.Alignment, o.Arg.Offset) 64 case *OperationLoad32: 65 var t string 66 if o.Signed { 67 t = "i64" 68 } else { 69 t = "u64" 70 } 71 str = fmt.Sprintf("%s.load32 (align=%d, offset=%d)", t, o.Arg.Alignment, o.Arg.Offset) 72 case *OperationStore: 73 str = fmt.Sprintf("%s.store (align=%d, offset=%d)", o.Type, o.Arg.Alignment, o.Arg.Offset) 74 case *OperationStore8: 75 str = fmt.Sprintf("store8 (align=%d, offset=%d)", o.Arg.Alignment, o.Arg.Offset) 76 case *OperationStore16: 77 str = fmt.Sprintf("store16 (align=%d, offset=%d)", o.Arg.Alignment, o.Arg.Offset) 78 case *OperationStore32: 79 str = fmt.Sprintf("i64.store32 (align=%d, offset=%d)", o.Arg.Alignment, o.Arg.Offset) 80 case *OperationMemorySize: 81 str = "memory.size" 82 case *OperationMemoryGrow: 83 str = "memory.grow" 84 case *OperationConstI32: 85 str = fmt.Sprintf("i32.const %d", o.Value) 86 case *OperationConstI64: 87 str = fmt.Sprintf("i64.const %d", o.Value) 88 case *OperationConstF32: 89 str = fmt.Sprintf("f32.const %f", o.Value) 90 case *OperationConstF64: 91 str = fmt.Sprintf("f64.const %f", o.Value) 92 case *OperationEq: 93 str = fmt.Sprintf("%s.eq", o.Type) 94 case *OperationNe: 95 str = fmt.Sprintf("%s.ne", o.Type) 96 case *OperationEqz: 97 str = fmt.Sprintf("%s.eqz", o.Type) 98 case *OperationLt: 99 str = fmt.Sprintf("%s.lt", o.Type) 100 case *OperationGt: 101 str = fmt.Sprintf("%s.gt", o.Type) 102 case *OperationLe: 103 str = fmt.Sprintf("%s.le", o.Type) 104 case *OperationGe: 105 str = fmt.Sprintf("%s.ge", o.Type) 106 case *OperationAdd: 107 str = fmt.Sprintf("%s.add", o.Type) 108 case *OperationSub: 109 str = fmt.Sprintf("%s.sub", o.Type) 110 case *OperationMul: 111 str = fmt.Sprintf("%s.mul", o.Type) 112 case *OperationClz: 113 str = fmt.Sprintf("%s.clz", o.Type) 114 case *OperationCtz: 115 str = fmt.Sprintf("%s.ctz", o.Type) 116 case *OperationPopcnt: 117 str = fmt.Sprintf("%s.popcnt", o.Type) 118 case *OperationDiv: 119 str = fmt.Sprintf("%s.div", o.Type) 120 case *OperationRem: 121 str = fmt.Sprintf("%s.rem", o.Type) 122 case *OperationAnd: 123 str = fmt.Sprintf("%s.and", o.Type) 124 case *OperationOr: 125 str = fmt.Sprintf("%s.or", o.Type) 126 case *OperationXor: 127 str = fmt.Sprintf("%s.xor", o.Type) 128 case *OperationShl: 129 str = fmt.Sprintf("%s.shl", o.Type) 130 case *OperationShr: 131 str = fmt.Sprintf("%s.shr", o.Type) 132 case *OperationRotl: 133 str = fmt.Sprintf("%s.rotl", o.Type) 134 case *OperationRotr: 135 str = fmt.Sprintf("%s.rotr", o.Type) 136 case *OperationAbs: 137 str = fmt.Sprintf("%s.abs", o.Type) 138 case *OperationNeg: 139 str = fmt.Sprintf("%s.neg", o.Type) 140 case *OperationCeil: 141 str = fmt.Sprintf("%s.ceil", o.Type) 142 case *OperationFloor: 143 str = fmt.Sprintf("%s.floor", o.Type) 144 case *OperationTrunc: 145 str = fmt.Sprintf("%s.trunc", o.Type) 146 case *OperationNearest: 147 str = fmt.Sprintf("%s.nearest", o.Type) 148 case *OperationSqrt: 149 str = fmt.Sprintf("%s.sqrt", o.Type) 150 case *OperationMin: 151 str = fmt.Sprintf("%s.min", o.Type) 152 case *OperationMax: 153 str = fmt.Sprintf("%s.max", o.Type) 154 case *OperationCopysign: 155 str = fmt.Sprintf("%s.copysign", o.Type) 156 case *OperationI32WrapFromI64: 157 str = "i32.wrap_from.i64" 158 case *OperationITruncFromF: 159 str = fmt.Sprintf("%s.truncate_from.%s", o.OutputType, o.InputType) 160 case *OperationFConvertFromI: 161 str = fmt.Sprintf("%s.convert_from.%s", o.OutputType, o.InputType) 162 case *OperationF32DemoteFromF64: 163 str = "f32.demote_from.f64" 164 case *OperationF64PromoteFromF32: 165 str = "f64.promote_from.f32" 166 case *OperationI32ReinterpretFromF32: 167 str = "i32.reinterpret_from.f32" 168 case *OperationI64ReinterpretFromF64: 169 str = "i64.reinterpret_from.f64" 170 case *OperationF32ReinterpretFromI32: 171 str = "f32.reinterpret_from.i32" 172 case *OperationF64ReinterpretFromI64: 173 str = "f64.reinterpret_from.i64" 174 case *OperationExtend: 175 var in, out string 176 if o.Signed { 177 in = "i32" 178 out = "i64" 179 } else { 180 in = "u32" 181 out = "u64" 182 } 183 str = fmt.Sprintf("%s.extend_from.%s", out, in) 184 case *OperationV128Const: 185 str = fmt.Sprintf("v128.const [%#x, %#x]", o.Lo, o.Hi) 186 case *OperationV128Add: 187 str = fmt.Sprintf("v128.add (shape=%s)", shapeName(o.Shape)) 188 case *OperationV128ITruncSatFromF: 189 if o.Signed { 190 str = fmt.Sprintf("v128.ITruncSatFrom%sS", shapeName(o.OriginShape)) 191 } else { 192 str = fmt.Sprintf("v128.ITruncSatFrom%sU", shapeName(o.OriginShape)) 193 } 194 default: 195 panic("unreachable: a bug in wazeroir implementation") 196 } 197 198 if !isLabel { 199 const indent = "\t" 200 str = indent + str 201 } 202 203 _, _ = w.WriteString(str + "\n") 204 }