cinap_lenrekadd hg and python4bb9e2215 years agoHistory
4351 lines · 104.0 KB · C
RawDownload
			if (x == NULL) { \				call_trace_protected(tstate->c_profilefunc, \					tstate->c_profileobj, \					tstate->frame, PyTrace_C_EXCEPTION, \					func); \				/* XXX should pass (type, value, tb) */ \			} else { \				if (call_trace(tstate->c_profilefunc, \					tstate->c_profileobj, \					tstate->frame, PyTrace_C_RETURN, \					func)) { \					Py_DECREF(x); \					x = NULL; \				} \			} \		} \	} \} else { \	x = call; \	} static PyObject *call_function(PyObject ***pp_stack, int oparg#ifdef WITH_TSC		, uint64* pintr0, uint64* pintr1#endif		){	int na = oparg & 0xff;	int nk = (oparg>>8) & 0xff;	int n = na + 2 * nk;	PyObject **pfunc = (*pp_stack) - n - 1;	PyObject *func = *pfunc;	PyObject *x, *w; 	/* Always dispatch PyCFunction first, because these are	   presumed to be the most frequent callable object.	*/	if (PyCFunction_Check(func) && nk == 0) {		int flags = PyCFunction_GET_FLAGS(func);		PyThreadState *tstate = PyThreadState_GET(); 		PCALL(PCALL_CFUNCTION);		if (flags & (METH_NOARGS | METH_O)) {			PyCFunction meth = PyCFunction_GET_FUNCTION(func);			PyObject *self = PyCFunction_GET_SELF(func);			if (flags & METH_NOARGS && na == 0) {				C_TRACE(x, (*meth)(self,NULL));			}			else if (flags & METH_O && na == 1) {				PyObject *arg = EXT_POP(*pp_stack);				C_TRACE(x, (*meth)(self,arg));				Py_DECREF(arg);			}			else {				err_args(func, flags, na);				x = NULL;			}		}		else {			PyObject *callargs;			callargs = load_args(pp_stack, na);			READ_TIMESTAMP(*pintr0);			C_TRACE(x, PyCFunction_Call(func,callargs,NULL));			READ_TIMESTAMP(*pintr1);			Py_XDECREF(callargs);		}	} else {		if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {			/* optimize access to bound methods */			PyObject *self = PyMethod_GET_SELF(func);			PCALL(PCALL_METHOD);			PCALL(PCALL_BOUND_METHOD);			Py_INCREF(self);			func = PyMethod_GET_FUNCTION(func);			Py_INCREF(func);			Py_DECREF(*pfunc);			*pfunc = self;			na++;			n++;		} else			Py_INCREF(func);		READ_TIMESTAMP(*pintr0);		if (PyFunction_Check(func))			x = fast_function(func, pp_stack, n, na, nk);		else			x = do_call(func, pp_stack, na, nk);		READ_TIMESTAMP(*pintr1);		Py_DECREF(func);	} 	/* Clear the stack of the function object.  Also removes           the arguments in case they weren't consumed already           (fast_function() and err_args() leave them on the stack).	 */	while ((*pp_stack) > pfunc) {		w = EXT_POP(*pp_stack);		Py_DECREF(w);		PCALL(PCALL_POP);	}	return x;} /* The fast_function() function optimize calls for which no argument   tuple is necessary; the objects are passed directly from the stack.   For the simplest case -- a function that takes only positional   arguments and is called with only positional arguments -- it   inlines the most primitive frame setup code from   PyEval_EvalCodeEx(), which vastly reduces the checks that must be   done before evaluating the frame.*/ static PyObject *fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk){	PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);	PyObject *globals = PyFunction_GET_GLOBALS(func);	PyObject *argdefs = PyFunction_GET_DEFAULTS(func);	PyObject **d = NULL;	int nd = 0; 	PCALL(PCALL_FUNCTION);	PCALL(PCALL_FAST_FUNCTION);	if (argdefs == NULL && co->co_argcount == n && nk==0 &&	    co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) {		PyFrameObject *f;		PyObject *retval = NULL;		PyThreadState *tstate = PyThreadState_GET();		PyObject **fastlocals, **stack;		int i; 		PCALL(PCALL_FASTER_FUNCTION);		assert(globals != NULL);		/* XXX Perhaps we should create a specialized		   PyFrame_New() that doesn't take locals, but does		   take builtins without sanity checking them.		*/		assert(tstate != NULL);		f = PyFrame_New(tstate, co, globals, NULL);		if (f == NULL)			return NULL; 		fastlocals = f->f_localsplus;		stack = (*pp_stack) - n; 		for (i = 0; i < n; i++) {			Py_INCREF(*stack);			fastlocals[i] = *stack++;		}		retval = PyEval_EvalFrameEx(f,0);		++tstate->recursion_depth;		Py_DECREF(f);		--tstate->recursion_depth;		return retval;	}	if (argdefs != NULL) {		d = &PyTuple_GET_ITEM(argdefs, 0);		nd = ((PyTupleObject *)argdefs)->ob_size;	}	return PyEval_EvalCodeEx(co, globals,				 (PyObject *)NULL, (*pp_stack)-n, na,				 (*pp_stack)-2*nk, nk, d, nd,				 PyFunction_GET_CLOSURE(func));} static PyObject *update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack,                    PyObject *func){	PyObject *kwdict = NULL;	if (orig_kwdict == NULL)		kwdict = PyDict_New();	else {		kwdict = PyDict_Copy(orig_kwdict);		Py_DECREF(orig_kwdict);	}	if (kwdict == NULL)		return NULL;	while (--nk >= 0) {		int err;		PyObject *value = EXT_POP(*pp_stack);		PyObject *key = EXT_POP(*pp_stack);		if (PyDict_GetItem(kwdict, key) != NULL) {                        PyErr_Format(PyExc_TypeError,                                     "%.200s%s got multiple values "                                     "for keyword argument '%.200s'",				     PyEval_GetFuncName(func),				     PyEval_GetFuncDesc(func),				     PyString_AsString(key));			Py_DECREF(key);			Py_DECREF(value);			Py_DECREF(kwdict);			return NULL;		}		err = PyDict_SetItem(kwdict, key, value);		Py_DECREF(key);		Py_DECREF(value);		if (err) {			Py_DECREF(kwdict);			return NULL;		}	}	return kwdict;} static PyObject *update_star_args(int nstack, int nstar, PyObject *stararg,		 PyObject ***pp_stack){	PyObject *callargs, *w; 	callargs = PyTuple_New(nstack + nstar);	if (callargs == NULL) {		return NULL;	}	if (nstar) {		int i;		for (i = 0; i < nstar; i++) {			PyObject *a = PyTuple_GET_ITEM(stararg, i);			Py_INCREF(a);			PyTuple_SET_ITEM(callargs, nstack + i, a);		}	}	while (--nstack >= 0) {		w = EXT_POP(*pp_stack);		PyTuple_SET_ITEM(callargs, nstack, w);	}	return callargs;} static PyObject *load_args(PyObject ***pp_stack, int na){	PyObject *args = PyTuple_New(na);	PyObject *w; 	if (args == NULL)		return NULL;	while (--na >= 0) {		w = EXT_POP(*pp_stack);		PyTuple_SET_ITEM(args, na, w);	}	return args;} static PyObject *do_call(PyObject *func, PyObject ***pp_stack, int na, int nk){	PyObject *callargs = NULL;	PyObject *kwdict = NULL;	PyObject *result = NULL; 	if (nk > 0) {		kwdict = update_keyword_args(NULL, nk, pp_stack, func);		if (kwdict == NULL)			goto call_fail;	}	callargs = load_args(pp_stack, na);	if (callargs == NULL)		goto call_fail;#ifdef CALL_PROFILE	/* At this point, we have to look at the type of func to	   update the call stats properly.  Do it here so as to avoid	   exposing the call stats machinery outside ceval.c	*/	if (PyFunction_Check(func))		PCALL(PCALL_FUNCTION);	else if (PyMethod_Check(func))		PCALL(PCALL_METHOD);	else if (PyType_Check(func))		PCALL(PCALL_TYPE);	else		PCALL(PCALL_OTHER);#endif	result = PyObject_Call(func, callargs, kwdict); call_fail:	Py_XDECREF(callargs);	Py_XDECREF(kwdict);	return result;} static PyObject *ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk){	int nstar = 0;	PyObject *callargs = NULL;	PyObject *stararg = NULL;	PyObject *kwdict = NULL;	PyObject *result = NULL; 	if (flags & CALL_FLAG_KW) {		kwdict = EXT_POP(*pp_stack);		if (!(kwdict && PyDict_Check(kwdict))) {			PyErr_Format(PyExc_TypeError,				     "%s%s argument after ** "				     "must be a dictionary",				     PyEval_GetFuncName(func),				     PyEval_GetFuncDesc(func));			goto ext_call_fail;		}	}	if (flags & CALL_FLAG_VAR) {		stararg = EXT_POP(*pp_stack);		if (!PyTuple_Check(stararg)) {			PyObject *t = NULL;			t = PySequence_Tuple(stararg);			if (t == NULL) {				if (PyErr_ExceptionMatches(PyExc_TypeError)) {					PyErr_Format(PyExc_TypeError,						     "%s%s argument after * "						     "must be a sequence",						     PyEval_GetFuncName(func),						     PyEval_GetFuncDesc(func));				}				goto ext_call_fail;			}			Py_DECREF(stararg);			stararg = t;		}		nstar = PyTuple_GET_SIZE(stararg);	}	if (nk > 0) {		kwdict = update_keyword_args(kwdict, nk, pp_stack, func);		if (kwdict == NULL)			goto ext_call_fail;	}	callargs = update_star_args(na, nstar, stararg, pp_stack);	if (callargs == NULL)		goto ext_call_fail;#ifdef CALL_PROFILE	/* At this point, we have to look at the type of func to	   update the call stats properly.  Do it here so as to avoid	   exposing the call stats machinery outside ceval.c	*/	if (PyFunction_Check(func))		PCALL(PCALL_FUNCTION);	else if (PyMethod_Check(func))		PCALL(PCALL_METHOD);	else if (PyType_Check(func))		PCALL(PCALL_TYPE);	else		PCALL(PCALL_OTHER);#endif	result = PyObject_Call(func, callargs, kwdict);      ext_call_fail:	Py_XDECREF(callargs);	Py_XDECREF(kwdict);	Py_XDECREF(stararg);	return result;} /* Extract a slice index from a PyInt or PyLong or an object with the   nb_index slot defined, and store in *pi.   Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX,   and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1.   Return 0 on error, 1 on success.*//* Note:  If v is NULL, return success without storing into *pi.  This   is because_PyEval_SliceIndex() is called by apply_slice(), which can be   called by the SLICE opcode with v and/or w equal to NULL.*/int_PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi){	if (v != NULL) {		Py_ssize_t x;		if (PyInt_Check(v)) {			/* XXX(nnorwitz): I think PyInt_AS_LONG is correct,			   however, it looks like it should be AsSsize_t.			   There should be a comment here explaining why.			*/			x = PyInt_AS_LONG(v);		}		else if (PyIndex_Check(v)) {			x = PyNumber_AsSsize_t(v, NULL);			if (x == -1 && PyErr_Occurred())				return 0;		}		else {			PyErr_SetString(PyExc_TypeError,					"slice indices must be integers or "					"None or have an __index__ method");			return 0;		}		*pi = x;	}	return 1;} #undef ISINDEX#define ISINDEX(x) ((x) == NULL || \		    PyInt_Check(x) || PyLong_Check(x) || PyIndex_Check(x)) static PyObject *apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */{	PyTypeObject *tp = u->ob_type;	PySequenceMethods *sq = tp->tp_as_sequence; 	if (sq && sq->sq_slice && ISINDEX(v) && ISINDEX(w)) {		Py_ssize_t ilow = 0, ihigh = PY_SSIZE_T_MAX;		if (!_PyEval_SliceIndex(v, &ilow))			return NULL;		if (!_PyEval_SliceIndex(w, &ihigh))			return NULL;		return PySequence_GetSlice(u, ilow, ihigh);	}	else {		PyObject *slice = PySlice_New(v, w, NULL);		if (slice != NULL) {			PyObject *res = PyObject_GetItem(u, slice);			Py_DECREF(slice);			return res;		}		else			return NULL;	}} static intassign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)	/* u[v:w] = x */{	PyTypeObject *tp = u->ob_type;	PySequenceMethods *sq = tp->tp_as_sequence; 	if (sq && sq->sq_ass_slice && ISINDEX(v) && ISINDEX(w)) {		Py_ssize_t ilow = 0, ihigh = PY_SSIZE_T_MAX;		if (!_PyEval_SliceIndex(v, &ilow))			return -1;		if (!_PyEval_SliceIndex(w, &ihigh))			return -1;		if (x == NULL)			return PySequence_DelSlice(u, ilow, ihigh);		else			return PySequence_SetSlice(u, ilow, ihigh, x);	}	else {		PyObject *slice = PySlice_New(v, w, NULL);		if (slice != NULL) {			int res;			if (x != NULL)				res = PyObject_SetItem(u, slice, x);			else				res = PyObject_DelItem(u, slice);			Py_DECREF(slice);			return res;		}		else			return -1;	}} static PyObject *cmp_outcome(int op, register PyObject *v, register PyObject *w){	int res = 0;	switch (op) {	case PyCmp_IS:		res = (v == w);		break;	case PyCmp_IS_NOT:		res = (v != w);		break;	case PyCmp_IN:		res = PySequence_Contains(w, v);		if (res < 0)			return NULL;		break;	case PyCmp_NOT_IN:		res = PySequence_Contains(w, v);		if (res < 0)			return NULL;		res = !res;		break;	case PyCmp_EXC_MATCH:		res = PyErr_GivenExceptionMatches(v, w);		break;	default:		return PyObject_RichCompare(v, w, op);	}	v = res ? Py_True : Py_False;	Py_INCREF(v);	return v;} static PyObject *import_from(PyObject *v, PyObject *name){	PyObject *x; 	x = PyObject_GetAttr(v, name);	if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {		PyErr_Format(PyExc_ImportError,			     "cannot import name %.230s",			     PyString_AsString(name));	}	return x;} 

Lines 3501–4000 of 4351. Previous lines