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:
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);