hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 6af48ef20993df64e67902b0e1c3090b4a1ae8c7
parent f4cc258c5d5613578b4695854f1eeb666b2641d8
Author: Sebastian <sebastian@sebsite.pw>
Date:   Mon,  6 Nov 2023 23:27:35 -0500

rt: simplify frame-walking functions

This simplifies the implementation, changes the interface of nextframe
to return a frame rather than a tagged union (so on aarch64 it fits
within two registers), makes the address in the frame nullable (to
account for what was previously a void result to nextframe), and makes
the docs consistent across all architectures.

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mrt/+aarch64/backtrace.ha | 20+++++++-------------
Mrt/+riscv64/backtrace.ha | 30+++++++++---------------------
Mrt/+x86_64/backtrace.ha | 30+++++++++---------------------
3 files changed, 25 insertions(+), 55 deletions(-)

diff --git a/rt/+aarch64/backtrace.ha b/rt/+aarch64/backtrace.ha @@ -1,24 +1,18 @@ // SPDX-License-Identifier: MPL-2.0 // (c) Hare authors <https://harelang.org> -fn getfp() **opaque; +fn getfp() *frame; -// Details for a stack frame. Contents are architecture-specific. +// Details for a stack frame. A null address indicates that you've reached the +// top of the stack. Contents are architecture-specific. export type frame = struct { fp: nullable *frame, lr: nullable *opaque, }; // Returns the caller's stack frame. Call [[nextframe]] to walk the stack. -export fn backtrace() frame = *(getfp(): *frame); - -// Returns the frame above the current frame, if any. -export fn nextframe(fp: *frame) (frame | void) = { - return match (fp.fp) { - case null => - yield void; - case let fp: *frame => - yield *fp; - }; -}; +export fn backtrace() frame = *getfp(); +// Returns the frame above the current frame. The current frame must contain a +// non-nullable address. +export fn nextframe(sframe: frame) frame = *(sframe.fp as *frame); diff --git a/rt/+riscv64/backtrace.ha b/rt/+riscv64/backtrace.ha @@ -1,29 +1,17 @@ // SPDX-License-Identifier: MPL-2.0 // (c) Hare authors <https://harelang.org> -fn getfp() **opaque; +fn getfp() *frame; -// Details for a stack frame. Contents are architecture-specific. +// Details for a stack frame. A null address indicates that you've reached the +// top of the stack. Contents are architecture-specific. export type frame = struct { - addr: *opaque + addr: nullable *frame, }; -// Returns the current stack frame. See [[nextframe]] to walk the stack. -export fn backtrace() frame = { - let fp = frame { - addr = getfp() - }; - // Skip the call to backtrace itself - return nextframe(fp) as frame; -}; +// Returns the caller's stack frame. Call [[nextframe]] to walk the stack. +export fn backtrace() frame = *getfp(); -// Returns the frame above the current frame, if any. -export fn nextframe(sframe: frame) (frame | void) = { - let addr = sframe.addr: *nullable *opaque; - match (*addr) { - case null => - return; - case let a: *opaque => - return frame { addr = a }; - }; -}; +// Returns the frame above the current frame. The current frame must contain a +// non-nullable address. +export fn nextframe(sframe: frame) frame = *(sframe.addr as *frame); diff --git a/rt/+x86_64/backtrace.ha b/rt/+x86_64/backtrace.ha @@ -1,29 +1,17 @@ // SPDX-License-Identifier: MPL-2.0 // (c) Hare authors <https://harelang.org> -fn getfp() **opaque; +fn getfp() *frame; -// Details for a stack frame. Contents are architecture-specific. +// Details for a stack frame. A null address indicates that you've reached the +// top of the stack. Contents are architecture-specific. export type frame = struct { - addr: *opaque + addr: nullable *frame, }; -// Returns the current stack frame. See [[nextframe]] to walk the stack. -export fn backtrace() frame = { - let fp = frame { - addr = getfp() - }; - // Skip the call to backtrace itself - return nextframe(fp) as frame; -}; +// Returns the caller's stack frame. Call [[nextframe]] to walk the stack. +export fn backtrace() frame = *getfp(); -// Returns the frame above the current frame, if any. -export fn nextframe(sframe: frame) (frame | void) = { - let addr = sframe.addr: *nullable *opaque; - match (*addr) { - case let a: *opaque => - return frame { addr = a }; - case null => - return; - }; -}; +// Returns the frame above the current frame. The current frame must contain a +// non-nullable address. +export fn nextframe(sframe: frame) frame = *(sframe.addr as *frame);