walk.ha (966B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 fn getfp() *stackframe; 5 6 // Details for a stack frame. Contents are architecture-specific. 7 export type stackframe = struct { 8 fp: nullable *stackframe, 9 lr: uintptr, 10 }; 11 12 // Returns the caller's stack frame. Call [[next]] to walk the stack. 13 export fn walk() stackframe = *getfp(); 14 15 // Returns the next stack frame walking the stack. 16 export fn next(frame: stackframe) (stackframe | done) = { 17 match (frame.fp) { 18 case null => 19 return done; 20 case let next: *stackframe => 21 if (!isaddrmapped(next)) { 22 return done; 23 }; 24 if (next.fp == null) { 25 return done; 26 }; 27 return *next; 28 }; 29 }; 30 31 // Return the program counter address for the given stack frame. 32 export fn frame_pc(frame: stackframe) uintptr = frame.lr; 33 34 // Implementation detail, constructs a synthetic stack frame. 35 fn mkframe(next: *stackframe, ip: uintptr) stackframe = { 36 return stackframe { 37 fp = next, 38 lr = ip, 39 }; 40 };