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  }