github.com/goplus/gossa@v0.3.25/binop_x.go (about) 1 package gossa 2 3 import ( 4 "reflect" 5 6 "golang.org/x/tools/go/ssa" 7 ) 8 9 func makeBinOpEQL(pfn *function, instr *ssa.BinOp) func(fr *frame) { 10 ir := pfn.regIndex(instr) 11 ix, kx, vx := pfn.regIndex3(instr.X) 12 iy, ky, vy := pfn.regIndex3(instr.Y) 13 xtyp := pfn.Interp.preToType(instr.X.Type()) 14 ytyp := pfn.Interp.preToType(instr.Y.Type()) 15 if xtyp == nil && ytyp == nil { 16 return func(fr *frame) { 17 fr.setReg(ir, true) 18 } 19 } 20 switch xtyp.Kind() { 21 case reflect.Bool, 22 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 23 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, 24 reflect.Float32, reflect.Float64, 25 reflect.Complex64, reflect.Complex128, 26 reflect.String: 27 if kx == kindConst && ky == kindConst { 28 v := vx == vy 29 return func(fr *frame) { 30 fr.setReg(ir, v) 31 } 32 } else if kx == kindConst { 33 return func(fr *frame) { 34 fr.setReg(ir, vx == fr.reg(iy)) 35 } 36 } else if ky == kindConst { 37 return func(fr *frame) { 38 fr.setReg(ir, fr.reg(ix) == vy) 39 } 40 } 41 return func(fr *frame) { 42 fr.setReg(ir, fr.reg(ix) == fr.reg(iy)) 43 } 44 case reflect.Interface: 45 return func(fr *frame) { 46 x := fr.reg(ix) 47 y := fr.reg(iy) 48 fr.setReg(ir, equalValue(reflect.ValueOf(x), reflect.ValueOf(y))) 49 } 50 case reflect.Array: 51 return func(fr *frame) { 52 x := fr.reg(ix) 53 y := fr.reg(iy) 54 fr.setReg(ir, equalArray(reflect.ValueOf(x), reflect.ValueOf(y))) 55 } 56 case reflect.Struct: 57 return func(fr *frame) { 58 x := fr.reg(ix) 59 y := fr.reg(iy) 60 fr.setReg(ir, equalStruct(reflect.ValueOf(x), reflect.ValueOf(y))) 61 } 62 case reflect.UnsafePointer: 63 return func(fr *frame) { 64 fr.setReg(ir, fr.reg(ix) == fr.reg(iy)) 65 } 66 case reflect.Chan: 67 xdir := xtyp.ChanDir() 68 ydir := ytyp.ChanDir() 69 if xdir != ydir { 70 if xdir == reflect.BothDir { 71 return func(fr *frame) { 72 x := fr.reg(ix) 73 x = reflect.ValueOf(x).Convert(ytyp).Interface() 74 fr.setReg(ir, x == fr.reg(iy)) 75 } 76 } else if ydir == reflect.BothDir { 77 return func(fr *frame) { 78 y := fr.reg(iy) 79 y = reflect.ValueOf(y).Convert(xtyp).Interface() 80 fr.setReg(ir, fr.reg(ix) == y) 81 } 82 } 83 } 84 return func(fr *frame) { 85 fr.setReg(ir, fr.reg(ix) == fr.reg(iy)) 86 } 87 case reflect.Ptr: 88 return func(fr *frame) { 89 x := fr.reg(ix) 90 y := fr.reg(iy) 91 fr.setReg(ir, reflect.ValueOf(x).Pointer() == reflect.ValueOf(y).Pointer()) 92 } 93 case reflect.Slice, reflect.Map, reflect.Func: 94 return func(fr *frame) { 95 x := fr.reg(ix) 96 y := fr.reg(iy) 97 b := reflect.ValueOf(x).IsNil() && reflect.ValueOf(y).IsNil() 98 fr.setReg(ir, b) 99 } 100 default: 101 panic("unreachable") 102 } 103 } 104 105 func makeBinOpNEQ(pfn *function, instr *ssa.BinOp) func(fr *frame) { 106 ir := pfn.regIndex(instr) 107 ix, kx, vx := pfn.regIndex3(instr.X) 108 iy, ky, vy := pfn.regIndex3(instr.Y) 109 xtyp := pfn.Interp.preToType(instr.X.Type()) 110 ytyp := pfn.Interp.preToType(instr.Y.Type()) 111 if xtyp == nil && ytyp == nil { 112 return func(fr *frame) { 113 fr.setReg(ir, false) 114 } 115 } 116 switch xtyp.Kind() { 117 case reflect.Bool, 118 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 119 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, 120 reflect.Float32, reflect.Float64, 121 reflect.Complex64, reflect.Complex128, 122 reflect.String: 123 if kx == kindConst && ky == kindConst { 124 v := vx != vy 125 return func(fr *frame) { 126 fr.setReg(ir, v) 127 } 128 } else if kx == kindConst { 129 return func(fr *frame) { 130 fr.setReg(ir, vx != fr.reg(iy)) 131 } 132 } else if ky == kindConst { 133 return func(fr *frame) { 134 fr.setReg(ir, fr.reg(ix) != vy) 135 } 136 } 137 return func(fr *frame) { 138 fr.setReg(ir, fr.reg(ix) != fr.reg(iy)) 139 } 140 case reflect.Interface: 141 return func(fr *frame) { 142 x := fr.reg(ix) 143 y := fr.reg(iy) 144 fr.setReg(ir, !equalValue(reflect.ValueOf(x), reflect.ValueOf(y))) 145 } 146 case reflect.Array: 147 return func(fr *frame) { 148 x := fr.reg(ix) 149 y := fr.reg(iy) 150 fr.setReg(ir, !equalArray(reflect.ValueOf(x), reflect.ValueOf(y))) 151 } 152 case reflect.Struct: 153 return func(fr *frame) { 154 x := fr.reg(ix) 155 y := fr.reg(iy) 156 fr.setReg(ir, !equalStruct(reflect.ValueOf(x), reflect.ValueOf(y))) 157 } 158 case reflect.UnsafePointer: 159 return func(fr *frame) { 160 fr.setReg(ir, fr.reg(ix) != fr.reg(iy)) 161 } 162 case reflect.Chan: 163 xdir := xtyp.ChanDir() 164 ydir := ytyp.ChanDir() 165 if xdir != ydir { 166 if xdir == reflect.BothDir { 167 return func(fr *frame) { 168 x := fr.reg(ix) 169 x = reflect.ValueOf(x).Convert(ytyp).Interface() 170 fr.setReg(ir, x != fr.reg(iy)) 171 } 172 } else if ydir == reflect.BothDir { 173 return func(fr *frame) { 174 y := fr.reg(iy) 175 y = reflect.ValueOf(y).Convert(xtyp).Interface() 176 fr.setReg(ir, fr.reg(ix) != y) 177 } 178 } 179 } 180 return func(fr *frame) { 181 fr.setReg(ir, fr.reg(ix) != fr.reg(iy)) 182 } 183 case reflect.Ptr: 184 return func(fr *frame) { 185 x := fr.reg(ix) 186 y := fr.reg(iy) 187 fr.setReg(ir, reflect.ValueOf(x).Pointer() != reflect.ValueOf(y).Pointer()) 188 } 189 case reflect.Slice, reflect.Map, reflect.Func: 190 return func(fr *frame) { 191 x := fr.reg(ix) 192 y := fr.reg(iy) 193 b := reflect.ValueOf(x).IsNil() && reflect.ValueOf(y).IsNil() 194 fr.setReg(ir, !b) 195 } 196 default: 197 panic("unreachable") 198 } 199 }