@@ -3626,7 +3626,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
3626
3626
}
3627
3627
3628
3628
TARGET (LOAD_ATTR_CLASS ) {
3629
- /* LOAD_METHOD, for class methods */
3630
3629
assert (cframe .use_tracing == 0 );
3631
3630
_PyLoadMethodCache * cache = (_PyLoadMethodCache * )next_instr ;
3632
3631
@@ -3649,6 +3648,46 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
3649
3648
NOTRACE_DISPATCH ();
3650
3649
}
3651
3650
3651
+ TARGET (LOAD_ATTR_PROPERTY ) {
3652
+ assert (cframe .use_tracing == 0 );
3653
+ DEOPT_IF (tstate -> interp -> eval_frame , LOAD_ATTR );
3654
+ _PyLoadMethodCache * cache = (_PyLoadMethodCache * )next_instr ;
3655
+
3656
+ PyObject * owner = TOP ();
3657
+ PyTypeObject * cls = Py_TYPE (owner );
3658
+ uint32_t type_version = read_u32 (cache -> type_version );
3659
+ DEOPT_IF (cls -> tp_version_tag != type_version , LOAD_ATTR );
3660
+ assert (type_version != 0 );
3661
+ PyObject * fget = read_obj (cache -> descr );
3662
+ PyFunctionObject * f = (PyFunctionObject * )fget ;
3663
+ uint32_t func_version = read_u32 (cache -> keys_version );
3664
+ assert (func_version != 0 );
3665
+ DEOPT_IF (f -> func_version != func_version , LOAD_ATTR );
3666
+ PyCodeObject * code = (PyCodeObject * )f -> func_code ;
3667
+ assert (code -> co_argcount == 1 );
3668
+ STAT_INC (LOAD_ATTR , hit );
3669
+
3670
+ Py_INCREF (fget );
3671
+ _PyInterpreterFrame * new_frame = _PyFrame_Push (tstate , f );
3672
+ if (new_frame == NULL ) {
3673
+ goto error ;
3674
+ }
3675
+ SET_TOP (NULL );
3676
+ int push_null = !(oparg & 1 );
3677
+ STACK_SHRINK (push_null );
3678
+ new_frame -> localsplus [0 ] = owner ;
3679
+ for (int i = 1 ; i < code -> co_nlocalsplus ; i ++ ) {
3680
+ new_frame -> localsplus [i ] = NULL ;
3681
+ }
3682
+ _PyFrame_SetStackPointer (frame , stack_pointer );
3683
+ JUMPBY (INLINE_CACHE_ENTRIES_LOAD_ATTR );
3684
+ frame -> prev_instr = next_instr - 1 ;
3685
+ new_frame -> previous = frame ;
3686
+ frame = cframe .current_frame = new_frame ;
3687
+ CALL_STAT_INC (inlined_py_calls );
3688
+ goto start_frame ;
3689
+ }
3690
+
3652
3691
TARGET (STORE_ATTR_ADAPTIVE ) {
3653
3692
assert (cframe .use_tracing == 0 );
3654
3693
_PyAttrCache * cache = (_PyAttrCache * )next_instr ;
@@ -4548,7 +4587,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
4548
4587
}
4549
4588
4550
4589
TARGET (LOAD_ATTR_METHOD_WITH_VALUES ) {
4551
- /* LOAD_METHOD, with cached method object */
4590
+ /* Cached method object */
4552
4591
assert (cframe .use_tracing == 0 );
4553
4592
PyObject * self = TOP ();
4554
4593
PyTypeObject * self_cls = Py_TYPE (self );
@@ -4574,8 +4613,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
4574
4613
}
4575
4614
4576
4615
TARGET (LOAD_ATTR_METHOD_WITH_DICT ) {
4577
- /* LOAD_METHOD, with a dict
4578
- Can be either a managed dict, or a tp_dictoffset offset.*/
4616
+ /* Can be either a managed dict, or a tp_dictoffset offset.*/
4579
4617
assert (cframe .use_tracing == 0 );
4580
4618
PyObject * self = TOP ();
4581
4619
PyTypeObject * self_cls = Py_TYPE (self );
0 commit comments