Skip to content

Commit a75042a

Browse files
committed
Alternative to restrict and conditional Py_NO_INLINE for PyMapping_GetOptionalItem
1 parent 7e5555a commit a75042a

File tree

5 files changed

+37
-33
lines changed

5 files changed

+37
-33
lines changed

Include/abstract.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,7 @@ PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o,
887887
*/
888888
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000
889889
PyAPI_FUNC(int) PyMapping_GetOptionalItem(PyObject *, PyObject *, PyObject **);
890+
PyAPI_FUNC(PyObject*) PyMapping_GetOptionalItem2(PyObject *, PyObject *, int *);
890891
PyAPI_FUNC(int) PyMapping_GetOptionalItemString(PyObject *, const char *, PyObject **);
891892
#endif
892893

Objects/abstract.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,8 @@ PyObject_GetItem(PyObject *o, PyObject *key)
205205
return type_error("'%.200s' object is not subscriptable", o);
206206
}
207207

208-
// MSVC fails during a tail call release build with loads of
209-
// error C4737: Unable to perform required tail call.
210-
// without using Py_NO_INLINE here, but PGO works fine.
211-
#if defined(_MSC_VER) && !defined(__clang__) && _Py_TAIL_CALL_INTERP && !defined(_Py_USING_PGO)
212-
Py_NO_INLINE
213-
#endif
214208
int
215-
PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **restrict result)
209+
PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **result)
216210
{
217211
if (PyDict_CheckExact(obj)) {
218212
return PyDict_GetItemRef(obj, key, result);
@@ -230,6 +224,14 @@ PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **restrict resu
230224
return 0;
231225
}
232226

227+
PyObject*
228+
PyMapping_GetOptionalItem2(PyObject *obj, PyObject *key, int *err)
229+
{
230+
PyObject* result;
231+
*err = PyMapping_GetOptionalItem(obj, key, &result);
232+
return result;
233+
}
234+
233235
int
234236
PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value)
235237
{

Python/bytecodes.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,8 +1507,8 @@ dummy_func(
15071507
}
15081508

15091509
inst(LOAD_BUILD_CLASS, ( -- bc)) {
1510-
PyObject *bc_o;
1511-
int err = PyMapping_GetOptionalItem(BUILTINS(), &_Py_ID(__build_class__), &bc_o);
1510+
int err;
1511+
PyObject *bc_o = PyMapping_GetOptionalItem2(BUILTINS(), &_Py_ID(__build_class__), &err);
15121512
ERROR_IF(err < 0);
15131513
if (bc_o == NULL) {
15141514
_PyErr_SetString(tstate, PyExc_NameError,
@@ -1711,8 +1711,9 @@ dummy_func(
17111711

17121712
inst(LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) {
17131713
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
1714-
PyObject *v_o;
1715-
int err = PyMapping_GetOptionalItem(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &v_o);
1714+
int err;
1715+
PyObject *v_o = PyMapping_GetOptionalItem2(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &err);
1716+
17161717
PyStackRef_CLOSE(mod_or_class_dict);
17171718
ERROR_IF(err < 0);
17181719
if (v_o == NULL) {
@@ -1735,11 +1736,11 @@ dummy_func(
17351736
else {
17361737
/* Slow-path if globals or builtins is not a dict */
17371738
/* namespace 1: globals */
1738-
int err = PyMapping_GetOptionalItem(GLOBALS(), name, &v_o);
1739+
v_o = PyMapping_GetOptionalItem2(GLOBALS(), name, &err);
17391740
ERROR_IF(err < 0);
17401741
if (v_o == NULL) {
17411742
/* namespace 2: builtins */
1742-
int err = PyMapping_GetOptionalItem(BUILTINS(), name, &v_o);
1743+
v_o = PyMapping_GetOptionalItem2(BUILTINS(), name, &err);
17431744
ERROR_IF(err < 0);
17441745
if (v_o == NULL) {
17451746
_PyEval_FormatExcCheckArg(
@@ -1898,14 +1899,14 @@ dummy_func(
18981899
}
18991900

19001901
inst(LOAD_FROM_DICT_OR_DEREF, (class_dict_st -- value)) {
1901-
PyObject *value_o;
19021902
PyObject *name;
19031903
PyObject *class_dict = PyStackRef_AsPyObjectBorrow(class_dict_st);
19041904

19051905
assert(class_dict);
19061906
assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus);
19071907
name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg);
1908-
int err = PyMapping_GetOptionalItem(class_dict, name, &value_o);
1908+
int err;
1909+
PyObject* value_o = PyMapping_GetOptionalItem2(class_dict, name, &err);
19091910
if (err < 0) {
19101911
ERROR_NO_POP();
19111912
}
@@ -2074,14 +2075,14 @@ dummy_func(
20742075
}
20752076

20762077
inst(SETUP_ANNOTATIONS, (--)) {
2077-
PyObject *ann_dict;
20782078
if (LOCALS() == NULL) {
20792079
_PyErr_Format(tstate, PyExc_SystemError,
20802080
"no locals found when setting up annotations");
20812081
ERROR_IF(true);
20822082
}
20832083
/* check if __annotations__ in locals()... */
2084-
int err = PyMapping_GetOptionalItem(LOCALS(), &_Py_ID(__annotations__), &ann_dict);
2084+
int err;
2085+
PyObject* ann_dict = PyMapping_GetOptionalItem2(LOCALS(), &_Py_ID(__annotations__), &err);
20852086
ERROR_IF(err < 0);
20862087
if (ann_dict == NULL) {
20872088
ann_dict = PyDict_New();

Python/executor_cases.c.h

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)