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  }