@@ -996,8 +996,18 @@ dummy_func(void) {
996996 }
997997
998998 op (_INIT_CALL_BOUND_METHOD_EXACT_ARGS , (callable , self_or_null , unused [oparg ] -- callable , self_or_null , unused [oparg ])) {
999- callable = sym_new_not_null (ctx );
1000- self_or_null = sym_new_not_null (ctx );
999+ PyObject * bound_method = sym_get_probable_value (callable );
1000+ if (bound_method != NULL && Py_TYPE (bound_method ) == & PyMethod_Type ) {
1001+ PyMethodObject * method = (PyMethodObject * )bound_method ;
1002+ callable = sym_new_not_null (ctx );
1003+ sym_set_recorded_value (callable , method -> im_func );
1004+ self_or_null = sym_new_not_null (ctx );
1005+ sym_set_recorded_value (self_or_null , method -> im_self );
1006+ }
1007+ else {
1008+ callable = sym_new_not_null (ctx );
1009+ self_or_null = sym_new_not_null (ctx );
1010+ }
10011011 }
10021012
10031013 op (_CHECK_FUNCTION_VERSION , (func_version /2 , callable , self_or_null , unused [oparg ] -- callable , self_or_null , unused [oparg ])) {
@@ -1019,6 +1029,19 @@ dummy_func(void) {
10191029 ADD_OP (_CHECK_FUNCTION_VERSION_INLINE , 0 , func_version );
10201030 uop_buffer_last (& ctx -> out_buffer )-> operand1 = (uintptr_t )method -> im_func ;
10211031 }
1032+ else {
1033+ // Guarding on the bound method, safe to promote.
1034+ PyObject * bound_method = sym_get_probable_value (callable );
1035+ if (bound_method != NULL && Py_TYPE (bound_method ) == & PyMethod_Type ) {
1036+ PyMethodObject * method = (PyMethodObject * )bound_method ;
1037+ PyObject * func = method -> im_func ;
1038+ if (PyFunction_Check (func ) &&
1039+ ((PyFunctionObject * )func )-> func_version == func_version ) {
1040+ _Py_BloomFilter_Add (dependencies , func );
1041+ sym_set_const (callable , bound_method );
1042+ }
1043+ }
1044+ }
10221045 sym_set_type (callable , & PyMethod_Type );
10231046 }
10241047
@@ -1057,6 +1080,18 @@ dummy_func(void) {
10571080 }
10581081 }
10591082
1083+ op (_EXPAND_METHOD , (callable , self_or_null , unused [oparg ] -- callable , self_or_null , unused [oparg ])) {
1084+ if (sym_is_const (ctx , callable ) && sym_matches_type (callable , & PyMethod_Type )) {
1085+ PyMethodObject * method = (PyMethodObject * )sym_get_const (ctx , callable );
1086+ callable = sym_new_const (ctx , method -> im_func );
1087+ self_or_null = sym_new_const (ctx , method -> im_self );
1088+ }
1089+ else {
1090+ callable = sym_new_not_null (ctx );
1091+ self_or_null = sym_new_not_null (ctx );
1092+ }
1093+ }
1094+
10601095 op (_MAYBE_EXPAND_METHOD , (callable , self_or_null , args [oparg ] -- callable , self_or_null , args [oparg ])) {
10611096 (void )args ;
10621097 callable = sym_new_not_null (ctx );
@@ -2226,6 +2261,10 @@ dummy_func(void) {
22262261 sym_set_recorded_value (func , (PyObject * )this_instr -> operand0 );
22272262 }
22282263
2264+ op (_RECORD_BOUND_METHOD , (callable , self , args [oparg ] -- callable , self , args [oparg ])) {
2265+ sym_set_recorded_value (callable , (PyObject * )this_instr -> operand0 );
2266+ }
2267+
22292268 op (_RECORD_NOS_GEN_FUNC , (nos , tos -- nos , tos )) {
22302269 PyFunctionObject * func = (PyFunctionObject * )this_instr -> operand0 ;
22312270 assert (func == NULL || PyFunction_Check (func ));
0 commit comments