GH-118095: Handle RETURN_GENERATOR in tier 2 (GH-118180)

This commit is contained in:
Mark Shannon 2024-04-25 11:32:47 +01:00 committed by GitHub
parent 10bb90ed49
commit f180b31e76
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 143 additions and 81 deletions

View file

@ -182,7 +182,7 @@ static inline void _Py_LeaveRecursiveCall(void) {
extern struct _PyInterpreterFrame* _PyEval_GetFrame(void);
extern PyObject* _Py_MakeCoro(PyFunctionObject *func);
PyAPI_FUNC(PyObject *)_Py_MakeCoro(PyFunctionObject *func);
/* Handle signals, pending calls, GIL drop request
and asynchronous exception */

View file

@ -110,7 +110,17 @@ _PyFrame_NumSlotsForCodeObject(PyCodeObject *code)
return code->co_framesize - FRAME_SPECIALS_SIZE;
}
void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest);
static inline void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest)
{
assert(src->stacktop >= _PyFrame_GetCode(src)->co_nlocalsplus);
*dest = *src;
for (int i = 1; i < src->stacktop; i++) {
dest->localsplus[i] = src->localsplus[i];
}
// Don't leave a dangling pointer to the old frame when creating generators
// and coroutines:
dest->previous = NULL;
}
/* Consumes reference to func and locals.
Does not initialize frame->previous, which happens
@ -256,7 +266,7 @@ _PyThreadState_HasStackSpace(PyThreadState *tstate, int size)
extern _PyInterpreterFrame *
_PyThreadState_PushFrame(PyThreadState *tstate, size_t size);
void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame);
PyAPI_FUNC(void) _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame);
/* Pushes a frame without checking for space.
* Must be guarded by _PyThreadState_HasStackSpace()

View file

@ -805,7 +805,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
case RETURN_CONST:
return 0;
case RETURN_GENERATOR:
return 0;
return 1;
case RETURN_VALUE:
return 0;
case SEND:
@ -1310,6 +1310,7 @@ _PyOpcode_macro_expansion[256] = {
[PUSH_NULL] = { .nuops = 1, .uops = { { _PUSH_NULL, 0, 0 } } },
[RESUME_CHECK] = { .nuops = 1, .uops = { { _RESUME_CHECK, 0, 0 } } },
[RETURN_CONST] = { .nuops = 2, .uops = { { _LOAD_CONST, 0, 0 }, { _POP_FRAME, 0, 0 } } },
[RETURN_GENERATOR] = { .nuops = 1, .uops = { { _RETURN_GENERATOR, 0, 0 } } },
[RETURN_VALUE] = { .nuops = 1, .uops = { { _POP_FRAME, 0, 0 } } },
[SETUP_ANNOTATIONS] = { .nuops = 1, .uops = { { _SETUP_ANNOTATIONS, 0, 0 } } },
[SET_ADD] = { .nuops = 1, .uops = { { _SET_ADD, 0, 0 } } },

View file

@ -231,6 +231,7 @@ extern "C" {
#define _PUSH_NULL PUSH_NULL
#define _REPLACE_WITH_TRUE 424
#define _RESUME_CHECK RESUME_CHECK
#define _RETURN_GENERATOR RETURN_GENERATOR
#define _SAVE_RETURN_OFFSET 425
#define _SEND 426
#define _SEND_GEN SEND_GEN

View file

@ -219,6 +219,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_CALL_METHOD_DESCRIPTOR_FAST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_MAKE_FUNCTION] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_SET_FUNCTION_ATTRIBUTE] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
[_RETURN_GENERATOR] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_BUILD_SLICE] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
[_CONVERT_VALUE] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
[_FORMAT_SIMPLE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
@ -445,6 +446,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_PUSH_NULL] = "_PUSH_NULL",
[_REPLACE_WITH_TRUE] = "_REPLACE_WITH_TRUE",
[_RESUME_CHECK] = "_RESUME_CHECK",
[_RETURN_GENERATOR] = "_RETURN_GENERATOR",
[_SAVE_RETURN_OFFSET] = "_SAVE_RETURN_OFFSET",
[_SETUP_ANNOTATIONS] = "_SETUP_ANNOTATIONS",
[_SET_ADD] = "_SET_ADD",
@ -894,6 +896,8 @@ int _PyUop_num_popped(int opcode, int oparg)
return 1;
case _SET_FUNCTION_ATTRIBUTE:
return 2;
case _RETURN_GENERATOR:
return 0;
case _BUILD_SLICE:
return 2 + ((oparg == 3) ? 1 : 0);
case _CONVERT_VALUE: