support WASI target (#1373)

* initial commit for WASI support

* merge "time" package with wasi build tag
* override syscall package with wasi build tag
* create runtime_wasm_{js,wasi}.go files
* create syscall_wasi.go file
* create time/zoneinfo_wasi.go file as the replacement of zoneinfo_js.go
* add targets/wasi.json target

* set visbility hidden for runtime extern variables

Accodring to the WASI docs (https://github.com/WebAssembly/WASI/blob/master/design/application-abi.md#current-unstable-abi),
none of exports of WASI executable(Command) should no be accessed.

v0.19.0 of bytecodealliance/wasmetime, which is often refered to as the reference implementation of WASI,
does not accept any exports except functions and the only limited variables like "table", "memory".

* merge syscall_{baremetal,wasi}.go

* fix js target build

* mv wasi functions to syscall/wasi && implement sleepTicks

* WASI: set visibility hidden for globals variables

* mv back syscall/wasi/* to runtime package

* WASI: add test

* unexport wasi types

* WASI test: fix wasmtime path

* stop changing visibility of runtime.alloc

* use GOOS=linux, GOARCH=arm for wasi target

Signed-off-by: mathetake <takeshi@tetrate.io>

* WASI: fix build tags for os/runtime packages

Signed-off-by: mathetake <takeshi@tetrate.io>

* run WASI test only on Linux

Signed-off-by: mathetake <takeshi@tetrate.io>

* set InternalLinkage instead of changing visibility

Signed-off-by: mathetake <takeshi@tetrate.io>
This commit is contained in:
Takeshi Yoneda
2020-09-30 04:58:03 +09:00
committed by GitHub
parent d39c7abb4d
commit f50ad3585d
17 changed files with 241 additions and 72 deletions
+7 -59
View File
@@ -2,35 +2,26 @@
package runtime
import "unsafe"
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 {
// Implements __wasi_iovec_t.
type __wasi_iovec_t 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 fd_write(id uint32, iovs *__wasi_iovec_t, 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{
putcharIOVec = __wasi_iovec_t{
buf: unsafe.Pointer(&putcharBuf),
bufLen: 1,
}
@@ -44,49 +35,6 @@ func putchar(c byte) {
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()