Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / third_party / cython / src / Cython / Utility / Generator.c
blob82dbb637a1ddb6d0ba5b1387072465c8907fb268
1 //////////////////// YieldFrom.proto ////////////////////
3 static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_GeneratorObject *gen, PyObject *source);
5 //////////////////// YieldFrom ////////////////////
6 //@requires: Generator
8 static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_GeneratorObject *gen, PyObject *source) {
9 PyObject *source_gen, *retval;
10 source_gen = PyObject_GetIter(source);
11 if (unlikely(!source_gen))
12 return NULL;
13 /* source_gen is now the iterator, make the first next() call */
14 retval = Py_TYPE(source_gen)->tp_iternext(source_gen);
15 if (likely(retval)) {
16 gen->yieldfrom = source_gen;
17 return retval;
19 Py_DECREF(source_gen);
20 return NULL;
23 //////////////////// Generator.proto ////////////////////
24 #define __Pyx_Generator_USED
25 #include <structmember.h>
26 #include <frameobject.h>
28 typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);
30 typedef struct {
31 PyObject_HEAD
32 __pyx_generator_body_t body;
33 PyObject *closure;
34 PyObject *exc_type;
35 PyObject *exc_value;
36 PyObject *exc_traceback;
37 PyObject *gi_weakreflist;
38 PyObject *classobj;
39 PyObject *yieldfrom;
40 int resume_label;
41 // using T_BOOL for property below requires char value
42 char is_running;
43 } __pyx_GeneratorObject;
45 static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body,
46 PyObject *closure);
47 static int __pyx_Generator_init(void);
48 static int __Pyx_Generator_clear(PyObject* self);
50 #if 1 || PY_VERSION_HEX < 0x030300B0
51 static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue);
52 #else
53 #define __Pyx_PyGen_FetchStopIterationValue(pvalue) PyGen_FetchStopIterationValue(pvalue)
54 #endif
56 //////////////////// Generator ////////////////////
57 //@requires: Exceptions.c::PyErrFetchRestore
58 //@requires: Exceptions.c::SwapException
59 //@requires: Exceptions.c::RaiseException
60 //@requires: ObjectHandling.c::PyObjectCallMethod
61 //@requires: CommonTypes.c::FetchCommonType
63 static PyObject *__Pyx_Generator_Next(PyObject *self);
64 static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value);
65 static PyObject *__Pyx_Generator_Close(PyObject *self);
66 static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args);
68 static PyTypeObject *__pyx_GeneratorType = 0;
70 #define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType)
71 #define __Pyx_Generator_Undelegate(gen) Py_CLEAR((gen)->yieldfrom)
73 // If StopIteration exception is set, fetches its 'value'
74 // attribute if any, otherwise sets pvalue to None.
76 // Returns 0 if no exception or StopIteration is set.
77 // If any other exception is set, returns -1 and leaves
78 // pvalue unchanged.
79 #if 1 || PY_VERSION_HEX < 0x030300B0
80 static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
81 PyObject *et, *ev, *tb;
82 PyObject *value = NULL;
84 __Pyx_ErrFetch(&et, &ev, &tb);
86 if (!et) {
87 Py_XDECREF(tb);
88 Py_XDECREF(ev);
89 Py_INCREF(Py_None);
90 *pvalue = Py_None;
91 return 0;
94 if (unlikely(et != PyExc_StopIteration) &&
95 unlikely(!PyErr_GivenExceptionMatches(et, PyExc_StopIteration))) {
96 __Pyx_ErrRestore(et, ev, tb);
97 return -1;
100 // most common case: plain StopIteration without or with separate argument
101 if (likely(et == PyExc_StopIteration)) {
102 if (likely(!ev) || !PyObject_IsInstance(ev, PyExc_StopIteration)) {
103 // PyErr_SetObject() and friends put the value directly into ev
104 if (!ev) {
105 Py_INCREF(Py_None);
106 ev = Py_None;
108 Py_XDECREF(tb);
109 Py_DECREF(et);
110 *pvalue = ev;
111 return 0;
114 // otherwise: normalise and check what that gives us
115 PyErr_NormalizeException(&et, &ev, &tb);
116 if (unlikely(!PyObject_IsInstance(ev, PyExc_StopIteration))) {
117 // looks like normalisation failed - raise the new exception
118 __Pyx_ErrRestore(et, ev, tb);
119 return -1;
121 Py_XDECREF(tb);
122 Py_DECREF(et);
123 #if PY_VERSION_HEX >= 0x030300A0
124 value = ((PyStopIterationObject *)ev)->value;
125 Py_INCREF(value);
126 Py_DECREF(ev);
127 #else
129 PyObject* args = PyObject_GetAttr(ev, PYIDENT("args"));
130 Py_DECREF(ev);
131 if (likely(args)) {
132 value = PyObject_GetItem(args, 0);
133 Py_DECREF(args);
135 if (unlikely(!value)) {
136 __Pyx_ErrRestore(NULL, NULL, NULL);
137 Py_INCREF(Py_None);
138 value = Py_None;
141 #endif
142 *pvalue = value;
143 return 0;
145 #endif
147 static CYTHON_INLINE
148 void __Pyx_Generator_ExceptionClear(__pyx_GeneratorObject *self) {
149 PyObject *exc_type = self->exc_type;
150 PyObject *exc_value = self->exc_value;
151 PyObject *exc_traceback = self->exc_traceback;
153 self->exc_type = NULL;
154 self->exc_value = NULL;
155 self->exc_traceback = NULL;
157 Py_XDECREF(exc_type);
158 Py_XDECREF(exc_value);
159 Py_XDECREF(exc_traceback);
162 static CYTHON_INLINE
163 int __Pyx_Generator_CheckRunning(__pyx_GeneratorObject *gen) {
164 if (unlikely(gen->is_running)) {
165 PyErr_SetString(PyExc_ValueError,
166 "generator already executing");
167 return 1;
169 return 0;
172 static CYTHON_INLINE
173 PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
174 PyObject *retval;
176 assert(!self->is_running);
178 if (unlikely(self->resume_label == 0)) {
179 if (unlikely(value && value != Py_None)) {
180 PyErr_SetString(PyExc_TypeError,
181 "can't send non-None value to a "
182 "just-started generator");
183 return NULL;
187 if (unlikely(self->resume_label == -1)) {
188 PyErr_SetNone(PyExc_StopIteration);
189 return NULL;
193 if (value) {
194 #if CYTHON_COMPILING_IN_PYPY
195 // FIXME: what to do in PyPy?
196 #else
197 /* Generators always return to their most recent caller, not
198 * necessarily their creator. */
199 if (self->exc_traceback) {
200 PyThreadState *tstate = PyThreadState_GET();
201 PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
202 PyFrameObject *f = tb->tb_frame;
204 Py_XINCREF(tstate->frame);
205 assert(f->f_back == NULL);
206 f->f_back = tstate->frame;
208 #endif
209 __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
210 &self->exc_traceback);
211 } else {
212 __Pyx_Generator_ExceptionClear(self);
215 self->is_running = 1;
216 retval = self->body((PyObject *) self, value);
217 self->is_running = 0;
219 if (retval) {
220 __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
221 &self->exc_traceback);
222 #if CYTHON_COMPILING_IN_PYPY
223 // FIXME: what to do in PyPy?
224 #else
225 /* Don't keep the reference to f_back any longer than necessary. It
226 * may keep a chain of frames alive or it could create a reference
227 * cycle. */
228 if (self->exc_traceback) {
229 PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
230 PyFrameObject *f = tb->tb_frame;
231 Py_CLEAR(f->f_back);
233 #endif
234 } else {
235 __Pyx_Generator_ExceptionClear(self);
238 return retval;
241 static CYTHON_INLINE
242 PyObject *__Pyx_Generator_FinishDelegation(__pyx_GeneratorObject *gen) {
243 PyObject *ret;
244 PyObject *val = NULL;
245 __Pyx_Generator_Undelegate(gen);
246 __Pyx_PyGen_FetchStopIterationValue(&val);
247 // val == NULL on failure => pass on exception
248 ret = __Pyx_Generator_SendEx(gen, val);
249 Py_XDECREF(val);
250 return ret;
253 static PyObject *__Pyx_Generator_Next(PyObject *self) {
254 __pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
255 PyObject *yf = gen->yieldfrom;
256 if (unlikely(__Pyx_Generator_CheckRunning(gen)))
257 return NULL;
258 if (yf) {
259 PyObject *ret;
260 // FIXME: does this really need an INCREF() ?
261 //Py_INCREF(yf);
262 /* YieldFrom code ensures that yf is an iterator */
263 gen->is_running = 1;
264 ret = Py_TYPE(yf)->tp_iternext(yf);
265 gen->is_running = 0;
266 //Py_DECREF(yf);
267 if (likely(ret)) {
268 return ret;
270 return __Pyx_Generator_FinishDelegation(gen);
272 return __Pyx_Generator_SendEx(gen, Py_None);
275 static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value) {
276 __pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
277 PyObject *yf = gen->yieldfrom;
278 if (unlikely(__Pyx_Generator_CheckRunning(gen)))
279 return NULL;
280 if (yf) {
281 PyObject *ret;
282 // FIXME: does this really need an INCREF() ?
283 //Py_INCREF(yf);
284 gen->is_running = 1;
285 if (__Pyx_Generator_CheckExact(yf)) {
286 ret = __Pyx_Generator_Send(yf, value);
287 } else {
288 if (value == Py_None)
289 ret = PyIter_Next(yf);
290 else
291 ret = __Pyx_PyObject_CallMethod1(yf, PYIDENT("send"), value);
293 gen->is_running = 0;
294 //Py_DECREF(yf);
295 if (likely(ret)) {
296 return ret;
298 return __Pyx_Generator_FinishDelegation(gen);
300 return __Pyx_Generator_SendEx(gen, value);
303 // This helper function is used by gen_close and gen_throw to
304 // close a subiterator being delegated to by yield-from.
305 static int __Pyx_Generator_CloseIter(__pyx_GeneratorObject *gen, PyObject *yf) {
306 PyObject *retval = NULL;
307 int err = 0;
309 if (__Pyx_Generator_CheckExact(yf)) {
310 retval = __Pyx_Generator_Close(yf);
311 if (!retval)
312 return -1;
313 } else {
314 PyObject *meth;
315 gen->is_running = 1;
316 meth = PyObject_GetAttr(yf, PYIDENT("close"));
317 if (unlikely(!meth)) {
318 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
319 PyErr_WriteUnraisable(yf);
321 PyErr_Clear();
322 } else {
323 retval = PyObject_CallFunction(meth, NULL);
324 Py_DECREF(meth);
325 if (!retval)
326 err = -1;
328 gen->is_running = 0;
330 Py_XDECREF(retval);
331 return err;
334 static PyObject *__Pyx_Generator_Close(PyObject *self) {
335 __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
336 PyObject *retval, *raised_exception;
337 PyObject *yf = gen->yieldfrom;
338 int err = 0;
340 if (unlikely(__Pyx_Generator_CheckRunning(gen)))
341 return NULL;
343 if (yf) {
344 Py_INCREF(yf);
345 err = __Pyx_Generator_CloseIter(gen, yf);
346 __Pyx_Generator_Undelegate(gen);
347 Py_DECREF(yf);
349 if (err == 0)
350 #if PY_VERSION_HEX < 0x02050000
351 PyErr_SetNone(PyExc_StopIteration);
352 #else
353 PyErr_SetNone(PyExc_GeneratorExit);
354 #endif
355 retval = __Pyx_Generator_SendEx(gen, NULL);
356 if (retval) {
357 Py_DECREF(retval);
358 PyErr_SetString(PyExc_RuntimeError,
359 "generator ignored GeneratorExit");
360 return NULL;
362 raised_exception = PyErr_Occurred();
363 if (!raised_exception
364 || raised_exception == PyExc_StopIteration
365 #if PY_VERSION_HEX >= 0x02050000
366 || raised_exception == PyExc_GeneratorExit
367 || PyErr_GivenExceptionMatches(raised_exception, PyExc_GeneratorExit)
368 #endif
369 || PyErr_GivenExceptionMatches(raised_exception, PyExc_StopIteration))
371 if (raised_exception) PyErr_Clear(); /* ignore these errors */
372 Py_INCREF(Py_None);
373 return Py_None;
375 return NULL;
378 static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) {
379 __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
380 PyObject *typ;
381 PyObject *tb = NULL;
382 PyObject *val = NULL;
383 PyObject *yf = gen->yieldfrom;
385 if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
386 return NULL;
388 if (unlikely(__Pyx_Generator_CheckRunning(gen)))
389 return NULL;
391 if (yf) {
392 PyObject *ret;
393 Py_INCREF(yf);
394 #if PY_VERSION_HEX >= 0x02050000
395 if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
396 int err = __Pyx_Generator_CloseIter(gen, yf);
397 Py_DECREF(yf);
398 __Pyx_Generator_Undelegate(gen);
399 if (err < 0)
400 return __Pyx_Generator_SendEx(gen, NULL);
401 goto throw_here;
403 #endif
404 gen->is_running = 1;
405 if (__Pyx_Generator_CheckExact(yf)) {
406 ret = __Pyx_Generator_Throw(yf, args);
407 } else {
408 PyObject *meth = PyObject_GetAttr(yf, PYIDENT("throw"));
409 if (unlikely(!meth)) {
410 Py_DECREF(yf);
411 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
412 gen->is_running = 0;
413 return NULL;
415 PyErr_Clear();
416 __Pyx_Generator_Undelegate(gen);
417 gen->is_running = 0;
418 goto throw_here;
420 ret = PyObject_CallObject(meth, args);
421 Py_DECREF(meth);
423 gen->is_running = 0;
424 Py_DECREF(yf);
425 if (!ret) {
426 ret = __Pyx_Generator_FinishDelegation(gen);
428 return ret;
430 throw_here:
431 __Pyx_Raise(typ, val, tb, NULL);
432 return __Pyx_Generator_SendEx(gen, NULL);
435 static int __Pyx_Generator_traverse(PyObject *self, visitproc visit, void *arg) {
436 __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
438 Py_VISIT(gen->closure);
439 Py_VISIT(gen->classobj);
440 Py_VISIT(gen->yieldfrom);
441 Py_VISIT(gen->exc_type);
442 Py_VISIT(gen->exc_value);
443 Py_VISIT(gen->exc_traceback);
444 return 0;
447 static int __Pyx_Generator_clear(PyObject *self) {
448 __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
450 Py_CLEAR(gen->closure);
451 Py_CLEAR(gen->classobj);
452 Py_CLEAR(gen->yieldfrom);
453 Py_CLEAR(gen->exc_type);
454 Py_CLEAR(gen->exc_value);
455 Py_CLEAR(gen->exc_traceback);
456 return 0;
459 static void __Pyx_Generator_dealloc(PyObject *self) {
460 __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
462 PyObject_GC_UnTrack(gen);
463 if (gen->gi_weakreflist != NULL)
464 PyObject_ClearWeakRefs(self);
466 if (gen->resume_label > 0) {
467 /* Generator is paused, so we need to close */
468 PyObject_GC_Track(self);
469 #if PY_VERSION_HEX >= 0x030400a1
470 if (PyObject_CallFinalizerFromDealloc(self))
471 #else
472 Py_TYPE(gen)->tp_del(self);
473 if (self->ob_refcnt > 0)
474 #endif
475 return; /* resurrected. :( */
476 PyObject_GC_UnTrack(self);
479 __Pyx_Generator_clear(self);
480 PyObject_GC_Del(gen);
483 static void __Pyx_Generator_del(PyObject *self) {
484 PyObject *res;
485 PyObject *error_type, *error_value, *error_traceback;
486 __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
488 if (gen->resume_label <= 0)
489 return ;
491 #if PY_VERSION_HEX < 0x030400a1
492 /* Temporarily resurrect the object. */
493 assert(self->ob_refcnt == 0);
494 self->ob_refcnt = 1;
495 #endif
497 /* Save the current exception, if any. */
498 __Pyx_ErrFetch(&error_type, &error_value, &error_traceback);
500 res = __Pyx_Generator_Close(self);
502 if (res == NULL)
503 PyErr_WriteUnraisable(self);
504 else
505 Py_DECREF(res);
507 /* Restore the saved exception. */
508 __Pyx_ErrRestore(error_type, error_value, error_traceback);
510 #if PY_VERSION_HEX < 0x030400a1
511 /* Undo the temporary resurrection; can't use DECREF here, it would
512 * cause a recursive call.
514 assert(self->ob_refcnt > 0);
515 if (--self->ob_refcnt == 0)
516 return; /* this is the normal path out */
518 /* close() resurrected it! Make it look like the original Py_DECREF
519 * never happened.
522 Py_ssize_t refcnt = self->ob_refcnt;
523 _Py_NewReference(self);
524 self->ob_refcnt = refcnt;
526 #if CYTHON_COMPILING_IN_CPYTHON
527 assert(PyType_IS_GC(self->ob_type) &&
528 _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
530 /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
531 * we need to undo that. */
532 _Py_DEC_REFTOTAL;
533 #endif
534 /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
535 * chain, so no more to do there.
536 * If COUNT_ALLOCS, the original decref bumped tp_frees, and
537 * _Py_NewReference bumped tp_allocs: both of those need to be
538 * undone.
540 #ifdef COUNT_ALLOCS
541 --Py_TYPE(self)->tp_frees;
542 --Py_TYPE(self)->tp_allocs;
543 #endif
544 #endif
547 static PyMemberDef __pyx_Generator_memberlist[] = {
548 {(char *) "gi_running",
549 #if PY_VERSION_HEX >= 0x02060000
550 T_BOOL,
551 #else
552 T_BYTE,
553 #endif
554 offsetof(__pyx_GeneratorObject, is_running),
555 READONLY,
556 NULL},
557 {0, 0, 0, 0, 0}
560 static PyMethodDef __pyx_Generator_methods[] = {
561 {__Pyx_NAMESTR("send"), (PyCFunction) __Pyx_Generator_Send, METH_O, 0},
562 {__Pyx_NAMESTR("throw"), (PyCFunction) __Pyx_Generator_Throw, METH_VARARGS, 0},
563 {__Pyx_NAMESTR("close"), (PyCFunction) __Pyx_Generator_Close, METH_NOARGS, 0},
564 {0, 0, 0, 0}
567 static PyTypeObject __pyx_GeneratorType_type = {
568 PyVarObject_HEAD_INIT(0, 0)
569 __Pyx_NAMESTR("generator"), /*tp_name*/
570 sizeof(__pyx_GeneratorObject), /*tp_basicsize*/
571 0, /*tp_itemsize*/
572 (destructor) __Pyx_Generator_dealloc,/*tp_dealloc*/
573 0, /*tp_print*/
574 0, /*tp_getattr*/
575 0, /*tp_setattr*/
576 #if PY_MAJOR_VERSION < 3
577 0, /*tp_compare*/
578 #else
579 0, /*reserved*/
580 #endif
581 0, /*tp_repr*/
582 0, /*tp_as_number*/
583 0, /*tp_as_sequence*/
584 0, /*tp_as_mapping*/
585 0, /*tp_hash*/
586 0, /*tp_call*/
587 0, /*tp_str*/
588 0, /*tp_getattro*/
589 0, /*tp_setattro*/
590 0, /*tp_as_buffer*/
591 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags*/
592 0, /*tp_doc*/
593 (traverseproc) __Pyx_Generator_traverse, /*tp_traverse*/
594 0, /*tp_clear*/
595 0, /*tp_richcompare*/
596 offsetof(__pyx_GeneratorObject, gi_weakreflist), /* tp_weaklistoffse */
597 0, /*tp_iter*/
598 (iternextfunc) __Pyx_Generator_Next, /*tp_iternext*/
599 __pyx_Generator_methods, /*tp_methods*/
600 __pyx_Generator_memberlist, /*tp_members*/
601 0, /*tp_getset*/
602 0, /*tp_base*/
603 0, /*tp_dict*/
604 0, /*tp_descr_get*/
605 0, /*tp_descr_set*/
606 0, /*tp_dictoffset*/
607 0, /*tp_init*/
608 0, /*tp_alloc*/
609 0, /*tp_new*/
610 0, /*tp_free*/
611 0, /*tp_is_gc*/
612 0, /*tp_bases*/
613 0, /*tp_mro*/
614 0, /*tp_cache*/
615 0, /*tp_subclasses*/
616 0, /*tp_weaklist*/
617 #if PY_VERSION_HEX >= 0x030400a1
618 0, /*tp_del*/
619 #else
620 __Pyx_Generator_del, /*tp_del*/
621 #endif
622 #if PY_VERSION_HEX >= 0x02060000
623 0, /*tp_version_tag*/
624 #endif
625 #if PY_VERSION_HEX >= 0x030400a1
626 __Pyx_Generator_del, /*tp_finalize*/
627 #endif
630 static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body,
631 PyObject *closure) {
632 __pyx_GeneratorObject *gen =
633 PyObject_GC_New(__pyx_GeneratorObject, &__pyx_GeneratorType_type);
635 if (gen == NULL)
636 return NULL;
638 gen->body = body;
639 gen->closure = closure;
640 Py_XINCREF(closure);
641 gen->is_running = 0;
642 gen->resume_label = 0;
643 gen->classobj = NULL;
644 gen->yieldfrom = NULL;
645 gen->exc_type = NULL;
646 gen->exc_value = NULL;
647 gen->exc_traceback = NULL;
648 gen->gi_weakreflist = NULL;
650 PyObject_GC_Track(gen);
651 return gen;
654 static int __pyx_Generator_init(void) {
655 /* on Windows, C-API functions can't be used in slots statically */
656 __pyx_GeneratorType_type.tp_getattro = PyObject_GenericGetAttr;
657 __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter;
659 __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type);
660 if (__pyx_GeneratorType == NULL) {
661 return -1;
663 return 0;