@@ -671,10 +671,11 @@ do { \
671
671
672
672
#endif
673
673
674
- PyObject * _Py_HOT_FUNCTION
675
674
#ifdef STACKLESS
676
- slp_eval_frame_value (PyFrameObject * f , int throwflag , PyObject * retval )
675
+ static PyObject * _Py_HOT_FUNCTION
676
+ slp_eval_frame_value (PyFrameObject * f , int throwflag , PyObject * retval_arg )
677
677
#else
678
+ PyObject * _Py_HOT_FUNCTION
678
679
_PyEval_EvalFrameDefault (PyFrameObject * f , int throwflag )
679
680
#endif
680
681
{
@@ -686,9 +687,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
686
687
int opcode ; /* Current opcode */
687
688
int oparg ; /* Current opcode argument, if any */
688
689
PyObject * * fastlocals , * * freevars ;
689
- #ifndef STACKLESS
690
690
PyObject * retval = NULL ; /* Return value */
691
- #endif
692
691
PyThreadState * tstate = _PyThreadState_GET ();
693
692
PyCodeObject * co ;
694
693
@@ -968,10 +967,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
968
967
Py_XDECREF(traceback); \
969
968
} while(0)
970
969
971
- /* Stackless specific defines start here. . */
970
+ /* Stackless specific macros and code start here. */
972
971
#ifdef STACKLESS
973
- int executing = f -> f_executing ;
974
-
975
972
#define SLP_CHECK_INTERRUPT () \
976
973
if (tstate->st.interrupt && !tstate->curexc_type) { \
977
974
if (tstate->st.tick_counter > tstate->st.tick_watermark) { \
@@ -989,6 +986,19 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
989
986
} \
990
987
tstate -> st .tick_counter ++ ;
991
988
989
+ int executing = f -> f_executing ;
990
+ assert (executing != SLP_FRAME_EXECUTING_INVALID );
991
+ if (executing != SLP_FRAME_EXECUTING_NO ) {
992
+ goto slp_setup_completed ;
993
+ }
994
+
995
+ /* push frame */
996
+ if (Py_EnterRecursiveCall ("" )) {
997
+ Py_XDECREF (retval_arg );
998
+ SLP_STORE_NEXT_FRAME (tstate , f -> f_back );
999
+ return NULL ;
1000
+ }
1001
+
992
1002
#else
993
1003
#define SLP_CHECK_INTERRUPT () ;
994
1004
@@ -997,11 +1007,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
997
1007
/* push frame */
998
1008
if (Py_EnterRecursiveCall ("" ))
999
1009
return NULL ;
1010
+ #endif
1000
1011
1001
- /* STACKLESS:
1002
- * the code starting from here on until the end-marker
1003
- * is duplicated below. Keep the two copies in sync!
1004
- */
1005
1012
tstate -> frame = f ;
1006
1013
1007
1014
if (tstate -> use_tracing ) {
@@ -1037,10 +1044,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
1037
1044
}
1038
1045
}
1039
1046
}
1040
- /* STACKLESS: end of duplicated code
1041
- */
1042
-
1043
- #endif /* #ifdef STACKLESS */
1047
+ #ifdef STACKLESS
1048
+ executing = SLP_FRAME_EXECUTING_NOVAL ;
1049
+ slp_setup_completed :
1050
+ #endif
1044
1051
1045
1052
if (PyDTrace_FUNCTION_ENTRY_ENABLED ())
1046
1053
dtrace_function_entry (f );
@@ -1086,14 +1093,14 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
1086
1093
lltrace = _PyDict_GetItemId (f -> f_globals , & PyId___ltrace__ ) != NULL ;
1087
1094
#endif
1088
1095
1089
- if (throwflag ) { /* support for generator.throw() */
1090
- assert (retval == NULL ); /* to prevent reference leaks */
1096
+ if (throwflag ) /* support for generator.throw() */
1091
1097
goto error ;
1092
- }
1093
-
1094
1098
1095
1099
#ifdef STACKLESS
1096
1100
assert (f -> f_executing == SLP_FRAME_EXECUTING_VALUE );
1101
+ assert (retval == NULL );
1102
+ retval = retval_arg ;
1103
+ retval_arg = NULL ;
1097
1104
switch (executing ){
1098
1105
case SLP_FRAME_EXECUTING_NOVAL :
1099
1106
/* don't push it, frame ignores value */
@@ -2026,12 +2033,14 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
2026
2033
STACKLESS_ASSERT ();
2027
2034
} else {
2028
2035
_Py_IDENTIFIER (send );
2029
- if (v == Py_None ) {
2036
+ if (v == Py_None )
2037
+ {
2030
2038
STACKLESS_PROPOSE_METHOD (tstate , receiver , tp_iternext );
2031
2039
retval = Py_TYPE (receiver )-> tp_iternext (receiver );
2032
2040
STACKLESS_ASSERT ();
2033
2041
}
2034
- else {
2042
+ else
2043
+ {
2035
2044
STACKLESS_PROPOSE_ALL (tstate );
2036
2045
retval = _PyObject_CallMethodIdObjArgs (receiver , & PyId_send , v , NULL );
2037
2046
STACKLESS_ASSERT ();
@@ -2043,7 +2052,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
2043
2052
HANDLE_UNWINDING (SLP_FRAME_EXECUTING_YIELD_FROM , 0 , retval );
2044
2053
}
2045
2054
if (0 ) {
2046
- slp_continue_slp_eval_frame_yield_from :
2055
+ slp_continue_slp_eval_frame_yield_from :
2047
2056
/* Initialize variables */
2048
2057
receiver = TOP ();
2049
2058
}
@@ -3132,7 +3141,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3132
3141
HANDLE_UNWINDING (SLP_FRAME_EXECUTING_ITER , 1 , next );
3133
3142
}
3134
3143
if (0 ) {
3135
- slp_continue_slp_eval_frame_iter :
3144
+ slp_continue_slp_eval_frame_iter :
3136
3145
SLP_SET_OPCODE_AND_OPARG ();
3137
3146
assert (opcode == FOR_ITER );
3138
3147
@@ -3234,7 +3243,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3234
3243
HANDLE_UNWINDING (SLP_FRAME_EXECUTING_SETUP_WITH , 1 , res );
3235
3244
}
3236
3245
if (0 ) {
3237
- slp_continue_slp_eval_frame_setup_with :
3246
+ slp_continue_slp_eval_frame_setup_with :
3238
3247
SLP_SET_OPCODE_AND_OPARG ();
3239
3248
assert (opcode == SETUP_WITH );
3240
3249
/* Initialize variables */
@@ -3323,7 +3332,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3323
3332
HANDLE_UNWINDING (SLP_FRAME_EXECUTING_WITH_CLEANUP , 0 , res );
3324
3333
}
3325
3334
if (0 ) {
3326
- slp_continue_slp_eval_frame_with_cleanup :
3335
+ slp_continue_slp_eval_frame_with_cleanup :
3327
3336
/* Initialize variables */
3328
3337
exc = TOP ();
3329
3338
if (exc == NULL )
@@ -3549,6 +3558,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3549
3558
Py_DECREF (func );
3550
3559
Py_DECREF (callargs );
3551
3560
Py_XDECREF (kwargs );
3561
+
3552
3562
#ifdef STACKLESS
3553
3563
if (STACKLESS_UNWINDING (result )) {
3554
3564
(void ) POP (); /* top of stack causes a GC related assertion error */
@@ -3798,29 +3808,24 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
3798
3808
}
3799
3809
3800
3810
/* pop frame */
3801
- /* exit_eval_frame: */
3802
- #ifndef STACKLESS
3803
3811
exit_eval_frame :
3804
3812
if (PyDTrace_FUNCTION_RETURN_ENABLED ())
3805
3813
dtrace_function_return (f );
3806
3814
Py_LeaveRecursiveCall ();
3807
3815
f -> f_executing = 0 ;
3808
- tstate -> frame = f -> f_back ;
3809
-
3810
- return _Py_CheckFunctionResult (NULL , retval , "PyEval_EvalFrameEx" );
3811
-
3812
- #else
3813
- if (PyDTrace_FUNCTION_RETURN_ENABLED ())
3814
- dtrace_function_return (f );
3815
- Py_LeaveRecursiveCall ();
3816
- f -> f_executing = 0 ;
3816
+ #ifdef STACKLESS
3817
3817
SLP_STORE_NEXT_FRAME (tstate , f -> f_back );
3818
+ Py_CLEAR (retval_arg );
3819
+ #else
3820
+ tstate -> frame = f -> f_back ;
3821
+ #endif
3818
3822
3819
3823
return _Py_CheckFunctionResult (NULL , retval , "PyEval_EvalFrameEx" );
3820
3824
3821
-
3825
+ #ifdef STACKLESS
3822
3826
stackless_interrupt_call :
3823
3827
/* interrupted during unwinding */
3828
+ assert (retval_arg == NULL );
3824
3829
assert (f -> f_executing == SLP_FRAME_EXECUTING_VALUE );
3825
3830
f -> f_executing = SLP_FRAME_EXECUTING_NOVAL ;
3826
3831
f -> f_stacktop = stack_pointer ;
@@ -3888,6 +3893,38 @@ handle_unwinding(int lineno, PyFrameObject *f,
3888
3893
return 0 ;
3889
3894
}
3890
3895
3896
+ PyObject *
3897
+ PyEval_EvalFrameEx_slp (PyFrameObject * f , int throwflag , PyObject * retval_arg )
3898
+ {
3899
+ PyThreadState * tstate = _PyThreadState_GET ();
3900
+ int executing = f -> f_executing ;
3901
+ if (executing == SLP_FRAME_EXECUTING_INVALID ) {
3902
+ -- tstate -> recursion_depth ;
3903
+ return slp_cannot_execute ((PyCFrameObject * )f , "PyEval_EvalFrameEx_slp" , retval_arg );
3904
+ } else if (executing == SLP_FRAME_EXECUTING_NO ) {
3905
+ /* Processing of a frame starts here */
3906
+
3907
+ /* Check, if an extension module has changed tstate->interp->eval_frame.
3908
+ * PEP 523 defines this function pointer as an API to customise the frame
3909
+ * evaluation. Stackless can not support this API. In order to prevent
3910
+ * undefined behavior, we terminate the interpreter.
3911
+ */
3912
+ if (tstate -> interp -> eval_frame != _PyEval_EvalFrameDefault )
3913
+ Py_FatalError ("An extension module has set a custom frame evaluation function (see PEP 523).\n"
3914
+ "Stackless Python does not support the frame evaluation API defined by PEP 523.\n"
3915
+ "The programm now terminates to prevent undefined behavior.\n" );
3916
+
3917
+ if (SLP_CSTACK_SAVE_NOW (tstate , f )) {
3918
+ /* Setup the C-stack and recursively call PyEval_EvalFrameEx_slp with the same arguments.
3919
+ * SLP_CSTACK_SAVE_NOW(tstate, f) will be false then.
3920
+ */
3921
+ return slp_eval_frame_newstack (f , throwflag , retval_arg );
3922
+ }
3923
+ }
3924
+ return slp_eval_frame_value (f , throwflag , retval_arg );
3925
+ }
3926
+
3927
+
3891
3928
static PyObject *
3892
3929
run_frame_dispatch (PyCFrameObject * cf , int exc , PyObject * retval )
3893
3930
{
@@ -4000,98 +4037,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
4000
4037
assert (SLP_CURRENT_FRAME_IS_VALID (tstate ));
4001
4038
return retval ;
4002
4039
}
4003
-
4004
- PyObject * _Py_HOT_FUNCTION
4005
- PyEval_EvalFrameEx_slp (PyFrameObject * f , int throwflag , PyObject * retval )
4006
- {
4007
- if (f -> f_executing == SLP_FRAME_EXECUTING_INVALID ) {
4008
- PyThreadState * tstate = _PyThreadState_GET ();
4009
- -- tstate -> recursion_depth ;
4010
- return slp_cannot_execute ((PyCFrameObject * )f , "PyEval_EvalFrameEx_slp" , retval );
4011
- } else if (f -> f_executing != SLP_FRAME_EXECUTING_NO ) {
4012
- return slp_eval_frame_value (f , throwflag , retval );
4013
- }
4014
-
4015
- PyThreadState * tstate = _PyThreadState_GET ();
4016
-
4017
- /* Check, if an extension module has changed tstate->interp->eval_frame.
4018
- * PEP 523 defines this function pointer as an API to customise the frame
4019
- * evaluation. Stackless can not support this API. In order to prevent
4020
- * undefined behavior, we terminate the interpreter.
4021
- */
4022
- if (tstate -> interp -> eval_frame != _PyEval_EvalFrameDefault )
4023
- Py_FatalError ("An extension module has set a custom frame evaluation function (see PEP 523).\n"
4024
- "Stackless Python does not support the frame evaluation API defined by PEP 523.\n"
4025
- "The programm now terminates to prevent undefined behavior.\n" );
4026
-
4027
- /* Start of code, similar to non stackless
4028
- * PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
4029
- */
4030
-
4031
- if (SLP_CSTACK_SAVE_NOW (tstate , f ))
4032
- return slp_eval_frame_newstack (f , throwflag , retval );
4033
-
4034
- /* push frame */
4035
- if (Py_EnterRecursiveCall ("" )) {
4036
- Py_XDECREF (retval );
4037
- SLP_STORE_NEXT_FRAME (tstate , f -> f_back );
4038
- return NULL ;
4039
- }
4040
-
4041
- /* STACKLESS:
4042
- * the code starting from here on until the end-marker
4043
- * is a copy of code above. Keep the two copies in sync!
4044
- */
4045
- tstate -> frame = f ;
4046
-
4047
- if (tstate -> use_tracing ) {
4048
- if (tstate -> c_tracefunc != NULL ) {
4049
- /* tstate->c_tracefunc, if defined, is a
4050
- function that will be called on *every* entry
4051
- to a code block. Its return value, if not
4052
- None, is a function that will be called at
4053
- the start of each executed line of code.
4054
- (Actually, the function must return itself
4055
- in order to continue tracing.) The trace
4056
- functions are called with three arguments:
4057
- a pointer to the current frame, a string
4058
- indicating why the function is called, and
4059
- an argument which depends on the situation.
4060
- The global trace function is also called
4061
- whenever an exception is detected. */
4062
- if (call_trace_protected (tstate -> c_tracefunc ,
4063
- tstate -> c_traceobj ,
4064
- tstate , f , PyTrace_CALL , Py_None )) {
4065
- /* Trace function raised an error */
4066
- goto exit_eval_frame ;
4067
- }
4068
- }
4069
- if (tstate -> c_profilefunc != NULL ) {
4070
- /* Similar for c_profilefunc, except it needn't
4071
- return itself and isn't called for "line" events */
4072
- if (call_trace_protected (tstate -> c_profilefunc ,
4073
- tstate -> c_profileobj ,
4074
- tstate , f , PyTrace_CALL , Py_None )) {
4075
- /* Profile function raised an error */
4076
- goto exit_eval_frame ;
4077
- }
4078
- }
4079
- }
4080
- /* STACKLESS: end of duplicated code
4081
- */
4082
-
4083
-
4084
- f -> f_executing = SLP_FRAME_EXECUTING_NOVAL ;
4085
- return slp_eval_frame_value (f , throwflag , retval );
4086
- exit_eval_frame :
4087
- Py_XDECREF (retval );
4088
- if (PyDTrace_FUNCTION_RETURN_ENABLED ())
4089
- dtrace_function_return (f );
4090
- Py_LeaveRecursiveCall ();
4091
- f -> f_executing = SLP_FRAME_EXECUTING_NO ;
4092
- SLP_STORE_NEXT_FRAME (tstate , f -> f_back );
4093
- return NULL ;
4094
- }
4095
4040
#endif /* #ifdef STACKLESS */
4096
4041
4097
4042
@@ -4288,7 +4233,6 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
4288
4233
if (f == NULL ) {
4289
4234
return NULL ;
4290
4235
}
4291
-
4292
4236
fastlocals = f -> f_localsplus ;
4293
4237
freevars = f -> f_localsplus + co -> co_nlocals ;
4294
4238
@@ -5076,7 +5020,7 @@ PyObject *
5076
5020
PyEval_GetGlobals (void )
5077
5021
{
5078
5022
PyFrameObject * current_frame = PyEval_GetFrame ();
5079
- #if 1 && defined STACKLESS
5023
+ #ifdef STACKLESS
5080
5024
if (current_frame == NULL ) {
5081
5025
PyThreadState * ts = _PyThreadState_GET ();
5082
5026
0 commit comments