diff --git a/src/runtime/runtime_wasm.go b/src/runtime/runtime_wasm.go index 154739b86..09216cc3f 100644 --- a/src/runtime/runtime_wasm.go +++ b/src/runtime/runtime_wasm.go @@ -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() diff --git a/targets/wasm_exec.js b/targets/wasm_exec.js index 665ac7950..3031d101c 100644 --- a/targets/wasm_exec.js +++ b/targets/wasm_exec.js @@ -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 { 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; }