Exemple #1
0
static PyObject *
channel_send_sequence(PyChannelObject *self, PyObject *v)
{
	STACKLESS_GETARG();
	PyThreadState *ts = PyThreadState_GET();
	/*unused: PyChannel_HeapType *t = (PyChannel_HeapType *) self->ob_type;*/
	PyObject *it;
	PyCFrameObject *f;

	if (!stackless)
		return _channel_send_sequence(self, v);

	it = PyObject_GetIter(v);
	if (it == NULL)
		return NULL;

	f = slp_cframe_new(channel_seq_callback, 1);
	if (f == NULL)
		goto error;

	f->ob1 = it;
	Py_INCREF(self);
	f->ob2 = (PyObject *) self;
	f->i = 0;
	f->n = 0;
	ts->frame = (PyFrameObject *) f;
	Py_INCREF(Py_None);
	return STACKLESS_PACK(Py_None);
error:
	Py_DECREF(it);
	return NULL;
}
Exemple #2
0
static PyObject *
channel_send_exception(PyObject *myself, PyObject *args)
{
	STACKLESS_GETARG();
	PyObject *retval = NULL;
	PyObject *klass = PySequence_GetItem(args, 0);

	if (klass == NULL)
		VALUE_ERROR("channel.send_exception(e, v...)", NULL);
	args = PySequence_GetSlice(args, 1, PySequence_Size(args));
	if (!args) {
		goto err_exit;
	}
	STACKLESS_PROMOTE_ALL();
	retval = impl_channel_send_exception((PyChannelObject*)myself,
						klass, args);
	STACKLESS_ASSERT();
	if (retval == NULL || STACKLESS_UNWINDING(retval)) {
		goto err_exit;
	}
	Py_INCREF(Py_None);
	retval = Py_None;
err_exit:
	Py_DECREF(klass);
	Py_XDECREF(args);
	return retval;
}
Exemple #3
0
static PyObject *
wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
{
	STACKLESS_GETARG();
	wrapperfunc wrapper = wp->descr->d_base->wrapper;
	PyObject *self = wp->self;
	PyObject *ret;

	if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
		wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
		STACKLESS_PROMOTE_WRAPPER(wp);
		ret = (*wk)(self, args, wp->descr->d_wrapped, kwds);
		STACKLESS_ASSERT();
		return ret;
	}

	if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_Size(kwds) != 0)) {
		PyErr_Format(PyExc_TypeError,
			     "wrapper %s doesn't take keyword arguments",
			     wp->descr->d_base->name);
		return NULL;
	}
	STACKLESS_PROMOTE_WRAPPER(wp);
	ret = (*wrapper)(self, args, wp->descr->d_wrapped);
	STACKLESS_ASSERT();
	return ret;
}
static TASKLET_KILL_HEAD(impl_tasklet_kill)
{
    STACKLESS_GETARG();
    PyObject *noargs;
    PyObject *ret;

    /*
     * silently do nothing if the tasklet is dead.
     * simple raising would kill ourself in this case.
     */
    if (slp_get_frame(task) == NULL)
        Py_RETURN_NONE;

    /* we might be called after exceptions are gone */
    if (PyExc_TaskletExit == NULL) {
        PyExc_TaskletExit = PyString_FromString("zombie");
        if (PyExc_TaskletExit == NULL)
            return NULL; /* give up */
    }
    noargs = PyTuple_New(0);
    STACKLESS_PROMOTE_ALL();
    ret = impl_tasklet_raise_exception(task, PyExc_TaskletExit,
                                       noargs);
    STACKLESS_ASSERT();
    Py_DECREF(noargs);
    return ret;
}
Exemple #5
0
static CHANNEL_SEND_HEAD(impl_channel_send)
{
	STACKLESS_GETARG();
	PyThreadState *ts = PyThreadState_GET();

	if(ts->st.main == NULL) return PyChannel_Send_M(self, arg);
	return generic_channel_action(self, arg, 1, stackless);
}
Exemple #6
0
static CHANNEL_RECEIVE_HEAD(impl_channel_receive)
{
	STACKLESS_GETARG();
	PyThreadState *ts = PyThreadState_GET();

	if (ts->st.main == NULL) return PyChannel_Receive_M(self);
	return generic_channel_action(self, Py_None, -1, stackless);
}
static PyObject *
impl_channel_send(PyChannelObject *self, PyObject *arg)
{
    STACKLESS_GETARG();
    PyThreadState *ts = PyThreadState_GET();

    if(ts->st.main == NULL) return PyChannel_Send_M(self, arg);
    return generic_channel_action(self, arg, 1, stackless);
}
static PyObject *
impl_channel_receive(PyChannelObject *self)
{
    STACKLESS_GETARG();
    PyThreadState *ts = PyThreadState_GET();

    if (ts->st.main == NULL) return PyChannel_Receive_M(self);
    return generic_channel_action(self, Py_None, -1, stackless);
}
static TASKLET_RUN_HEAD(impl_tasklet_run)
{
    STACKLESS_GETARG();
    PyThreadState *ts = PyThreadState_GET();

    assert(PyTasklet_Check(task));
    if (ts->st.main == NULL) return PyTasklet_Run_M(task);
    if (PyTasklet_Insert(task))
        return NULL;
    return slp_schedule_task(ts->st.current, task, stackless, 0);
}
Exemple #10
0
static PyObject *
channel_iternext(PyChannelObject *self)
{
	STACKLESS_GETARG();

	if (self->flags.closing && self->balance == 0) {
		/* signal the end of the iteration */
		return NULL;
	}
	STACKLESS_PROMOTE_ALL();
	return impl_channel_receive(self);
}
Exemple #11
0
static PyObject *
schedule_generic(PyObject *self, PyObject *args, PyObject *kwds, int remove)
{
	STACKLESS_GETARG();
	PyObject *retval = (PyObject *) PyThreadState_GET()->st.current;
	static char *argnames[] = {"retval", NULL};

	if (PyTuple_GET_SIZE(args) > 0) {
		if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:schedule",
						 argnames, &retval))
			return NULL;
	}
	STACKLESS_PROMOTE_ALL();
	return PyStackless_Schedule(retval, remove);
}
Exemple #12
0
static PyObject *
run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals,
	 PyCompilerFlags *flags, PyArena *arena)
{
	STACKLESS_GETARG();
	PyCodeObject *co;
	PyObject *v;
	co = PyAST_Compile(mod, filename, flags, arena);
	if (co == NULL)
		return NULL;
	STACKLESS_PROMOTE_ALL();
	v = PyEval_EvalCode(co, globals, locals);
	STACKLESS_ASSERT();
	Py_DECREF(co);
	return v;
}
Exemple #13
0
static PyObject *
classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
		      PyObject *kwds)
{
	STACKLESS_GETARG();
	PyObject *func, *result;

	func = PyCFunction_New(descr->d_method, (PyObject *)descr->d_type);
	if (func == NULL)
		return NULL;

	STACKLESS_PROMOTE_ALL();
	result = PyEval_CallObjectWithKeywords(func, args, kwds);
	STACKLESS_ASSERT();
	Py_DECREF(func);
	return result;
}
Exemple #14
0
static CHANNEL_SEND_EXCEPTION_HEAD(impl_channel_send_exception)
{
	STACKLESS_GETARG();
	PyThreadState *ts = PyThreadState_GET();
	PyObject *bomb, *ret = NULL;

	assert(PyChannel_Check(self));
	if (ts->st.main == NULL)
		return PyChannel_SendException_M(self, klass, args);

	bomb = slp_make_bomb(klass, args, "channel.send_exception");
	if (bomb != NULL) {
		ret = generic_channel_action(self, bomb, 1, stackless);
		Py_DECREF(bomb);
	}
	return ret;
}
Exemple #15
0
static PyObject *
wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
{
	STACKLESS_GETARG();
	Py_ssize_t argc;
	PyObject *self, *func, *result;

	/* Make sure that the first argument is acceptable as 'self' */
	assert(PyTuple_Check(args));
	argc = PyTuple_GET_SIZE(args);
	if (argc < 1) {
		PyErr_Format(PyExc_TypeError,
			     "descriptor '%.300s' of '%.100s' "
			     "object needs an argument",
			     descr_name((PyDescrObject *)descr),
			     descr->d_type->tp_name);
		return NULL;
	}
	self = PyTuple_GET_ITEM(args, 0);
	if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) {
		PyErr_Format(PyExc_TypeError,
			     "descriptor '%.200s' "
			     "requires a '%.100s' object "
			     "but received a '%.100s'",
			     descr_name((PyDescrObject *)descr),
			     descr->d_type->tp_name,
			     self->ob_type->tp_name);
		return NULL;
	}

	func = PyWrapper_New((PyObject *)descr, self);
	if (func == NULL)
		return NULL;
	args = PyTuple_GetSlice(args, 1, argc);
	if (args == NULL) {
		Py_DECREF(func);
		return NULL;
	}
	STACKLESS_PROMOTE_ALL();
	result = PyEval_CallObjectWithKeywords(func, args, kwds);
	STACKLESS_ASSERT();
	Py_DECREF(args);
	Py_DECREF(func);
	return result;
}
static PyObject *
impl_channel_send_throw(PyChannelObject *self, PyObject *exc, PyObject *val, PyObject *tb)
{
    STACKLESS_GETARG();
    PyThreadState *ts = PyThreadState_GET();
    PyObject *bomb, *ret = NULL;

    assert(PyChannel_Check(self));
    if (ts->st.main == NULL)
        return PyChannel_SendThrow_M(self, exc, val, tb);

    bomb = slp_exc_to_bomb(exc, val, tb);
    if (bomb != NULL) {
        ret = generic_channel_action(self, bomb, 1, stackless);
        Py_DECREF(bomb);
    }
    return ret;
}
static TASKLET_RAISE_EXCEPTION_HEAD(impl_tasklet_raise_exception)
{
    STACKLESS_GETARG();
    PyThreadState *ts = PyThreadState_GET();
    PyObject *bomb;

    if (ts->st.main == NULL)
        return PyTasklet_RaiseException_M(self, klass, args);
    bomb = slp_make_bomb(klass, args, "tasklet.raise_exception");
    if (bomb == NULL)
        return NULL;
    TASKLET_SETVAL_OWN(self, bomb);
    /* if the tasklet is dead, do not run it (no frame) but explode */
    if (slp_get_frame(self) == NULL) {
        TASKLET_CLAIMVAL(self, &bomb);
        return slp_bomb_explode(bomb);
    }
    return slp_schedule_task(ts->st.current, self, stackless, 0);
}
Exemple #18
0
PyObject *
PyRun_StringFlags(const char *str, int start, PyObject *globals,
		  PyObject *locals, PyCompilerFlags *flags)
{
	STACKLESS_GETARG();
	PyObject *ret = NULL;
	mod_ty mod;
	PyArena *arena = PyArena_New();
	if (arena == NULL)
		return NULL;
	
	mod = PyParser_ASTFromString(str, "<string>", start, flags, arena);
	if (mod != NULL) {
		STACKLESS_PROMOTE_ALL();
		ret = run_mod(mod, "<string>", globals, locals, flags, arena);
	}
	PyArena_Free(arena);
	return ret;
}
Exemple #19
0
PyObject *
PyStackless_Schedule(PyObject *retval, int remove)
{
	STACKLESS_GETARG();
	PyThreadState *ts = PyThreadState_GET();
	PyTaskletObject *prev = ts->st.current, *next = prev->next;
	PyObject *ret = NULL;

	if (ts->st.main == NULL) return PyStackless_Schedule_M(retval, remove);
	Py_INCREF(prev);
	TASKLET_SETVAL(prev, retval);
	if (remove) {
		slp_current_remove();
		Py_DECREF(prev);
	}
	ret = slp_schedule_task(prev, next, stackless);
	Py_DECREF(prev);
	return ret;
}
static PyObject *
tasklet_raise_exception(PyObject *myself, PyObject *args)
{
    STACKLESS_GETARG();
    PyObject *result = NULL;
    PyObject *klass = PySequence_GetItem(args, 0);

    if (klass == NULL)
        VALUE_ERROR("tasklet.raise_exception(e, v...)", NULL);
    args = PySequence_GetSlice(args, 1, PySequence_Size(args));
    if (!args) goto err_exit;
    STACKLESS_PROMOTE_ALL();
    result = impl_tasklet_raise_exception(
        (PyTaskletObject*)myself, klass, args);
    STACKLESS_ASSERT();
err_exit:
    Py_DECREF(klass);
    Py_XDECREF(args);
    return result;
}
Exemple #21
0
PyObject *
PyStackless_Schedule(PyObject *retval, int remove)
{
    STACKLESS_GETARG();
    PyThreadState *ts = PyThreadState_GET();
    PyTaskletObject *prev = ts->st.current, *next = prev->next;
    PyObject *ret = NULL;
    int switched;

    if (ts->st.main == NULL) return PyStackless_Schedule_M(retval, remove);
    /* make sure we hold a reference to the previous tasklet */
    Py_INCREF(prev);
    TASKLET_SETVAL(prev, retval);
    if (remove) {
        slp_current_remove();
        Py_DECREF(prev);
        if (next == prev)
            next = 0; /* we were the last runnable tasklet */
    }
    /* we mustn't DECREF prev here (after the slp_schedule_task().
     * This could be the last reference, thus
     * promting emergency reactivation of the tasklet,
     * and soft switching isn't really done until we have unwound.
     * Use the delayed release mechanism instead.
     */
    assert(ts->st.del_post_switch == NULL);
    ts->st.del_post_switch = (PyObject*)prev;

    ret = slp_schedule_task(prev, next, stackless, &switched);

    /* however, if this was a no-op (e.g. prev==next, or an error occurred)
     * we need to decref prev ourselves
     */
    if (!switched)
        Py_CLEAR(ts->st.del_post_switch);
    return ret;
}
static PyObject *
channel_send_throw(PyObject *myself, PyObject *args)
{
    STACKLESS_GETARG();

    PyObject *typ;
    PyObject *tb = Py_None;
    PyObject *val = Py_None;
    PyObject *retval;
    if (!PyArg_UnpackTuple(args, "send_throw", 1, 3, &typ, &val, &tb))
        return NULL;

    STACKLESS_PROMOTE_ALL();
    retval = impl_channel_send_throw((PyChannelObject*)myself,
        typ, val, tb);
    STACKLESS_ASSERT();
    if (retval == NULL || STACKLESS_UNWINDING(retval)) {
        goto err_exit;
    }
    Py_INCREF(Py_None);
    retval = Py_None;
err_exit:
    return retval;
}
Exemple #23
0
PyObject *
PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
		  PyObject *locals, int closeit, PyCompilerFlags *flags)
{
	STACKLESS_GETARG();
	PyObject *ret;
	mod_ty mod;
	PyArena *arena = PyArena_New();
	if (arena == NULL)
		return NULL;
	
	mod = PyParser_ASTFromFile(fp, filename, start, 0, 0,
				   flags, NULL, arena);
	if (closeit)
		fclose(fp);
	if (mod == NULL) {
		PyArena_Free(arena);
		return NULL;
	}
	STACKLESS_PROMOTE_ALL();
	ret = run_mod(mod, filename, globals, locals, flags, arena);
	PyArena_Free(arena);
	return ret;
}
static PyObject *
channel_send(PyObject *self, PyObject *arg)
{
    STACKLESS_GETARG();
    return generic_channel_action((PyChannelObject*)self, arg, 1, stackless);
}
Exemple #25
0
PyObject *
PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
{
    STACKLESS_GETARG();
    PyCFunctionObject* f = (PyCFunctionObject*)func;
    PyCFunction meth = PyCFunction_GET_FUNCTION(func);
    PyObject *self = PyCFunction_GET_SELF(func);
    Py_ssize_t size;

#ifdef STACKLESS
    switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS)) {
#else
    switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
#endif
    case METH_VARARGS:
        if (kw == NULL || PyDict_Size(kw) == 0)
            WRAP_RETURN( (*meth)(self, arg) )
        break;
    case METH_VARARGS | METH_KEYWORDS:
        WRAP_RETURN( (*(PyCFunctionWithKeywords)meth)(self, arg, kw) )
    case METH_NOARGS:
        if (kw == NULL || PyDict_Size(kw) == 0) {
            size = PyTuple_GET_SIZE(arg);
            if (size == 0)
                WRAP_RETURN( (*meth)(self, NULL) )
            PyErr_Format(PyExc_TypeError,
                "%.200s() takes no arguments (%zd given)",
                f->m_ml->ml_name, size);
            return NULL;
        }
        break;
    case METH_O:
        if (kw == NULL || PyDict_Size(kw) == 0) {
            size = PyTuple_GET_SIZE(arg);
            if (size == 1)
                WRAP_RETURN( (*meth)(self, PyTuple_GET_ITEM(arg, 0)) )
            PyErr_Format(PyExc_TypeError,
                "%.200s() takes exactly one argument (%zd given)",
                f->m_ml->ml_name, size);
            return NULL;
        }
        break;
    default:
        PyErr_SetString(PyExc_SystemError, "Bad call flags in "
                "PyCFunction_Call. METH_OLDARGS is no "
                "longer supported!");
            
        return NULL;
    }
    PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
             f->m_ml->ml_name);
    return NULL;
}

/* Methods (the standard built-in methods, that is) */

static void
meth_dealloc(PyCFunctionObject *m)
{
    _PyObject_GC_UNTRACK(m);
    Py_XDECREF(m->m_self);
    Py_XDECREF(m->m_module);
    if (numfree < PyCFunction_MAXFREELIST) {
        m->m_self = (PyObject *)free_list;
        free_list = m;
        numfree++;
    }
    else {
        PyObject_GC_Del(m);
    }
}
PyObject *
PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
{
	STACKLESS_GETARG();
	PyCFunctionObject* f = (PyCFunctionObject*)func;
	PyCFunction meth = PyCFunction_GET_FUNCTION(func);
	PyObject *self = PyCFunction_GET_SELF(func);
	Py_ssize_t size;

#ifdef STACKLESS
	switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS)) {
#else
	switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
#endif
	case METH_VARARGS:
		if (kw == NULL || PyDict_Size(kw) == 0)
			WRAP_RETURN( (*meth)(self, arg) )
		break;
	case METH_VARARGS | METH_KEYWORDS:
	case METH_OLDARGS | METH_KEYWORDS:
		WRAP_RETURN( (*(PyCFunctionWithKeywords)meth)(self, arg, kw) )
	case METH_NOARGS:
		if (kw == NULL || PyDict_Size(kw) == 0) {
			size = PyTuple_GET_SIZE(arg);
			if (size == 0)
				WRAP_RETURN( (*meth)(self, NULL) )
			PyErr_Format(PyExc_TypeError,
			    "%.200s() takes no arguments (%zd given)",
			    f->m_ml->ml_name, size);
			return NULL;
		}
		break;
	case METH_O:
		if (kw == NULL || PyDict_Size(kw) == 0) {
			size = PyTuple_GET_SIZE(arg);
			if (size == 1)
				WRAP_RETURN( (*meth)(self, PyTuple_GET_ITEM(arg, 0)) )
			PyErr_Format(PyExc_TypeError,
			    "%.200s() takes exactly one argument (%zd given)",
			    f->m_ml->ml_name, size);
			return NULL;
		}
		break;
	case METH_OLDARGS:
		/* the really old style */
		if (kw == NULL || PyDict_Size(kw) == 0) {
			size = PyTuple_GET_SIZE(arg);
			if (size == 1)
				arg = PyTuple_GET_ITEM(arg, 0);
			else if (size == 0)
				arg = NULL;
			WRAP_RETURN( (*meth)(self, arg) )
		}
		break;
	default:
		PyErr_BadInternalCall();
		return NULL;
	}
	PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
		     f->m_ml->ml_name);
	return NULL;
}