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  }