Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit bf0c174

Browse files
authored
Stackless issue #272: convert macro HANDLE_UNWINDING to a function
Convert most of the macro HANDLE_UNWINDING in ceval.c to a static inline function handle_inline(). This improves maintainability.
1 parent bb7b88b commit bf0c174

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

Python/ceval.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,18 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
596596
#define LLTRACE_HANDLE_UNWINDING(obj__, msg__) (void)1
597597
#endif
598598

599+
#if 1
600+
static inline int
601+
handle_unwinding(int lineno, PyFrameObject *f,
602+
PyObject **stack_pointer, int oparg, PyThreadState *tstate,
603+
const _Py_CODEUNIT *first_instr, const _Py_CODEUNIT *next_instr,
604+
char frame_func, int has_opcode, PyObject **pretval);
605+
#define HANDLE_UNWINDING(frame_func, has_opcode, retval__) \
606+
if (handle_unwinding(__LINE__, f, stack_pointer, oparg, tstate, \
607+
first_instr, next_instr, (frame_func), (has_opcode), &(retval__)))\
608+
return (retval__)
609+
#else
610+
/* keep the old macro in case of performance problems */
599611
#define HANDLE_UNWINDING(frame_func, has_opcode, retval__) \
600612
do { \
601613
if (has_opcode) \
@@ -642,6 +654,7 @@ do { \
642654
next_instr += 1 + EXTENDED_ARG_OFFSET(oparg); \
643655
LLTRACE_HANDLE_UNWINDING((retval__), "handle_unwinding end:");\
644656
} while(0)
657+
#endif
645658

646659
/* To be called in the slp_continue_<xxxx> block, if
647660
* HANDLE_UNWINDING is used with has_opcode==1
@@ -3824,6 +3837,56 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
38243837

38253838

38263839
#ifdef STACKLESS
3840+
static inline int
3841+
handle_unwinding(int lineno, PyFrameObject *f,
3842+
PyObject **stack_pointer, int oparg, PyThreadState *tstate,
3843+
const _Py_CODEUNIT *first_instr, const _Py_CODEUNIT *next_instr,
3844+
char frame_func, int has_opcode, PyObject **pretval)
3845+
{
3846+
assert(*pretval); /* check argument */
3847+
if (has_opcode)
3848+
next_instr -= 1 + EXTENDED_ARG_OFFSET(oparg);
3849+
assert(SLP_FRAME_EXECUTING_VALUE == f->f_executing);
3850+
if (frame_func != SLP_FRAME_EXECUTING_VALUE) {
3851+
f->f_executing = frame_func;
3852+
/* check argument: must be an executing frame with retval */
3853+
assert(frame_func != SLP_FRAME_EXECUTING_NOVAL);
3854+
assert(SLP_FRAME_IS_EXECUTING(f));
3855+
}
3856+
/* keep the reference to the frame to be called. */
3857+
f->f_stacktop = stack_pointer;
3858+
/* Set f->f_lasti to the instruction before the current one or to the */
3859+
/* first instruction (-1). See "f->f_lasti refers to ..." above. */
3860+
f->f_lasti = INSTR_OFFSET() != 0 ?
3861+
assert(INSTR_OFFSET() >= sizeof(_Py_CODEUNIT)),
3862+
(int)(INSTR_OFFSET() - sizeof(_Py_CODEUNIT)) : -1;
3863+
if (SLP_PEEK_NEXT_FRAME(tstate)->f_back != f) {
3864+
LLTRACE_HANDLE_UNWINDING(STACKLESS_RETVAL(tstate, *pretval), "handle_unwinding return:");
3865+
return 1;
3866+
}
3867+
STACKLESS_UNPACK(tstate, *pretval);
3868+
{
3869+
LLTRACE_HANDLE_UNWINDING(*pretval, "handle_unwinding call next frame:");
3870+
PyFrameObject *f2 = SLP_CLAIM_NEXT_FRAME(tstate);
3871+
*pretval = CALL_FRAME_FUNCTION(f2, 0, *pretval);
3872+
Py_DECREF(f2);
3873+
if (SLP_PEEK_NEXT_FRAME(tstate) != f) {
3874+
assert(f->f_executing == (frame_func));
3875+
LLTRACE_HANDLE_UNWINDING(STACKLESS_RETVAL(tstate, *pretval), "handle_unwinding return from next frame:");
3876+
return 1;
3877+
}
3878+
f2 = SLP_CLAIM_NEXT_FRAME(tstate);
3879+
assert(f == f2);
3880+
Py_DECREF(f2);
3881+
}
3882+
if (STACKLESS_UNWINDING(*pretval))
3883+
STACKLESS_UNPACK(tstate, *pretval);
3884+
f->f_stacktop = NULL;
3885+
assert(f->f_executing == frame_func);
3886+
f->f_executing = SLP_FRAME_EXECUTING_VALUE;
3887+
LLTRACE_HANDLE_UNWINDING(*pretval, "handle_unwinding end:");
3888+
return 0;
3889+
}
38273890

38283891
static PyObject *
38293892
run_frame_dispatch(PyCFrameObject *cf, int exc, PyObject *retval)

0 commit comments

Comments
 (0)