bool BINARY_OPERATION_ADD_TUPLE_OBJECT_INPLACE(PyObject **operand1, PyObject *operand2) {
    assert(operand1);
    CHECK_OBJECT(*operand1);
    CHECK_OBJECT(operand2);
    assert(PyTuple_CheckExact(*operand1));

    PyObject *result;

    if (PyTuple_CheckExact(operand2)) {
        // TODO: No tuple specific code, create one and use it, although it
        // is probably not too common to in-place to them.
        result = PySequence_InPlaceConcat(*operand1, operand2);
    } else if (PySequence_Check(operand2)) {
        result = PySequence_InPlaceConcat(*operand1, operand2);
    } else {
        result = PyNumber_InPlaceAdd(*operand1, operand2);
    }

    if (unlikely(result == NULL)) {
        return false;
    }

    // We got an object handed, that we have to release.
    Py_DECREF(*operand1);

    // That's our return value then. As we use a dedicated variable, it's
    // OK that way.
    *operand1 = result;

    return true;
}
Пример #2
0
static PyObject *t_sequence_seq_inplace_concat(t_sequence *self,
                                               PyObject *values)
{
    PyObject *result;

    if (self->itemvalue.flags & V_PURE)
        result = PySequence_InPlaceConcat(self->sequence, values);
    else
    {
        values = _prepareValues((t_itemvalue *) self, values);
        if (!values)
            return NULL;

        result = PySequence_InPlaceConcat(self->sequence, values);
        Py_DECREF(values);
    }

    if (!result)
        return NULL;

    if (result == self->sequence)
    {
        if (_t_itemvalue__setDirty((t_itemvalue *) self, 0) < 0)
        {
            Py_DECREF(result);
            return NULL;
        }

        Py_DECREF(result);
        Py_INCREF((PyObject *) self);
        result = (PyObject *) self;
    }
     
    return result;
}
Пример #3
0
/**
 * Extends __dir__ with the extra attributes accessible through
 * resulttuple_getattro()
 */
static PyObject *
resulttuple_dir(PyObject *self)
{
    PyObject *mapping_attr;
    PyObject *items = NULL;
    PyObject *mapping = NULL;
    PyObject *mapping_values = NULL;
    PyObject *result = NULL;

    mapping_attr = PYGLIB_PyUnicode_FromString (tuple_indices_key);
    mapping = PyTuple_Type.tp_getattro (self, mapping_attr);
    Py_DECREF (mapping_attr);
    if (mapping == NULL)
        goto error;
    items = PyObject_Dir ((PyObject*)self->ob_type);
    if (items == NULL)
        goto error;
    mapping_values = PyDict_Keys (mapping);
    if (mapping_values == NULL)
        goto error;
    result = PySequence_InPlaceConcat (items, mapping_values);

error:
    Py_XDECREF (items);
    Py_XDECREF (mapping);
    Py_XDECREF (mapping_values);

    return result;
}
bool BINARY_OPERATION_ADD_OBJECT_LIST_INPLACE(PyObject **operand1, PyObject *operand2) {
    assert(operand1);
    CHECK_OBJECT(*operand1);
    CHECK_OBJECT(operand2);
    assert(PyList_CheckExact(operand2));

    PyObject *result;

    if (PyList_CheckExact(*operand1)) {
        return LIST_EXTEND_FROM_LIST(*operand1, operand2);
    } else if (PySequence_Check(*operand1)) {
        result = PySequence_InPlaceConcat(*operand1, operand2);
    } else {
        result = PyNumber_InPlaceAdd(*operand1, operand2);
    }

    if (unlikely(result == NULL)) {
        return false;
    }

    // We got an object handed, that we have to release.
    Py_DECREF(*operand1);

    // That's our return value then. As we use a dedicated variable, it's
    // OK that way.
    *operand1 = result;

    return true;
}
Пример #5
0
    List &List::operator+=(const List &rhs)
    {
        PyObject *obj = PySequence_InPlaceConcat(mPtr, rhs.borrowReference());
        PW_PyExcept_Check("List::operator+=");
        Py_DECREF(obj);

        return *this;
    }
Пример #6
0
static PyObject *t_sequence_extend(t_sequence *self, PyObject *args)
{
    PyObject *values, *result;
    int setDirty = 1;

    if (!PyArg_ParseTuple(args, "O|i", &values, &setDirty))
        return NULL;

    if (self->itemvalue.flags & V_PURE)
        result = PySequence_InPlaceConcat(self->sequence, values);
    else
    {
        values = _prepareValues((t_itemvalue *) self, values);
        if (!values)
            return NULL;
        result = PySequence_InPlaceConcat(self->sequence, values);
        Py_DECREF(values);
    }

    if (!result)
        return NULL;

    if (result == self->sequence)
    {
        if (setDirty && _t_itemvalue__setDirty((t_itemvalue *) self, 0) < 0)
        {
            Py_DECREF(result);
            return NULL;
        }

        Py_DECREF(result);
        Py_RETURN_NONE;
    }

    Py_DECREF(result);
    PyErr_SetString(PyExc_NotImplementedError, "in-place concat");

    return NULL;
}
Пример #7
0
PyObject* fastdraw (PyObject* self, PyObject* args) {
    // don't do much error checking because the point of this is performance
    // and we own the class calling this; guaranteed to get
    // [obj], pygame.Surface, {obj: set(Graphic)}, [pygame.Rect]
    // and layers is sorted
    PyObject* layers_in, * sfc, * graphics_in, * dirty;
    PyObject** layers, *** graphics, ** gs, * g, * g_dirty, * g_rect, * r_o,
            ** graphics_obj, * tmp, * pre_draw, * clip, * dbl_tmp[2], * rtn,
            * opaque_in, * dirty_opaque, * l_dirty_opaque, ** dirty_by_layer,
            * rs, * draw_in, * draw;
    char* dbl[4] = {"was_visible", "visible", "_last_postrot_rect",
                    "_postrot_rect"};
    int n_layers, * n_graphics, i, j, k, l, n, n_dirty, r_new, r_good;
    PyRectObject* r, * tmp_r;
    if (!PyArg_UnpackTuple(args, "fastdraw", 4, 4, &layers_in, &sfc,
                           &graphics_in, &dirty))
        return NULL;

    pre_draw = PyString_FromString("_pre_draw"); // NOTE: ref[+1a]
    clip = PyString_FromString("clip"); // NOTE: ref[+1b]
    // get arrays of layers, graphics and sizes
    // NOTE: ref[+2]
    layers_in = PySequence_Fast(layers_in, "layers: expected sequence");
    n_layers = PySequence_Fast_GET_SIZE(layers_in);
    layers = PySequence_Fast_ITEMS(layers_in);
    graphics_obj = PyMem_New(PyObject*, n_layers); // NOTE: alloc[+1]
    n_graphics = PyMem_New(int, n_layers); // NOTE: alloc[+2]
    graphics = PyMem_New(PyObject**, n_layers); // NOTE: alloc[+3]
    for (i = 0; i < n_layers; i++) { // graphics_in
        // NOTE: ref[+3]
        tmp = PySequence_Fast(PyDict_GetItem(graphics_in, layers[i]),
                              "graphics values: expected sequence");
        // need to keep it around since graphics references its array
        graphics_obj[i] = tmp;
        n_graphics[i] = PySequence_Fast_GET_SIZE(tmp);
        graphics[i] = PySequence_Fast_ITEMS(tmp);
    }
    // get dirty rects from graphics
    for (i = 0; i < n_layers; i++) { // graphics
        gs = graphics[i];
        for (j = 0; j < n_graphics[i]; j++) { // gs
            g = gs[j];
            PyObject_CallMethodObjArgs(g, pre_draw, NULL);
            // NOTE: ref[+4] (list)
            g_dirty = PyObject_GetAttrString(g, "_dirty");
            for (k = 0; k < 2; k++) // last/current
                // NOTE: ref[+5]
                dbl_tmp[k] = PyObject_GetAttrString(g, dbl[k]);
            if (dbl_tmp[0] != dbl_tmp[1]) {
                // visiblity changed since last draw: set dirty everywhere
                Py_DECREF(g_dirty); // NOTE: ref[-4]
                g_dirty = PyList_New(1); // NOTE: ref[+4]
                // NOTE: ref[+6]
                g_rect = PyObject_GetAttrString(g, "_postrot_rect");
                PyList_SET_ITEM(g_dirty, 0, g_rect); // NOTE: ref[-6]
                PyObject_SetAttrString(g, "_dirty", g_dirty);
            }
            n = PyList_GET_SIZE(g_dirty);
            for (k = 0; k < 2; k++) { // last/current
                if (dbl_tmp[k] == Py_True) {
                    // NOTE: ref[+6] (pygame.Rect)
                    g_rect = PyObject_GetAttrString(g, dbl[k + 2]);
                    for (l = 0; l < n; l++) { // g_dirty
                        r_o = PyList_GET_ITEM(g_dirty, l); // pygame.Rect
                        // NOTE: ref[+7]
                        r_o = PyObject_CallMethodObjArgs(r_o, clip, g_rect,
                                                         NULL);
                        PyList_Append(dirty, r_o);
                        Py_DECREF(r_o); // NOTE: ref[-7]
                    }
                    Py_DECREF(g_rect); // NOTE: ref[-6]
                }
            }
            Py_DECREF(dbl_tmp[0]);
            Py_DECREF(dbl_tmp[1]); // NOTE: ref[-5]
            Py_DECREF(g_dirty); // NOTE: ref[-4]
            tmp = PyObject_GetAttrString(g, "visible"); // NOTE: ref[+4]
            PyObject_SetAttrString(g, "was_visible", tmp);
            Py_DECREF(tmp); // NOTE: ref[-4]
        }
    }

    // only have something to do if dirty is non-empty
    rtn = Py_False;
    Py_INCREF(rtn); // since we're (possibly) returning it
    n_dirty = PyList_GET_SIZE(dirty);
    if (PyList_GET_SIZE(dirty) == 0) {
        goto end;
    }

    opaque_in = PyString_FromString("opaque_in"); // NOTE: ref[+4]
    dirty_opaque = PyList_New(0); // NOTE: ref[+5]
    dirty_by_layer = PyMem_New(PyObject*, n_layers); // NOTE: alloc[+4]
    for (i = 0; i < n_layers; i++) { // graphics
        gs = graphics[i];
        n = n_graphics[i];
        // get opaque regions of dirty rects
        l_dirty_opaque = PyList_New(0); // NOTE: ref[+6]
        for (j = 0; j < n_dirty; j++) { // dirty
            r = (PyRectObject*) PyList_GET_ITEM(dirty, j); // pygame.Rect
            r_new = 0;
            r_good = 1;
            for (k = 0; k < n; k++) { // gs
                g = gs[k];
                // NOTE: ref[+7]
                g_rect = PyObject_GetAttrString(g, "_postrot_rect");
                if (r_new) tmp_r = r;
                // NOTE: ref[+8]
                r = (PyRectObject*)
                    PyObject_CallMethodObjArgs((PyObject*) r, clip, g_rect,
                                               NULL);
                if (r_new) Py_DECREF(tmp_r); // NOTE: ref[-8](k>0)
                r_new = 1;
                Py_DECREF(g_rect); // NOTE: ref[-7]
                // NOTE: ref[+7]
                tmp = PyObject_CallMethodObjArgs(g, opaque_in, (PyObject*) r,
                                                 NULL);
                r_good = r->r.w > 0 && r->r.h > 0 && tmp == Py_True;
                Py_DECREF(tmp); // NOTE: ref[-7]
                if (!r_good) break;
            }
            if (r_good) PyList_Append(l_dirty_opaque, (PyObject*) r);
            if (r_new) Py_DECREF((PyObject*) r); // NOTE: ref[-8](k=0)
        }
        // undirty below opaque graphics and make dirty rects disjoint
        // NOTE: ref[+7]
        dirty_by_layer[i] = mk_disjoint(dirty, dirty_opaque);
        tmp = dirty_opaque;
        // NOTE: ref[+8] (not sure why this returns a new reference)
        dirty_opaque = PySequence_InPlaceConcat(dirty_opaque, l_dirty_opaque);
        Py_DECREF(tmp); // NOTE: ref[-5] ref[-8+5]
        Py_DECREF(l_dirty_opaque); // NOTE: ref[-6] ref[-7+6]
    }

    draw = PyString_FromString("_draw"); // NOTE: ref[+7]
    // redraw in dirty rects
    for (i = n_layers - 1; i >= 0; i--) { // layers
        rs = dirty_by_layer[i];
        n = PyList_GET_SIZE(rs);
        gs = graphics[i];
        for (j = 0; j < n_graphics[i]; j++) { // gs
            g = gs[j];
            tmp = PyObject_GetAttrString(g, "visible"); // NOTE: ref[+8]
            if (tmp == Py_True) {
                // NOTE: ref[+9]
                g_rect = PyObject_GetAttrString(g, "_postrot_rect");
                draw_in = PyList_New(0); // NOTE: ref[+10]
                for (k = 0; k < n; k++) { // rs
                    r = (PyRectObject*) PyList_GET_ITEM(rs, k);
                    // NOTE: ref[+11]
                    r = (PyRectObject*)
                        PyObject_CallMethodObjArgs(g_rect, clip, r, NULL);
                    if (r->r.w > 0 && r->r.h > 0)
                        PyList_Append(draw_in, (PyObject*) r);
                    Py_DECREF(r); // NOTE: ref[-11]
                }
                if (PyList_GET_SIZE(draw_in) > 0) {
                    PyObject_CallMethodObjArgs(g, draw, sfc, draw_in, NULL);
                }
                Py_DECREF(draw_in); // NOTE: ref[-10]
                Py_DECREF(g_rect); // NOTE: ref[-9]
            }
            Py_DECREF(tmp); // ref[-8]
            tmp = PyList_New(0); // NOTE: ref[+8]
            PyObject_SetAttrString(g, "_dirty", tmp);
            Py_DECREF(tmp); // NOTE: ref[-8]
        }
    }

    // add up dirty rects to return
    Py_DECREF(rtn);
    rtn = PyList_New(0);
    for (i = 0; i < n_layers; i++) { // dirty_by_layer
        tmp = rtn;
        // NOTE: ref[+8] (not sure why this returns a new reference)
        rtn = PySequence_InPlaceConcat(rtn, dirty_by_layer[i]);
        Py_DECREF(tmp); // NOTE: ref[-8]
    }

    // cleanup (in reverse order)
    Py_DECREF(draw); // NOTE: ref[-7]
    // NOTE: ref[-6]
    for (i = 0; i < n_layers; i++) Py_DECREF(dirty_by_layer[i]);
    PyMem_Free(dirty_by_layer); // NOTE: alloc[-4]
    Py_DECREF(dirty_opaque); // NOTE: ref[-5]
    Py_DECREF(opaque_in); // NOTE: ref[-4]
end:
    for (i = 0; i < n_layers; i++) Py_DECREF(graphics_obj[i]); // NOTE: ref[-3]
    PyMem_Free(graphics); // NOTE: alloc[-3]
    PyMem_Free(n_graphics); // NOTE: alloc[-2]
    PyMem_Free(graphics_obj); // NOTE: alloc[-1]
    Py_DECREF(layers_in); // NOTE: ref[-2]
    Py_DECREF(clip); // NOTE: ref[-1b]
    Py_DECREF(pre_draw); // NOTE: ref[-1a]
    return rtn;
}
Пример #8
0
static PyObject *cdefer_Deferred__runCallbacks(cdefer_Deferred *self) {
    PyObject *cb;
    PyObject *item;
    PyObject *callbacktuple;
    PyObject *callback;
    PyObject *args;
    PyObject *newArgs;
    PyObject *newArgs2;
    PyObject *kwargs;
    PyObject *_continue;
    PyObject *type, *value, *traceback;
    PyObject *tmp;
    PyObject *result;
    int size;
    int offset;
    const char *callback_name;

    if (self->running_callbacks) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    if (!self->paused) {
        cb = self->callbacks;

        if (!PyList_Check(cb)) {
            PyErr_SetString(PyExc_TypeError, "callbacks must be a list");
            return NULL;
        }

        for (;;) {
            size = PyList_GET_SIZE(cb);
            if (size == -1) {
                return NULL;
            }
            if (self->callback_index >= size) {
                break;
            }

            item = PyList_GET_ITEM(cb, self->callback_index);
            if (!item) {
                return NULL;
            }
            if (cdefer_Deferred__verify_callbacks_item(item)) {
                return NULL;
            }

            if (PyObject_IsInstance(self->result, failure_class)) {
                offset = 1;
                callback_name = "errback";
            } else {
                offset = 0;
                callback_name = "callback";
            }

            callbacktuple = PyTuple_GET_ITEM(item, offset);
            if (!callbacktuple) {
                return NULL;
            }

            if (cdefer_Deferred__verify_callback_entry(callback_name, callbacktuple)) {
                return NULL;
            }

            callback = PyTuple_GET_ITEM(callbacktuple, 0);
            if(!callback) {
                return NULL;
            }

            if (callback == Py_None) {
                ++self->callback_index;
                continue;
            }

            args = PyTuple_GET_ITEM(callbacktuple, 1);
            if (!args) {
                return NULL;
            }

            kwargs = PyTuple_GET_ITEM(callbacktuple, 2);
            if (!kwargs) {
                return NULL;
            }

            newArgs = Py_BuildValue("(O)", self->result);
            if (!newArgs) {
                return NULL;
            }

            if (args != Py_None) {
                newArgs2 = PySequence_InPlaceConcat(newArgs, args);
                Py_CLEAR(newArgs);
                if (!newArgs2) {
                    return NULL;
                }
            } else {
                newArgs2 = newArgs;
                newArgs = NULL;
            }

            ++self->callback_index;
            if (kwargs == Py_None) {
                kwargs = NULL;
            }
            self->running_callbacks = 1;
            tmp = PyObject_Call(callback, newArgs2, kwargs);
            self->running_callbacks = 0;
            Py_DECREF(self->result);
            self->result = tmp;

            Py_CLEAR(newArgs2);

            if (!self->result) {
                PyErr_Fetch(&type, &value, &traceback);
                PyErr_NormalizeException(&type, &value, &traceback);
                if (!traceback) {
                    traceback = Py_None;
                    Py_INCREF(traceback);
                }

                self->result = PyObject_CallFunction(failure_class, "OOO", value, type, traceback);
                if (!self->result) {
                    PyErr_Restore(type, value, traceback);
                    return NULL;
                }
                Py_DECREF(type);
                Py_DECREF(value);
                Py_DECREF(traceback);
                continue;
            }
            if (PyObject_TypeCheck(self->result, &cdefer_DeferredType)) {
                PyObject *self_result;

                if (PyList_SetSlice(cb, 0, self->callback_index, NULL) == -1) {
                    return NULL;
                }
                self->callback_index = 0;

                result = PyObject_CallMethod((PyObject *)self, "pause", NULL);
                if (!result) {
                    return NULL;
                }
                Py_DECREF(result);

                _continue = PyObject_GetAttrString((PyObject *)self,
                                                   "_continue");
                if (!_continue) {
                    return NULL;
                }

                self_result = self->result;
                Py_INCREF(self_result);
                result = cdefer_Deferred__addCallbacks(
                    (cdefer_Deferred *)self->result, _continue,
                    _continue, Py_None, Py_None, Py_None, Py_None);
                Py_DECREF(self_result);
                /* The reference was either copied/incref'd or not
                 * (when errored) in addCallbacks, either way, we own
                 * one too, and don't need it anymore. */
                Py_DECREF(_continue);

                if (!result) {
                    return NULL;
                }
                Py_DECREF(result);

                goto endLabel;
            }
        }
        if (PyList_SetSlice(cb, 0, PyList_GET_SIZE(cb), NULL) == -1) {
            return NULL;
        }
        self->callback_index = 0;
    }
endLabel:
    if (PyObject_IsInstance(self->result, failure_class)) {
        result = PyObject_CallMethod((PyObject *)self->result,
                                     "cleanFailure", NULL);
        if (!result) {
            return NULL;
        }
        Py_DECREF(result);
        if (cdefer_Deferred__set_debuginfo_fail_result(self) == -1) {
            return NULL;
        }
    } else {
        if (cdefer_Deferred__clear_debuginfo(self) == -1) {
            return NULL;
        }
    }
    Py_INCREF(Py_None);
    return Py_None;
}