Jelajahi Sumber

add `__self__` and `__func__` for `bound_method`

blueloveTH 2 tahun lalu
induk
melakukan
5faac18935
4 mengubah file dengan 16 tambahan dan 9 penghapusan
  1. 2 2
      src/gc.h
  2. 3 3
      src/obj.h
  3. 8 1
      src/pocketpy.h
  4. 3 3
      src/vm.h

+ 2 - 2
src/gc.h

@@ -137,8 +137,8 @@ template<> inline void gc_mark<NameDict>(NameDict& t){
 }
 
 template<> inline void gc_mark<BoundMethod>(BoundMethod& t){
-    OBJ_MARK(t.obj);
-    OBJ_MARK(t.method);
+    OBJ_MARK(t.self);
+    OBJ_MARK(t.func);
 }
 
 template<> inline void gc_mark<Function>(Function& t){

+ 3 - 3
src/obj.h

@@ -46,9 +46,9 @@ struct Function{
 };
 
 struct BoundMethod {
-    PyObject* obj;
-    PyObject* method;
-    BoundMethod(PyObject* obj, PyObject* method) : obj(obj), method(method) {}
+    PyObject* self;
+    PyObject* func;
+    BoundMethod(PyObject* self, PyObject* func) : self(self), func(func) {}
 };
 
 struct Range {

+ 8 - 1
src/pocketpy.h

@@ -631,7 +631,7 @@ inline void add_module_dis(VM* vm){
     PyObject* mod = vm->new_module("dis");
     vm->bind_func<1>(mod, "dis", [](VM* vm, ArgsView args) {
         PyObject* f = args[0];
-        if(is_type(f, vm->tp_bound_method)) f = CAST(BoundMethod, args[0]).method;
+        if(is_type(f, vm->tp_bound_method)) f = CAST(BoundMethod, args[0]).func;
         CodeObject_ code = CAST(Function&, f).decl->code;
         (*vm->_stdout) << vm->disassemble(code);
         return vm->None;
@@ -804,6 +804,13 @@ inline void VM::post_init(){
         const PyTypeInfo& info = vm->_all_types[OBJ_GET(Type, args[0])];
         return VAR(info.name);
     }));
+
+    _t(tp_bound_method)->attr().set("__self__", property([](VM* vm, ArgsView args){
+        return CAST(BoundMethod&, args[0]).self;
+    }));
+    _t(tp_bound_method)->attr().set("__func__", property([](VM* vm, ArgsView args){
+        return CAST(BoundMethod&, args[0]).func;
+    }));
 #endif
 }
 

+ 3 - 3
src/vm.h

@@ -789,9 +789,9 @@ inline PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){
     if(is_non_tagged_type(callable, tp_bound_method)){
         if(method_call) FATAL_ERROR();
         auto& bm = CAST(BoundMethod&, callable);
-        callable = bm.method;      // get unbound method
-        p1[-(ARGC + 2)] = bm.method;
-        p1[-(ARGC + 1)] = bm.obj;
+        callable = bm.func;      // get unbound method
+        p1[-(ARGC + 2)] = bm.func;
+        p1[-(ARGC + 1)] = bm.self;
         method_call = true;
         // [unbound, self, args..., kwargs...]
     }