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
+117
View File
@@ -0,0 +1,117 @@
// +build wasm,wasi
package runtime
import (
"unsafe"
)
type timeUnit int64
//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()
}
func ticksToNanoseconds(ticks timeUnit) int64 {
return int64(ticks)
}
func nanosecondsToTicks(ns int64) timeUnit {
return timeUnit(ns)
}
const (
asyncScheduler = false
timePrecisionNanoseconds = 1000 // TODO: how can we determine the appropriate `precision`?
)
var (
sleepTicksSubscription = __wasi_subscription_t{
userData: 0,
u: __wasi_subscription_u_t{
tag: __wasi_eventtype_t_clock,
u: __wasi_subscription_clock_t{
userData: 0,
id: 0,
timeout: 0,
precision: timePrecisionNanoseconds,
flags: 0,
},
},
}
sleepTicksResult = __wasi_event_t{}
sleepTicksNEvents uint32
)
func sleepTicks(d timeUnit) {
sleepTicksSubscription.u.u.timeout = int64(d)
poll_oneoff(&sleepTicksSubscription, &sleepTicksResult, 1, &sleepTicksNEvents)
}
func ticks() timeUnit {
var nano int64
clock_time_get(0, timePrecisionNanoseconds, &nano)
return timeUnit(nano)
}
// Implementations of wasi_unstable APIs
//go:wasm-module wasi_unstable
//export clock_time_get
func clock_time_get(clockid uint32, precision uint64, time *int64) (errno uint16)
//go:wasm-module wasi_unstable
//export poll_oneoff
func poll_oneoff(in *__wasi_subscription_t, out *__wasi_event_t, nsubscriptions uint32, nevents *uint32) (errno uint16)
type __wasi_eventtype_t = uint8
const (
__wasi_eventtype_t_clock __wasi_eventtype_t = 0
// TODO: __wasi_eventtype_t_fd_read __wasi_eventtype_t = 1
// TODO: __wasi_eventtype_t_fd_write __wasi_eventtype_t = 2
)
type (
// https://github.com/wasmerio/wasmer/blob/1.0.0-alpha3/lib/wasi/src/syscalls/types.rs#L584-L588
__wasi_subscription_t struct {
userData uint64
u __wasi_subscription_u_t
}
__wasi_subscription_u_t struct {
tag __wasi_eventtype_t
// TODO: support fd_read/fd_write event
u __wasi_subscription_clock_t
}
// https://github.com/wasmerio/wasmer/blob/1.0.0-alpha3/lib/wasi/src/syscalls/types.rs#L711-L718
__wasi_subscription_clock_t struct {
userData uint64
id uint32
timeout int64
precision int64
flags uint16
}
)
type (
// https://github.com/wasmerio/wasmer/blob/1.0.0-alpha3/lib/wasi/src/syscalls/types.rs#L191-L198
__wasi_event_t struct {
userData uint64
errno uint16
eventType __wasi_eventtype_t
// only used for fd_read or fd_write events
// TODO: support fd_read/fd_write event
_ struct {
nBytes uint64
flags uint16
}
}
)