import { proc_exit, fd_write, iovec, random_get } from "./bindings/wasi_snapshot_preview1"; // A WASI-wide reusable temporary buffer to store and work with out values. Must // be large enough to fit any operation it is used in, i.e. process/writeString. // @ts-ignore: decorator @lazy export const tempbuf = memory.data(4 * sizeof()); import { MAX_DOUBLE_LENGTH, decimalCount32, dtoa_buffered } from "util/number"; export function wasi_abort( message: string | null = null, fileName: string | null = null, lineNumber: u32 = 0, columnNumber: u32 = 0 ): void { // 0: iov.buf // 4: iov.buf_len // 8: len // 12: buf... const iovPtr: usize = 0; const lenPtr: usize = iovPtr + offsetof(); const bufPtr: usize = lenPtr + sizeof(); changetype(iovPtr).buf = bufPtr; var ptr = bufPtr; store(ptr, 0x203A74726F6261); ptr += 7; // 'abort: ' if (message != null) { ptr += String.UTF8.encodeUnsafe(changetype(message), message.length, ptr); } store(ptr, 0x206E6920); ptr += 4; // ' in ' if (fileName != null) { ptr += String.UTF8.encodeUnsafe(changetype(fileName), fileName.length, ptr); } store(ptr++, 0x28); // ( var len = decimalCount32(lineNumber); ptr += len; do { let t = lineNumber / 10; store(--ptr, 0x30 + lineNumber % 10); lineNumber = t; } while (lineNumber); ptr += len; store(ptr++, 0x3A); // : len = decimalCount32(columnNumber); ptr += len; do { let t = columnNumber / 10; store(--ptr, 0x30 + columnNumber % 10); columnNumber = t; } while (columnNumber); ptr += len; store(ptr, 0x0A29); ptr += 2; // )\n changetype(iovPtr).buf_len = ptr - bufPtr; fd_write(2, iovPtr, 1, lenPtr); proc_exit(255); } export function wasi_trace( message: string, n: i32 = 0, a0: f64 = 0, a1: f64 = 0, a2: f64 = 0, a3: f64 = 0, a4: f64 = 0 ): void { // 0: iov.buf // 4: iov.buf_len // 8: len // 12: buf... var iovPtr = __alloc(offsetof() + sizeof() + 1 + (max(String.UTF8.byteLength(message), MAX_DOUBLE_LENGTH << 1))); var lenPtr = iovPtr + offsetof(); var bufPtr = lenPtr + sizeof(); changetype(iovPtr).buf = bufPtr; store(bufPtr, 0x203A6563617274); // 'trace: ' changetype(iovPtr).buf_len = 7; fd_write(2, iovPtr, 1, lenPtr); changetype(iovPtr).buf_len = String.UTF8.encodeUnsafe(changetype(message), message.length, bufPtr); fd_write(2, iovPtr, 1, lenPtr); if (n) { store(bufPtr++, 0x20); // space changetype(iovPtr).buf_len = 1 + String.UTF8.encodeUnsafe(bufPtr, dtoa_buffered(bufPtr, a0), bufPtr); fd_write(2, iovPtr, 1, lenPtr); if (n > 1) { changetype(iovPtr).buf_len = 1 + String.UTF8.encodeUnsafe(bufPtr, dtoa_buffered(bufPtr, a1), bufPtr); fd_write(2, iovPtr, 1, lenPtr); if (n > 2) { changetype(iovPtr).buf_len = 1 + String.UTF8.encodeUnsafe(bufPtr, dtoa_buffered(bufPtr, a2), bufPtr); fd_write(2, iovPtr, 1, lenPtr); if (n > 3) { changetype(iovPtr).buf_len = 1 + String.UTF8.encodeUnsafe(bufPtr, dtoa_buffered(bufPtr, a3), bufPtr); fd_write(2, iovPtr, 1, lenPtr); if (n > 4) { changetype(iovPtr).buf_len = 1 + String.UTF8.encodeUnsafe(bufPtr, dtoa_buffered(bufPtr, a4), bufPtr); fd_write(2, iovPtr, 1, lenPtr); } } } } --bufPtr; } store(bufPtr, 0x0A); // \n changetype(iovPtr).buf_len = 1; fd_write(2, iovPtr, 1, lenPtr); __free(iovPtr); } export function wasi_seed(): f64 { var rand: u64; do { random_get(tempbuf, 8); rand = load(tempbuf); } while (!rand); return reinterpret(rand); }