diff --git a/include/pocketpy/config.h b/include/pocketpy/config.h index c04d292f..21eb80f2 100644 --- a/include/pocketpy/config.h +++ b/include/pocketpy/config.h @@ -19,11 +19,6 @@ #define PK_ENABLE_THREAD 0 #endif -// Enable this for `vm->_ceval_on_step` -#ifndef PK_ENABLE_CEVAL_CALLBACK // can be overrided by cmake -#define PK_ENABLE_CEVAL_CALLBACK 0 -#endif - // GC min threshold #ifndef PK_GC_MIN_THRESHOLD // can be overrided by cmake #define PK_GC_MIN_THRESHOLD 32768 diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index f1a87ea0..be3abab0 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -150,9 +150,10 @@ public: // cached code objects for FSTRING_EVAL std::map _cached_codes; -#if PK_ENABLE_CEVAL_CALLBACK + // for user defined logic void (*_ceval_on_step)(VM*, Frame*, Bytecode bc) = nullptr; -#endif + // for line_profiler (users not to use this) + void (*_ceval_on_step_profile)(VM*, Frame*, Bytecode bc) = nullptr; PrintFunc _stdout; PrintFunc _stderr; diff --git a/include/typings/line_profiler.pyi b/include/typings/line_profiler.pyi index 53a66878..c35066f7 100644 --- a/include/typings/line_profiler.pyi +++ b/include/typings/line_profiler.pyi @@ -5,6 +5,6 @@ class LineProfiler: def add_function(self, func: Callable) -> None: ... - def runcall(self, func: Callable, *args, **kw) -> None: ... + def runcall(self, func: Callable, *args) -> None: ... def print_stats(self) -> None: ... diff --git a/src/ceval.cpp b/src/ceval.cpp index 21b909bc..cb491f61 100644 --- a/src/ceval.cpp +++ b/src/ceval.cpp @@ -66,15 +66,15 @@ PyObject* VM::_run_top_frame(){ */ { -#if PK_ENABLE_CEVAL_CALLBACK -#define CEVAL_STEP() byte = frame->next_bytecode(); if(_ceval_on_step) _ceval_on_step(this, frame.get(), byte) -#else -#define CEVAL_STEP() byte = frame->next_bytecode() -#endif +#define CEVAL_STEP_CALLBACK() \ + if(_ceval_on_step) _ceval_on_step(this, frame.get(), byte); \ + if(_ceval_on_step_profile) _ceval_on_step_profile(this, frame.get(), byte); #define DISPATCH_OP_CALL() { frame = top_frame(); goto __NEXT_FRAME; } __NEXT_FRAME: - Bytecode CEVAL_STEP(); + Bytecode byte = frame->next_bytecode(); + CEVAL_STEP_CALLBACK(); + // cache const CodeObject* co = frame->co; const auto& co_consts = co->consts; @@ -86,13 +86,13 @@ static void* OP_LABELS[] = { #undef OPCODE }; -#define DISPATCH() { CEVAL_STEP(); goto *OP_LABELS[byte.op];} +#define DISPATCH() { byte = frame->next_bytecode(); CEVAL_STEP_CALLBACK(); goto *OP_LABELS[byte.op];} #define TARGET(op) CASE_OP_##op: goto *OP_LABELS[byte.op]; #else #define TARGET(op) case OP_##op: -#define DISPATCH() { CEVAL_STEP(); goto __NEXT_STEP;} +#define DISPATCH() { byte = frame->next_bytecode(); CEVAL_STEP_CALLBACK(); goto __NEXT_STEP;} __NEXT_STEP:; #if PK_DEBUG_CEVAL_STEP @@ -831,7 +831,7 @@ __NEXT_STEP:; #undef DISPATCH #undef TARGET #undef DISPATCH_OP_CALL -#undef CEVAL_STEP +#undef CEVAL_STEP_CALLBACK /**********************************************************************/ PK_UNREACHABLE() }catch(HandledException){ diff --git a/src/line_profiler.cpp b/src/line_profiler.cpp index d5848004..76ac28f7 100644 --- a/src/line_profiler.cpp +++ b/src/line_profiler.cpp @@ -15,9 +15,16 @@ struct LineProfiler{ return vm->None; }); - vm->bind(type, "runcall(self, func, *args, **kw)", [](VM* vm, ArgsView args){ - // ... - return vm->None; + vm->bind(type, "runcall(self, func, *args)", [](VM* vm, ArgsView view){ + LineProfiler& self = PK_OBJ_GET(LineProfiler, view[0]); + // enable_by_count + PyObject* func = view[1]; + const Tuple& args = CAST(Tuple&, view[2]); + for(PyObject* arg : args) vm->s_data.push(arg); + vm->s_data.push(func); + PyObject* ret = vm->vectorcall(args.size()); + // disable_by_count + return ret; }); vm->bind(type, "print_stats(self)", [](VM* vm, ArgsView args){