add __self__ and __func__ for bound_method

This commit is contained in:
blueloveTH 2023-04-22 10:40:59 +08:00
parent f0c8841721
commit 5faac18935
4 changed files with 16 additions and 9 deletions

View File

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

View File

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

View File

@ -631,7 +631,7 @@ inline void add_module_dis(VM* vm){
PyObject* mod = vm->new_module("dis"); PyObject* mod = vm->new_module("dis");
vm->bind_func<1>(mod, "dis", [](VM* vm, ArgsView args) { vm->bind_func<1>(mod, "dis", [](VM* vm, ArgsView args) {
PyObject* f = args[0]; 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; CodeObject_ code = CAST(Function&, f).decl->code;
(*vm->_stdout) << vm->disassemble(code); (*vm->_stdout) << vm->disassemble(code);
return vm->None; return vm->None;
@ -804,6 +804,13 @@ inline void VM::post_init(){
const PyTypeInfo& info = vm->_all_types[OBJ_GET(Type, args[0])]; const PyTypeInfo& info = vm->_all_types[OBJ_GET(Type, args[0])];
return VAR(info.name); 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 #endif
} }

View File

@ -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(is_non_tagged_type(callable, tp_bound_method)){
if(method_call) FATAL_ERROR(); if(method_call) FATAL_ERROR();
auto& bm = CAST(BoundMethod&, callable); auto& bm = CAST(BoundMethod&, callable);
callable = bm.method; // get unbound method callable = bm.func; // get unbound method
p1[-(ARGC + 2)] = bm.method; p1[-(ARGC + 2)] = bm.func;
p1[-(ARGC + 1)] = bm.obj; p1[-(ARGC + 1)] = bm.self;
method_call = true; method_call = true;
// [unbound, self, args..., kwargs...] // [unbound, self, args..., kwargs...]
} }