summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index d34d6bf..8c17e51 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -3698,6 +3698,7 @@ handle_eval_breaker:
DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR);
assert(type_version != 0);
PyObject *fget = read_obj(cache->descr);
+ assert(Py_IS_TYPE(fget, &PyFunction_Type));
PyFunctionObject *f = (PyFunctionObject *)fget;
uint32_t func_version = read_u32(cache->keys_version);
assert(func_version != 0);
@@ -3709,8 +3710,8 @@ handle_eval_breaker:
Py_INCREF(fget);
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f);
SET_TOP(NULL);
- int push_null = !(oparg & 1);
- STACK_SHRINK(push_null);
+ int shrink_stack = !(oparg & 1);
+ STACK_SHRINK(shrink_stack);
new_frame->localsplus[0] = owner;
for (int i = 1; i < code->co_nlocalsplus; i++) {
new_frame->localsplus[i] = NULL;
@@ -3724,6 +3725,44 @@ handle_eval_breaker:
goto start_frame;
}
+ TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) {
+ assert(cframe.use_tracing == 0);
+ DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR);
+ _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr;
+ PyObject *owner = TOP();
+ PyTypeObject *cls = Py_TYPE(owner);
+ uint32_t type_version = read_u32(cache->type_version);
+ DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR);
+ assert(type_version != 0);
+ PyObject *getattribute = read_obj(cache->descr);
+ assert(Py_IS_TYPE(getattribute, &PyFunction_Type));
+ PyFunctionObject *f = (PyFunctionObject *)getattribute;
+ PyCodeObject *code = (PyCodeObject *)f->func_code;
+ DEOPT_IF(((PyCodeObject *)f->func_code)->co_argcount != 2, LOAD_ATTR);
+ DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
+ STAT_INC(LOAD_ATTR, hit);
+
+ PyObject *name = GETITEM(names, oparg >> 1);
+ Py_INCREF(f);
+ _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f);
+ SET_TOP(NULL);
+ int shrink_stack = !(oparg & 1);
+ STACK_SHRINK(shrink_stack);
+ Py_INCREF(name);
+ new_frame->localsplus[0] = owner;
+ new_frame->localsplus[1] = name;
+ for (int i = 2; i < code->co_nlocalsplus; i++) {
+ new_frame->localsplus[i] = NULL;
+ }
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+ JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
+ frame->prev_instr = next_instr - 1;
+ new_frame->previous = frame;
+ frame = cframe.current_frame = new_frame;
+ CALL_STAT_INC(inlined_py_calls);
+ goto start_frame;
+ }
+
TARGET(STORE_ATTR_ADAPTIVE) {
assert(cframe.use_tracing == 0);
_PyAttrCache *cache = (_PyAttrCache *)next_instr;