github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/ssa/interp/external.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package interp 6 7 // Emulated functions that we cannot interpret because they are 8 // external or because they use "unsafe" or "reflect" operations. 9 10 import ( 11 "bytes" 12 "math" 13 "os" 14 "runtime" 15 "sort" 16 "strconv" 17 "strings" 18 "time" 19 "unicode/utf8" 20 ) 21 22 type externalFn func(fr *frame, args []value) value 23 24 // TODO(adonovan): fix: reflect.Value abstracts an lvalue or an 25 // rvalue; Set() causes mutations that can be observed via aliases. 26 // We have not captured that correctly here. 27 28 // Key strings are from Function.String(). 29 var externals = make(map[string]externalFn) 30 31 func init() { 32 // That little dot ۰ is an Arabic zero numeral (U+06F0), categories [Nd]. 33 for k, v := range map[string]externalFn{ 34 "(reflect.Value).Bool": ext۰reflect۰Value۰Bool, 35 "(reflect.Value).CanAddr": ext۰reflect۰Value۰CanAddr, 36 "(reflect.Value).CanInterface": ext۰reflect۰Value۰CanInterface, 37 "(reflect.Value).Elem": ext۰reflect۰Value۰Elem, 38 "(reflect.Value).Field": ext۰reflect۰Value۰Field, 39 "(reflect.Value).Float": ext۰reflect۰Value۰Float, 40 "(reflect.Value).Index": ext۰reflect۰Value۰Index, 41 "(reflect.Value).Int": ext۰reflect۰Value۰Int, 42 "(reflect.Value).Interface": ext۰reflect۰Value۰Interface, 43 "(reflect.Value).IsNil": ext۰reflect۰Value۰IsNil, 44 "(reflect.Value).IsValid": ext۰reflect۰Value۰IsValid, 45 "(reflect.Value).Kind": ext۰reflect۰Value۰Kind, 46 "(reflect.Value).Len": ext۰reflect۰Value۰Len, 47 "(reflect.Value).MapIndex": ext۰reflect۰Value۰MapIndex, 48 "(reflect.Value).MapKeys": ext۰reflect۰Value۰MapKeys, 49 "(reflect.Value).NumField": ext۰reflect۰Value۰NumField, 50 "(reflect.Value).NumMethod": ext۰reflect۰Value۰NumMethod, 51 "(reflect.Value).Pointer": ext۰reflect۰Value۰Pointer, 52 "(reflect.Value).Set": ext۰reflect۰Value۰Set, 53 "(reflect.Value).String": ext۰reflect۰Value۰String, 54 "(reflect.Value).Type": ext۰reflect۰Value۰Type, 55 "(reflect.Value).Uint": ext۰reflect۰Value۰Uint, 56 "(reflect.error).Error": ext۰reflect۰error۰Error, 57 "(reflect.rtype).Bits": ext۰reflect۰rtype۰Bits, 58 "(reflect.rtype).Elem": ext۰reflect۰rtype۰Elem, 59 "(reflect.rtype).Field": ext۰reflect۰rtype۰Field, 60 "(reflect.rtype).In": ext۰reflect۰rtype۰In, 61 "(reflect.rtype).Kind": ext۰reflect۰rtype۰Kind, 62 "(reflect.rtype).NumField": ext۰reflect۰rtype۰NumField, 63 "(reflect.rtype).NumIn": ext۰reflect۰rtype۰NumIn, 64 "(reflect.rtype).NumMethod": ext۰reflect۰rtype۰NumMethod, 65 "(reflect.rtype).NumOut": ext۰reflect۰rtype۰NumOut, 66 "(reflect.rtype).Out": ext۰reflect۰rtype۰Out, 67 "(reflect.rtype).Size": ext۰reflect۰rtype۰Size, 68 "(reflect.rtype).String": ext۰reflect۰rtype۰String, 69 "bytes.Equal": ext۰bytes۰Equal, 70 "bytes.IndexByte": ext۰bytes۰IndexByte, 71 "fmt.Sprint": ext۰fmt۰Sprint, 72 "math.Abs": ext۰math۰Abs, 73 "math.Exp": ext۰math۰Exp, 74 "math.Float32bits": ext۰math۰Float32bits, 75 "math.Float32frombits": ext۰math۰Float32frombits, 76 "math.Float64bits": ext۰math۰Float64bits, 77 "math.Float64frombits": ext۰math۰Float64frombits, 78 "math.Inf": ext۰math۰Inf, 79 "math.IsNaN": ext۰math۰IsNaN, 80 "math.Ldexp": ext۰math۰Ldexp, 81 "math.Log": ext۰math۰Log, 82 "math.Min": ext۰math۰Min, 83 "math.NaN": ext۰math۰NaN, 84 "math.Sqrt": ext۰math۰Sqrt, 85 "os.Exit": ext۰os۰Exit, 86 "os.Getenv": ext۰os۰Getenv, 87 "reflect.New": ext۰reflect۰New, 88 "reflect.SliceOf": ext۰reflect۰SliceOf, 89 "reflect.TypeOf": ext۰reflect۰TypeOf, 90 "reflect.ValueOf": ext۰reflect۰ValueOf, 91 "reflect.Zero": ext۰reflect۰Zero, 92 "runtime.Breakpoint": ext۰runtime۰Breakpoint, 93 "runtime.GC": ext۰runtime۰GC, 94 "runtime.GOMAXPROCS": ext۰runtime۰GOMAXPROCS, 95 "runtime.GOROOT": ext۰runtime۰GOROOT, 96 "runtime.Goexit": ext۰runtime۰Goexit, 97 "runtime.Gosched": ext۰runtime۰Gosched, 98 "runtime.NumCPU": ext۰runtime۰NumCPU, 99 "sort.Float64s": ext۰sort۰Float64s, 100 "sort.Ints": ext۰sort۰Ints, 101 "sort.Strings": ext۰sort۰Strings, 102 "strconv.Atoi": ext۰strconv۰Atoi, 103 "strconv.Itoa": ext۰strconv۰Itoa, 104 "strconv.FormatFloat": ext۰strconv۰FormatFloat, 105 "strings.Count": ext۰strings۰Count, 106 "strings.EqualFold": ext۰strings۰EqualFold, 107 "strings.Index": ext۰strings۰Index, 108 "strings.IndexByte": ext۰strings۰IndexByte, 109 "strings.Replace": ext۰strings۰Replace, 110 "strings.ToLower": ext۰strings۰ToLower, 111 "time.Sleep": ext۰time۰Sleep, 112 "unicode/utf8.DecodeRuneInString": ext۰unicode۰utf8۰DecodeRuneInString, 113 } { 114 externals[k] = v 115 } 116 } 117 118 func ext۰bytes۰Equal(fr *frame, args []value) value { 119 // func Equal(a, b []byte) bool 120 a := args[0].([]value) 121 b := args[1].([]value) 122 if len(a) != len(b) { 123 return false 124 } 125 for i := range a { 126 if a[i] != b[i] { 127 return false 128 } 129 } 130 return true 131 } 132 133 func ext۰bytes۰IndexByte(fr *frame, args []value) value { 134 // func IndexByte(s []byte, c byte) int 135 s := args[0].([]value) 136 c := args[1].(byte) 137 for i, b := range s { 138 if b.(byte) == c { 139 return i 140 } 141 } 142 return -1 143 } 144 145 func ext۰math۰Float64frombits(fr *frame, args []value) value { 146 return math.Float64frombits(args[0].(uint64)) 147 } 148 149 func ext۰math۰Float64bits(fr *frame, args []value) value { 150 return math.Float64bits(args[0].(float64)) 151 } 152 153 func ext۰math۰Float32frombits(fr *frame, args []value) value { 154 return math.Float32frombits(args[0].(uint32)) 155 } 156 157 func ext۰math۰Abs(fr *frame, args []value) value { 158 return math.Abs(args[0].(float64)) 159 } 160 161 func ext۰math۰Exp(fr *frame, args []value) value { 162 return math.Exp(args[0].(float64)) 163 } 164 165 func ext۰math۰Float32bits(fr *frame, args []value) value { 166 return math.Float32bits(args[0].(float32)) 167 } 168 169 func ext۰math۰Min(fr *frame, args []value) value { 170 return math.Min(args[0].(float64), args[1].(float64)) 171 } 172 173 func ext۰math۰NaN(fr *frame, args []value) value { 174 return math.NaN() 175 } 176 177 func ext۰math۰IsNaN(fr *frame, args []value) value { 178 return math.IsNaN(args[0].(float64)) 179 } 180 181 func ext۰math۰Inf(fr *frame, args []value) value { 182 return math.Inf(args[0].(int)) 183 } 184 185 func ext۰math۰Ldexp(fr *frame, args []value) value { 186 return math.Ldexp(args[0].(float64), args[1].(int)) 187 } 188 189 func ext۰math۰Log(fr *frame, args []value) value { 190 return math.Log(args[0].(float64)) 191 } 192 193 func ext۰math۰Sqrt(fr *frame, args []value) value { 194 return math.Sqrt(args[0].(float64)) 195 } 196 197 func ext۰runtime۰Breakpoint(fr *frame, args []value) value { 198 runtime.Breakpoint() 199 return nil 200 } 201 202 func ext۰sort۰Ints(fr *frame, args []value) value { 203 x := args[0].([]value) 204 sort.Slice(x, func(i, j int) bool { 205 return x[i].(int) < x[j].(int) 206 }) 207 return nil 208 } 209 func ext۰sort۰Strings(fr *frame, args []value) value { 210 x := args[0].([]value) 211 sort.Slice(x, func(i, j int) bool { 212 return x[i].(string) < x[j].(string) 213 }) 214 return nil 215 } 216 func ext۰sort۰Float64s(fr *frame, args []value) value { 217 x := args[0].([]value) 218 sort.Slice(x, func(i, j int) bool { 219 return x[i].(float64) < x[j].(float64) 220 }) 221 return nil 222 } 223 224 func ext۰strconv۰Atoi(fr *frame, args []value) value { 225 i, e := strconv.Atoi(args[0].(string)) 226 if e != nil { 227 return tuple{i, iface{fr.i.runtimeErrorString, e.Error()}} 228 } 229 return tuple{i, iface{}} 230 } 231 func ext۰strconv۰Itoa(fr *frame, args []value) value { 232 return strconv.Itoa(args[0].(int)) 233 } 234 func ext۰strconv۰FormatFloat(fr *frame, args []value) value { 235 return strconv.FormatFloat(args[0].(float64), args[1].(byte), args[2].(int), args[3].(int)) 236 } 237 238 func ext۰strings۰Count(fr *frame, args []value) value { 239 return strings.Count(args[0].(string), args[1].(string)) 240 } 241 242 func ext۰strings۰EqualFold(fr *frame, args []value) value { 243 return strings.EqualFold(args[0].(string), args[1].(string)) 244 } 245 func ext۰strings۰IndexByte(fr *frame, args []value) value { 246 return strings.IndexByte(args[0].(string), args[1].(byte)) 247 } 248 249 func ext۰strings۰Index(fr *frame, args []value) value { 250 return strings.Index(args[0].(string), args[1].(string)) 251 } 252 253 func ext۰strings۰Replace(fr *frame, args []value) value { 254 // func Replace(s, old, new string, n int) string 255 s := args[0].(string) 256 new := args[1].(string) 257 old := args[2].(string) 258 n := args[3].(int) 259 return strings.Replace(s, old, new, n) 260 } 261 262 func ext۰strings۰ToLower(fr *frame, args []value) value { 263 return strings.ToLower(args[0].(string)) 264 } 265 266 func ext۰runtime۰GOMAXPROCS(fr *frame, args []value) value { 267 // Ignore args[0]; don't let the interpreted program 268 // set the interpreter's GOMAXPROCS! 269 return runtime.GOMAXPROCS(0) 270 } 271 272 func ext۰runtime۰Goexit(fr *frame, args []value) value { 273 // TODO(adonovan): don't kill the interpreter's main goroutine. 274 runtime.Goexit() 275 return nil 276 } 277 278 func ext۰runtime۰GOROOT(fr *frame, args []value) value { 279 return runtime.GOROOT() 280 } 281 282 func ext۰runtime۰GC(fr *frame, args []value) value { 283 runtime.GC() 284 return nil 285 } 286 287 func ext۰runtime۰Gosched(fr *frame, args []value) value { 288 runtime.Gosched() 289 return nil 290 } 291 292 func ext۰runtime۰NumCPU(fr *frame, args []value) value { 293 return runtime.NumCPU() 294 } 295 296 func ext۰time۰Sleep(fr *frame, args []value) value { 297 time.Sleep(time.Duration(args[0].(int64))) 298 return nil 299 } 300 301 func valueToBytes(v value) []byte { 302 in := v.([]value) 303 b := make([]byte, len(in)) 304 for i := range in { 305 b[i] = in[i].(byte) 306 } 307 return b 308 } 309 310 func ext۰os۰Getenv(fr *frame, args []value) value { 311 name := args[0].(string) 312 switch name { 313 case "GOSSAINTERP": 314 return "1" 315 case "GOARCH": 316 return "amd64" 317 case "GOOS": 318 return "linux" 319 } 320 return os.Getenv(name) 321 } 322 323 func ext۰os۰Exit(fr *frame, args []value) value { 324 panic(exitPanic(args[0].(int))) 325 } 326 327 func ext۰unicode۰utf8۰DecodeRuneInString(fr *frame, args []value) value { 328 r, n := utf8.DecodeRuneInString(args[0].(string)) 329 return tuple{r, n} 330 } 331 332 // A fake function for turning an arbitrary value into a string. 333 // Handles only the cases needed by the tests. 334 // Uses same logic as 'print' built-in. 335 func ext۰fmt۰Sprint(fr *frame, args []value) value { 336 buf := new(bytes.Buffer) 337 wasStr := false 338 for i, arg := range args[0].([]value) { 339 x := arg.(iface).v 340 _, isStr := x.(string) 341 if i > 0 && !wasStr && !isStr { 342 buf.WriteByte(' ') 343 } 344 wasStr = isStr 345 buf.WriteString(toString(x)) 346 } 347 return buf.String() 348 }