github.com/goplusjs/gopherjs@v1.2.6-0.20211206034512-f187917453b8/compiler/natives/src/runtime/runtime.go (about) 1 // +build js 2 3 package runtime 4 5 import ( 6 "runtime/internal/sys" 7 "unsafe" 8 9 "github.com/gopherjs/gopherjs/js" 10 ) 11 12 const GOOS = sys.GOOS 13 const GOARCH = "js" 14 const Compiler = "gopherjs" 15 16 type eface struct { 17 _type *_type 18 data unsafe.Pointer 19 } 20 21 type _type struct { 22 str string 23 kind uint8 24 } 25 26 func (t *_type) string() string { 27 return t.str 28 } 29 30 func (t *_type) pkgpath() string { 31 return "" 32 } 33 34 // An errorString represents a runtime error described by a single string. 35 type errorString string 36 37 func (e errorString) RuntimeError() {} 38 39 func (e errorString) Error() string { 40 return "runtime error: " + string(e) 41 } 42 43 func init() { 44 jsPkg := js.Global.Get("$packages").Get("github.com/gopherjs/gopherjs/js") 45 js.Global.Set("$jsObjectPtr", jsPkg.Get("Object").Get("ptr")) 46 js.Global.Set("$jsErrorPtr", jsPkg.Get("Error").Get("ptr")) 47 js.Global.Set("$throwRuntimeError", js.InternalObject(throw)) 48 // avoid dead code elimination 49 var e error 50 e = &TypeAssertionError{} 51 _ = e 52 } 53 54 func GOROOT() string { 55 process := js.Global.Get("process") 56 if process == js.Undefined { 57 return "/" 58 } 59 goroot := process.Get("env").Get("GOROOT") 60 if goroot != js.Undefined { 61 return goroot.String() 62 } 63 // sys.DefaultGoroot is now gone, can't use it as fallback anymore. 64 // TODO: See if a better solution is needed. 65 return "/usr/local/go" 66 } 67 68 func Breakpoint() { 69 js.Debugger() 70 } 71 72 func Caller(skip int) (pc uintptr, file string, line int, ok bool) { 73 info := js.Global.Get("Error").New().Get("stack").Call("split", "\n").Index(skip + 2) 74 if info == js.Undefined { 75 return 0, "", 0, false 76 } 77 parts := info.Call("substring", info.Call("indexOf", "(").Int()+1, info.Call("indexOf", ")").Int()).Call("split", ":") 78 return 0, parts.Index(0).String(), parts.Index(1).Int(), true 79 } 80 81 func Callers(skip int, pc []uintptr) int { 82 return 0 83 } 84 85 // CallersFrames is not implemented for GOARCH=js. 86 // TODO: Implement if possible. 87 func CallersFrames(callers []uintptr) *Frames { return &Frames{} } 88 89 type Frames struct{} 90 91 func (ci *Frames) Next() (frame Frame, more bool) { return } 92 93 type Frame struct { 94 PC uintptr 95 Func *Func 96 Function string 97 File string 98 Line int 99 Entry uintptr 100 } 101 102 func GC() { 103 } 104 105 func Goexit() { 106 js.Global.Get("$curGoroutine").Set("exit", true) 107 js.Global.Call("$throw", nil) 108 } 109 110 func GOMAXPROCS(n int) int { 111 return 1 112 } 113 114 func Gosched() { 115 c := make(chan struct{}) 116 js.Global.Call("$setTimeout", js.InternalObject(func() { close(c) }), 0) 117 <-c 118 } 119 120 func NumCPU() int { 121 return 1 122 } 123 124 func NumGoroutine() int { 125 return js.Global.Get("$totalGoroutines").Int() 126 } 127 128 type MemStats struct { 129 // General statistics. 130 Alloc uint64 // bytes allocated and still in use 131 TotalAlloc uint64 // bytes allocated (even if freed) 132 Sys uint64 // bytes obtained from system (sum of XxxSys below) 133 Lookups uint64 // number of pointer lookups 134 Mallocs uint64 // number of mallocs 135 Frees uint64 // number of frees 136 137 // Main allocation heap statistics. 138 HeapAlloc uint64 // bytes allocated and still in use 139 HeapSys uint64 // bytes obtained from system 140 HeapIdle uint64 // bytes in idle spans 141 HeapInuse uint64 // bytes in non-idle span 142 HeapReleased uint64 // bytes released to the OS 143 HeapObjects uint64 // total number of allocated objects 144 145 // Low-level fixed-size structure allocator statistics. 146 // Inuse is bytes used now. 147 // Sys is bytes obtained from system. 148 StackInuse uint64 // bytes used by stack allocator 149 StackSys uint64 150 MSpanInuse uint64 // mspan structures 151 MSpanSys uint64 152 MCacheInuse uint64 // mcache structures 153 MCacheSys uint64 154 BuckHashSys uint64 // profiling bucket hash table 155 GCSys uint64 // GC metadata 156 OtherSys uint64 // other system allocations 157 158 // Garbage collector statistics. 159 NextGC uint64 // next collection will happen when HeapAlloc ≥ this amount 160 LastGC uint64 // end time of last collection (nanoseconds since 1970) 161 PauseTotalNs uint64 162 PauseNs [256]uint64 // circular buffer of recent GC pause durations, most recent at [(NumGC+255)%256] 163 PauseEnd [256]uint64 // circular buffer of recent GC pause end times 164 NumGC uint32 165 GCCPUFraction float64 // fraction of CPU time used by GC 166 EnableGC bool 167 DebugGC bool 168 169 // Per-size allocation statistics. 170 // 61 is NumSizeClasses in the C code. 171 BySize [61]struct { 172 Size uint32 173 Mallocs uint64 174 Frees uint64 175 } 176 } 177 178 func ReadMemStats(m *MemStats) { 179 } 180 181 func SetFinalizer(x, f interface{}) { 182 } 183 184 type Func struct { 185 opaque struct{} // unexported field to disallow conversions 186 } 187 188 func (_ *Func) Entry() uintptr { return 0 } 189 func (_ *Func) FileLine(pc uintptr) (file string, line int) { return "", 0 } 190 func (_ *Func) Name() string { return "" } 191 192 func FuncForPC(pc uintptr) *Func { 193 return nil 194 } 195 196 var MemProfileRate int = 512 * 1024 197 198 func SetBlockProfileRate(rate int) { 199 } 200 201 func SetMutexProfileFraction(rate int) int { 202 // TODO: Investigate this. If it's possible to implement, consider doing so, otherwise remove this comment. 203 return 0 204 } 205 206 func Stack(buf []byte, all bool) int { 207 s := js.Global.Get("Error").New().Get("stack") 208 if s == js.Undefined { 209 return 0 210 } 211 return copy(buf, s.Call("substr", s.Call("indexOf", "\n").Int()+1).String()) 212 } 213 214 func LockOSThread() {} 215 216 func UnlockOSThread() {} 217 218 func Version() string { 219 return sys.TheVersion 220 } 221 222 func StartTrace() error { return nil } 223 func StopTrace() {} 224 func ReadTrace() []byte 225 226 // We fake a cgo environment to catch errors. Therefor we have to implement this and always return 0 227 func NumCgoCall() int64 { 228 return 0 229 } 230 231 func efaceOf(ep *interface{}) *eface { 232 panic("efaceOf: not supported") 233 } 234 235 func KeepAlive(interface{}) {} 236 237 func throw(s string) { 238 panic(errorString(s)) 239 } 240 241 // These are used by panicwrap. Not implemented for GOARCH=js. 242 // TODO: Implement if possible. 243 func getcallerpc() uintptr { return 0 } 244 func findfunc(pc uintptr) funcInfo { return funcInfo{} } 245 func funcname(f funcInfo) string { return "" } 246 247 type funcInfo struct{} 248 249 func rand32() uint32 { 250 return uint32(js.Global.Get("Math").Call("random").Float() * (1<<32 - 1)) 251 } 252 253 var ( 254 fastrand0 uint32 255 fastrand1 uint32 256 ) 257 258 func init() { 259 fastrand0 = rand32() 260 fastrand1 = rand32() 261 } 262 263 func fastrand() uint32 { 264 // Implement xorshift64+: 2 32-bit xorshift sequences added together. 265 // Shift triplet [17,7,16] was calculated as indicated in Marsaglia's 266 // Xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf 267 // This generator passes the SmallCrush suite, part of TestU01 framework: 268 // http://simul.iro.umontreal.ca/testu01/tu01.html 269 s1, s0 := fastrand0, fastrand1 270 s1 ^= s1 << 17 271 s1 = s1 ^ s0 ^ s1>>7 ^ s0>>16 272 fastrand0, fastrand1 = s0, s1 273 return s0 + s1 274 }