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  }