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  }