GoPLS Viewer

Home|gopls/go/ssa/interp/external.go
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
5package interp
6
7// Emulated functions that we cannot interpret because they are
8// external or because they use "unsafe" or "reflect" operations.
9
10import (
11    "bytes"
12    "math"
13    "os"
14    "runtime"
15    "sort"
16    "strconv"
17    "strings"
18    "time"
19    "unicode/utf8"
20)
21
22type externalFn func(fr *frameargs []valuevalue
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().
29var externals = make(map[string]externalFn)
30
31func init() {
32    // That little dot ۰ is an Arabic zero numeral (U+06F0), categories [Nd].
33    for kv := 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
118func ext۰bytes۰Equal(fr *frameargs []valuevalue {
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
133func ext۰bytes۰IndexByte(fr *frameargs []valuevalue {
134    // func IndexByte(s []byte, c byte) int
135    s := args[0].([]value)
136    c := args[1].(byte)
137    for ib := range s {
138        if b.(byte) == c {
139            return i
140        }
141    }
142    return -1
143}
144
145func ext۰math۰Float64frombits(fr *frameargs []valuevalue {
146    return math.Float64frombits(args[0].(uint64))
147}
148
149func ext۰math۰Float64bits(fr *frameargs []valuevalue {
150    return math.Float64bits(args[0].(float64))
151}
152
153func ext۰math۰Float32frombits(fr *frameargs []valuevalue {
154    return math.Float32frombits(args[0].(uint32))
155}
156
157func ext۰math۰Abs(fr *frameargs []valuevalue {
158    return math.Abs(args[0].(float64))
159}
160
161func ext۰math۰Exp(fr *frameargs []valuevalue {
162    return math.Exp(args[0].(float64))
163}
164
165func ext۰math۰Float32bits(fr *frameargs []valuevalue {
166    return math.Float32bits(args[0].(float32))
167}
168
169func ext۰math۰Min(fr *frameargs []valuevalue {
170    return math.Min(args[0].(float64), args[1].(float64))
171}
172
173func ext۰math۰NaN(fr *frameargs []valuevalue {
174    return math.NaN()
175}
176
177func ext۰math۰IsNaN(fr *frameargs []valuevalue {
178    return math.IsNaN(args[0].(float64))
179}
180
181func ext۰math۰Inf(fr *frameargs []valuevalue {
182    return math.Inf(args[0].(int))
183}
184
185func ext۰math۰Ldexp(fr *frameargs []valuevalue {
186    return math.Ldexp(args[0].(float64), args[1].(int))
187}
188
189func ext۰math۰Log(fr *frameargs []valuevalue {
190    return math.Log(args[0].(float64))
191}
192
193func ext۰math۰Sqrt(fr *frameargs []valuevalue {
194    return math.Sqrt(args[0].(float64))
195}
196
197func ext۰runtime۰Breakpoint(fr *frameargs []valuevalue {
198    runtime.Breakpoint()
199    return nil
200}
201
202func ext۰sort۰Ints(fr *frameargs []valuevalue {
203    x := args[0].([]value)
204    sort.Slice(x, func(ij intbool {
205        return x[i].(int) < x[j].(int)
206    })
207    return nil
208}
209func ext۰sort۰Strings(fr *frameargs []valuevalue {
210    x := args[0].([]value)
211    sort.Slice(x, func(ij intbool {
212        return x[i].(string) < x[j].(string)
213    })
214    return nil
215}
216func ext۰sort۰Float64s(fr *frameargs []valuevalue {
217    x := args[0].([]value)
218    sort.Slice(x, func(ij intbool {
219        return x[i].(float64) < x[j].(float64)
220    })
221    return nil
222}
223
224func ext۰strconv۰Atoi(fr *frameargs []valuevalue {
225    ie := strconv.Atoi(args[0].(string))
226    if e != nil {
227        return tuple{iiface{fr.i.runtimeErrorStringe.Error()}}
228    }
229    return tuple{iiface{}}
230}
231func ext۰strconv۰Itoa(fr *frameargs []valuevalue {
232    return strconv.Itoa(args[0].(int))
233}
234func ext۰strconv۰FormatFloat(fr *frameargs []valuevalue {
235    return strconv.FormatFloat(args[0].(float64), args[1].(byte), args[2].(int), args[3].(int))
236}
237
238func ext۰strings۰Count(fr *frameargs []valuevalue {
239    return strings.Count(args[0].(string), args[1].(string))
240}
241
242func ext۰strings۰EqualFold(fr *frameargs []valuevalue {
243    return strings.EqualFold(args[0].(string), args[1].(string))
244}
245func ext۰strings۰IndexByte(fr *frameargs []valuevalue {
246    return strings.IndexByte(args[0].(string), args[1].(byte))
247}
248
249func ext۰strings۰Index(fr *frameargs []valuevalue {
250    return strings.Index(args[0].(string), args[1].(string))
251}
252
253func ext۰strings۰Replace(fr *frameargs []valuevalue {
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(soldnewn)
260}
261
262func ext۰strings۰ToLower(fr *frameargs []valuevalue {
263    return strings.ToLower(args[0].(string))
264}
265
266func ext۰runtime۰GOMAXPROCS(fr *frameargs []valuevalue {
267    // Ignore args[0]; don't let the interpreted program
268    // set the interpreter's GOMAXPROCS!
269    return runtime.GOMAXPROCS(0)
270}
271
272func ext۰runtime۰Goexit(fr *frameargs []valuevalue {
273    // TODO(adonovan): don't kill the interpreter's main goroutine.
274    runtime.Goexit()
275    return nil
276}
277
278func ext۰runtime۰GOROOT(fr *frameargs []valuevalue {
279    return runtime.GOROOT()
280}
281
282func ext۰runtime۰GC(fr *frameargs []valuevalue {
283    runtime.GC()
284    return nil
285}
286
287func ext۰runtime۰Gosched(fr *frameargs []valuevalue {
288    runtime.Gosched()
289    return nil
290}
291
292func ext۰runtime۰NumCPU(fr *frameargs []valuevalue {
293    return runtime.NumCPU()
294}
295
296func ext۰time۰Sleep(fr *frameargs []valuevalue {
297    time.Sleep(time.Duration(args[0].(int64)))
298    return nil
299}
300
301func valueToBytes(v value) []byte {
302    in := v.([]value)
303    b := make([]bytelen(in))
304    for i := range in {
305        b[i] = in[i].(byte)
306    }
307    return b
308}
309
310func ext۰os۰Getenv(fr *frameargs []valuevalue {
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
323func ext۰os۰Exit(fr *frameargs []valuevalue {
324    panic(exitPanic(args[0].(int)))
325}
326
327func ext۰unicode۰utf8۰DecodeRuneInString(fr *frameargs []valuevalue {
328    rn := utf8.DecodeRuneInString(args[0].(string))
329    return tuple{rn}
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.
335func ext۰fmt۰Sprint(fr *frameargs []valuevalue {
336    buf := new(bytes.Buffer)
337    wasStr := false
338    for iarg := 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}
349
MembersX
ext۰math۰Exp.fr
ext۰runtime۰GOROOT.fr
ext۰strings۰EqualFold.fr
ext۰os۰Getenv.args
ext۰bytes۰Equal.RangeStmt_5922.i
ext۰math۰Float64bits.fr
ext۰strconv۰Itoa.args
ext۰math۰IsNaN.args
ext۰strconv۰Atoi.i
ext۰strings۰EqualFold
ext۰strings۰Replace
ext۰runtime۰NumCPU
bytes
runtime
strconv
ext۰math۰Abs
ext۰strings۰IndexByte.fr
ext۰unicode۰utf8۰DecodeRuneInString.fr
ext۰strconv۰Itoa
ext۰strings۰ToLower.args
ext۰runtime۰GC
ext۰math۰Float32frombits
ext۰math۰Ldexp.args
ext۰runtime۰Breakpoint
valueToBytes.RangeStmt_10335.i
os
ext۰bytes۰IndexByte
ext۰time۰Sleep.fr
ext۰strings۰Replace.args
ext۰os۰Exit
ext۰math۰NaN.args
ext۰math۰IsNaN.fr
ext۰math۰Log.fr
ext۰bytes۰Equal
valueToBytes.v
ext۰fmt۰Sprint.RangeStmt_11106.BlockStmt.x
valueToBytes.b
ext۰os۰Exit.fr
ext۰bytes۰IndexByte.RangeStmt_6147.i
ext۰math۰Float64frombits.args
ext۰time۰Sleep
ext۰runtime۰Goexit
ext۰runtime۰Goexit.fr
ext۰runtime۰GC.fr
ext۰runtime۰Gosched.fr
ext۰math۰IsNaN
ext۰strings۰IndexByte
ext۰runtime۰GOMAXPROCS.args
ext۰math۰Exp
ext۰math۰Ldexp.fr
ext۰sort۰Float64s.fr
ext۰strconv۰Atoi
ext۰strconv۰Atoi.e
ext۰strings۰Count.args
utf8
ext۰math۰NaN.fr
ext۰math۰Inf
ext۰strings۰Index.fr
ext۰runtime۰Breakpoint.fr
ext۰unicode۰utf8۰DecodeRuneInString.r
strings
ext۰math۰Float32bits
ext۰math۰Min.fr
ext۰fmt۰Sprint.wasStr
ext۰bytes۰IndexByte.RangeStmt_6147.b
ext۰math۰Exp.args
ext۰sort۰Ints.args
ext۰math۰Float64bits
ext۰sort۰Ints
ext۰strings۰ToLower
ext۰runtime۰Goexit.args
ext۰os۰Getenv.fr
ext۰os۰Exit.args
ext۰math۰Min.args
ext۰sort۰Strings.args
ext۰strings۰ToLower.fr
ext۰strings۰EqualFold.args
ext۰runtime۰NumCPU.fr
ext۰fmt۰Sprint.buf
ext۰math۰Abs.args
ext۰math۰Log.args
ext۰sort۰Strings.fr
ext۰math۰Float64bits.args
ext۰math۰Float32frombits.args
ext۰math۰NaN
ext۰strconv۰Atoi.args
ext۰strconv۰FormatFloat.args
init
ext۰bytes۰Equal.fr
ext۰bytes۰IndexByte.args
valueToBytes
ext۰fmt۰Sprint.RangeStmt_11106.arg
ext۰runtime۰GOMAXPROCS.fr
ext۰runtime۰GC.args
ext۰math۰Float32bits.args
ext۰math۰Ldexp
ext۰strings۰Index.args
ext۰runtime۰GOROOT
ext۰time۰Sleep.args
ext۰unicode۰utf8۰DecodeRuneInString.n
sort
ext۰bytes۰Equal.args
ext۰strings۰Replace.fr
ext۰math۰Min
ext۰sort۰Float64s.args
ext۰runtime۰GOROOT.args
ext۰runtime۰Gosched.args
ext۰runtime۰NumCPU.args
ext۰fmt۰Sprint
ext۰sort۰Strings
ext۰strings۰Index
ext۰runtime۰GOMAXPROCS
init.RangeStmt_818.k
ext۰math۰Sqrt
ext۰math۰Sqrt.fr
ext۰sort۰Float64s
ext۰strconv۰Itoa.fr
math
time
externalFn
ext۰strconv۰FormatFloat
ext۰strings۰IndexByte.args
ext۰os۰Getenv
ext۰unicode۰utf8۰DecodeRuneInString.args
ext۰math۰Float32frombits.fr
ext۰strconv۰FormatFloat.fr
ext۰strings۰Count
ext۰fmt۰Sprint.fr
ext۰fmt۰Sprint.RangeStmt_11106.i
ext۰runtime۰Gosched
init.RangeStmt_818.v
ext۰math۰Abs.fr
ext۰math۰Float32bits.fr
ext۰math۰Inf.fr
ext۰math۰Inf.args
ext۰math۰Sqrt.args
ext۰strconv۰Atoi.fr
ext۰unicode۰utf8۰DecodeRuneInString
ext۰fmt۰Sprint.args
ext۰bytes۰IndexByte.fr
ext۰math۰Log
ext۰runtime۰Breakpoint.args
ext۰math۰Float64frombits
ext۰math۰Float64frombits.fr
ext۰strings۰Count.fr
ext۰sort۰Ints.fr
Members
X