Просмотр исходного кода

improve `py_inspect_currentfunction`

blueloveTH 15 часов назад
Родитель
Сommit
cf70668a2f
5 измененных файлов с 13 добавлено и 16 удалено
  1. 2 1
      include/pocketpy/interpreter/vm.h
  2. 2 2
      include/pocketpy/pocketpy.h
  3. 1 1
      src/interpreter/ceval.c
  4. 6 8
      src/interpreter/vm.c
  5. 2 4
      src/public/Inspection.c

+ 2 - 1
include/pocketpy/interpreter/vm.h

@@ -63,7 +63,8 @@ typedef struct VM {
     CachedNames cached_names;
     CachedNames cached_names;
 
 
     py_StackRef curr_class;
     py_StackRef curr_class;
-    py_StackRef curr_decl_based_function;   // this is for get current function without frame
+    py_StackRef curr_function;
+    
     TraceInfo trace_info;
     TraceInfo trace_info;
     WatchdogInfo watchdog_info;
     WatchdogInfo watchdog_info;
     LineProfiler line_profiler;
     LineProfiler line_profiler;

+ 2 - 2
include/pocketpy/pocketpy.h

@@ -391,9 +391,9 @@ PK_API void py_tphookattributes(py_Type type,
 
 
 /************* Inspection *************/
 /************* Inspection *************/
 
 
-/// Get the current `function` object on the stack.
+/// Get the current `Callable` object on the stack of the most recent vectorcall.
 /// Return `NULL` if not available.
 /// Return `NULL` if not available.
-/// NOTE: This function should be placed at the beginning of your decl-based bindings.
+/// NOTE: This function should be placed at the beginning of your bindings or you will get wrong result.
 PK_API py_StackRef py_inspect_currentfunction();
 PK_API py_StackRef py_inspect_currentfunction();
 /// Get the current `module` object where the code is executed.
 /// Get the current `module` object where the code is executed.
 /// Return `NULL` if not available.
 /// Return `NULL` if not available.

+ 1 - 1
src/interpreter/ceval.c

@@ -1244,7 +1244,7 @@ __ERROR:
 __ERROR_RE_RAISE:
 __ERROR_RE_RAISE:
     do {
     do {
         self->curr_class = NULL;
         self->curr_class = NULL;
-        self->curr_decl_based_function = NULL;
+        self->curr_function = NULL;
     } while(0);
     } while(0);
 
 
     int target = Frame__goto_exception_handler(frame, &self->stack, &self->unhandled_exc);
     int target = Frame__goto_exception_handler(frame, &self->stack, &self->unhandled_exc);

+ 6 - 8
src/interpreter/vm.c

@@ -103,7 +103,8 @@ void VM__ctor(VM* self) {
 
 
     self->ctx = NULL;
     self->ctx = NULL;
     self->curr_class = NULL;
     self->curr_class = NULL;
-    self->curr_decl_based_function = NULL;
+    self->curr_function = NULL;
+
     memset(&self->trace_info, 0, sizeof(TraceInfo));
     memset(&self->trace_info, 0, sizeof(TraceInfo));
     memset(&self->watchdog_info, 0, sizeof(WatchdogInfo));
     memset(&self->watchdog_info, 0, sizeof(WatchdogInfo));
     LineProfiler__ctor(&self->line_profiler);
     LineProfiler__ctor(&self->line_profiler);
@@ -482,8 +483,8 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
     }
     }
 #endif
 #endif
 
 
-    py_Ref p1 = self->stack.sp - kwargc * 2;
-    py_Ref p0 = p1 - argc - 2;
+    py_StackRef p1 = self->stack.sp - kwargc * 2;
+    py_StackRef p0 = p1 - argc - 2;
     // [callable, <self>, args..., kwargs...]
     // [callable, <self>, args..., kwargs...]
     //      ^p0                    ^p1      ^_sp
     //      ^p0                    ^p1      ^_sp
 
 
@@ -496,7 +497,8 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
         // [unbound, self, args..., kwargs...]
         // [unbound, self, args..., kwargs...]
     }
     }
 
 
-    py_Ref argv = p0 + 1 + (int)py_isnil(p0 + 1);
+    py_StackRef argv = p0 + 1 + (int)py_isnil(p0 + 1);
+    self->curr_function = p0;  // set current function for inspection
 
 
     if(p0->type == tp_function) {
     if(p0->type == tp_function) {
         Function* fn = py_touserdata(p0);
         Function* fn = py_touserdata(p0);
@@ -516,10 +518,8 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
                     return opcall ? RES_CALL : VM__run_top_frame(self);
                     return opcall ? RES_CALL : VM__run_top_frame(self);
                 } else {
                 } else {
                     // decl-based binding
                     // decl-based binding
-                    self->curr_decl_based_function = p0;
                     bool ok = py_callcfunc(fn->cfunc, co->nlocals, argv);
                     bool ok = py_callcfunc(fn->cfunc, co->nlocals, argv);
                     self->stack.sp = p0;
                     self->stack.sp = p0;
-                    self->curr_decl_based_function = NULL;
                     return ok ? RES_RETURN : RES_ERROR;
                     return ok ? RES_RETURN : RES_ERROR;
                 }
                 }
             }
             }
@@ -545,10 +545,8 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
                     return opcall ? RES_CALL : VM__run_top_frame(self);
                     return opcall ? RES_CALL : VM__run_top_frame(self);
                 } else {
                 } else {
                     // decl-based binding
                     // decl-based binding
-                    self->curr_decl_based_function = p0;
                     bool ok = py_callcfunc(fn->cfunc, co->nlocals, argv);
                     bool ok = py_callcfunc(fn->cfunc, co->nlocals, argv);
                     self->stack.sp = p0;
                     self->stack.sp = p0;
-                    self->curr_decl_based_function = NULL;
                     return ok ? RES_RETURN : RES_ERROR;
                     return ok ? RES_RETURN : RES_ERROR;
                 }
                 }
             case FuncType_GENERATOR: {
             case FuncType_GENERATOR: {

+ 2 - 4
src/public/Inspection.c

@@ -3,10 +3,8 @@
 
 
 py_StackRef py_inspect_currentfunction() {
 py_StackRef py_inspect_currentfunction() {
     VM* vm = pk_current_vm;
     VM* vm = pk_current_vm;
-    if(vm->curr_decl_based_function) return vm->curr_decl_based_function;
-    py_Frame* frame = vm->top_frame;
-    if(!frame || frame->is_locals_special) return NULL;
-    return frame->p0;
+    if(vm->curr_function >= vm->stack.sp) return NULL;
+    return vm->curr_function;
 }
 }
 
 
 py_GlobalRef py_inspect_currentmodule() {
 py_GlobalRef py_inspect_currentmodule() {