tinygo/src/runtime/runtime.go
Ayke van Laethem 5aa8b71ae1
compiler: implement builtin copy(dst, src []T)
Not implemented: copying a string into a []byte slice.
2018-09-06 10:37:44 +02:00

113 строки
2,8 КиБ
Go

package runtime
import (
"unsafe"
)
const Compiler = "tgo"
// The compiler will fill this with calls to the initialization function of each
// package.
func initAll()
// These signatures are used to call the correct main function: with scheduling
// or without scheduling.
func main_main()
func main_mainAsync(parent *coroutine) *coroutine
// The compiler will change this to true if there are 'go' statements in the
// compiled program and turn it into a const.
var hasScheduler bool
// Entry point for Go. Initialize all packages and call main.main().
//go:export main
func main() int {
// Run initializers of all packages.
initAll()
// This branch must be optimized away. Only one of the targets must remain,
// or there will be link errors.
if hasScheduler {
// Initialize main and run the scheduler.
coro := main_mainAsync(nil)
scheduler(coro)
return 0
} else {
// No scheduler is necessary. Call main directly.
main_main()
return 0
}
}
func Sleep(d Duration) {
// This function is treated specially by the compiler: when goroutines are
// used, it is transformed into a llvm.coro.suspend() call.
// When goroutines are not used this function behaves as normal.
sleep(d)
}
func GOMAXPROCS(n int) int {
// Note: setting GOMAXPROCS is ignored.
return 1
}
func GOROOT() string {
// TODO: don't hardcode but take the one at compile time.
return "/usr/local/go"
}
// Copy size bytes from src to dst. The memory areas must not overlap.
func memcpy(dst, src unsafe.Pointer, size uintptr) {
for i := uintptr(0); i < size; i++ {
*(*uint8)(unsafe.Pointer(uintptr(dst) + i)) = *(*uint8)(unsafe.Pointer(uintptr(src) + i))
}
}
// Copy size bytes from src to dst. The memory areas may overlap and will do the
// correct thing.
func memmove(dst, src unsafe.Pointer, size uintptr) {
if uintptr(dst) < uintptr(src) {
// Copy forwards.
memcpy(dst, src, size)
return
}
// Copy backwards.
i := size
for {
i--
*(*uint8)(unsafe.Pointer(uintptr(dst) + i)) = *(*uint8)(unsafe.Pointer(uintptr(src) + i))
if i == 0 {
break
}
}
}
// Set the given number of bytes to zero.
func memzero(ptr unsafe.Pointer, size uintptr) {
for i := uintptr(0); i < size; i++ {
*(*byte)(unsafe.Pointer(uintptr(ptr) + i)) = 0
}
}
// Compare two same-size buffers for equality.
func memequal(x, y unsafe.Pointer, n uintptr) bool {
for i := uintptr(0); i < n; i++ {
cx := *(*uint8)(unsafe.Pointer(uintptr(x) + i))
cy := *(*uint8)(unsafe.Pointer(uintptr(y) + i))
if cx != cy {
return false
}
}
return true
}
// Builtin copy(dst, src) function: copy bytes from dst to src.
func sliceCopy(dst, src unsafe.Pointer, dstLen, srcLen lenType, elemSize uintptr) lenType {
// n = min(srcLen, dstLen)
n := srcLen
if n > dstLen {
n = dstLen
}
memmove(dst, src, uintptr(n)*elemSize)
return n
}