blueloveTH 2 лет назад
Родитель
Сommit
6cff9ff9ec
5 измененных файлов с 23 добавлено и 20 удалено
  1. 0 5
      include/pocketpy/config.h
  2. 3 2
      include/pocketpy/vm.h
  3. 1 1
      include/typings/line_profiler.pyi
  4. 9 9
      src/ceval.cpp
  5. 10 3
      src/line_profiler.cpp

+ 0 - 5
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

+ 3 - 2
include/pocketpy/vm.h

@@ -150,9 +150,10 @@ public:
     // cached code objects for FSTRING_EVAL
     std::map<std::string_view, CodeObject_> _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;

+ 1 - 1
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: ...

+ 9 - 9
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){

+ 10 - 3
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){