void generatorEntry(BoxedGenerator* g) { { assert(g->cls == generator_cls); assert(g->function->cls == function_cls); threading::pushGenerator(g, g->stack_begin, g->returnContext); try { RegisterHelper context_registerer(g, __builtin_frame_address(0)); // call body of the generator BoxedFunctionBase* func = g->function; Box** args = g->args ? &g->args->elts[0] : nullptr; callCLFunc<ExceptionStyle::CXX>(func->f, nullptr, func->f->numReceivedArgs(), func->closure, g, func->globals, g->arg1, g->arg2, g->arg3, args); } catch (ExcInfo e) { // unhandled exception: propagate the exception to the caller g->exception = e; } // we returned from the body of the generator. next/send/throw will notify the caller g->entryExited = true; threading::popGenerator(); } swapContext(&g->context, g->returnContext, 0); }
void generatorEntry(BoxedGenerator* g) noexcept { { assert(g->cls == generator_cls); assert(g->function->cls == function_cls); assert(g->returnValue == Py_None); Py_CLEAR(g->returnValue); { RegisterHelper context_registerer(g, __builtin_frame_address(0)); g->top_caller_frame_info = (FrameInfo*)cur_thread_state.frame_info; // call body of the generator BoxedFunctionBase* func = g->function; // unnecessary because the generator owns g->function // KEEP_ALIVE(func); Box** args = g->args ? &g->args->elts[0] : nullptr; auto r = callCLFunc<ExceptionStyle::CAPI, NOT_REWRITABLE>(func->code, nullptr, func->code->numReceivedArgs(), func->closure, g, func->globals, g->arg1, g->arg2, g->arg3, args); if (r) Py_DECREF(r); else { // unhandled exception: propagate the exception to the caller PyErr_Fetch(&g->exception.type, &g->exception.value, &g->exception.traceback); PyErr_Clear(); } } // we returned from the body of the generator. next/send/throw will notify the caller g->entryExited = true; } assert(g->top_caller_frame_info == cur_thread_state.frame_info); swapContext(&g->context, g->returnContext, 0); }