#include "Python.h" #ifdef STACKLESS #include "stackless_impl.h" /* Shorthands to return certain errors */ PyObject * slp_type_error(const char *msg) { PyErr_SetString(PyExc_TypeError, msg); return NULL; } PyObject * slp_runtime_error(const char *msg) { PyErr_SetString(PyExc_RuntimeError, msg); return NULL; } PyObject * slp_value_error(const char *msg) { PyErr_SetString(PyExc_ValueError, msg); return NULL; } PyObject * slp_null_error(void) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_SystemError, "null argument to internal routine"); return NULL; } /* CAUTION: This function returns a borrowed reference */ PyFrameObject * slp_get_frame(PyTaskletObject *task) { PyThreadState *ts; if (task->topframe == NULL || task->cstate == NULL) return NULL; ts = task->cstate->tstate; return ts->st.current == task ? ts->frame : task->f.frame; } PyTaskletFlagStruc * slp_get_flags(PyTaskletObject *task) { PyThreadState *ts; assert(task->cstate != NULL); ts = task->cstate->tstate; return ts->st.current == task ? &ts->st.flags : &task->flags; } void slp_check_pending_irq() { PyThreadState *ts = PyThreadState_GET(); if (ts->st.flags.pending_irq) { if (ts->st.flags.atomic) return; if (ts->st.nesting_level && !ts->st.flags.ignore_nesting) return; /* trigger interrupt */ if (_Py_Ticker > 0) _Py_Ticker = 0; ts->st.ticker = 0; ts->st.flags.pending_irq = 0; } } int slp_return_wrapper(PyObject *retval) { STACKLESS_ASSERT(); if (retval == NULL) return -1; if (retval == Py_UnwindToken) return 1; Py_DECREF(retval); return 0; } int slp_int_wrapper(PyObject *retval) { int ret = -909090; STACKLESS_ASSERT(); if (retval != NULL) { ret = PyInt_AsLong(retval); Py_DECREF(retval); } return ret; } int slp_current_wrapper( int(*func)(PyTaskletObject*), PyTaskletObject *task ) { PyThreadState *ts = PyThreadState_GET(); int ret; ts->st.main = (PyTaskletObject*)Py_None; ret = func(task); ts->st.main = NULL; return ret; } #endif