1. my class CallFrame {
  2. has $.annotations;
  3. has $.my;
  4. method SET-SELF(\level, Mu \ctx is raw, Mu \bt is raw) {
  5. nqp::stmts(
  6. (my int $i = nqp::add_i(level,1)),
  7. ($!annotations := nqp::atkey(
  8. nqp::atpos(nqp::getattr(bt,List,'$!reified'),$i),
  9. 'annotations'
  10. )),
  11. (my $ctx := ctx),
  12. nqp::while(
  13. nqp::isgt_i(($i = nqp::sub_i($i,1)),0),
  14. $ctx := nqp::ctxcaller($ctx)
  15. ),
  16. ($!my :=
  17. nqp::p6bindattrinvres(nqp::create(Stash),Map,'$!storage',$ctx)),
  18. self
  19. )
  20. }
  21. only method new(CallFrame: Int $level = 0) { # MUST BE AN only
  22. nqp::create(CallFrame).SET-SELF( # wrt to backtrace levels
  23. $level,
  24. nqp::ctxcaller(nqp::ctx),
  25. nqp::backtrace(nqp::handle(nqp::die(''),'CATCH',nqp::exception))
  26. )
  27. }
  28. method line() { nqp::atkey($!annotations,'line') }
  29. method file() { nqp::atkey($!annotations,'file') }
  30. method code() {
  31. nqp::getcodeobj(nqp::ctxcode(nqp::getattr($!my,Map,'$!storage')))
  32. }
  33. method callframe(Int $?) {
  34. X::NYI.new(feature => 'Callframe.callframe').throw;
  35. }
  36. multi method gist(CallFrame:D:) {
  37. nqp::atkey($!annotations,'file')
  38. ~ ' at line '
  39. ~ nqp::atkey($!annotations,'line')
  40. }
  41. method annotations() {
  42. nqp::p6bindattrinvres(nqp::create(Map),Map,'$!storage',$!annotations)
  43. }
  44. }
  45. only sub callframe(Int $level = 0) { # MUST BE an only wrt to backtrace levels
  46. nqp::create(CallFrame).SET-SELF(
  47. $level,
  48. nqp::ctxcaller(nqp::ctx),
  49. nqp::backtrace(nqp::handle(nqp::die(''),'CATCH',nqp::exception))
  50. )
  51. }