kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

154_frame_return_address.toy (1040B)


      1 // @frame_address / @return_address: walk the frame-pointer chain at levels
      2 // 0/1/2. The functions are @[.noinline] so the call chain is real at every opt
      3 // level: inside deepest(), level 0/1/2 name deepest/middle/outer respectively.
      4 // The stack grows down, so each caller frame sits at a higher address than its
      5 // callee; return addresses are never null. Exits 42 on success.
      6 
      7 fn @[.noinline] deepest(): i64 {
      8   let f0: usize = @frame_address(0) as usize;
      9   let f1: usize = @frame_address(1) as usize;
     10   let f2: usize = @frame_address(2) as usize;
     11   let r0: usize = @return_address(0) as usize;
     12   let r1: usize = @return_address(1) as usize;
     13   if f0 == 0 { return 1; }
     14   if r0 == 0 { return 2; }
     15   if r1 == 0 { return 3; }
     16   if f1 <= f0 { return 4; }  // caller frame is higher (stack grows down)
     17   if f2 <= f1 { return 5; }
     18   return 42;
     19 }
     20 
     21 fn @[.noinline] middle(): i64 { return deepest(); }
     22 fn @[.noinline] outer(): i64 { return middle(); }
     23 
     24 fn __user_main(): i64 { return outer(); }
     25 
     26 fn main(): i32 { return __user_main() as i32; }