mirror of
https://github.com/python/cpython.git
synced 2025-08-23 02:04:56 +00:00
GH-121784: Generate an error during code gen if a variable is marked unused
, but is used and thus cached in a prior uop. (#121788)
* Reject uop definitions that declare values as 'unused' that are already cached by prior uops * Track which variables are defined and only load from memory when needed * Support explicit `flush` in macro definitions. * Make sure stack is flushed in where needed.
This commit is contained in:
parent
169324c27a
commit
3eacfc1a4d
9 changed files with 443 additions and 255 deletions
|
@ -3448,7 +3448,7 @@ dummy_func(
|
|||
}
|
||||
}
|
||||
|
||||
op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, unused, unused[oparg] -- callable, unused, unused[oparg])) {
|
||||
op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
EXIT_IF(!PyFunction_Check(callable_o));
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable_o;
|
||||
|
@ -3479,7 +3479,6 @@ dummy_func(
|
|||
assert(PyStackRef_IsNull(null));
|
||||
assert(Py_TYPE(callable_o) == &PyMethod_Type);
|
||||
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
|
||||
stack_pointer[-1 - oparg] = self; // Patch stack as it is used by _PY_FRAME_GENERAL
|
||||
method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
|
||||
assert(PyFunction_Check(PyStackRef_AsPyObjectBorrow(method)));
|
||||
PyStackRef_CLOSE(callable);
|
||||
|
@ -3490,6 +3489,7 @@ dummy_func(
|
|||
_CHECK_PEP_523 +
|
||||
_CHECK_METHOD_VERSION +
|
||||
_EXPAND_METHOD +
|
||||
flush + // so that self is in the argument array
|
||||
_PY_FRAME_GENERAL +
|
||||
_SAVE_RETURN_OFFSET +
|
||||
_PUSH_FRAME;
|
||||
|
@ -3544,16 +3544,12 @@ dummy_func(
|
|||
EXIT_IF(Py_TYPE(PyStackRef_AsPyObjectBorrow(callable)) != &PyMethod_Type);
|
||||
}
|
||||
|
||||
op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, unused, unused[oparg] -- func, self, unused[oparg])) {
|
||||
op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- func, self, unused[oparg])) {
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
STAT_INC(CALL, hit);
|
||||
stack_pointer[-1 - oparg] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); // Patch stack as it is used by _INIT_CALL_PY_EXACT_ARGS
|
||||
stack_pointer[-2 - oparg] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); // This is used by CALL, upon deoptimization
|
||||
self = stack_pointer[-1 - oparg];
|
||||
func = stack_pointer[-2 - oparg];
|
||||
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
|
||||
func = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
|
||||
PyStackRef_CLOSE(callable);
|
||||
// self may be unused in tier 1, so silence warnings.
|
||||
(void)self;
|
||||
}
|
||||
|
||||
op(_CHECK_PEP_523, (--)) {
|
||||
|
@ -3568,7 +3564,7 @@ dummy_func(
|
|||
EXIT_IF(code->co_argcount != oparg + (!PyStackRef_IsNull(self_or_null)));
|
||||
}
|
||||
|
||||
op(_CHECK_STACK_SPACE, (callable, unused, unused[oparg] -- callable, unused, unused[oparg])) {
|
||||
op(_CHECK_STACK_SPACE, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable_o;
|
||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||
|
@ -3609,6 +3605,7 @@ dummy_func(
|
|||
_CHECK_PEP_523 +
|
||||
_CHECK_CALL_BOUND_METHOD_EXACT_ARGS +
|
||||
_INIT_CALL_BOUND_METHOD_EXACT_ARGS +
|
||||
flush + // In case the following deopt
|
||||
_CHECK_FUNCTION_VERSION +
|
||||
_CHECK_FUNCTION_EXACT_ARGS +
|
||||
_CHECK_STACK_SPACE +
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue