cinap_lenrekadd hg and python4bb9e2215 years agoHistory
941 lines · 28.6 KB · C
RawDownload
WRAP_BINARY(proxy_ixor, PyNumber_InPlaceXor)WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr) static intproxy_nonzero(PyWeakReference *proxy){    PyObject *o = PyWeakref_GET_OBJECT(proxy);    if (!proxy_checkref(proxy))        return -1;    return PyObject_IsTrue(o);} static voidproxy_dealloc(PyWeakReference *self){    if (self->wr_callback != NULL)        PyObject_GC_UnTrack((PyObject *)self);    clear_weakref(self);    PyObject_GC_Del(self);} /* sequence slots */ static PyObject *proxy_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j){    if (!proxy_checkref(proxy))        return NULL;    return PySequence_GetSlice(PyWeakref_GET_OBJECT(proxy), i, j);} static intproxy_ass_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j, PyObject *value){    if (!proxy_checkref(proxy))        return -1;    return PySequence_SetSlice(PyWeakref_GET_OBJECT(proxy), i, j, value);} static intproxy_contains(PyWeakReference *proxy, PyObject *value){    if (!proxy_checkref(proxy))        return -1;    return PySequence_Contains(PyWeakref_GET_OBJECT(proxy), value);}  /* mapping slots */ static Py_ssize_tproxy_length(PyWeakReference *proxy){    if (!proxy_checkref(proxy))        return -1;    return PyObject_Length(PyWeakref_GET_OBJECT(proxy));} WRAP_BINARY(proxy_getitem, PyObject_GetItem) static intproxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value){    if (!proxy_checkref(proxy))        return -1;     if (value == NULL)        return PyObject_DelItem(PyWeakref_GET_OBJECT(proxy), key);    else        return PyObject_SetItem(PyWeakref_GET_OBJECT(proxy), key, value);} /* iterator slots */ static PyObject *proxy_iter(PyWeakReference *proxy){    if (!proxy_checkref(proxy))        return NULL;    return PyObject_GetIter(PyWeakref_GET_OBJECT(proxy));} static PyObject *proxy_iternext(PyWeakReference *proxy){    if (!proxy_checkref(proxy))        return NULL;    return PyIter_Next(PyWeakref_GET_OBJECT(proxy));}  static PyNumberMethods proxy_as_number = {    proxy_add,              /*nb_add*/    proxy_sub,              /*nb_subtract*/    proxy_mul,              /*nb_multiply*/    proxy_div,              /*nb_divide*/    proxy_mod,              /*nb_remainder*/    proxy_divmod,           /*nb_divmod*/    proxy_pow,              /*nb_power*/    proxy_neg,              /*nb_negative*/    proxy_pos,              /*nb_positive*/    proxy_abs,              /*nb_absolute*/    (inquiry)proxy_nonzero, /*nb_nonzero*/    proxy_invert,           /*nb_invert*/    proxy_lshift,           /*nb_lshift*/    proxy_rshift,           /*nb_rshift*/    proxy_and,              /*nb_and*/    proxy_xor,              /*nb_xor*/    proxy_or,               /*nb_or*/    0,                      /*nb_coerce*/    proxy_int,              /*nb_int*/    proxy_long,             /*nb_long*/    proxy_float,            /*nb_float*/    0,                      /*nb_oct*/    0,                      /*nb_hex*/    proxy_iadd,             /*nb_inplace_add*/    proxy_isub,             /*nb_inplace_subtract*/    proxy_imul,             /*nb_inplace_multiply*/    proxy_idiv,             /*nb_inplace_divide*/    proxy_imod,             /*nb_inplace_remainder*/    proxy_ipow,             /*nb_inplace_power*/    proxy_ilshift,          /*nb_inplace_lshift*/    proxy_irshift,          /*nb_inplace_rshift*/    proxy_iand,             /*nb_inplace_and*/    proxy_ixor,             /*nb_inplace_xor*/    proxy_ior,              /*nb_inplace_or*/}; static PySequenceMethods proxy_as_sequence = {    (lenfunc)proxy_length,      /*sq_length*/    0,                          /*sq_concat*/    0,                          /*sq_repeat*/    0,                          /*sq_item*/    (ssizessizeargfunc)proxy_slice, /*sq_slice*/    0,                          /*sq_ass_item*/    (ssizessizeobjargproc)proxy_ass_slice, /*sq_ass_slice*/    (objobjproc)proxy_contains, /* sq_contains */}; static PyMappingMethods proxy_as_mapping = {    (lenfunc)proxy_length,        /*mp_length*/    proxy_getitem,                /*mp_subscript*/    (objobjargproc)proxy_setitem, /*mp_ass_subscript*/};  PyTypeObject_PyWeakref_ProxyType = {    PyObject_HEAD_INIT(&PyType_Type)    0,    "weakproxy",    sizeof(PyWeakReference),    0,    /* methods */    (destructor)proxy_dealloc,          /* tp_dealloc */    0,				        /* tp_print */    0,				        /* tp_getattr */    0, 				        /* tp_setattr */    proxy_compare,		        /* tp_compare */    (reprfunc)proxy_repr,	        /* tp_repr */    &proxy_as_number,		        /* tp_as_number */    &proxy_as_sequence,		        /* tp_as_sequence */    &proxy_as_mapping,		        /* tp_as_mapping */    0,	                                /* tp_hash */    0,	                                /* tp_call */    proxy_str,                          /* tp_str */    proxy_getattr,                      /* tp_getattro */    (setattrofunc)proxy_setattr,        /* tp_setattro */    0,				        /* tp_as_buffer */    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC    | Py_TPFLAGS_CHECKTYPES,            /* tp_flags */    0,                                  /* tp_doc */    (traverseproc)gc_traverse,          /* tp_traverse */    (inquiry)gc_clear,                  /* tp_clear */    0,                                  /* tp_richcompare */    0,                                  /* tp_weaklistoffset */    (getiterfunc)proxy_iter,            /* tp_iter */    (iternextfunc)proxy_iternext,       /* tp_iternext */};  PyTypeObject_PyWeakref_CallableProxyType = {    PyObject_HEAD_INIT(&PyType_Type)    0,    "weakcallableproxy",    sizeof(PyWeakReference),    0,    /* methods */    (destructor)proxy_dealloc,          /* tp_dealloc */    0,				        /* tp_print */    0,				        /* tp_getattr */    0, 				        /* tp_setattr */    proxy_compare,		        /* tp_compare */    (unaryfunc)proxy_repr,	        /* tp_repr */    &proxy_as_number,		        /* tp_as_number */    &proxy_as_sequence,		        /* tp_as_sequence */    &proxy_as_mapping,		        /* tp_as_mapping */    0,	                                /* tp_hash */    proxy_call,	                        /* tp_call */    proxy_str,	                        /* tp_str */    proxy_getattr,                      /* tp_getattro */    (setattrofunc)proxy_setattr,        /* tp_setattro */    0,				        /* tp_as_buffer */    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC    | Py_TPFLAGS_CHECKTYPES,            /* tp_flags */    0,                                  /* tp_doc */    (traverseproc)gc_traverse,          /* tp_traverse */    (inquiry)gc_clear,                  /* tp_clear */    0,                                  /* tp_richcompare */    0,                                  /* tp_weaklistoffset */    (getiterfunc)proxy_iter,            /* tp_iter */    (iternextfunc)proxy_iternext,       /* tp_iternext */};   PyObject *PyWeakref_NewRef(PyObject *ob, PyObject *callback){    PyWeakReference *result = NULL;    PyWeakReference **list;    PyWeakReference *ref, *proxy;     if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) {        PyErr_Format(PyExc_TypeError,		     "cannot create weak reference to '%s' object",                     ob->ob_type->tp_name);        return NULL;    }    list = GET_WEAKREFS_LISTPTR(ob);    get_basic_refs(*list, &ref, &proxy);    if (callback == Py_None)        callback = NULL;    if (callback == NULL)        /* return existing weak reference if it exists */        result = ref;    if (result != NULL)        Py_INCREF(result);    else {        /* Note: new_weakref() can trigger cyclic GC, so the weakref           list on ob can be mutated.  This means that the ref and           proxy pointers we got back earlier may have been collected,           so we need to compute these values again before we use           them. */        result = new_weakref(ob, callback);        if (result != NULL) {            get_basic_refs(*list, &ref, &proxy);            if (callback == NULL) {                if (ref == NULL)                    insert_head(result, list);                else {                    /* Someone else added a ref without a callback                       during GC.  Return that one instead of this one                       to avoid violating the invariants of the list                       of weakrefs for ob. */                    Py_DECREF(result);                    Py_INCREF(ref);                    result = ref;                }            }            else {                PyWeakReference *prev;                 prev = (proxy == NULL) ? ref : proxy;                if (prev == NULL)                    insert_head(result, list);                else                    insert_after(result, prev);            }        }    }    return (PyObject *) result;}  PyObject *PyWeakref_NewProxy(PyObject *ob, PyObject *callback){    PyWeakReference *result = NULL;    PyWeakReference **list;    PyWeakReference *ref, *proxy;     if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) {        PyErr_Format(PyExc_TypeError,		     "cannot create weak reference to '%s' object",                     ob->ob_type->tp_name);        return NULL;    }    list = GET_WEAKREFS_LISTPTR(ob);    get_basic_refs(*list, &ref, &proxy);    if (callback == Py_None)        callback = NULL;    if (callback == NULL)        /* attempt to return an existing weak reference if it exists */        result = proxy;    if (result != NULL)        Py_INCREF(result);    else {        /* Note: new_weakref() can trigger cyclic GC, so the weakref           list on ob can be mutated.  This means that the ref and           proxy pointers we got back earlier may have been collected,           so we need to compute these values again before we use           them. */        result = new_weakref(ob, callback);        if (result != NULL) {            PyWeakReference *prev;             if (PyCallable_Check(ob))                result->ob_type = &_PyWeakref_CallableProxyType;            else                result->ob_type = &_PyWeakref_ProxyType;            get_basic_refs(*list, &ref, &proxy);            if (callback == NULL) {                if (proxy != NULL) {                    /* Someone else added a proxy without a callback                       during GC.  Return that one instead of this one                       to avoid violating the invariants of the list                       of weakrefs for ob. */                    Py_DECREF(result);                    Py_INCREF(result = proxy);                    goto skip_insert;                }                prev = ref;            }            else                prev = (proxy == NULL) ? ref : proxy;             if (prev == NULL)                insert_head(result, list);            else                insert_after(result, prev);        skip_insert:            ;        }    }    return (PyObject *) result;}  PyObject *PyWeakref_GetObject(PyObject *ref){    if (ref == NULL || !PyWeakref_Check(ref)) {        PyErr_BadInternalCall();        return NULL;    }    return PyWeakref_GET_OBJECT(ref);} /* Note that there's an inlined copy-paste of handle_callback() in gcmodule.c's * handle_weakrefs(). */static voidhandle_callback(PyWeakReference *ref, PyObject *callback){    PyObject *cbresult = PyObject_CallFunctionObjArgs(callback, ref, NULL);     if (cbresult == NULL)        PyErr_WriteUnraisable(callback);    else        Py_DECREF(cbresult);} /* This function is called by the tp_dealloc handler to clear weak references. * * This iterates through the weak references for 'object' and calls callbacks * for those references which have one.  It returns when all callbacks have * been attempted. */voidPyObject_ClearWeakRefs(PyObject *object){    PyWeakReference **list;     if (object == NULL        || !PyType_SUPPORTS_WEAKREFS(object->ob_type)        || object->ob_refcnt != 0) {        PyErr_BadInternalCall();        return;    }    list = GET_WEAKREFS_LISTPTR(object);    /* Remove the callback-less basic and proxy references */    if (*list != NULL && (*list)->wr_callback == NULL) {        clear_weakref(*list);        if (*list != NULL && (*list)->wr_callback == NULL)            clear_weakref(*list);    }    if (*list != NULL) {        PyWeakReference *current = *list;        Py_ssize_t count = _PyWeakref_GetWeakrefCount(current);        int restore_error = PyErr_Occurred() ? 1 : 0;        PyObject *err_type, *err_value, *err_tb;         if (restore_error)            PyErr_Fetch(&err_type, &err_value, &err_tb);        if (count == 1) {            PyObject *callback = current->wr_callback;             current->wr_callback = NULL;            clear_weakref(current);            if (callback != NULL) {                handle_callback(current, callback);                Py_DECREF(callback);            }        }        else {            PyObject *tuple;            Py_ssize_t i = 0;                tuple = PyTuple_New(count * 2);            if (tuple == NULL) {                if (restore_error)                    PyErr_Fetch(&err_type, &err_value, &err_tb);                return;            }             for (i = 0; i < count; ++i) {                PyWeakReference *next = current->wr_next;                 Py_INCREF(current);                PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);                PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);                current->wr_callback = NULL;                clear_weakref(current);                current = next;            }            for (i = 0; i < count; ++i) {                PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);                 if (callback != NULL) {                    PyObject *item = PyTuple_GET_ITEM(tuple, i * 2);                    handle_callback((PyWeakReference *)item, callback);                }            }            Py_DECREF(tuple);        }        if (restore_error)            PyErr_Restore(err_type, err_value, err_tb);    }}

Lines 501–941 of 941. Previous lines