소스 검색

fix a bug of `_class` in `Function`

blueloveTH 2 년 전
부모
커밋
53e4043e0e
3개의 변경된 파일9개의 추가작업 그리고 6개의 파일을 삭제
  1. 5 2
      include/pocketpy/codeobject.h
  2. 3 3
      src/ceval.cpp
  3. 1 1
      src/pocketpy.cpp

+ 5 - 2
include/pocketpy/codeobject.h

@@ -190,8 +190,12 @@ struct NativeFunc {
 
 struct Function{
     FuncDecl_ decl;
-    PyObject* _module;
+    PyObject* _module;  // weak ref
+    PyObject* _class;   // weak ref
     NameDict_ _closure;
+
+    explicit Function(FuncDecl_ decl, PyObject* _module, PyObject* _class, NameDict_ _closure):
+        decl(decl), _module(_module), _class(_class), _closure(_closure) {}
 };
 
 template<>
@@ -203,7 +207,6 @@ struct Py_<Function> final: PyObject {
     }
     void _obj_gc_mark() override {
         _value.decl->_gc_mark();
-        if(_value._module != nullptr) PK_OBJ_MARK(_value._module);
         if(_value._closure != nullptr) gc_mark_namedict(*_value._closure);
     }
 

+ 3 - 3
src/ceval.cpp

@@ -89,10 +89,10 @@ __NEXT_STEP:;
         PyObject* obj;
         if(decl->nested){
             NameDict_ captured = frame->_locals.to_namedict();
-            obj = VAR(Function({decl, frame->_module, captured}));
+            obj = VAR(Function(decl, frame->_module, nullptr, captured));
             captured->set(decl->code->name, obj);
         }else{
-            obj = VAR(Function({decl, frame->_module}));
+            obj = VAR(Function(decl, frame->_module, nullptr, nullptr));
         }
         PUSH(obj);
     } DISPATCH();
@@ -689,7 +689,7 @@ __NEXT_STEP:;
         StrName _name(byte.arg);
         PyObject* _0 = POPX();
         if(is_non_tagged_type(_0, tp_function)){
-            _0->attr().set(__class__, TOP());
+            PK_OBJ_GET(Function, _0)._class = TOP();
         }
         TOP()->attr().set(_name, _0);
     } DISPATCH();

+ 1 - 1
src/pocketpy.cpp

@@ -123,7 +123,7 @@ void init_builtins(VM* _vm) {
         }else if(args.size() == 0){
             FrameId frame = vm->top_frame();
             if(frame->_callable != nullptr){
-                class_arg = frame->_callable->attr().try_get_likely_found(__class__);
+                class_arg = PK_OBJ_GET(Function, frame->_callable)._class;
                 if(frame->_locals.size() > 0) self_arg = frame->_locals[0];
             }
             if(class_arg == nullptr || self_arg == nullptr){