@@ -26,14 +26,13 @@ use crate::frozen;
2626use crate :: function:: PyFuncArgs ;
2727use crate :: import;
2828use crate :: obj:: objbool;
29- use crate :: obj:: objbuiltinfunc:: { PyBuiltinFunction , PyBuiltinMethod } ;
3029use crate :: obj:: objcode:: { PyCode , PyCodeRef } ;
3130use crate :: obj:: objdict:: PyDictRef ;
32- use crate :: obj:: objfunction:: { PyBoundMethod , PyFunction } ;
3331use crate :: obj:: objint:: PyInt ;
3432use crate :: obj:: objiter;
3533use crate :: obj:: objlist:: PyList ;
3634use crate :: obj:: objmodule:: { self , PyModule } ;
35+ use crate :: obj:: objobject;
3736use crate :: obj:: objstr:: { PyString , PyStringRef } ;
3837use crate :: obj:: objtuple:: PyTuple ;
3938use crate :: obj:: objtype:: { self , PyClassRef } ;
@@ -656,31 +655,23 @@ impl VirtualMachine {
656655 }
657656 }
658657
659- fn _invoke ( & self , func_ref : & PyObjectRef , args : PyFuncArgs ) -> PyResult {
660- vm_trace ! ( "Invoke: {:?} {:?}" , func_ref, args) ;
661-
662- if let Some ( py_func) = func_ref. payload :: < PyFunction > ( ) {
658+ fn _invoke ( & self , callable : & PyObjectRef , args : PyFuncArgs ) -> PyResult {
659+ vm_trace ! ( "Invoke: {:?} {:?}" , callable, args) ;
660+ let class = callable. class ( ) ;
661+ let slots = class. slots . borrow ( ) ;
662+ if let Some ( slot_call) = slots. borrow ( ) . call . as_ref ( ) {
663663 self . trace_event ( TraceEvent :: Call ) ?;
664- let res = py_func. invoke ( args, self ) ;
664+ let args = args. insert ( callable. clone ( ) ) ;
665+ let result = slot_call ( self , args) ;
665666 self . trace_event ( TraceEvent :: Return ) ?;
666- res
667- } else if let Some ( PyBoundMethod {
668- ref function,
669- ref object,
670- } ) = func_ref. payload ( )
671- {
672- let args = args. insert ( object. clone ( ) ) ;
673- self . invoke ( & function, args)
674- } else if let Some ( builtin_func) = func_ref. payload :: < PyBuiltinFunction > ( ) {
675- builtin_func. as_func ( ) ( self , args)
676- } else if let Some ( method) = func_ref. payload :: < PyBuiltinMethod > ( ) {
677- method. as_func ( ) ( self , args)
678- } else if self . is_callable ( & func_ref) {
679- self . call_method ( & func_ref, "__call__" , args)
667+ result
668+ } else if objtype:: class_has_attr ( & class, "__call__" ) {
669+ let result = self . call_method ( & callable, "__call__" , args) ;
670+ result
680671 } else {
681672 Err ( self . new_type_error ( format ! (
682673 "'{}' object is not callable" ,
683- func_ref . class( ) . name
674+ callable . class( ) . name
684675 ) ) )
685676 }
686677 }
@@ -889,12 +880,8 @@ impl VirtualMachine {
889880 }
890881
891882 pub fn is_callable ( & self , obj : & PyObjectRef ) -> bool {
892- match_class ! ( match obj {
893- PyFunction => true ,
894- PyBoundMethod => true ,
895- PyBuiltinFunction => true ,
896- obj => objtype:: class_has_attr( & obj. class( ) , "__call__" ) ,
897- } )
883+ obj. class ( ) . slots . borrow ( ) . call . is_some ( )
884+ || objtype:: class_has_attr ( & obj. class ( ) , "__call__" )
898885 }
899886
900887 #[ inline]
@@ -1311,8 +1298,7 @@ impl VirtualMachine {
13111298 attr_value : impl Into < PyObjectRef > ,
13121299 ) -> PyResult < ( ) > {
13131300 let val = attr_value. into ( ) ;
1314- self . set_attr ( module, attr_name, val) ?;
1315- Ok ( ( ) )
1301+ objobject:: object_setattr ( module. clone ( ) , attr_name. try_into_ref ( self ) ?, val, self )
13161302 }
13171303}
13181304
0 commit comments