github.com/goplus/gossa@v0.3.25/opcvt_x.go (about) 1 package gossa 2 3 import ( 4 "reflect" 5 6 "github.com/goplus/gossa/internal/xtype" 7 "golang.org/x/tools/go/ssa" 8 ) 9 10 func makeTypeChangeInstr(pfn *function, instr *ssa.ChangeType) func(fr *frame) { 11 typ := pfn.Interp.preToType(instr.Type()) 12 ir := pfn.regIndex(instr) 13 ix, kx, vx := pfn.regIndex3(instr.X) 14 if kx.isStatic() { 15 var v interface{} 16 if vx == nil { 17 v = reflect.New(typ).Elem().Interface() 18 } else { 19 v = reflect.ValueOf(vx).Convert(typ).Interface() 20 } 21 return func(fr *frame) { 22 fr.setReg(ir, v) 23 } 24 } 25 kind := typ.Kind() 26 switch kind { 27 case reflect.Ptr, reflect.Chan, reflect.Map, reflect.Func, reflect.Slice: 28 t := xtype.TypeOfType(typ) 29 return func(fr *frame) { 30 x := fr.reg(ix) 31 fr.setReg(ir, xtype.ConvertPtr(t, x)) 32 } 33 case reflect.Struct, reflect.Array: 34 t := xtype.TypeOfType(typ) 35 return func(fr *frame) { 36 x := fr.reg(ix) 37 fr.setReg(ir, xtype.ConvertDirect(t, x)) 38 } 39 case reflect.Interface: 40 return func(fr *frame) { 41 x := fr.reg(ix) 42 if x == nil { 43 fr.setReg(ir, reflect.New(typ).Elem().Interface()) 44 } else { 45 fr.setReg(ir, reflect.ValueOf(x).Convert(typ).Interface()) 46 } 47 } 48 case reflect.Bool: 49 if typ.PkgPath() == "" { 50 return func(fr *frame) { 51 x := fr.reg(ix) 52 fr.setReg(ir, xtype.Bool(x)) 53 } 54 } else { 55 t := xtype.TypeOfType(typ) 56 return func(fr *frame) { 57 x := fr.reg(ix) 58 fr.setReg(ir, xtype.ConvertBool(t, x)) 59 } 60 } 61 case reflect.Int: 62 if typ.PkgPath() == "" { 63 return func(fr *frame) { 64 x := fr.reg(ix) 65 fr.setReg(ir, xtype.Int(x)) 66 } 67 } else { 68 t := xtype.TypeOfType(typ) 69 return func(fr *frame) { 70 x := fr.reg(ix) 71 fr.setReg(ir, xtype.ConvertInt(t, x)) 72 } 73 } 74 case reflect.Int8: 75 if typ.PkgPath() == "" { 76 return func(fr *frame) { 77 x := fr.reg(ix) 78 fr.setReg(ir, xtype.Int8(x)) 79 } 80 } else { 81 t := xtype.TypeOfType(typ) 82 return func(fr *frame) { 83 x := fr.reg(ix) 84 fr.setReg(ir, xtype.ConvertInt8(t, x)) 85 } 86 } 87 case reflect.Int16: 88 if typ.PkgPath() == "" { 89 return func(fr *frame) { 90 x := fr.reg(ix) 91 fr.setReg(ir, xtype.Int16(x)) 92 } 93 } else { 94 t := xtype.TypeOfType(typ) 95 return func(fr *frame) { 96 x := fr.reg(ix) 97 fr.setReg(ir, xtype.ConvertInt16(t, x)) 98 } 99 } 100 case reflect.Int32: 101 if typ.PkgPath() == "" { 102 return func(fr *frame) { 103 x := fr.reg(ix) 104 fr.setReg(ir, xtype.Int32(x)) 105 } 106 } else { 107 t := xtype.TypeOfType(typ) 108 return func(fr *frame) { 109 x := fr.reg(ix) 110 fr.setReg(ir, xtype.ConvertInt32(t, x)) 111 } 112 } 113 case reflect.Int64: 114 if typ.PkgPath() == "" { 115 return func(fr *frame) { 116 x := fr.reg(ix) 117 fr.setReg(ir, xtype.Int64(x)) 118 } 119 } else { 120 t := xtype.TypeOfType(typ) 121 return func(fr *frame) { 122 x := fr.reg(ix) 123 fr.setReg(ir, xtype.ConvertInt64(t, x)) 124 } 125 } 126 case reflect.Uint: 127 if typ.PkgPath() == "" { 128 return func(fr *frame) { 129 x := fr.reg(ix) 130 fr.setReg(ir, xtype.Uint(x)) 131 } 132 } else { 133 t := xtype.TypeOfType(typ) 134 return func(fr *frame) { 135 x := fr.reg(ix) 136 fr.setReg(ir, xtype.ConvertUint(t, x)) 137 } 138 } 139 case reflect.Uint8: 140 if typ.PkgPath() == "" { 141 return func(fr *frame) { 142 x := fr.reg(ix) 143 fr.setReg(ir, xtype.Uint8(x)) 144 } 145 } else { 146 t := xtype.TypeOfType(typ) 147 return func(fr *frame) { 148 x := fr.reg(ix) 149 fr.setReg(ir, xtype.ConvertUint8(t, x)) 150 } 151 } 152 case reflect.Uint16: 153 if typ.PkgPath() == "" { 154 return func(fr *frame) { 155 x := fr.reg(ix) 156 fr.setReg(ir, xtype.Uint16(x)) 157 } 158 } else { 159 t := xtype.TypeOfType(typ) 160 return func(fr *frame) { 161 x := fr.reg(ix) 162 fr.setReg(ir, xtype.ConvertUint16(t, x)) 163 } 164 } 165 case reflect.Uint32: 166 if typ.PkgPath() == "" { 167 return func(fr *frame) { 168 x := fr.reg(ix) 169 fr.setReg(ir, xtype.Uint32(x)) 170 } 171 } else { 172 t := xtype.TypeOfType(typ) 173 return func(fr *frame) { 174 x := fr.reg(ix) 175 fr.setReg(ir, xtype.ConvertUint32(t, x)) 176 } 177 } 178 case reflect.Uint64: 179 if typ.PkgPath() == "" { 180 return func(fr *frame) { 181 x := fr.reg(ix) 182 fr.setReg(ir, xtype.Uint64(x)) 183 } 184 } else { 185 t := xtype.TypeOfType(typ) 186 return func(fr *frame) { 187 x := fr.reg(ix) 188 fr.setReg(ir, xtype.ConvertUint64(t, x)) 189 } 190 } 191 case reflect.Uintptr: 192 if typ.PkgPath() == "" { 193 return func(fr *frame) { 194 x := fr.reg(ix) 195 fr.setReg(ir, xtype.Uintptr(x)) 196 } 197 } else { 198 t := xtype.TypeOfType(typ) 199 return func(fr *frame) { 200 x := fr.reg(ix) 201 fr.setReg(ir, xtype.ConvertUintptr(t, x)) 202 } 203 } 204 case reflect.Float32: 205 if typ.PkgPath() == "" { 206 return func(fr *frame) { 207 x := fr.reg(ix) 208 fr.setReg(ir, xtype.Float32(x)) 209 } 210 } else { 211 t := xtype.TypeOfType(typ) 212 return func(fr *frame) { 213 x := fr.reg(ix) 214 fr.setReg(ir, xtype.ConvertFloat32(t, x)) 215 } 216 } 217 case reflect.Float64: 218 if typ.PkgPath() == "" { 219 return func(fr *frame) { 220 x := fr.reg(ix) 221 fr.setReg(ir, xtype.Float64(x)) 222 } 223 } else { 224 t := xtype.TypeOfType(typ) 225 return func(fr *frame) { 226 x := fr.reg(ix) 227 fr.setReg(ir, xtype.ConvertFloat64(t, x)) 228 } 229 } 230 case reflect.Complex64: 231 if typ.PkgPath() == "" { 232 return func(fr *frame) { 233 x := fr.reg(ix) 234 fr.setReg(ir, xtype.Complex64(x)) 235 } 236 } else { 237 t := xtype.TypeOfType(typ) 238 return func(fr *frame) { 239 x := fr.reg(ix) 240 fr.setReg(ir, xtype.ConvertComplex64(t, x)) 241 } 242 } 243 case reflect.Complex128: 244 if typ.PkgPath() == "" { 245 return func(fr *frame) { 246 x := fr.reg(ix) 247 fr.setReg(ir, xtype.Complex128(x)) 248 } 249 } else { 250 t := xtype.TypeOfType(typ) 251 return func(fr *frame) { 252 x := fr.reg(ix) 253 fr.setReg(ir, xtype.ConvertComplex128(t, x)) 254 } 255 } 256 case reflect.String: 257 if typ.PkgPath() == "" { 258 return func(fr *frame) { 259 x := fr.reg(ix) 260 fr.setReg(ir, xtype.String(x)) 261 } 262 } else { 263 t := xtype.TypeOfType(typ) 264 return func(fr *frame) { 265 x := fr.reg(ix) 266 fr.setReg(ir, xtype.ConvertString(t, x)) 267 } 268 } 269 } 270 panic("unreachable") 271 } 272 273 func makeConvertInstr(pfn *function, interp *Interp, instr *ssa.Convert) func(fr *frame) { 274 typ := interp.preToType(instr.Type()) 275 xtyp := interp.preToType(instr.X.Type()) 276 kind := typ.Kind() 277 xkind := xtyp.Kind() 278 ir := pfn.regIndex(instr) 279 ix, kx, vx := pfn.regIndex3(instr.X) 280 switch kind { 281 case reflect.UnsafePointer: 282 if xkind == reflect.Uintptr { 283 return func(fr *frame) { 284 v := fr.uintptr(ix) 285 fr.setReg(ir, toUnsafePointer(v)) 286 } 287 } else if xkind == reflect.Ptr { 288 return func(fr *frame) { 289 v := fr.pointer(ix) 290 fr.setReg(ir, v) 291 } 292 } 293 case reflect.Uintptr: 294 if xkind == reflect.UnsafePointer { 295 return func(fr *frame) { 296 v := fr.pointer(ix) 297 fr.setReg(ir, uintptr(v)) 298 } 299 } 300 case reflect.Ptr: 301 if xkind == reflect.UnsafePointer { 302 t := xtype.TypeOfType(typ) 303 return func(fr *frame) { 304 v := fr.reg(ix) 305 fr.setReg(ir, xtype.Make(t, v)) 306 } 307 } 308 case reflect.Slice: 309 if xkind == reflect.String { 310 t := xtype.TypeOfType(typ) 311 elem := typ.Elem() 312 switch elem.Kind() { 313 case reflect.Uint8: 314 return func(fr *frame) { 315 v := fr.string(ix) 316 fr.setReg(ir, xtype.Make(t, []byte(v))) 317 } 318 case reflect.Int32: 319 return func(fr *frame) { 320 v := fr.string(ix) 321 fr.setReg(ir, xtype.Make(t, []rune(v))) 322 } 323 } 324 } 325 case reflect.String: 326 if xkind == reflect.Slice { 327 t := xtype.TypeOfType(typ) 328 elem := xtyp.Elem() 329 switch elem.Kind() { 330 case reflect.Uint8: 331 return func(fr *frame) { 332 v := fr.bytes(ix) 333 fr.setReg(ir, xtype.Make(t, string(v))) 334 } 335 case reflect.Int32: 336 return func(fr *frame) { 337 v := fr.runes(ix) 338 fr.setReg(ir, xtype.Make(t, string(v))) 339 } 340 } 341 } 342 } 343 if kx.isStatic() { 344 v := reflect.ValueOf(vx) 345 return func(fr *frame) { 346 fr.setReg(ir, v.Convert(typ).Interface()) 347 } 348 } 349 switch kind { 350 case reflect.Int: 351 return cvtInt(ir, ix, xkind, xtyp, typ) 352 case reflect.Int8: 353 return cvtInt8(ir, ix, xkind, xtyp, typ) 354 case reflect.Int16: 355 return cvtInt16(ir, ix, xkind, xtyp, typ) 356 case reflect.Int32: 357 return cvtInt32(ir, ix, xkind, xtyp, typ) 358 case reflect.Int64: 359 return cvtInt64(ir, ix, xkind, xtyp, typ) 360 case reflect.Uint: 361 return cvtUint(ir, ix, xkind, xtyp, typ) 362 case reflect.Uint8: 363 return cvtUint8(ir, ix, xkind, xtyp, typ) 364 case reflect.Uint16: 365 return cvtUint16(ir, ix, xkind, xtyp, typ) 366 case reflect.Uint32: 367 return cvtUint32(ir, ix, xkind, xtyp, typ) 368 case reflect.Uint64: 369 return cvtUint64(ir, ix, xkind, xtyp, typ) 370 case reflect.Uintptr: 371 return cvtUintptr(ir, ix, xkind, xtyp, typ) 372 case reflect.Float32: 373 return cvtFloat32(ir, ix, xkind, xtyp, typ) 374 case reflect.Float64: 375 return cvtFloat64(ir, ix, xkind, xtyp, typ) 376 case reflect.Complex64: 377 return cvtComplex64(ir, ix, xkind, xtyp, typ) 378 case reflect.Complex128: 379 return cvtComplex128(ir, ix, xkind, xtyp, typ) 380 } 381 return func(fr *frame) { 382 v := reflect.ValueOf(fr.reg(ix)) 383 fr.setReg(ir, v.Convert(typ).Interface()) 384 } 385 }