Files
tinygo/src/runtime/runtime_wasm.go
T
Ayke van Laethem fed433c046 compiler: add support for atomic operations
This also implements DisableInterrupts/EnableInterrupts for RISC-V, as
those operations were needed to implement a few libcalls.
2020-05-28 15:11:46 +02:00

105 lines
2.2 KiB
Go

// +build wasm
package runtime
import "unsafe"
type timeUnit float64 // time in milliseconds, just like Date.now() in JavaScript
// Implements __wasi_ciovec_t and __wasi_iovec_t.
type wasiIOVec struct {
buf unsafe.Pointer
bufLen uint
}
//go:wasm-module wasi_unstable
//export fd_write
func fd_write(id uint32, iovs *wasiIOVec, iovs_len uint, nwritten *uint) (errno uint)
func postinit() {}
//export _start
func _start() {
// These need to be initialized early so that the heap can be initialized.
heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize)
run()
}
// Using global variables to avoid heap allocation.
var (
putcharBuf = byte(0)
putcharIOVec = wasiIOVec{
buf: unsafe.Pointer(&putcharBuf),
bufLen: 1,
}
)
func putchar(c byte) {
// write to stdout
const stdout = 1
var nwritten uint
putcharBuf = c
fd_write(stdout, &putcharIOVec, 1, &nwritten)
}
var handleEvent func()
//go:linkname setEventHandler syscall/js.setEventHandler
func setEventHandler(fn func()) {
handleEvent = fn
}
//export resume
func resume() {
go func() {
handleEvent()
}()
scheduler()
}
//export go_scheduler
func go_scheduler() {
scheduler()
}
const asyncScheduler = true
func ticksToNanoseconds(ticks timeUnit) int64 {
// The JavaScript API works in float64 milliseconds, so convert to
// nanoseconds first before converting to a timeUnit (which is a float64),
// to avoid precision loss.
return int64(ticks * 1e6)
}
func nanosecondsToTicks(ns int64) timeUnit {
// The JavaScript API works in float64 milliseconds, so convert to timeUnit
// (which is a float64) first before dividing, to avoid precision loss.
return timeUnit(ns) / 1e6
}
// This function is called by the scheduler.
// Schedule a call to runtime.scheduler, do not actually sleep.
//export runtime.sleepTicks
func sleepTicks(d timeUnit)
//export runtime.ticks
func ticks() timeUnit
// Abort executes the wasm 'unreachable' instruction.
func abort() {
trap()
}
// TinyGo does not yet support any form of parallelism on WebAssembly, so these
// can be left empty.
//go:linkname procPin sync/atomic.runtime_procPin
func procPin() {
}
//go:linkname procUnpin sync/atomic.runtime_procUnpin
func procUnpin() {
}