OLD | NEW |
1 // Copyright 2013 The Go Authors. All rights reserved. | 1 // Copyright 2013 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package interp | 5 package interp |
6 | 6 |
7 // Emulated functions that we cannot interpret because they are | 7 // Emulated functions that we cannot interpret because they are |
8 // external or because they use "unsafe" or "reflect" operations. | 8 // external or because they use "unsafe" or "reflect" operations. |
9 | 9 |
10 import ( | 10 import ( |
11 "exp/ssa" | 11 "exp/ssa" |
12 "math" | 12 "math" |
13 "os" | 13 "os" |
14 "runtime" | 14 "runtime" |
15 "syscall" | 15 "syscall" |
16 "time" | 16 "time" |
17 ) | 17 ) |
18 | 18 |
19 type externalFn func(fn *ssa.Function, args []value, slots []value) value | 19 type externalFn func(fn *ssa.Function, args []value) value |
20 | 20 |
21 // Key strings are from Function.FullName(). | 21 // Key strings are from Function.FullName(). |
22 // That little dot ۰ is an Arabic zero numeral (U+06F0), categories [Nd]. | 22 // That little dot ۰ is an Arabic zero numeral (U+06F0), categories [Nd]. |
23 var externals = map[string]externalFn{ | 23 var externals = map[string]externalFn{ |
24 "(reflect.Value).CanAddr": ext۰reflect۰Value۰CanAddr, | 24 "(reflect.Value).CanAddr": ext۰reflect۰Value۰CanAddr, |
25 "(reflect.Value).CanInterface": ext۰reflect۰Value۰CanInterface, | 25 "(reflect.Value).CanInterface": ext۰reflect۰Value۰CanInterface, |
26 "(reflect.Value).Elem": ext۰reflect۰Value۰Elem, | 26 "(reflect.Value).Elem": ext۰reflect۰Value۰Elem, |
27 "(reflect.Value).Field": ext۰reflect۰Value۰Field, | 27 "(reflect.Value).Field": ext۰reflect۰Value۰Field, |
28 "(reflect.Value).Index": ext۰reflect۰Value۰Index, | 28 "(reflect.Value).Index": ext۰reflect۰Value۰Index, |
29 "(reflect.Value).Int": ext۰reflect۰Value۰Int, | 29 "(reflect.Value).Int": ext۰reflect۰Value۰Int, |
30 "(reflect.Value).Interface": ext۰reflect۰Value۰Interface, | 30 "(reflect.Value).Interface": ext۰reflect۰Value۰Interface, |
31 "(reflect.Value).IsNil": ext۰reflect۰Value۰IsNil, | 31 "(reflect.Value).IsNil": ext۰reflect۰Value۰IsNil, |
32 "(reflect.Value).IsValid": ext۰reflect۰Value۰IsValid, | 32 "(reflect.Value).IsValid": ext۰reflect۰Value۰IsValid, |
33 "(reflect.Value).Kind": ext۰reflect۰Value۰Kind, | 33 "(reflect.Value).Kind": ext۰reflect۰Value۰Kind, |
34 "(reflect.Value).Len": ext۰reflect۰Value۰Len, | 34 "(reflect.Value).Len": ext۰reflect۰Value۰Len, |
35 "(reflect.Value).NumField": ext۰reflect۰Value۰NumField, | 35 "(reflect.Value).NumField": ext۰reflect۰Value۰NumField, |
36 "(reflect.Value).Pointer": ext۰reflect۰Value۰Pointer, | 36 "(reflect.Value).Pointer": ext۰reflect۰Value۰Pointer, |
| 37 "(reflect.Value).String": ext۰reflect۰Value۰String, |
37 "(reflect.Value).Type": ext۰reflect۰Value۰Type, | 38 "(reflect.Value).Type": ext۰reflect۰Value۰Type, |
38 "(reflect.rtype).Bits": ext۰reflect۰rtype۰Bits, | 39 "(reflect.rtype).Bits": ext۰reflect۰rtype۰Bits, |
39 "(reflect.rtype).Elem": ext۰reflect۰rtype۰Elem, | 40 "(reflect.rtype).Elem": ext۰reflect۰rtype۰Elem, |
40 "(reflect.rtype).Kind": ext۰reflect۰rtype۰Kind, | 41 "(reflect.rtype).Kind": ext۰reflect۰rtype۰Kind, |
41 "(reflect.rtype).String": ext۰reflect۰rtype۰String, | 42 "(reflect.rtype).String": ext۰reflect۰rtype۰String, |
42 "math.Float32bits": ext۰math۰Float32bits, | 43 "math.Float32bits": ext۰math۰Float32bits, |
43 "math.Float32frombits": ext۰math۰Float32frombits, | 44 "math.Float32frombits": ext۰math۰Float32frombits, |
44 "math.Float64bits": ext۰math۰Float64bits, | 45 "math.Float64bits": ext۰math۰Float64bits, |
45 "math.Float64frombits": ext۰math۰Float64frombits, | 46 "math.Float64frombits": ext۰math۰Float64frombits, |
46 "reflect.TypeOf": ext۰reflect۰TypeOf, | 47 "reflect.TypeOf": ext۰reflect۰TypeOf, |
(...skipping 14 matching lines...) Expand all Loading... |
61 "sync/atomic.StoreInt32": ext۰atomic۰StoreInt32, | 62 "sync/atomic.StoreInt32": ext۰atomic۰StoreInt32, |
62 "sync/atomic.StoreUint32": ext۰atomic۰StoreUint32, | 63 "sync/atomic.StoreUint32": ext۰atomic۰StoreUint32, |
63 "syscall.Exit": ext۰syscall۰Exit, | 64 "syscall.Exit": ext۰syscall۰Exit, |
64 "syscall.Getpid": ext۰syscall۰Getpid, | 65 "syscall.Getpid": ext۰syscall۰Getpid, |
65 "syscall.Kill": ext۰syscall۰Kill, | 66 "syscall.Kill": ext۰syscall۰Kill, |
66 "syscall.Write": ext۰syscall۰Write, | 67 "syscall.Write": ext۰syscall۰Write, |
67 "time.Sleep": ext۰time۰Sleep, | 68 "time.Sleep": ext۰time۰Sleep, |
68 "time.now": ext۰time۰now, | 69 "time.now": ext۰time۰now, |
69 } | 70 } |
70 | 71 |
71 func ext۰math۰Float64frombits(fn *ssa.Function, args []value, slots []value) val
ue { | 72 func ext۰math۰Float64frombits(fn *ssa.Function, args []value) value { |
72 return math.Float64frombits(args[0].(uint64)) | 73 return math.Float64frombits(args[0].(uint64)) |
73 } | 74 } |
74 | 75 |
75 func ext۰math۰Float64bits(fn *ssa.Function, args []value, slots []value) value { | 76 func ext۰math۰Float64bits(fn *ssa.Function, args []value) value { |
76 return math.Float64bits(args[0].(float64)) | 77 return math.Float64bits(args[0].(float64)) |
77 } | 78 } |
78 | 79 |
79 func ext۰math۰Float32frombits(fn *ssa.Function, args []value, slots []value) val
ue { | 80 func ext۰math۰Float32frombits(fn *ssa.Function, args []value) value { |
80 return math.Float32frombits(args[0].(uint32)) | 81 return math.Float32frombits(args[0].(uint32)) |
81 } | 82 } |
82 | 83 |
83 func ext۰math۰Float32bits(fn *ssa.Function, args []value, slots []value) value { | 84 func ext۰math۰Float32bits(fn *ssa.Function, args []value) value { |
84 return math.Float32bits(args[0].(float32)) | 85 return math.Float32bits(args[0].(float32)) |
85 } | 86 } |
86 | 87 |
87 func ext۰runtime۰Breakpoint(fn *ssa.Function, args []value, slots []value) value
{ | 88 func ext۰runtime۰Breakpoint(fn *ssa.Function, args []value) value { |
88 runtime.Breakpoint() | 89 runtime.Breakpoint() |
89 return nil | 90 return nil |
90 } | 91 } |
91 | 92 |
92 func ext۰runtime۰getgoroot(fn *ssa.Function, args []value, slots []value) value
{ | 93 func ext۰runtime۰getgoroot(fn *ssa.Function, args []value) value { |
93 return os.Getenv("GOROOT") | 94 return os.Getenv("GOROOT") |
94 } | 95 } |
95 | 96 |
96 func ext۰runtime۰GOMAXPROCS(fn *ssa.Function, args []value, slots []value) value
{ | 97 func ext۰runtime۰GOMAXPROCS(fn *ssa.Function, args []value) value { |
97 return runtime.GOMAXPROCS(args[0].(int)) | 98 return runtime.GOMAXPROCS(args[0].(int)) |
98 } | 99 } |
99 | 100 |
100 func ext۰runtime۰GC(fn *ssa.Function, args []value, slots []value) value { | 101 func ext۰runtime۰GC(fn *ssa.Function, args []value) value { |
101 runtime.GC() | 102 runtime.GC() |
102 return nil | 103 return nil |
103 } | 104 } |
104 | 105 |
105 func ext۰runtime۰Gosched(fn *ssa.Function, args []value, slots []value) value { | 106 func ext۰runtime۰Gosched(fn *ssa.Function, args []value) value { |
106 runtime.Gosched() | 107 runtime.Gosched() |
107 return nil | 108 return nil |
108 } | 109 } |
109 | 110 |
110 func ext۰runtime۰ReadMemStats(fn *ssa.Function, args []value, slots []value) val
ue { | 111 func ext۰runtime۰ReadMemStats(fn *ssa.Function, args []value) value { |
111 // TODO(adonovan): populate args[0].(Struct) | 112 // TODO(adonovan): populate args[0].(Struct) |
112 return nil | 113 return nil |
113 } | 114 } |
114 | 115 |
115 func ext۰atomic۰LoadUint32(fn *ssa.Function, args []value, slots []value) value
{ | 116 func ext۰atomic۰LoadUint32(fn *ssa.Function, args []value) value { |
116 // TODO(adonovan): fix: not atomic! | 117 // TODO(adonovan): fix: not atomic! |
117 return (*args[0].(*value)).(uint32) | 118 return (*args[0].(*value)).(uint32) |
118 } | 119 } |
119 | 120 |
120 func ext۰atomic۰StoreUint32(fn *ssa.Function, args []value, slots []value) value
{ | 121 func ext۰atomic۰StoreUint32(fn *ssa.Function, args []value) value { |
121 // TODO(adonovan): fix: not atomic! | 122 // TODO(adonovan): fix: not atomic! |
122 *args[0].(*value) = args[1].(uint32) | 123 *args[0].(*value) = args[1].(uint32) |
123 return nil | 124 return nil |
124 } | 125 } |
125 | 126 |
126 func ext۰atomic۰LoadInt32(fn *ssa.Function, args []value, slots []value) value { | 127 func ext۰atomic۰LoadInt32(fn *ssa.Function, args []value) value { |
127 // TODO(adonovan): fix: not atomic! | 128 // TODO(adonovan): fix: not atomic! |
128 return (*args[0].(*value)).(int32) | 129 return (*args[0].(*value)).(int32) |
129 } | 130 } |
130 | 131 |
131 func ext۰atomic۰StoreInt32(fn *ssa.Function, args []value, slots []value) value
{ | 132 func ext۰atomic۰StoreInt32(fn *ssa.Function, args []value) value { |
132 // TODO(adonovan): fix: not atomic! | 133 // TODO(adonovan): fix: not atomic! |
133 *args[0].(*value) = args[1].(int32) | 134 *args[0].(*value) = args[1].(int32) |
134 return nil | 135 return nil |
135 } | 136 } |
136 | 137 |
137 func ext۰atomic۰CompareAndSwapInt32(fn *ssa.Function, args []value, slots []valu
e) value { | 138 func ext۰atomic۰CompareAndSwapInt32(fn *ssa.Function, args []value) value { |
138 // TODO(adonovan): fix: not atomic! | 139 // TODO(adonovan): fix: not atomic! |
139 p := args[0].(*value) | 140 p := args[0].(*value) |
140 if (*p).(int32) == args[1].(int32) { | 141 if (*p).(int32) == args[1].(int32) { |
141 *p = args[2].(int32) | 142 *p = args[2].(int32) |
142 return true | 143 return true |
143 } | 144 } |
144 return false | 145 return false |
145 } | 146 } |
146 | 147 |
147 func ext۰atomic۰AddInt32(fn *ssa.Function, args []value, slots []value) value { | 148 func ext۰atomic۰AddInt32(fn *ssa.Function, args []value) value { |
148 // TODO(adonovan): fix: not atomic! | 149 // TODO(adonovan): fix: not atomic! |
149 p := args[0].(*value) | 150 p := args[0].(*value) |
150 newv := (*p).(int32) + args[1].(int32) | 151 newv := (*p).(int32) + args[1].(int32) |
151 *p = newv | 152 *p = newv |
152 return newv | 153 return newv |
153 } | 154 } |
154 | 155 |
155 func ext۰runtime۰SetFinalizer(fn *ssa.Function, args []value, slots []value) val
ue { | 156 func ext۰runtime۰SetFinalizer(fn *ssa.Function, args []value) value { |
156 return nil // ignore | 157 return nil // ignore |
157 } | 158 } |
158 | 159 |
159 func ext۰time۰now(fn *ssa.Function, args []value, slots []value) value { | 160 func ext۰time۰now(fn *ssa.Function, args []value) value { |
160 nano := time.Now().UnixNano() | 161 nano := time.Now().UnixNano() |
161 return tuple{int64(nano / 1e9), int32(nano % 1e9)} | 162 return tuple{int64(nano / 1e9), int32(nano % 1e9)} |
162 } | 163 } |
163 | 164 |
164 func ext۰time۰Sleep(fn *ssa.Function, args []value, slots []value) value { | 165 func ext۰time۰Sleep(fn *ssa.Function, args []value) value { |
165 time.Sleep(time.Duration(args[0].(int64))) | 166 time.Sleep(time.Duration(args[0].(int64))) |
166 return nil | 167 return nil |
167 } | 168 } |
168 | 169 |
169 func ext۰syscall۰Exit(fn *ssa.Function, args []value, slots []value) value { | 170 func ext۰syscall۰Exit(fn *ssa.Function, args []value) value { |
170 » // We could emulate syscall.Syscall but it's more effort. | 171 » panic(exitPanic(args[0].(int))) |
171 » syscall.Exit(args[0].(int)) | |
172 » return nil | |
173 } | 172 } |
174 | 173 |
175 func ext۰syscall۰Getpid(fn *ssa.Function, args []value, slots []value) value { | 174 func ext۰syscall۰Getpid(fn *ssa.Function, args []value) value { |
176 // We could emulate syscall.Syscall but it's more effort. | 175 // We could emulate syscall.Syscall but it's more effort. |
177 return syscall.Getpid() | 176 return syscall.Getpid() |
178 } | 177 } |
179 | 178 |
180 // The set of remaining native functions we need to implement (as needed): | 179 // The set of remaining native functions we need to implement (as needed): |
181 | 180 |
182 // bytes/bytes.go:42:func Equal(a, b []byte) bool | 181 // bytes/bytes.go:42:func Equal(a, b []byte) bool |
183 // bytes/bytes_decl.go:8:func IndexByte(s []byte, c byte) int // asm_$GOARCH.s | 182 // bytes/bytes_decl.go:8:func IndexByte(s []byte, c byte) int // asm_$GOARCH.s |
184 // crypto/aes/cipher_asm.go:10:func hasAsm() bool | 183 // crypto/aes/cipher_asm.go:10:func hasAsm() bool |
185 // crypto/aes/cipher_asm.go:11:func encryptBlockAsm(nr int, xk *uint32, dst, src
*byte) | 184 // crypto/aes/cipher_asm.go:11:func encryptBlockAsm(nr int, xk *uint32, dst, src
*byte) |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 // syscall/syscall_unix.go:23:func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uin
tptr, err Errno) | 286 // syscall/syscall_unix.go:23:func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uin
tptr, err Errno) |
288 // syscall/syscall_unix.go:24:func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr
) (r1, r2 uintptr, err Errno) | 287 // syscall/syscall_unix.go:24:func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr
) (r1, r2 uintptr, err Errno) |
289 // syscall/syscall_unix.go:25:func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2
uintptr, err Errno) | 288 // syscall/syscall_unix.go:25:func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2
uintptr, err Errno) |
290 // syscall/syscall_unix.go:26:func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uint
ptr) (r1, r2 uintptr, err Errno) | 289 // syscall/syscall_unix.go:26:func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uint
ptr) (r1, r2 uintptr, err Errno) |
291 // time/sleep.go:25:func startTimer(*runtimeTimer) | 290 // time/sleep.go:25:func startTimer(*runtimeTimer) |
292 // time/sleep.go:26:func stopTimer(*runtimeTimer) bool | 291 // time/sleep.go:26:func stopTimer(*runtimeTimer) bool |
293 // time/time.go:758:func now() (sec int64, nsec int32) | 292 // time/time.go:758:func now() (sec int64, nsec int32) |
294 // unsafe/unsafe.go:27:func Sizeof(v ArbitraryType) uintptr | 293 // unsafe/unsafe.go:27:func Sizeof(v ArbitraryType) uintptr |
295 // unsafe/unsafe.go:32:func Offsetof(v ArbitraryType) uintptr | 294 // unsafe/unsafe.go:32:func Offsetof(v ArbitraryType) uintptr |
296 // unsafe/unsafe.go:37:func Alignof(v ArbitraryType) uintptr | 295 // unsafe/unsafe.go:37:func Alignof(v ArbitraryType) uintptr |
OLD | NEW |