Skip to content

Commit 8d1a6e3

Browse files
committed
Rewrite "escape-y" uses of PyObject_Vectorcall and PyMapping_GetOptionalItem
1 parent ae1ec5c commit 8d1a6e3

4 files changed

Lines changed: 158 additions & 111 deletions

File tree

Python/bytecodes.c

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,10 +1390,11 @@ dummy_func(
13901390
}
13911391

13921392
inst(LOAD_BUILD_CLASS, ( -- bc)) {
1393-
PyObject *bc_o;
1394-
int err = PyMapping_GetOptionalItem(BUILTINS(), &_Py_ID(__build_class__), &bc_o);
1395-
ERROR_IF(err < 0, error);
1393+
PyObject *bc_o = PyObject_GetItem(BUILTINS(), &_Py_ID(__build_class__));
13961394
if (bc_o == NULL) {
1395+
assert(_PyErr_Occurred(tstate));
1396+
ERROR_IF(!_PyErr_ExceptionMatches(tstate, PyExc_KeyError), error);
1397+
_PyErr_Clear(tstate);
13971398
_PyErr_SetString(tstate, PyExc_NameError,
13981399
"__build_class__ not found");
13991400
ERROR_IF(true, error);
@@ -1585,11 +1586,12 @@ dummy_func(
15851586

15861587
inst(LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) {
15871588
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
1588-
PyObject *v_o;
1589-
int err = PyMapping_GetOptionalItem(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name, &v_o);
1589+
PyObject *v_o = PyObject_GetItem(PyStackRef_AsPyObjectBorrow(mod_or_class_dict), name);
15901590
PyStackRef_CLOSE(mod_or_class_dict);
1591-
ERROR_IF(err < 0, error);
15921591
if (v_o == NULL) {
1592+
assert(_PyErr_Occurred(tstate));
1593+
ERROR_IF(!_PyErr_ExceptionMatches(tstate, PyExc_KeyError), error);
1594+
_PyErr_Clear(tstate);
15931595
if (PyDict_CheckExact(GLOBALS())
15941596
&& PyDict_CheckExact(BUILTINS()))
15951597
{
@@ -1609,13 +1611,17 @@ dummy_func(
16091611
else {
16101612
/* Slow-path if globals or builtins is not a dict */
16111613
/* namespace 1: globals */
1612-
int err = PyMapping_GetOptionalItem(GLOBALS(), name, &v_o);
1613-
ERROR_IF(err < 0, error);
1614+
v_o = PyObject_GetItem(GLOBALS(), name);
16141615
if (v_o == NULL) {
1616+
assert(_PyErr_Occurred(tstate));
1617+
ERROR_IF(!_PyErr_ExceptionMatches(tstate, PyExc_KeyError), error);
1618+
_PyErr_Clear(tstate);
16151619
/* namespace 2: builtins */
1616-
int err = PyMapping_GetOptionalItem(BUILTINS(), name, &v_o);
1617-
ERROR_IF(err < 0, error);
1620+
v_o = PyObject_GetItem(BUILTINS(), name);
16181621
if (v_o == NULL) {
1622+
assert(_PyErr_Occurred(tstate));
1623+
ERROR_IF(!_PyErr_ExceptionMatches(tstate, PyExc_KeyError), error);
1624+
_PyErr_Clear(tstate);
16191625
_PyEval_FormatExcCheckArg(
16201626
tstate, PyExc_NameError,
16211627
NAME_ERROR_MSG, name);
@@ -1785,18 +1791,19 @@ dummy_func(
17851791
}
17861792

17871793
inst(LOAD_FROM_DICT_OR_DEREF, (class_dict_st -- value)) {
1788-
PyObject *value_o;
17891794
PyObject *name;
17901795
PyObject *class_dict = PyStackRef_AsPyObjectBorrow(class_dict_st);
17911796

17921797
assert(class_dict);
17931798
assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus);
17941799
name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg);
1795-
int err = PyMapping_GetOptionalItem(class_dict, name, &value_o);
1796-
if (err < 0) {
1797-
ERROR_NO_POP();
1798-
}
1799-
if (!value_o) {
1800+
PyObject *value_o = PyObject_GetItem(class_dict, name);
1801+
if (value_o == NULL) {
1802+
assert(_PyErr_Occurred(tstate));
1803+
if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
1804+
ERROR_NO_POP();
1805+
}
1806+
_PyErr_Clear(tstate);
18001807
PyCellObject *cell = (PyCellObject *)PyStackRef_AsPyObjectBorrow(GETLOCAL(oparg));
18011808
value_o = PyCell_GetRef(cell);
18021809
if (value_o == NULL) {
@@ -1934,19 +1941,20 @@ dummy_func(
19341941
}
19351942

19361943
inst(SETUP_ANNOTATIONS, (--)) {
1937-
PyObject *ann_dict;
19381944
if (LOCALS() == NULL) {
19391945
_PyErr_Format(tstate, PyExc_SystemError,
19401946
"no locals found when setting up annotations");
19411947
ERROR_IF(true, error);
19421948
}
19431949
/* check if __annotations__ in locals()... */
1944-
int err = PyMapping_GetOptionalItem(LOCALS(), &_Py_ID(__annotations__), &ann_dict);
1945-
ERROR_IF(err < 0, error);
1950+
PyObject *ann_dict = PyObject_GetItem(LOCALS(), &_Py_ID(__annotations__));
19461951
if (ann_dict == NULL) {
1952+
assert(_PyErr_Occurred(tstate));
1953+
ERROR_IF(!_PyErr_ExceptionMatches(tstate, PyExc_KeyError), error);
1954+
_PyErr_Clear(tstate);
19471955
ann_dict = PyDict_New();
19481956
ERROR_IF(ann_dict == NULL, error);
1949-
err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__),
1957+
int err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__),
19501958
ann_dict);
19511959
Py_DECREF(ann_dict);
19521960
ERROR_IF(err, error);
@@ -2041,8 +2049,13 @@ dummy_func(
20412049
}
20422050
// we make no attempt to optimize here; specializations should
20432051
// handle any case whose performance we care about
2044-
PyObject *stack[] = {class, self};
2045-
PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
2052+
PyObject *super;
2053+
if (oparg & 2) {
2054+
super = PyObject_CallFunctionObjArgs(global_super, class, self);
2055+
}
2056+
else {
2057+
super = PyObject_CallNoArgs(global_super);
2058+
}
20462059
if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
20472060
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
20482061
if (super == NULL) {
@@ -3306,10 +3319,14 @@ dummy_func(
33063319
}
33073320
assert(PyStackRef_LongCheck(lasti));
33083321
(void)lasti; // Shut up compiler warning if asserts are off
3309-
PyObject *stack[5] = {NULL, PyStackRef_AsPyObjectBorrow(exit_self), exc, val_o, tb};
3310-
int has_self = !PyStackRef_IsNull(exit_self);
3311-
PyObject *res_o = PyObject_Vectorcall(exit_func_o, stack + 2 - has_self,
3312-
(3 + has_self) | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
3322+
PyObject *res_o;
3323+
if (PyStackRef_IsNull(exit_self)) {
3324+
res_o = PyObject_CallFunctionObjArgs(exit_func_o, exc, val_o, tb);
3325+
}
3326+
else {
3327+
PyObject *exit_self_o = PyStackRef_AsPyObjectBorrow(exit_self);
3328+
res_o = PyObject_CallFunctionObjArgs(exit_func_o, exit_self_o, exc, val_o, tb);
3329+
}
33133330
ERROR_IF(res_o == NULL, error);
33143331
res = PyStackRef_FromPyObjectSteal(res_o);
33153332
}

Python/executor_cases.c.h

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

0 commit comments

Comments
 (0)