@@ -663,32 +663,33 @@ static int specialize_attr_loadmethod(PyObject* owner, _Py_CODEUNIT* instr, PyOb
663
663
PyObject * descr , DescriptorClassification kind );
664
664
static int specialize_class_load_attr (PyObject * owner , _Py_CODEUNIT * instr , PyObject * name );
665
665
666
- int
666
+ void
667
667
_Py_Specialize_LoadAttr (PyObject * owner , _Py_CODEUNIT * instr , PyObject * name )
668
668
{
669
669
assert (_PyOpcode_Caches [LOAD_ATTR ] == INLINE_CACHE_ENTRIES_LOAD_ATTR );
670
670
_PyAttrCache * cache = (_PyAttrCache * )(instr + 1 );
671
+ PyTypeObject * type = Py_TYPE (owner );
672
+ if (!_PyType_IsReady (type )) {
673
+ // We *might* not really need this check, but we inherited it from
674
+ // PyObject_GenericGetAttr and friends... and this way we still do the
675
+ // right thing if someone forgets to call PyType_Ready(type):
676
+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_OTHER );
677
+ goto fail ;
678
+ }
671
679
if (PyModule_CheckExact (owner )) {
672
- int err = specialize_module_load_attr (owner , instr , name , LOAD_ATTR ,
673
- LOAD_ATTR_MODULE );
674
- if ( err ) {
680
+ if ( specialize_module_load_attr (owner , instr , name , LOAD_ATTR ,
681
+ LOAD_ATTR_MODULE ))
682
+ {
675
683
goto fail ;
676
684
}
677
685
goto success ;
678
686
}
679
687
if (PyType_Check (owner )) {
680
- int err = specialize_class_load_attr (owner , instr , name );
681
- if (err ) {
688
+ if (specialize_class_load_attr (owner , instr , name )) {
682
689
goto fail ;
683
690
}
684
691
goto success ;
685
692
}
686
- PyTypeObject * type = Py_TYPE (owner );
687
- if (type -> tp_dict == NULL ) {
688
- if (PyType_Ready (type ) < 0 ) {
689
- return -1 ;
690
- }
691
- }
692
693
PyObject * descr = NULL ;
693
694
DescriptorClassification kind = analyze_descriptor (type , name , & descr , 0 );
694
695
assert (descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN );
@@ -803,35 +804,36 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
803
804
case ABSENT :
804
805
break ;
805
806
}
806
- int err = specialize_dict_access (
807
- owner , instr , type , kind , name ,
808
- LOAD_ATTR , LOAD_ATTR_INSTANCE_VALUE , LOAD_ATTR_WITH_HINT
809
- );
810
- if (err < 0 ) {
811
- return -1 ;
812
- }
813
- if (err ) {
807
+ if (specialize_dict_access (owner , instr , type , kind , name , LOAD_ATTR ,
808
+ LOAD_ATTR_INSTANCE_VALUE , LOAD_ATTR_WITH_HINT ))
809
+ {
814
810
goto success ;
815
811
}
816
812
fail :
817
813
STAT_INC (LOAD_ATTR , failure );
818
814
assert (!PyErr_Occurred ());
819
815
_Py_SET_OPCODE (* instr , LOAD_ATTR );
820
816
cache -> counter = adaptive_counter_backoff (cache -> counter );
821
- return 0 ;
817
+ return ;
822
818
success :
823
819
STAT_INC (LOAD_ATTR , success );
824
820
assert (!PyErr_Occurred ());
825
821
cache -> counter = adaptive_counter_cooldown ();
826
- return 0 ;
827
822
}
828
823
829
- int
824
+ void
830
825
_Py_Specialize_StoreAttr (PyObject * owner , _Py_CODEUNIT * instr , PyObject * name )
831
826
{
832
827
assert (_PyOpcode_Caches [STORE_ATTR ] == INLINE_CACHE_ENTRIES_STORE_ATTR );
833
828
_PyAttrCache * cache = (_PyAttrCache * )(instr + 1 );
834
829
PyTypeObject * type = Py_TYPE (owner );
830
+ if (!_PyType_IsReady (type )) {
831
+ // We *might* not really need this check, but we inherited it from
832
+ // PyObject_GenericSetAttr and friends... and this way we still do the
833
+ // right thing if someone forgets to call PyType_Ready(type):
834
+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_OTHER );
835
+ goto fail ;
836
+ }
835
837
if (PyModule_CheckExact (owner )) {
836
838
SPECIALIZATION_FAIL (STORE_ATTR , SPEC_FAIL_OVERRIDDEN );
837
839
goto fail ;
@@ -890,28 +892,21 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
890
892
case ABSENT :
891
893
break ;
892
894
}
893
-
894
- int err = specialize_dict_access (
895
- owner , instr , type , kind , name ,
896
- STORE_ATTR , STORE_ATTR_INSTANCE_VALUE , STORE_ATTR_WITH_HINT
897
- );
898
- if (err < 0 ) {
899
- return -1 ;
900
- }
901
- if (err ) {
895
+ if (specialize_dict_access (owner , instr , type , kind , name , STORE_ATTR ,
896
+ STORE_ATTR_INSTANCE_VALUE , STORE_ATTR_WITH_HINT ))
897
+ {
902
898
goto success ;
903
899
}
904
900
fail :
905
901
STAT_INC (STORE_ATTR , failure );
906
902
assert (!PyErr_Occurred ());
907
903
_Py_SET_OPCODE (* instr , STORE_ATTR );
908
904
cache -> counter = adaptive_counter_backoff (cache -> counter );
909
- return 0 ;
905
+ return ;
910
906
success :
911
907
STAT_INC (STORE_ATTR , success );
912
908
assert (!PyErr_Occurred ());
913
909
cache -> counter = adaptive_counter_cooldown ();
914
- return 0 ;
915
910
}
916
911
917
912
0 commit comments