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.
7 // Emulated functions that we cannot interpret because they are
8 // external or because they use "unsafe" or "reflect" operations.
20 type externalFn func(fr *frame, args []value) value
22 // TODO(adonovan): fix: reflect.Value abstracts an lvalue or an
23 // rvalue; Set() causes mutations that can be observed via aliases.
24 // We have not captured that correctly here.
26 // Key strings are from Function.String().
27 var externals = make(map[string]externalFn)
30 // That little dot ۰ is an Arabic zero numeral (U+06F0), categories [Nd].
31 for k, v := range map[string]externalFn{
32 "(reflect.Value).Bool": ext۰reflect۰Value۰Bool,
33 "(reflect.Value).CanAddr": ext۰reflect۰Value۰CanAddr,
34 "(reflect.Value).CanInterface": ext۰reflect۰Value۰CanInterface,
35 "(reflect.Value).Elem": ext۰reflect۰Value۰Elem,
36 "(reflect.Value).Field": ext۰reflect۰Value۰Field,
37 "(reflect.Value).Float": ext۰reflect۰Value۰Float,
38 "(reflect.Value).Index": ext۰reflect۰Value۰Index,
39 "(reflect.Value).Int": ext۰reflect۰Value۰Int,
40 "(reflect.Value).Interface": ext۰reflect۰Value۰Interface,
41 "(reflect.Value).IsNil": ext۰reflect۰Value۰IsNil,
42 "(reflect.Value).IsValid": ext۰reflect۰Value۰IsValid,
43 "(reflect.Value).Kind": ext۰reflect۰Value۰Kind,
44 "(reflect.Value).Len": ext۰reflect۰Value۰Len,
45 "(reflect.Value).MapIndex": ext۰reflect۰Value۰MapIndex,
46 "(reflect.Value).MapKeys": ext۰reflect۰Value۰MapKeys,
47 "(reflect.Value).NumField": ext۰reflect۰Value۰NumField,
48 "(reflect.Value).NumMethod": ext۰reflect۰Value۰NumMethod,
49 "(reflect.Value).Pointer": ext۰reflect۰Value۰Pointer,
50 "(reflect.Value).Set": ext۰reflect۰Value۰Set,
51 "(reflect.Value).String": ext۰reflect۰Value۰String,
52 "(reflect.Value).Type": ext۰reflect۰Value۰Type,
53 "(reflect.Value).Uint": ext۰reflect۰Value۰Uint,
54 "(reflect.error).Error": ext۰reflect۰error۰Error,
55 "(reflect.rtype).Bits": ext۰reflect۰rtype۰Bits,
56 "(reflect.rtype).Elem": ext۰reflect۰rtype۰Elem,
57 "(reflect.rtype).Field": ext۰reflect۰rtype۰Field,
58 "(reflect.rtype).In": ext۰reflect۰rtype۰In,
59 "(reflect.rtype).Kind": ext۰reflect۰rtype۰Kind,
60 "(reflect.rtype).NumField": ext۰reflect۰rtype۰NumField,
61 "(reflect.rtype).NumIn": ext۰reflect۰rtype۰NumIn,
62 "(reflect.rtype).NumMethod": ext۰reflect۰rtype۰NumMethod,
63 "(reflect.rtype).NumOut": ext۰reflect۰rtype۰NumOut,
64 "(reflect.rtype).Out": ext۰reflect۰rtype۰Out,
65 "(reflect.rtype).Size": ext۰reflect۰rtype۰Size,
66 "(reflect.rtype).String": ext۰reflect۰rtype۰String,
67 "bytes.Equal": ext۰bytes۰Equal,
68 "bytes.IndexByte": ext۰bytes۰IndexByte,
69 "fmt.Sprint": ext۰fmt۰Sprint,
70 "math.Abs": ext۰math۰Abs,
71 "math.Exp": ext۰math۰Exp,
72 "math.Float32bits": ext۰math۰Float32bits,
73 "math.Float32frombits": ext۰math۰Float32frombits,
74 "math.Float64bits": ext۰math۰Float64bits,
75 "math.Float64frombits": ext۰math۰Float64frombits,
76 "math.Inf": ext۰math۰Inf,
77 "math.IsNaN": ext۰math۰IsNaN,
78 "math.Ldexp": ext۰math۰Ldexp,
79 "math.Log": ext۰math۰Log,
80 "math.Min": ext۰math۰Min,
81 "math.NaN": ext۰math۰NaN,
82 "os.Exit": ext۰os۰Exit,
83 "os.Getenv": ext۰os۰Getenv,
84 "reflect.New": ext۰reflect۰New,
85 "reflect.SliceOf": ext۰reflect۰SliceOf,
86 "reflect.TypeOf": ext۰reflect۰TypeOf,
87 "reflect.ValueOf": ext۰reflect۰ValueOf,
88 "reflect.Zero": ext۰reflect۰Zero,
89 "runtime.Breakpoint": ext۰runtime۰Breakpoint,
90 "runtime.GC": ext۰runtime۰GC,
91 "runtime.GOMAXPROCS": ext۰runtime۰GOMAXPROCS,
92 "runtime.GOROOT": ext۰runtime۰GOROOT,
93 "runtime.Goexit": ext۰runtime۰Goexit,
94 "runtime.Gosched": ext۰runtime۰Gosched,
95 "runtime.NumCPU": ext۰runtime۰NumCPU,
96 "strings.Count": ext۰strings۰Count,
97 "strings.Index": ext۰strings۰Index,
98 "strings.IndexByte": ext۰strings۰IndexByte,
99 "strings.Replace": ext۰strings۰Replace,
100 "time.Sleep": ext۰time۰Sleep,
101 "unicode/utf8.DecodeRuneInString": ext۰unicode۰utf8۰DecodeRuneInString,
107 func ext۰bytes۰Equal(fr *frame, args []value) value {
108 // func Equal(a, b []byte) bool
109 a := args[0].([]value)
110 b := args[1].([]value)
111 if len(a) != len(b) {
122 func ext۰bytes۰IndexByte(fr *frame, args []value) value {
123 // func IndexByte(s []byte, c byte) int
124 s := args[0].([]value)
126 for i, b := range s {
134 func ext۰math۰Float64frombits(fr *frame, args []value) value {
135 return math.Float64frombits(args[0].(uint64))
138 func ext۰math۰Float64bits(fr *frame, args []value) value {
139 return math.Float64bits(args[0].(float64))
142 func ext۰math۰Float32frombits(fr *frame, args []value) value {
143 return math.Float32frombits(args[0].(uint32))
146 func ext۰math۰Abs(fr *frame, args []value) value {
147 return math.Abs(args[0].(float64))
150 func ext۰math۰Exp(fr *frame, args []value) value {
151 return math.Exp(args[0].(float64))
154 func ext۰math۰Float32bits(fr *frame, args []value) value {
155 return math.Float32bits(args[0].(float32))
158 func ext۰math۰Min(fr *frame, args []value) value {
159 return math.Min(args[0].(float64), args[1].(float64))
162 func ext۰math۰NaN(fr *frame, args []value) value {
166 func ext۰math۰IsNaN(fr *frame, args []value) value {
167 return math.IsNaN(args[0].(float64))
170 func ext۰math۰Inf(fr *frame, args []value) value {
171 return math.Inf(args[0].(int))
174 func ext۰math۰Ldexp(fr *frame, args []value) value {
175 return math.Ldexp(args[0].(float64), args[1].(int))
178 func ext۰math۰Log(fr *frame, args []value) value {
179 return math.Log(args[0].(float64))
182 func ext۰runtime۰Breakpoint(fr *frame, args []value) value {
187 func ext۰strings۰Count(fr *frame, args []value) value {
188 return strings.Count(args[0].(string), args[1].(string))
191 func ext۰strings۰IndexByte(fr *frame, args []value) value {
192 return strings.IndexByte(args[0].(string), args[1].(byte))
195 func ext۰strings۰Index(fr *frame, args []value) value {
196 return strings.Index(args[0].(string), args[1].(string))
199 func ext۰strings۰Replace(fr *frame, args []value) value {
200 // func Replace(s, old, new string, n int) string
201 s := args[0].(string)
202 new := args[1].(string)
203 old := args[2].(string)
205 return strings.Replace(s, old, new, n)
208 func ext۰runtime۰GOMAXPROCS(fr *frame, args []value) value {
209 // Ignore args[0]; don't let the interpreted program
210 // set the interpreter's GOMAXPROCS!
211 return runtime.GOMAXPROCS(0)
214 func ext۰runtime۰Goexit(fr *frame, args []value) value {
215 // TODO(adonovan): don't kill the interpreter's main goroutine.
220 func ext۰runtime۰GOROOT(fr *frame, args []value) value {
221 return runtime.GOROOT()
224 func ext۰runtime۰GC(fr *frame, args []value) value {
229 func ext۰runtime۰Gosched(fr *frame, args []value) value {
234 func ext۰runtime۰NumCPU(fr *frame, args []value) value {
235 return runtime.NumCPU()
238 func ext۰time۰Sleep(fr *frame, args []value) value {
239 time.Sleep(time.Duration(args[0].(int64)))
243 func valueToBytes(v value) []byte {
245 b := make([]byte, len(in))
252 func ext۰os۰Getenv(fr *frame, args []value) value {
253 name := args[0].(string)
262 return os.Getenv(name)
265 func ext۰os۰Exit(fr *frame, args []value) value {
266 panic(exitPanic(args[0].(int)))
269 func ext۰unicode۰utf8۰DecodeRuneInString(fr *frame, args []value) value {
270 r, n := utf8.DecodeRuneInString(args[0].(string))
274 // A fake function for turning an arbitrary value into a string.
275 // Handles only the cases needed by the tests.
276 // Uses same logic as 'print' built-in.
277 func ext۰fmt۰Sprint(fr *frame, args []value) value {
278 buf := new(bytes.Buffer)
280 for i, arg := range args[0].([]value) {
282 _, isStr := x.(string)
283 if i > 0 && !wasStr && !isStr {
287 buf.WriteString(toString(x))