wasm: use wasi ABI for basic startup/stdout
This allows TinyGo-built binaries to run under wasmtime, for example: tinygo build -o test.wasm -no-debug -target=wasm examples/test wasmtime run test.wasm 0
Этот коммит содержится в:
родитель
eb9c2c276e
коммит
24a0f237d8
2 изменённых файлов: 50 добавлений и 36 удалений
|
@ -2,35 +2,43 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
type timeUnit float64 // time in milliseconds, just like Date.now() in JavaScript
|
||||
|
||||
const tickMicros = 1000000
|
||||
|
||||
//go:export io_get_stdout
|
||||
func io_get_stdout() int32
|
||||
|
||||
//go:export resource_write
|
||||
func resource_write(id int32, ptr *uint8, len int32) int32
|
||||
|
||||
var stdout int32
|
||||
|
||||
func init() {
|
||||
stdout = io_get_stdout()
|
||||
// Implements __wasi_ciovec_t and __wasi_iovec_t.
|
||||
type wasiIOVec struct {
|
||||
buf unsafe.Pointer
|
||||
bufLen uint
|
||||
}
|
||||
|
||||
//go:export _start
|
||||
//go:wasm-module wasi_unstable
|
||||
//export fd_write
|
||||
func fd_write(id uint32, iovs *wasiIOVec, iovs_len uint, nwritten *uint) (errno uint)
|
||||
|
||||
//export _start
|
||||
func _start() {
|
||||
initAll()
|
||||
}
|
||||
|
||||
//go:export cwa_main
|
||||
func cwa_main() {
|
||||
initAll() // _start is not called by olin/cwa so has to be called here
|
||||
callMain()
|
||||
}
|
||||
|
||||
// Using global variables to avoid heap allocation.
|
||||
var (
|
||||
putcharBuf = byte(0)
|
||||
putcharIOVec = wasiIOVec{
|
||||
buf: unsafe.Pointer(&putcharBuf),
|
||||
bufLen: 1,
|
||||
}
|
||||
)
|
||||
|
||||
func putchar(c byte) {
|
||||
resource_write(stdout, &c, 1)
|
||||
// write to stdout
|
||||
const stdout = 1
|
||||
var nwritten uint
|
||||
putcharBuf = c
|
||||
fd_write(stdout, &putcharIOVec, 1, &nwritten)
|
||||
}
|
||||
|
||||
var handleEvent func()
|
||||
|
|
|
@ -181,31 +181,37 @@
|
|||
|
||||
const timeOrigin = Date.now() - performance.now();
|
||||
this.importObject = {
|
||||
env: {
|
||||
io_get_stdout: function() {
|
||||
return 1;
|
||||
},
|
||||
|
||||
resource_write: function(fd, ptr, len) {
|
||||
wasi_unstable: {
|
||||
// https://github.com/bytecodealliance/wasmtime/blob/master/docs/WASI-api.md#__wasi_fd_write
|
||||
fd_write: function(fd, iovs_ptr, iovs_len, nwritten_ptr) {
|
||||
let nwritten = 0;
|
||||
if (fd == 1) {
|
||||
for (let i=0; i<len; i++) {
|
||||
let c = mem().getUint8(ptr+i);
|
||||
if (c == 13) { // CR
|
||||
// ignore
|
||||
} else if (c == 10) { // LF
|
||||
// write line
|
||||
let line = decoder.decode(new Uint8Array(logLine));
|
||||
logLine = [];
|
||||
console.log(line);
|
||||
} else {
|
||||
logLine.push(c);
|
||||
for (let iovs_i=0; iovs_i<iovs_len;iovs_i++) {
|
||||
let iov_ptr = iovs_ptr+iovs_i*8; // assuming wasm32
|
||||
let ptr = mem().getUint32(iov_ptr + 0, true);
|
||||
let len = mem().getUint32(iov_ptr + 4, true);
|
||||
for (let i=0; i<len; i++) {
|
||||
let c = mem().getUint8(ptr+i);
|
||||
if (c == 13) { // CR
|
||||
// ignore
|
||||
} else if (c == 10) { // LF
|
||||
// write line
|
||||
let line = decoder.decode(new Uint8Array(logLine));
|
||||
logLine = [];
|
||||
console.log(line);
|
||||
} else {
|
||||
logLine.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error('invalid file descriptor:', fd);
|
||||
}
|
||||
mem().setUint32(nwritten_ptr, nwritten, true);
|
||||
return 0;
|
||||
},
|
||||
|
||||
},
|
||||
env: {
|
||||
// func ticks() float64
|
||||
"runtime.ticks": () => {
|
||||
return timeOrigin + performance.now();
|
||||
|
@ -344,7 +350,7 @@
|
|||
setTimeout(resolve, 0); // make sure it is asynchronous
|
||||
};
|
||||
});
|
||||
this._inst.exports.cwa_main();
|
||||
this._inst.exports._start();
|
||||
if (this.exited) {
|
||||
break;
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче