From 6152b0bd5786614ee038a1b24bf1a5c3c7e029d1 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Wed, 24 Jan 2024 08:39:45 +0100 Subject: [PATCH] Add `debug.caller()` (#390) * Add `debug.caller()` * fix non-precompiled --- src/be_debuglib.c | 23 +++++++++++++++++++++++ tests/debug.be | 27 ++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/be_debuglib.c b/src/be_debuglib.c index fac4bfb5..2e4ee9bf 100644 --- a/src/be_debuglib.c +++ b/src/be_debuglib.c @@ -13,6 +13,7 @@ #include "be_debug.h" #include "be_map.h" #include "be_vm.h" +#include "be_exec.h" #include #if BE_USE_DEBUG_MODULE @@ -103,6 +104,26 @@ static int m_traceback(bvm *vm) be_return_nil(vm); } +static int m_caller(bvm *vm) +{ + int depth = 1; + if (be_top(vm) >= 1 && be_isint(vm, 1)) { + depth = be_toint(vm, 1); + if (depth < 0) { + depth = -depth; /* take absolute value */ + } + } + bcallframe *cf = (bcallframe*)be_stack_top(&vm->callstack) - depth; + bcallframe *base = be_stack_base(&vm->callstack); + if (cf >= base) { + bvalue *reg = be_incrtop(vm); + var_setval(reg, cf->func); + be_return(vm); + } else { + be_return_nil(vm); + } +} + #if BE_USE_DEBUG_HOOK static int m_sethook(bvm *vm) { @@ -236,6 +257,7 @@ be_native_module_attr_table(debug) { be_native_module_function("varname", m_varname), be_native_module_function("upvname", m_upvname) #endif + be_native_module_function("caller", m_caller), be_native_module_function("gcdebug", m_gcdebug) }; @@ -252,6 +274,7 @@ module debug (scope: global, depend: BE_USE_DEBUG_MODULE) { top, func(m_top) varname, func(m_varname), BE_DEBUG_VAR_INFO upvname, func(m_upvname), BE_DEBUG_VAR_INFO + caller, func(m_caller) // individual counters allocs, func(m_allocs) frees, func(m_frees) diff --git a/tests/debug.be b/tests/debug.be index 9e732f6c..88b559d8 100644 --- a/tests/debug.be +++ b/tests/debug.be @@ -1,4 +1,29 @@ import debug class A end -debug.attrdump(A) #- should not crash -# \ No newline at end of file +debug.attrdump(A) #- should not crash -# + +# debug.caller() +def caller_name_chain() + import debug + import introspect + var i = 1 + var ret = [] + var caller = debug.caller(i) + while caller + ret.push(introspect.name(caller)) + i += 1 + caller = debug.caller(i) + end + return ret +end +var chain = caller_name_chain() +assert(chain[0] == 'caller_name_chain') + +def guess_my_name__() + return caller_name_chain() +end +chain = guess_my_name__() +print(chain) +assert(chain[0] == 'caller_name_chain') +assert(chain[1] == 'guess_my_name__')