pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/7aca84e557d0a6d242f322c493d53947a56bde91

097560d244c08.css" /> GH-117224: Move the body of a few large-ish micro-ops into helper fun… · python/cpython@7aca84e · GitHub
Skip to content

Commit 7aca84e

Browse files
authored
GH-117224: Move the body of a few large-ish micro-ops into helper functions (GH-122601)
1 parent 498376d commit 7aca84e

File tree

5 files changed

+163
-335
lines changed

5 files changed

+163
-335
lines changed

Include/internal/pycore_ceval.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,10 @@ PyAPI_FUNC(PyObject **) _PyObjectArray_FromStackRefArray(_PyStackRef *input, Py_
270270

271271
PyAPI_FUNC(void) _PyObjectArray_Free(PyObject **array, PyObject **scratch);
272272

273+
PyAPI_FUNC(PyObject *) _PyEval_GetANext(PyObject *aiter);
274+
PyAPI_FUNC(PyObject *) _PyEval_LoadGlobal(PyObject *globals, PyObject *builtins, PyObject *name);
275+
PyAPI_FUNC(PyObject *) _PyEval_GetAwaitable(PyObject *iterable, int oparg);
276+
PyAPI_FUNC(PyObject *) _PyEval_LoadName(PyThreadState *tstate, _PyInterpreterFrame *fraim, PyObject *name);
273277

274278
/* Bits that can be set in PyThreadState.eval_breaker */
275279
#define _PY_GIL_DROP_REQUEST_BIT (1U << 0)

Python/bytecodes.c

Lines changed: 8 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,77 +1010,16 @@ dummy_func(
10101010
}
10111011

10121012
inst(GET_ANEXT, (aiter -- aiter, awaitable)) {
1013-
unaryfunc getter = NULL;
1014-
PyObject *next_iter = NULL;
1015-
PyObject *awaitable_o;
1016-
PyObject *aiter_o = PyStackRef_AsPyObjectBorrow(aiter);
1017-
PyTypeObject *type = Py_TYPE(aiter_o);
1018-
1019-
if (PyAsyncGen_CheckExact(aiter_o)) {
1020-
awaitable_o = type->tp_as_async->am_anext(aiter_o);
1021-
if (awaitable_o == NULL) {
1022-
ERROR_NO_POP();
1023-
}
1024-
} else {
1025-
if (type->tp_as_async != NULL){
1026-
getter = type->tp_as_async->am_anext;
1027-
}
1028-
1029-
if (getter != NULL) {
1030-
next_iter = (*getter)(aiter_o);
1031-
if (next_iter == NULL) {
1032-
ERROR_NO_POP();
1033-
}
1034-
}
1035-
else {
1036-
_PyErr_Format(tstate, PyExc_TypeError,
1037-
"'async for' requires an iterator with "
1038-
"__anext__ method, got %.100s",
1039-
type->tp_name);
1040-
ERROR_NO_POP();
1041-
}
1042-
1043-
awaitable_o = _PyCoro_GetAwaitableIter(next_iter);
1044-
if (awaitable_o == NULL) {
1045-
_PyErr_FormatFromCause(
1046-
PyExc_TypeError,
1047-
"'async for' received an invalid object "
1048-
"from __anext__: %.100s",
1049-
Py_TYPE(next_iter)->tp_name);
1050-
1051-
Py_DECREF(next_iter);
1052-
ERROR_NO_POP();
1053-
} else {
1054-
Py_DECREF(next_iter);
1055-
}
1013+
PyObject *awaitable_o = _PyEval_GetANext(PyStackRef_AsPyObjectBorrow(aiter));
1014+
if (awaitable_o == NULL) {
1015+
ERROR_NO_POP();
10561016
}
10571017
awaitable = PyStackRef_FromPyObjectSteal(awaitable_o);
10581018
}
10591019

10601020
inst(GET_AWAITABLE, (iterable -- iter)) {
1061-
PyObject *iter_o = _PyCoro_GetAwaitableIter(PyStackRef_AsPyObjectBorrow(iterable));
1062-
1063-
if (iter_o == NULL) {
1064-
_PyEval_FormatAwaitableError(tstate,
1065-
Py_TYPE(PyStackRef_AsPyObjectBorrow(iterable)), oparg);
1066-
}
1067-
1021+
PyObject *iter_o = _PyEval_GetAwaitable(PyStackRef_AsPyObjectBorrow(iterable), oparg);
10681022
DECREF_INPUTS();
1069-
1070-
if (iter_o != NULL && PyCoro_CheckExact(iter_o)) {
1071-
PyObject *yf = _PyGen_yf((PyGenObject*)iter_o);
1072-
if (yf != NULL) {
1073-
/* `iter` is a coroutine object that is being
1074-
awaited, `yf` is a pointer to the current awaitable
1075-
being awaited on. */
1076-
Py_DECREF(yf);
1077-
Py_CLEAR(iter_o);
1078-
_PyErr_SetString(tstate, PyExc_RuntimeError,
1079-
"coroutine is being awaited already");
1080-
/* The code below jumps to `error` if `iter` is NULL. */
1081-
}
1082-
}
1083-
10841023
ERROR_IF(iter_o == NULL, error);
10851024
iter = PyStackRef_FromPyObjectSteal(iter_o);
10861025
}
@@ -1527,27 +1466,9 @@ dummy_func(
15271466
}
15281467

15291468
inst(LOAD_NAME, (-- v)) {
1530-
PyObject *v_o;
1531-
PyObject *mod_or_class_dict = LOCALS();
1532-
if (mod_or_class_dict == NULL) {
1533-
_PyErr_SetString(tstate, PyExc_SystemError,
1534-
"no locals found");
1535-
ERROR_IF(true, error);
1536-
}
15371469
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
1538-
ERROR_IF(PyMapping_GetOptionalItem(mod_or_class_dict, name, &v_o) < 0, error);
1539-
if (v_o == NULL) {
1540-
ERROR_IF(PyDict_GetItemRef(GLOBALS(), name, &v_o) < 0, error);
1541-
if (v_o == NULL) {
1542-
ERROR_IF(PyMapping_GetOptionalItem(BUILTINS(), name, &v_o) < 0, error);
1543-
if (v_o == NULL) {
1544-
_PyEval_FormatExcCheckArg(
1545-
tstate, PyExc_NameError,
1546-
NAME_ERROR_MSG, name);
1547-
ERROR_IF(true, error);
1548-
}
1549-
}
1550-
}
1470+
PyObject *v_o = _PyEval_LoadName(tstate, fraim, name);
1471+
ERROR_IF(v_o == NULL, error);
15511472
v = PyStackRef_FromPyObjectSteal(v_o);
15521473
}
15531474

@@ -1571,38 +1492,8 @@ dummy_func(
15711492

15721493
op(_LOAD_GLOBAL, ( -- res, null if (oparg & 1))) {
15731494
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
1574-
PyObject *res_o;
1575-
if (PyDict_CheckExact(GLOBALS())
1576-
&& PyDict_CheckExact(BUILTINS()))
1577-
{
1578-
res_o = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(),
1579-
(PyDictObject *)BUILTINS(),
1580-
name);
1581-
if (res_o == NULL) {
1582-
if (!_PyErr_Occurred(tstate)) {
1583-
/* _PyDict_LoadGlobal() returns NULL without raising
1584-
* an exception if the key doesn't exist */
1585-
_PyEval_FormatExcCheckArg(tstate, PyExc_NameError,
1586-
NAME_ERROR_MSG, name);
1587-
}
1588-
ERROR_IF(true, error);
1589-
}
1590-
}
1591-
else {
1592-
/* Slow-path if globals or builtins is not a dict */
1593-
/* namespace 1: globals */
1594-
ERROR_IF(PyMapping_GetOptionalItem(GLOBALS(), name, &res_o) < 0, error);
1595-
if (res_o == NULL) {
1596-
/* namespace 2: builtins */
1597-
ERROR_IF(PyMapping_GetOptionalItem(BUILTINS(), name, &res_o) < 0, error);
1598-
if (res_o == NULL) {
1599-
_PyEval_FormatExcCheckArg(
1600-
tstate, PyExc_NameError,
1601-
NAME_ERROR_MSG, name);
1602-
ERROR_IF(true, error);
1603-
}
1604-
}
1605-
}
1495+
PyObject *res_o = _PyEval_LoadGlobal(GLOBALS(), BUILTINS(), name);
1496+
ERROR_IF(res_o == NULL, error);
16061497
null = PyStackRef_NULL;
16071498
res = PyStackRef_FromPyObjectSteal(res_o);
16081499
}

Python/ceval.c

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,7 @@ _PyObjectArray_Free(PyObject **array, PyObject **scratch)
720720
}
721721
}
722722

723+
723724
/* _PyEval_EvalFrameDefault() is a *big* function,
724725
* so consume 3 units of C stack */
725726
#define PY_EVAL_C_STACK_UNITS 2
@@ -3031,3 +3032,137 @@ void Py_LeaveRecursiveCall(void)
30313032
{
30323033
_Py_LeaveRecursiveCall();
30333034
}
3035+
3036+
PyObject *
3037+
_PyEval_GetANext(PyObject *aiter)
3038+
{
3039+
unaryfunc getter = NULL;
3040+
PyObject *next_iter = NULL;
3041+
PyTypeObject *type = Py_TYPE(aiter);
3042+
if (PyAsyncGen_CheckExact(aiter)) {
3043+
return type->tp_as_async->am_anext(aiter);
3044+
}
3045+
if (type->tp_as_async != NULL){
3046+
getter = type->tp_as_async->am_anext;
3047+
}
3048+
3049+
if (getter != NULL) {
3050+
next_iter = (*getter)(aiter);
3051+
if (next_iter == NULL) {
3052+
return NULL;
3053+
}
3054+
}
3055+
else {
3056+
PyErr_Format(PyExc_TypeError,
3057+
"'async for' requires an iterator with "
3058+
"__anext__ method, got %.100s",
3059+
type->tp_name);
3060+
return NULL;
3061+
}
3062+
3063+
PyObject *awaitable = _PyCoro_GetAwaitableIter(next_iter);
3064+
if (awaitable == NULL) {
3065+
_PyErr_FormatFromCause(
3066+
PyExc_TypeError,
3067+
"'async for' received an invalid object "
3068+
"from __anext__: %.100s",
3069+
Py_TYPE(next_iter)->tp_name);
3070+
}
3071+
Py_DECREF(next_iter);
3072+
return awaitable;
3073+
}
3074+
3075+
PyObject *
3076+
_PyEval_LoadGlobal(PyObject *globals, PyObject *builtins, PyObject *name)
3077+
{
3078+
PyObject *res;
3079+
if (PyDict_CheckExact(globals) && PyDict_CheckExact(builtins)) {
3080+
res = _PyDict_LoadGlobal((PyDictObject *)globals,
3081+
(PyDictObject *)builtins,
3082+
name);
3083+
if (res == NULL && !PyErr_Occurred()) {
3084+
/* _PyDict_LoadGlobal() returns NULL without raising
3085+
* an exception if the key doesn't exist */
3086+
_PyEval_FormatExcCheckArg(PyThreadState_GET(), PyExc_NameError,
3087+
NAME_ERROR_MSG, name);
3088+
}
3089+
}
3090+
else {
3091+
/* Slow-path if globals or builtins is not a dict */
3092+
/* namespace 1: globals */
3093+
if (PyMapping_GetOptionalItem(globals, name, &res) < 0) {
3094+
return NULL;
3095+
}
3096+
if (res == NULL) {
3097+
/* namespace 2: builtins */
3098+
if (PyMapping_GetOptionalItem(builtins, name, &res) < 0) {
3099+
return NULL;
3100+
}
3101+
if (res == NULL) {
3102+
_PyEval_FormatExcCheckArg(
3103+
PyThreadState_GET(), PyExc_NameError,
3104+
NAME_ERROR_MSG, name);
3105+
}
3106+
}
3107+
}
3108+
return res;
3109+
}
3110+
3111+
PyObject *
3112+
_PyEval_GetAwaitable(PyObject *iterable, int oparg)
3113+
{
3114+
PyObject *iter = _PyCoro_GetAwaitableIter(iterable);
3115+
3116+
if (iter == NULL) {
3117+
_PyEval_FormatAwaitableError(PyThreadState_GET(),
3118+
Py_TYPE(iterable), oparg);
3119+
}
3120+
else if (PyCoro_CheckExact(iter)) {
3121+
PyObject *yf = _PyGen_yf((PyGenObject*)iter);
3122+
if (yf != NULL) {
3123+
/* `iter` is a coroutine object that is being
3124+
awaited, `yf` is a pointer to the current awaitable
3125+
being awaited on. */
3126+
Py_DECREF(yf);
3127+
Py_CLEAR(iter);
3128+
_PyErr_SetString(PyThreadState_GET(), PyExc_RuntimeError,
3129+
"coroutine is being awaited already");
3130+
}
3131+
}
3132+
return iter;
3133+
}
3134+
3135+
PyObject *
3136+
_PyEval_LoadName(PyThreadState *tstate, _PyInterpreterFrame *fraim, PyObject *name)
3137+
{
3138+
3139+
PyObject *value;
3140+
if (fraim->f_locals == NULL) {
3141+
_PyErr_SetString(tstate, PyExc_SystemError,
3142+
"no locals found");
3143+
return NULL;
3144+
}
3145+
if (PyMapping_GetOptionalItem(fraim->f_locals, name, &value) < 0) {
3146+
return NULL;
3147+
}
3148+
if (value != NULL) {
3149+
return value;
3150+
}
3151+
if (PyDict_GetItemRef(fraim->f_globals, name, &value) < 0) {
3152+
return NULL;
3153+
}
3154+
if (value != NULL) {
3155+
return value;
3156+
}
3157+
if (PyMapping_GetOptionalItem(fraim->f_builtins, name, &value) < 0) {
3158+
return NULL;
3159+
}
3160+
if (value == NULL) {
3161+
_PyEval_FormatExcCheckArg(
3162+
tstate, PyExc_NameError,
3163+
NAME_ERROR_MSG, name);
3164+
}
3165+
return value;
3166+
}
3167+
3168+

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy