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; }
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; }
/** * 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; }
List &List::operator+=(const List &rhs) { PyObject *obj = PySequence_InPlaceConcat(mPtr, rhs.borrowReference()); PW_PyExcept_Check("List::operator+="); Py_DECREF(obj); return *this; }
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; }
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; }
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; }