| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 49cfcf9 commit 91ee09b
21 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -13,7 +13,6 @@ extern "C" { | |||
| 13 | 13 | ||
| 14 | 14 | #ifdef SLP_BUILD_CORE | |
| 15 | 15 | ||
| 16 | - #include "frameobject.h" | ||
| 17 | 16 | #if defined(MS_WIN32) && !defined(MS_WIN64) && defined(_M_IX86) | |
| 18 | 17 | #define SLP_SEH32 | |
| 19 | 18 | #endif | |
@@ -237,22 +236,39 @@ typedef struct _channel { | |||
| 237 | 236 | PyObject *chan_weakreflist; | |
| 238 | 237 | } PyChannelObject; | |
| 239 | 238 | ||
| 239 | + struct _cframe; | ||
| 240 | + typedef PyObject *(PyFrame_ExecFunc) (struct _cframe *, int, PyObject *); | ||
| 241 | + /* | ||
| 242 | + * How to write frame execution functions: | ||
| 243 | + * | ||
| 244 | + * Special rule for frame execution functions: the function owns a reference to retval! | ||
| 245 | + * | ||
| 246 | + * PyObject * example(PyCFrameObject *f, int exc, PyObject *retval) | ||
| 247 | + * { | ||
| 248 | + * PyThreadState *ts = _PyThreadState_GET(); | ||
| 249 | + * | ||
| 250 | + * do something .... | ||
| 251 | + * If you change retval, use Py_SETREF(retval, new_value) or Py_CLEAR(retval). | ||
| 252 | + * | ||
| 253 | + * SLP_STORE_NEXT_FRAME(ts, f->f_back); | ||
| 254 | + * return retval; | ||
| 255 | + * } | ||
| 256 | + * | ||
| 257 | + */ | ||
| 240 | 258 | ||
| 241 | 259 | /*** important stuctures: cframe ***/ | |
| 242 | 260 | ||
| 243 | 261 | typedef struct _cframe { | |
| 244 | 262 | PyObject_VAR_HEAD | |
| 245 | 263 | struct _frame *f_back; /* previous frame, or NULL */ | |
| 246 | - PyFrame_ExecFunc *f_execute; | ||
| 247 | 264 | ||
| 248 | 265 | /* | |
| 249 | - * the above part is compatible with frames. | ||
| 250 | - * Note that I have re-arranged some fields in the frames | ||
| 251 | - * to keep cframes as small as possible. | ||
| 266 | + * the above part is compatible with regular frames. | ||
| 252 | 267 | */ | |
| 253 | 268 | ||
| 254 | - /* these can be used as the CFrame likes to */ | ||
| 269 | + PyFrame_ExecFunc *f_execute; | ||
| 255 | 270 | ||
| 271 | + /* these can be used as the CFrame likes to */ | ||
| 256 | 272 | PyObject *ob1; | |
| 257 | 273 | PyObject *ob2; | |
| 258 | 274 | PyObject *ob3; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,28 +8,6 @@ | |||
| 8 | 8 | extern "C" { | |
| 9 | 9 | #endif | |
| 10 | 10 | ||
| 11 | - #ifdef STACKLESS | ||
| 12 | - typedef PyObject *(PyFrame_ExecFunc) (struct _frame *, int, PyObject *); | ||
| 13 | - /* | ||
| 14 | - * How to write frame execution functions: | ||
| 15 | - * | ||
| 16 | - * Special rule for frame execution functions: the function owns a reference to retval! | ||
| 17 | - * | ||
| 18 | - * PyObject * example(PyFrameObject *f, int exc, PyObject *retval) | ||
| 19 | - * { | ||
| 20 | - * PyThreadState *ts = _PyThreadState_GET(); | ||
| 21 | - * | ||
| 22 | - * do something .... | ||
| 23 | - * if you change retval, use Py_SETREF(retval, new_value) or | ||
| 24 | - * Py_CLEAR(retval) | ||
| 25 | - * | ||
| 26 | - * SLP_STORE_NEXT_FRAME(ts, f->f_back); | ||
| 27 | - * return retval; | ||
| 28 | - * } | ||
| 29 | - * | ||
| 30 | - */ | ||
| 31 | - #endif | ||
| 32 | - | ||
| 33 | 11 | typedef struct { | |
| 34 | 12 | int b_type; /* what kind of block this is */ | |
| 35 | 13 | int b_handler; /* where to jump to find handler */ | |
@@ -39,11 +17,7 @@ typedef struct { | |||
| 39 | 17 | typedef struct _frame { | |
| 40 | 18 | PyObject_VAR_HEAD | |
| 41 | 19 | struct _frame *f_back; /* previous frame, or NULL */ | |
| 42 | - #ifdef STACKLESS | ||
| 43 | - PyFrame_ExecFunc *f_execute;/* support for soft stackless */ | ||
| 44 | - #else | ||
| 45 | 20 | PyCodeObject *f_code; /* code segment */ | |
| 46 | - #endif | ||
| 47 | 21 | PyObject *f_builtins; /* builtin symbol table (PyDictObject) */ | |
| 48 | 22 | PyObject *f_globals; /* global symbol table (PyDictObject) */ | |
| 49 | 23 | PyObject *f_locals; /* local symbol table (any mapping) */ | |
@@ -69,9 +43,6 @@ typedef struct _frame { | |||
| 69 | 43 | int f_iblock; /* index in f_blockstack */ | |
| 70 | 44 | char f_executing; /* whether the frame is still executing */ | |
| 71 | 45 | PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */ | |
| 72 | - #ifdef STACKLESS | ||
| 73 | - PyCodeObject *f_code; /* code segment */ | ||
| 74 | - #endif | ||
| 75 | 46 | PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */ | |
| 76 | 47 | } PyFrameObject; | |
| 77 | 48 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,15 +19,15 @@ int slp_find_execfuncs(PyTypeObject *type, PyObject *exec_name, | |||
| 19 | 19 | PyFrame_ExecFunc **good, | |
| 20 | 20 | PyFrame_ExecFunc **bad); | |
| 21 | 21 | ||
| 22 | - PyObject * slp_find_execname(PyFrameObject *f, int *valid); | ||
| 22 | + PyObject * slp_find_execname(PyCFrameObject *f, int *valid); | ||
| 23 | 23 | ||
| 24 | - PyObject * slp_cannot_execute(PyFrameObject *f, const char *exec_name, PyObject *retval); | ||
| 24 | + PyObject * slp_cannot_execute(PyCFrameObject *f, const char *exec_name, PyObject *retval); | ||
| 25 | 25 | ||
| 26 | 26 | /* macros to define and use an invalid frame executor */ | |
| 27 | 27 | ||
| 28 | 28 | #define SLP_DEF_INVALID_EXEC(procname) \ | |
| 29 | 29 | static PyObject *\ | |
| 30 | - cannot_##procname(PyFrameObject *f, int exc, PyObject *retval) \ | ||
| 30 | + cannot_##procname(PyCFrameObject *f, int exc, PyObject *retval) \ | ||
| 31 | 31 | { \ | |
| 32 | 32 | return slp_cannot_execute(f, #procname, retval); \ | |
| 33 | 33 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,6 +17,7 @@ extern "C" { | |||
| 17 | 17 | ||
| 18 | 18 | #ifdef SLP_BUILD_CORE | |
| 19 | 19 | ||
| 20 | + #include "frameobject.h" | ||
| 20 | 21 | #ifdef Py_BUILD_CORE | |
| 21 | 22 | #include "pycore_pystate.h" /* for _PyRuntime */ | |
| 22 | 23 | #endif | |
@@ -39,7 +40,7 @@ extern "C" { | |||
| 39 | 40 | * were created with an older Cython compiled with regular C-Python. | |
| 40 | 41 | * See Stackless issue #168 | |
| 41 | 42 | */ | |
| 42 | - #define SLP_END_OF_OLD_CYTHON_HACK_VERSION (0x030800b1) | ||
| 43 | + #define SLP_END_OF_OLD_CYTHON_HACK_VERSION (0x030800a1) | ||
| 43 | 44 | #endif | |
| 44 | 45 | ||
| 45 | 46 | /* | |
@@ -325,8 +326,9 @@ PyObject * slp_wrap_call_frame(PyFrameObject *frame, int exc, PyObject *retval); | |||
| 325 | 326 | } while (0) | |
| 326 | 327 | ||
| 327 | 328 | #define CALL_FRAME_FUNCTION(frame_, exc, retval) \ | |
| 328 | - (assert((frame_) && (frame_)->f_execute), \ | ||
| 329 | - ((frame_)->f_execute((frame_), (exc), (retval)))) | ||
| 329 | + (assert((frame_) && (!PyCFrame_Check(frame_) || ((PyCFrameObject *)(frame_))->f_execute)), \ | ||
| 330 | + (PyCFrame_Check(frame_) ? (((PyCFrameObject *)(frame_))->f_execute(((PyCFrameObject *)(frame_)), (exc), (retval))) : \ | ||
| 331 | + PyEval_EvalFrameEx_slp((frame_), (exc), (retval)))) | ||
| 330 | 332 | ||
| 331 | 333 | #endif | |
| 332 | 334 | ||
@@ -378,18 +380,10 @@ PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx_slp(struct _frame *, int, PyObject *); | |||
| 378 | 380 | /* eval_frame with stack overflow, triggered there with a macro */ | |
| 379 | 381 | PyObject * slp_eval_frame_newstack(struct _frame *f, int throwflag, PyObject *retval); | |
| 380 | 382 | ||
| 381 | - /* the new eval_frame loop with or without value or resuming an iterator | ||
| 382 | - or setting up or cleaning up a with block */ | ||
| 383 | - PyObject * slp_eval_frame_value(struct _frame *f, int throwflag, PyObject *retval); | ||
| 384 | - PyObject * slp_eval_frame_noval(struct _frame *f, int throwflag, PyObject *retval); | ||
| 385 | - PyObject * slp_eval_frame_iter(struct _frame *f, int throwflag, PyObject *retval); | ||
| 386 | - PyObject * slp_eval_frame_setup_with(struct _frame *f, int throwflag, PyObject *retval); | ||
| 387 | - PyObject * slp_eval_frame_with_cleanup(struct _frame *f, int throwflag, PyObject *retval); | ||
| 388 | - PyObject * slp_eval_frame_yield_from(struct _frame *f, int throwflag, PyObject *retval); | ||
| 389 | 383 | /* other eval_frame functions from module/scheduling.c */ | |
| 390 | - PyObject * slp_restore_tracing(PyFrameObject *f, int exc, PyObject *retval); | ||
| 384 | + PyObject * slp_restore_tracing(PyCFrameObject *cf, int exc, PyObject *retval); | ||
| 391 | 385 | /* other eval_frame functions from Objects/typeobject.c */ | |
| 392 | - PyObject * slp_tp_init_callback(PyFrameObject *f, int exc, PyObject *retval); | ||
| 386 | + PyObject * slp_tp_init_callback(PyCFrameObject *cf, int exc, PyObject *retval); | ||
| 393 | 387 | /* functions related to pickling */ | |
| 394 | 388 | PyObject * slp_reduce_frame(PyFrameObject * frame); | |
| 395 | 389 | ||
@@ -765,13 +759,13 @@ PyTaskletTStateStruc * slp_get_saved_tstate(PyTaskletObject *task); | |||
| 765 | 759 | /* | |
| 766 | 760 | * Channel related prototypes | |
| 767 | 761 | */ | |
| 768 | - PyObject * slp_channel_seq_callback(struct _frame *f, int throwflag, PyObject *retval); | ||
| 762 | + PyObject * slp_channel_seq_callback(PyCFrameObject *f, int throwflag, PyObject *retval); | ||
| 769 | 763 | PyObject * slp_get_channel_callback(void); | |
| 770 | 764 | ||
| 771 | 765 | /* | |
| 772 | 766 | * contextvars related prototypes | |
| 773 | 767 | */ | |
| 774 | - PyObject* slp_context_run_callback(PyFrameObject *f, int exc, PyObject *result); | ||
| 768 | + PyObject* slp_context_run_callback(PyCFrameObject *f, int exc, PyObject *result); | ||
| 775 | 769 | ||
| 776 | 770 | /* macro for use when interrupting tasklets from watchdog */ | |
| 777 | 771 | #define TASKLET_NESTING_OK(task) \ | |
@@ -788,6 +782,48 @@ void slp_head_unlock(void); | |||
| 788 | 782 | ||
| 789 | 783 | long slp_parse_thread_id(PyObject *thread_id, unsigned long *id); | |
| 790 | 784 | ||
| 785 | + /* | ||
| 786 | + * Symbolic names for values stored in PyFrameObject.f_executing | ||
| 787 | + * | ||
| 788 | + * Regular C-Python only uses two values | ||
| 789 | + * 0: the frame is not executing | ||
| 790 | + * 1: the frame is executing | ||
| 791 | + * | ||
| 792 | + * Stackless Python extends the range of values to indicate, what to do | ||
| 793 | + * upon the next invocation of PyEval_EvalFrameEx_slp. | ||
| 794 | + */ | ||
| 795 | + | ||
| 796 | + /* Frame is invalid and PyEval_EvalFrameEx_slp must raise an exception. | ||
| 797 | + * Only set, if the frame was unpickled and had C-state on the stack. | ||
| 798 | + */ | ||
| 799 | + #define SLP_FRAME_EXECUTING_INVALID (-1) | ||
| 800 | + | ||
| 801 | + /* Frame is new or completely executed. */ | ||
| 802 | + #define SLP_FRAME_EXECUTING_NO 0 | ||
| 803 | + | ||
| 804 | + /* Frame is executing, value in retval is valid and must be pushed onto the stack. */ | ||
| 805 | + #define SLP_FRAME_EXECUTING_VALUE 1 | ||
| 806 | + | ||
| 807 | + /* Frame is executing, ignore value in retval. | ||
| 808 | + * This is used at the start of a frame or after an interrupt. */ | ||
| 809 | + #define SLP_FRAME_EXECUTING_NOVAL 2 | ||
| 810 | + | ||
| 811 | + /* Frame is executing, continue opcode ITER */ | ||
| 812 | + #define SLP_FRAME_EXECUTING_ITER 3 | ||
| 813 | + | ||
| 814 | + /* Frame is executing, continue opcode SETUP_WITH */ | ||
| 815 | + #define SLP_FRAME_EXECUTING_SETUP_WITH 4 | ||
| 816 | + | ||
| 817 | + /* Frame is executing, continue opcode WITH_CLEANUP */ | ||
| 818 | + #define SLP_FRAME_EXECUTING_WITH_CLEANUP 5 | ||
| 819 | + | ||
| 820 | + /* Frame is executing, continue opcode YIELD_FROM */ | ||
| 821 | + #define SLP_FRAME_EXECUTING_YIELD_FROM 6 | ||
| 822 | + | ||
| 823 | + /* Test, if the frame is executing */ | ||
| 824 | + #define SLP_FRAME_IS_EXECUTING(frame_) \ | ||
| 825 | + ((frame_)->f_executing >= SLP_FRAME_EXECUTING_VALUE && \ | ||
| 826 | + (frame_)->f_executing <= SLP_FRAME_EXECUTING_YIELD_FROM) | ||
| 791 | 827 | ||
| 792 | 828 | ||
| 793 | 829 | #endif /* #ifdef SLP_BUILD_CORE */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -354,7 +354,6 @@ function_code_fastcall(PyCodeObject *co, PyObject *const *args, Py_ssize_t nargs | |||
| 354 | 354 | } | |
| 355 | 355 | ||
| 356 | 356 | #ifdef STACKLESS | |
| 357 | - f->f_execute = PyEval_EvalFrameEx_slp; | ||
| 358 | 357 | if (stackless) { | |
| 359 | 358 | Py_INCREF(Py_None); | |
| 360 | 359 | result = Py_None; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -751,9 +751,6 @@ _PyFrame_New_NoTrack(PyThreadState *tstate, PyCodeObject *code, | |||
| 751 | 751 | f->f_trace_opcodes = 0; | |
| 752 | 752 | f->f_trace_lines = 1; | |
| 753 | 753 | ||
| 754 | - #ifdef STACKLESS | ||
| 755 | - f->f_execute = NULL; | ||
| 756 | - #endif | ||
| 757 | 754 | return f; | |
| 758 | 755 | } | |
| 759 | 756 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -166,7 +166,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, int exc, int closing, PyObject* ob | |||
| 166 | 166 | ||
| 167 | 167 | /* callback for (async) generators and coroutines. */ | |
| 168 | 168 | static PyObject * | |
| 169 | - gen_iternext_callback(PyFrameObject *f, int exc, PyObject *result); | ||
| 169 | + gen_iternext_callback(PyCFrameObject *f, int exc, PyObject *result); | ||
| 170 | 170 | ||
| 171 | 171 | /* Additional callback-code for async generators. */ | |
| 172 | 172 | static PyObject * | |
@@ -310,8 +310,6 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, int exc, int closing, PyObject * o | |||
| 310 | 310 | gen->gi_exc_state.previous_item = tstate->exc_info; | |
| 311 | 311 | tstate->exc_info = &gen->gi_exc_state; | |
| 312 | 312 | ||
| 313 | - f->f_execute = PyEval_EvalFrameEx_slp; | ||
| 314 | - | ||
| 315 | 313 | Py_INCREF(gen); | |
| 316 | 314 | Py_XINCREF(arg); | |
| 317 | 315 | Py_XINCREF(ob3); | |
@@ -341,10 +339,10 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, int exc, int closing, PyObject * o | |||
| 341 | 339 | } | |
| 342 | 340 | ||
| 343 | 341 | static PyObject* | |
| 344 | - gen_iternext_callback(PyFrameObject *f, int exc, PyObject *result) | ||
| 342 | + gen_iternext_callback(PyCFrameObject *cf, int exc, PyObject *result) | ||
| 345 | 343 | { | |
| 346 | 344 | PyThreadState *ts = _PyThreadState_GET(); | |
| 347 | - PyCFrameObject *cf = (PyCFrameObject *) f; | ||
| 345 | + PyFrameObject *f = (PyFrameObject *) cf; | ||
| 348 | 346 | PyGenObject *gen = (PyGenObject *) cf->ob1; | |
| 349 | 347 | PyObject *arg = cf->ob2; | |
| 350 | 348 | PyObject *ob3 = cf->ob3; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6781,10 +6781,10 @@ slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value) | |||
| 6781 | 6781 | ||
| 6782 | 6782 | #ifdef STACKLESS | |
| 6783 | 6783 | PyObject * | |
| 6784 | - slp_tp_init_callback(PyFrameObject *f, int exc, PyObject *retval) | ||
| 6784 | + slp_tp_init_callback(PyCFrameObject *cf, int exc, PyObject *retval) | ||
| 6785 | 6785 | { | |
| 6786 | 6786 | PyThreadState *ts = _PyThreadState_GET(); | |
| 6787 | - PyCFrameObject *cf = (PyCFrameObject *) f; | ||
| 6787 | + PyFrameObject *f = (PyFrameObject *) cf; | ||
| 6788 | 6788 | ||
| 6789 | 6789 | f = cf->f_back; | |
| 6790 | 6790 | if (retval != NULL) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments