int _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) { PyTupleObject *v; PyTupleObject *sv; Py_ssize_t i; Py_ssize_t oldsize; v = (PyTupleObject *) *pv; if (v == NULL || Py_TYPE(v) != &PyTuple_Type || (Py_SIZE(v) != 0 && Py_REFCNT(v) != 1)) { *pv = 0; Py_XDECREF(v); PyErr_BadInternalCall(); return -1; } oldsize = Py_SIZE(v); if (oldsize == newsize) return 0; if (oldsize == 0) { /* Empty tuples are often shared, so we should never resize them in-place even if we do own the only (current) reference */ Py_DECREF(v); *pv = PyTuple_New(newsize); return *pv == NULL ? -1 : 0; } /* XXX UNREF/NEWREF interface should be more symmetrical */ _Py_DEC_REFTOTAL; if (_PyObject_GC_IS_TRACKED(v)) _PyObject_GC_UNTRACK(v); _Py_ForgetReference((PyObject *) v); /* DECREF items deleted by shrinkage */ for (i = newsize; i < oldsize; i++) { Py_XDECREF(v->ob_item[i]); v->ob_item[i] = NULL; } sv = PyObject_GC_Resize(PyTupleObject, v, newsize); if (sv == NULL) { *pv = NULL; PyObject_GC_Del(v); return -1; } _Py_NewReference((PyObject *) sv); /* Zero out items added by growing */ if (newsize > oldsize) memset(&sv->ob_item[oldsize], 0, sizeof(*sv->ob_item) * (newsize - oldsize)); *pv = (PyObject *) sv; _PyObject_GC_TRACK(sv); return 0; }
PyFrameObject * PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, PyObject *locals) { PyFrameObject *back = tstate->frame; PyFrameObject *f; PyObject *builtins; Py_ssize_t i; #ifdef Py_DEBUG if (code == NULL || globals == NULL || !PyDict_Check(globals) || (locals != NULL && !PyMapping_Check(locals))) { PyErr_BadInternalCall(); return NULL; } #endif if (back == NULL || back->f_globals != globals) { builtins = PyDict_GetItem(globals, builtin_object); if (builtins) { if (PyModule_Check(builtins)) { builtins = PyModule_GetDict(builtins); assert(!builtins || PyDict_Check(builtins)); } else if (!PyDict_Check(builtins)) builtins = NULL; } if (builtins == NULL) { /* No builtins! Make up a minimal one Give them 'None', at least. */ builtins = PyDict_New(); if (builtins == NULL || PyDict_SetItemString( builtins, "None", Py_None) < 0) return NULL; } else Py_INCREF(builtins); } else { /* If we share the globals, we share the builtins. Save a lookup and a call. */ builtins = back->f_builtins; assert(builtins != NULL && PyDict_Check(builtins)); Py_INCREF(builtins); } if (code->co_zombieframe != NULL) { f = code->co_zombieframe; code->co_zombieframe = NULL; _Py_NewReference((PyObject *)f); assert(f->f_code == code); } else { Py_ssize_t extras, ncells, nfrees; ncells = PyTuple_GET_SIZE(code->co_cellvars); nfrees = PyTuple_GET_SIZE(code->co_freevars); extras = code->co_stacksize + code->co_nlocals + ncells + nfrees; if (free_list == NULL) { f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, extras); if (f == NULL) { Py_DECREF(builtins); return NULL; } } else { assert(numfree > 0); --numfree; f = free_list; free_list = free_list->f_back; if (f->ob_size < extras) { f = PyObject_GC_Resize(PyFrameObject, f, extras); if (f == NULL) { Py_DECREF(builtins); return NULL; } } _Py_NewReference((PyObject *)f); } f->f_code = code; extras = code->co_nlocals + ncells + nfrees; f->f_valuestack = f->f_localsplus + extras; for (i=0; i<extras; i++) f->f_localsplus[i] = NULL; f->f_locals = NULL; f->f_trace = NULL; f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL; } f->f_stacktop = f->f_valuestack; f->f_builtins = builtins; Py_XINCREF(back); f->f_back = back; Py_INCREF(code); Py_INCREF(globals); f->f_globals = globals; /* Most functions have CO_NEWLOCALS and CO_OPTIMIZED set. */ if ((code->co_flags & (CO_NEWLOCALS | CO_OPTIMIZED)) == (CO_NEWLOCALS | CO_OPTIMIZED)) ; /* f_locals = NULL; will be set by PyFrame_FastToLocals() */ else if (code->co_flags & CO_NEWLOCALS) { locals = PyDict_New(); if (locals == NULL) { Py_DECREF(f); return NULL; } f->f_locals = locals; } else { if (locals == NULL) locals = globals; Py_INCREF(locals); f->f_locals = locals; } f->f_tstate = tstate; f->f_lasti = -1; f->f_lineno = code->co_firstlineno; f->f_iblock = 0; #ifdef STACKLESS f->f_execute = NULL; #endif _PyObject_GC_TRACK(f); return f; }