bpo-46409: Make generators in bytecode (GH-30633)

* Add RETURN_GENERATOR and JUMP_NO_INTERRUPT opcodes.

* Trim frame and generator by word each.

* Minor refactor of frame.c

* Update test.test_sys to account for smaller frames.

* Treat generator functions as normal functions when evaluating and specializing.
This commit is contained in:
Mark Shannon 2022-01-20 11:46:39 +00:00 • committed by GitHub
parent d05a66339b
commit b04dfbbe4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 236 additions and 205 deletions

View file

@ -242,6 +242,7 @@ mark_stacks(PyCodeObject *code_obj, int len)
break;
}
case JUMP_ABSOLUTE:
case JUMP_NO_INTERRUPT:
j = get_arg(code, i);
assert(j < len);
if (stacks[j] == UNINITIALIZED && j < i) {
@ -625,7 +626,7 @@ frame_dealloc(PyFrameObject *f)
{
/* It is the responsibility of the owning generator/coroutine
* to have cleared the generator pointer */
assert(f->f_frame->generator == NULL);
assert(!f->f_frame->is_generator);
if (_PyObject_GC_IS_TRACKED(f)) {
_PyObject_GC_UNTRACK(f);
@ -698,8 +699,11 @@ frame_clear(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
"cannot clear an executing frame");
return NULL;
}
if (f->f_frame->generator) {
_PyGen_Finalize(f->f_frame->generator);
if (f->f_frame->is_generator) {
assert(!f->f_owns_frame);
size_t offset_in_gen = offsetof(PyGenObject, gi_iframe);
PyObject *gen = (PyObject *)(((char *)f->f_frame) - offset_in_gen);
_PyGen_Finalize(gen);
}
(void)frame_tp_clear(f);
Py_RETURN_NONE;