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