File tree Expand file tree Collapse file tree 2 files changed +44
-0
lines changed
Expand file tree Collapse file tree 2 files changed +44
-0
lines changed Original file line number Diff line number Diff line change @@ -561,6 +561,10 @@ extern void _Py_ClearTLBCIndex(_PyThreadStateImpl *tstate);
561561extern int _Py_ClearUnusedTLBC (PyInterpreterState * interp );
562562#endif
563563
564+
565+ PyAPI_FUNC (int ) _PyCode_Returns (PyCodeObject * );
566+
567+
564568#ifdef __cplusplus
565569}
566570#endif
Original file line number Diff line number Diff line change @@ -1689,6 +1689,46 @@ PyCode_GetFreevars(PyCodeObject *code)
16891689 return _PyCode_GetFreevars (code );
16901690}
16911691
1692+
1693+ int
1694+ _PyCode_Returns (PyCodeObject * co )
1695+ {
1696+ // Look up None in co_consts.
1697+ Py_ssize_t nconsts = PyTuple_Size (co -> co_consts );
1698+ int none_index = 0 ;
1699+ for (; none_index < nconsts ; none_index ++ ) {
1700+ if (PyTuple_GET_ITEM (co -> co_consts , none_index ) == Py_None ) {
1701+ break ;
1702+ }
1703+ }
1704+ if (none_index == nconsts ) {
1705+ // None wasn't there, which means there was no implicit return,
1706+ // "return", or "return None". That means there must be
1707+ // an explicit return (non-None).
1708+ return 1 ;
1709+ }
1710+
1711+ // Walk the bytecode, looking for RETURN_VALUE.
1712+ Py_ssize_t len = Py_SIZE (co );
1713+ for (int i = 0 ; i < len ; i ++ ) {
1714+ _Py_CODEUNIT inst = _Py_GetBaseCodeUnit (co , i );
1715+ if (inst .op .code == RETURN_VALUE ) {
1716+ assert (i != 0 );
1717+ // Ignore it if it returns None.
1718+ _Py_CODEUNIT prev = _Py_GetBaseCodeUnit (co , i - 1 );
1719+ if (prev .op .code == LOAD_CONST ) {
1720+ // We don't worry about EXTENDED_ARG for now.
1721+ if (prev .op .arg == none_index ) {
1722+ continue ;
1723+ }
1724+ }
1725+ return 1 ;
1726+ }
1727+ }
1728+ return 0 ;
1729+ }
1730+
1731+
16921732#ifdef _Py_TIER2
16931733
16941734static void
You can’t perform that action at this time.
0 commit comments