github.com/goplus/igop@v0.25.0/binop_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 "golang.org/x/tools/go/ssa" 23 ) 24 25 func makeBinOpEQL(pfn *function, instr *ssa.BinOp) func(fr *frame) { 26 ir := pfn.regIndex(instr) 27 ix, kx, vx := pfn.regIndex3(instr.X) 28 iy, ky, vy := pfn.regIndex3(instr.Y) 29 xtyp := pfn.Interp.preToType(instr.X.Type()) 30 ytyp := pfn.Interp.preToType(instr.Y.Type()) 31 if xtyp == nil && ytyp == nil { 32 return func(fr *frame) { 33 fr.setReg(ir, true) 34 } 35 } 36 switch xtyp.Kind() { 37 case reflect.Bool, 38 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 39 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, 40 reflect.Float32, reflect.Float64, 41 reflect.Complex64, reflect.Complex128, 42 reflect.String: 43 if kx == kindConst && ky == kindConst { 44 v := vx == vy 45 return func(fr *frame) { 46 fr.setReg(ir, v) 47 } 48 } else if kx == kindConst { 49 return func(fr *frame) { 50 fr.setReg(ir, vx == fr.reg(iy)) 51 } 52 } else if ky == kindConst { 53 return func(fr *frame) { 54 fr.setReg(ir, fr.reg(ix) == vy) 55 } 56 } 57 return func(fr *frame) { 58 fr.setReg(ir, fr.reg(ix) == fr.reg(iy)) 59 } 60 case reflect.Interface: 61 return func(fr *frame) { 62 fr.setReg(ir, fr.reg(ix) == fr.reg(iy)) 63 } 64 case reflect.Array: 65 if xtyp == ytyp { 66 return func(fr *frame) { 67 fr.setReg(ir, fr.reg(ix) == fr.reg(iy)) 68 } 69 } 70 return func(fr *frame) { 71 x := fr.reg(ix) 72 y := fr.reg(iy) 73 fr.setReg(ir, x == reflect.ValueOf(y).Convert(xtyp).Interface()) 74 } 75 case reflect.Struct: 76 return func(fr *frame) { 77 fr.setReg(ir, fr.reg(ix) == fr.reg(iy)) 78 } 79 case reflect.UnsafePointer: 80 return func(fr *frame) { 81 fr.setReg(ir, fr.reg(ix) == fr.reg(iy)) 82 } 83 case reflect.Chan: 84 xdir := xtyp.ChanDir() 85 ydir := ytyp.ChanDir() 86 if xdir != ydir { 87 if xdir == reflect.BothDir { 88 return func(fr *frame) { 89 x := fr.reg(ix) 90 x = reflect.ValueOf(x).Convert(ytyp).Interface() 91 fr.setReg(ir, x == fr.reg(iy)) 92 } 93 } else if ydir == reflect.BothDir { 94 return func(fr *frame) { 95 y := fr.reg(iy) 96 y = reflect.ValueOf(y).Convert(xtyp).Interface() 97 fr.setReg(ir, fr.reg(ix) == y) 98 } 99 } 100 } 101 return func(fr *frame) { 102 fr.setReg(ir, fr.reg(ix) == fr.reg(iy)) 103 } 104 case reflect.Ptr: 105 return func(fr *frame) { 106 x := fr.reg(ix) 107 y := fr.reg(iy) 108 fr.setReg(ir, reflect.ValueOf(x).Pointer() == reflect.ValueOf(y).Pointer()) 109 } 110 case reflect.Slice, reflect.Map, reflect.Func: 111 return func(fr *frame) { 112 x := fr.reg(ix) 113 y := fr.reg(iy) 114 b := reflect.ValueOf(x).IsNil() && reflect.ValueOf(y).IsNil() 115 fr.setReg(ir, b) 116 } 117 default: 118 panic("unreachable") 119 } 120 } 121 122 func makeBinOpNEQ(pfn *function, instr *ssa.BinOp) func(fr *frame) { 123 ir := pfn.regIndex(instr) 124 ix, kx, vx := pfn.regIndex3(instr.X) 125 iy, ky, vy := pfn.regIndex3(instr.Y) 126 xtyp := pfn.Interp.preToType(instr.X.Type()) 127 ytyp := pfn.Interp.preToType(instr.Y.Type()) 128 if xtyp == nil && ytyp == nil { 129 return func(fr *frame) { 130 fr.setReg(ir, false) 131 } 132 } 133 switch xtyp.Kind() { 134 case reflect.Bool, 135 reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 136 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, 137 reflect.Float32, reflect.Float64, 138 reflect.Complex64, reflect.Complex128, 139 reflect.String: 140 if kx == kindConst && ky == kindConst { 141 v := vx != vy 142 return func(fr *frame) { 143 fr.setReg(ir, v) 144 } 145 } else if kx == kindConst { 146 return func(fr *frame) { 147 fr.setReg(ir, vx != fr.reg(iy)) 148 } 149 } else if ky == kindConst { 150 return func(fr *frame) { 151 fr.setReg(ir, fr.reg(ix) != vy) 152 } 153 } 154 return func(fr *frame) { 155 fr.setReg(ir, fr.reg(ix) != fr.reg(iy)) 156 } 157 case reflect.Interface: 158 return func(fr *frame) { 159 fr.setReg(ir, fr.reg(ix) != fr.reg(iy)) 160 } 161 case reflect.Array: 162 if xtyp == ytyp { 163 return func(fr *frame) { 164 fr.setReg(ir, fr.reg(ix) != fr.reg(iy)) 165 } 166 } 167 return func(fr *frame) { 168 x := fr.reg(ix) 169 y := fr.reg(iy) 170 fr.setReg(ir, x != reflect.ValueOf(y).Convert(xtyp).Interface()) 171 } 172 case reflect.Struct: 173 return func(fr *frame) { 174 fr.setReg(ir, fr.reg(ix) != fr.reg(iy)) 175 } 176 case reflect.UnsafePointer: 177 return func(fr *frame) { 178 fr.setReg(ir, fr.reg(ix) != fr.reg(iy)) 179 } 180 case reflect.Chan: 181 xdir := xtyp.ChanDir() 182 ydir := ytyp.ChanDir() 183 if xdir != ydir { 184 if xdir == reflect.BothDir { 185 return func(fr *frame) { 186 x := fr.reg(ix) 187 x = reflect.ValueOf(x).Convert(ytyp).Interface() 188 fr.setReg(ir, x != fr.reg(iy)) 189 } 190 } else if ydir == reflect.BothDir { 191 return func(fr *frame) { 192 y := fr.reg(iy) 193 y = reflect.ValueOf(y).Convert(xtyp).Interface() 194 fr.setReg(ir, fr.reg(ix) != y) 195 } 196 } 197 } 198 return func(fr *frame) { 199 fr.setReg(ir, fr.reg(ix) != fr.reg(iy)) 200 } 201 case reflect.Ptr: 202 return func(fr *frame) { 203 x := fr.reg(ix) 204 y := fr.reg(iy) 205 fr.setReg(ir, reflect.ValueOf(x).Pointer() != reflect.ValueOf(y).Pointer()) 206 } 207 case reflect.Slice, reflect.Map, reflect.Func: 208 return func(fr *frame) { 209 x := fr.reg(ix) 210 y := fr.reg(iy) 211 b := reflect.ValueOf(x).IsNil() && reflect.ValueOf(y).IsNil() 212 fr.setReg(ir, !b) 213 } 214 default: 215 panic("unreachable") 216 } 217 }