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