runtime.mx raw

   1  package runtime
   2  
   3  import (
   4  	"unsafe"
   5  )
   6  
   7  //go:generate go run ../../tools/gen-critical-atomics -out ./atomics_critical.go
   8  
   9  const Compiler = "moxie"
  10  
  11  // Unit for the 'ticks' and 'sleepTicks' functions.
  12  //
  13  // This is the native time unit for the given system. One timeUnit tick might be
  14  // 1ns or 100ns on a desktop system, or 1/32768s on baremetal systems with a
  15  // low-power RTC. Many other tick durations are possible.
  16  //
  17  // Conversion from time units to nanoseconds and back is done using
  18  // ticksToNanoseconds and nanosecondsToTicks, which need to be implemented for
  19  // each system as needed.
  20  type timeUnit int64
  21  
  22  // The compiler will fill this with calls to the initialization function of each
  23  // package.
  24  func initAll()
  25  
  26  //go:linkname callMain main.main
  27  func callMain()
  28  
  29  func GOMAXPROCS(n int) int {
  30  	// Note: setting GOMAXPROCS is ignored.
  31  	return 1
  32  }
  33  
  34  func GOROOT() string {
  35  	// TODO: don't hardcode but take the one at compile time.
  36  	return "/usr/local/go"
  37  }
  38  
  39  // Copy size bytes from src to dst. The memory areas must not overlap.
  40  // This function is implemented by the compiler as a call to a LLVM intrinsic
  41  // like llvm.memcpy.p0.p0.i32(dst, src, size, false).
  42  func memcpy(dst, src unsafe.Pointer, size uintptr)
  43  
  44  // Copy size bytes from src to dst. The memory areas may overlap and will do the
  45  // correct thing.
  46  // This function is implemented by the compiler as a call to a LLVM intrinsic
  47  // like llvm.memmove.p0.p0.i32(dst, src, size, false).
  48  func memmove(dst, src unsafe.Pointer, size uintptr)
  49  
  50  // Set the given number of bytes to zero.
  51  // This function is implemented by the compiler as a call to a LLVM intrinsic
  52  // like llvm.memset.p0.i32(ptr, 0, size, false).
  53  func memzero(ptr unsafe.Pointer, size uintptr)
  54  
  55  // Return the current stack pointer using the llvm.stacksave.p0 intrinsic.
  56  // It is normally used together with llvm.stackrestore.p0 but also works to get
  57  // the current stack pointer in a platform-independent way.
  58  func stacksave() unsafe.Pointer
  59  
  60  // Special LLVM intrinsic that returns the SP register on entry to the calling
  61  // function.
  62  //
  63  //export llvm.sponentry.p0
  64  func llvm_sponentry() unsafe.Pointer
  65  
  66  //export strlen
  67  func strlen(ptr unsafe.Pointer) uintptr
  68  
  69  //export malloc
  70  func malloc(size uintptr) unsafe.Pointer
  71  
  72  // Return the address of an exported function.
  73  // This is mainly useful to pass a function pointer without extra context
  74  // parameter to C, for example.
  75  func exportedFuncPtr(fn func()) uintptr
  76  
  77  // Compare two same-size buffers for equality.
  78  func memequal(x, y unsafe.Pointer, n uintptr) bool {
  79  	for i := uintptr(0); i < n; i++ {
  80  		cx := *(*uint8)(unsafe.Add(x, i))
  81  		cy := *(*uint8)(unsafe.Add(y, i))
  82  		if cx != cy {
  83  			return false
  84  		}
  85  	}
  86  	return true
  87  }
  88  
  89  func nanotime() int64 {
  90  	return ticksToNanoseconds(ticks())
  91  }
  92  
  93  // Copied from the Go runtime source code.
  94  //
  95  //go:linkname os_sigpipe os.sigpipe
  96  func os_sigpipe() {
  97  	runtimePanic("too many writes on closed pipe")
  98  }
  99  
 100  // LockOSThread wires the calling goroutine to its current operating system thread.
 101  // Stub for now
 102  // Called by go1.18 standard library on windows, see https://github.com/golang/go/issues/49320
 103  func LockOSThread() {
 104  }
 105  
 106  // UnlockOSThread undoes an earlier call to LockOSThread.
 107  // Stub for now
 108  func UnlockOSThread() {
 109  }
 110  
 111  // KeepAlive makes sure the value in the interface is alive until at least the
 112  // point of the call.
 113  func KeepAlive(x interface{})
 114  
 115  // AddCleanup is a dummy cleanup implementation. It doesn't do any cleaning up.
 116  //
 117  // We base this on the following loophole in the official runtime.AddCleanup
 118  // documentation:
 119  //
 120  // > The cleanup(arg) call is not always guaranteed to run; in particular it is
 121  // > not guaranteed to run before program exit.
 122  //
 123  // So it's technically correct (the best kind of correct) to not run any
 124  // cleanups. But of course, this can lead to resource leaks so cleanups may need
 125  // to be implemented eventually.
 126  func AddCleanup[T, S any](ptr *T, cleanup func(S), arg S) Cleanup {
 127  	return Cleanup{}
 128  }
 129  
 130  type Cleanup struct{}
 131  
 132  func (c Cleanup) Stop() {}
 133  
 134  //go:linkname registerWeakPointer weak.runtime_registerWeakPointer
 135  func registerWeakPointer(ptr unsafe.Pointer) unsafe.Pointer {
 136  	// TODO: unimplemented.
 137  	// I hope not implementing this won't break anything, like packages that
 138  	// expect weak pointers to be GC'd before they actually are.
 139  	return ptr
 140  }
 141  
 142  var godebugUpdate func(string, string)
 143  
 144  //go:linkname godebug_setUpdate internal/godebug.setUpdate
 145  func godebug_setUpdate(update func(string, string)) {
 146  	// The 'update' function needs to be called whenever the GODEBUG environment
 147  	// variable changes (for example, via os.Setenv).
 148  	godebugUpdate = update
 149  }
 150  
 151  //go:linkname godebug_setNewIncNonDefault internal/godebug.setNewIncNonDefault
 152  func godebug_setNewIncNonDefault(newIncNonDefault func(string) func()) {
 153  	// Dummy function necessary in Go 1.21.
 154  }
 155  
 156  // Write to the given file descriptor.
 157  // This is called from internal/godebug starting with Go 1.21, and only seems to
 158  // be called with the stderr file descriptor.
 159  func write(fd uintptr, p unsafe.Pointer, n int32) int32 {
 160  	if fd == 2 { // stderr
 161  		// Convert to a string, because we know that p won't change during the
 162  		// call to printstring.
 163  		// TODO: use unsafe.String instead once we require Go 1.20.
 164  		s := _string{
 165  			ptr:    (*byte)(p),
 166  			length: uintptr(n),
 167  			cap:    uintptr(n),
 168  		}
 169  		str := *(*string)(unsafe.Pointer(&s))
 170  		printstring(str)
 171  		return n
 172  	}
 173  	return 0
 174  }
 175  
 176  // getAuxv is linknamed from golang.org/x/sys/cpu.
 177  func getAuxv() []uintptr {
 178  	return nil
 179  }
 180  
 181  // Called from cgo to obtain the errno value.
 182  func cgo_errno() uintptr {
 183  	return uintptr(*libc_errno_location())
 184  }
 185