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