@runtimeMode
module Panic

from "runtime/unsafe/wasmi32" include WasmI32
use WasmI32.{ (+) }

foreign wasm fd_write:
  (WasmI32, WasmI32, WasmI32, WasmI32) => WasmI32 from "wasi_snapshot_preview1"

primitive unreachable = "@unreachable"

// HACK: Allocate static buffer for printing (40 bytes)
// Would be nice to have a better way to allocate a static block from
// the runtime heap, but this is the only module that needs to do it
let iov = WasmI32.fromGrain([> 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n])

provide let panic = (msg: String) => {
  let ptr = WasmI32.fromGrain(msg)
  let written = iov + 32n
  let lf = iov + 36n
  WasmI32.store(iov, ptr + 8n, 0n)
  WasmI32.store(iov, WasmI32.load(ptr, 4n), 4n)
  WasmI32.store8(lf, 10n, 0n)
  WasmI32.store(iov, lf, 8n)
  WasmI32.store(iov, 1n, 12n)
  fd_write(2n, iov, 2n, written)
  unreachable()
}
