github.com/goplus/gossa@v0.3.25/unop_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 makeUnOpNOT(pfn *function, instr *ssa.UnOp) func(fr *frame) { 11 ir := pfn.regIndex(instr) 12 ix, kx, vx := pfn.regIndex3(instr.X) 13 typ := pfn.Interp.preToType(instr.Type()) 14 if typ.PkgPath() == "" { 15 if kx == kindConst { 16 v := !vx.(bool) 17 return func(fr *frame) { 18 fr.setReg(ir, v) 19 } 20 } 21 return func(fr *frame) { 22 v := !fr.reg(ix).(bool) 23 fr.setReg(ir, v) 24 } 25 } else { 26 if kx == kindConst { 27 v := xtype.Not(vx) 28 return func(fr *frame) { 29 fr.setReg(ir, v) 30 } 31 } 32 return func(fr *frame) { 33 v := xtype.Not(fr.reg(ix)) 34 fr.setReg(ir, v) 35 } 36 } 37 } 38 39 func makeUnOpMUL(pfn *function, instr *ssa.UnOp) func(fr *frame) { 40 ir := pfn.regIndex(instr) 41 ix, kx, vx := pfn.regIndex3(instr.X) 42 if kx == kindGlobal { 43 v := reflect.ValueOf(vx) 44 return func(fr *frame) { 45 elem := v.Elem() 46 if !elem.IsValid() { 47 panic(runtimeError("invalid memory address or nil pointer dereference")) 48 } 49 fr.setReg(ir, elem.Interface()) 50 } 51 } 52 return func(fr *frame) { 53 elem := reflect.ValueOf(fr.reg(ix)).Elem() 54 if !elem.IsValid() { 55 panic(runtimeError("invalid memory address or nil pointer dereference")) 56 } 57 fr.setReg(ir, elem.Interface()) 58 } 59 } 60 61 func makeUnOpARROW(pfn *function, instr *ssa.UnOp) func(fr *frame) { 62 ir := pfn.regIndex(instr) 63 ix, kx, vx := pfn.regIndex3(instr.X) 64 typ := pfn.Interp.preToType(instr.X.Type()).Elem() 65 if kx == kindGlobal { 66 x := reflect.ValueOf(vx) 67 if instr.CommaOk { 68 return func(fr *frame) { 69 v, ok := x.Recv() 70 if !ok { 71 v = reflect.New(typ).Elem() 72 } 73 fr.setReg(ir, tuple{v.Interface(), ok}) 74 } 75 } 76 return func(fr *frame) { 77 v, ok := x.Recv() 78 if !ok { 79 v = reflect.New(typ).Elem() 80 } 81 fr.setReg(ir, v.Interface()) 82 } 83 } 84 if instr.CommaOk { 85 return func(fr *frame) { 86 x := reflect.ValueOf(fr.reg(ix)) 87 v, ok := x.Recv() 88 if !ok { 89 v = reflect.New(typ).Elem() 90 } 91 fr.setReg(ir, tuple{v.Interface(), ok}) 92 } 93 } 94 return func(fr *frame) { 95 x := reflect.ValueOf(fr.reg(ix)) 96 v, ok := x.Recv() 97 if !ok { 98 v = reflect.New(typ).Elem() 99 } 100 fr.setReg(ir, v.Interface()) 101 } 102 }