my class CallFrame { has $.annotations; has $.my; # cannot be a private method due to sub callframe method SET-SELF( \level, Mu \ctx is raw, Mu \bt is raw ) is implementation-detail { nqp::stmts( (my int $i = nqp::add_i(level,1)), (my $bt := nqp::atpos(nqp::getattr(bt,List,'$!reified'),$i)), ($!annotations := nqp::isnull($bt) ?? $bt !! nqp::atkey($bt,'annotations')), (my $ctx := ctx), nqp::while( nqp::isgt_i(--$i,0), nqp::ifnull( ($ctx := nqp::ctxcallerskipthunks($ctx)), fail "No callframe at level {level}" ) ), ($!my := nqp::p6bindattrinvres(Stash.new,Map,'$!storage',$ctx)), self ) } only method new(CallFrame: Int:D $level = 0) { # MUST BE AN only nqp::create(CallFrame).SET-SELF( # wrt to backtrace levels $level, nqp::ctxcallerskipthunks(nqp::ctx), nqp::backtrace(nqp::handle(nqp::die(''),'CATCH',nqp::exception)) ) } method line() { nqp::atkey($!annotations,'line') } method file() { nqp::atkey($!annotations,'file') } method code() { my \vm-code = nqp::ctxcode(nqp::getattr($!my,Map,'$!storage')); nqp::isnull(vm-code) ?? Nil !! nqp::getcodeobj(vm-code) } method callframe(Int:D $?) { NYI('Callframe.callframe').throw; } multi method gist(CallFrame:D:) { nqp::atkey($!annotations,'file') ~ ' at line ' ~ nqp::atkey($!annotations,'line') } method annotations() { nqp::p6bindattrinvres(nqp::create(Map),Map,'$!storage',$!annotations) } } only sub callframe(Int:D $level = 0) { # MUST BE an only wrt to backtrace levels nqp::create(CallFrame).SET-SELF( $level, nqp::ctxcallerskipthunks(nqp::ctx), nqp::backtrace(nqp::handle(nqp::die(''),'CATCH',nqp::exception)) ) } # vim: expandtab shiftwidth=4