? build-debug ? ingmar.txt ? Objects/listobject.c-mine ? Python/compile.c-mine Index: Include/ceval.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/ceval.h,v retrieving revision 2.50 diff -c -r2.50 ceval.h *** Include/ceval.h 28 Oct 2003 12:05:46 -0000 2.50 --- Include/ceval.h 13 Jan 2004 16:30:10 -0000 *************** *** 27,32 **** --- 27,35 ---- struct _frame; /* Avoid including frameobject.h */ + PyObject *PyEval_RunFrame(struct _frame* f); + PyObject *PyEval_DoCall(PyObject *func, PyObject ***pp_stack, int na, int nk); + PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void); PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void); PyAPI_FUNC(PyObject *) PyEval_GetLocals(void); Index: Include/funcobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/funcobject.h,v retrieving revision 2.26 diff -c -r2.26 funcobject.h *** Include/funcobject.h 31 Jan 2003 18:33:15 -0000 2.26 --- Include/funcobject.h 13 Jan 2004 16:30:10 -0000 *************** *** 8,23 **** #endif typedef struct { ! PyObject_HEAD ! PyObject *func_code; ! PyObject *func_globals; ! PyObject *func_defaults; ! PyObject *func_closure; ! PyObject *func_doc; ! PyObject *func_name; ! PyObject *func_dict; ! PyObject *func_weakreflist; ! PyObject *func_module; } PyFunctionObject; PyAPI_DATA(PyTypeObject) PyFunction_Type; --- 8,24 ---- #endif typedef struct { ! PyObject_HEAD ! PyObject *func_code; ! PyObject *func_globals; ! PyObject *func_defaults; ! PyObject *func_closure; ! PyObject *func_doc; ! PyObject *func_name; ! PyObject *func_dict; ! PyObject *func_weakreflist; ! PyObject *func_module; ! pythoncallfunc func_caller; } PyFunctionObject; PyAPI_DATA(PyTypeObject) PyFunction_Type; Index: Include/methodobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/methodobject.h,v retrieving revision 2.27 diff -c -r2.27 methodobject.h *** Include/methodobject.h 13 Dec 2003 11:26:10 -0000 2.27 --- Include/methodobject.h 13 Jan 2004 16:30:10 -0000 *************** *** 74,83 **** char *); typedef struct { ! PyObject_HEAD ! PyMethodDef *m_ml; ! PyObject *m_self; ! PyObject *m_module; } PyCFunctionObject; #ifdef __cplusplus --- 74,84 ---- char *); typedef struct { ! PyObject_HEAD ! PyMethodDef *m_ml; ! PyObject *m_self; ! PyObject *m_module; ! pythoncallfunc m_caller; } PyCFunctionObject; #ifdef __cplusplus Index: Include/object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.125 diff -c -r2.125 object.h *** Include/object.h 9 Nov 2003 16:38:39 -0000 2.125 --- Include/object.h 13 Jan 2004 16:30:10 -0000 *************** *** 240,245 **** --- 240,246 ---- typedef int (*initproc)(PyObject *, PyObject *, PyObject *); typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); typedef PyObject *(*allocfunc)(struct _typeobject *, int); + typedef PyObject *(*pythoncallfunc)(PyObject*, PyObject***, int, int); typedef struct _typeobject { PyObject_VAR_HEAD *************** *** 316,321 **** --- 317,323 ---- PyObject *tp_subclasses; PyObject *tp_weaklist; destructor tp_del; + pythoncallfunc tp_pythoncall; #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ Index: Objects/classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.174 diff -c -r2.174 classobject.c *** Objects/classobject.c 22 Nov 2003 23:55:50 -0000 2.174 --- Objects/classobject.c 13 Jan 2004 16:30:12 -0000 *************** *** 478,483 **** --- 478,492 ---- 0, /* tp_init */ 0, /* tp_alloc */ class_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + PyEval_DoCall, /* tp_pythoncall */ }; int *************** *** 670,678 **** _Py_NewReference((PyObject *)inst); inst->ob_refcnt = refcnt; _PyObject_GC_TRACK(inst); ! /* If Py_REF_DEBUG, the original decref dropped _Py_RefTotal, ! * but _Py_NewReference bumped it again, so that's a wash. ! * If Py_TRACE_REFS, _Py_NewReference re-added self to the * object chain, so no more to do there either. * If COUNT_ALLOCS, the original decref bumped tp_frees, and * _Py_NewReference bumped tp_allocs: both of those need to --- 679,688 ---- _Py_NewReference((PyObject *)inst); inst->ob_refcnt = refcnt; _PyObject_GC_TRACK(inst); ! /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal. ! * Undo that. */ ! _Py_DEC_REFTOTAL; ! /* If Py_TRACE_REFS, _Py_NewReference re-added self to the * object chain, so no more to do there either. * If COUNT_ALLOCS, the original decref bumped tp_frees, and * _Py_NewReference bumped tp_allocs: both of those need to *************** *** 952,959 **** PyErr_Clear(); return _Py_HashPointer(inst); } } - Py_XDECREF(func); PyErr_SetString(PyExc_TypeError, "unhashable instance"); return -1; } --- 962,974 ---- PyErr_Clear(); return _Py_HashPointer(inst); } + else { + Py_DECREF(func); + } + } + else { + Py_DECREF(func); } PyErr_SetString(PyExc_TypeError, "unhashable instance"); return -1; } *************** *** 2082,2087 **** --- 2097,2111 ---- 0, /* tp_init */ 0, /* tp_alloc */ instance_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + PyEval_DoCall, /* tp_pythoncall */ }; *************** *** 2461,2466 **** --- 2485,2522 ---- return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj, cls); } + static PyObject* + instancemethod_pythoncall(PyObject *func, PyObject ***pp_stack, int na, int nk) + { + PyObject **pfunc = (*pp_stack) - na - 2*nk - 1; + PyObject *self = PyMethod_GET_SELF(func); + PyObject *x; + + if (self != NULL) { + Py_INCREF(self); + func = PyMethod_GET_FUNCTION(func); + Py_INCREF(func); + Py_DECREF(*pfunc); + *pfunc = self; + na++; + } + else { + Py_INCREF(func); + } + + if (PyFunction_Check(func)) { + x = ((PyFunctionObject*)func)->func_caller( + func, pp_stack, na, nk); + } + else { + x = PyEval_DoCall(func, pp_stack, na, nk); + } + + Py_DECREF(func); + + return x; + } + PyTypeObject PyMethod_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, *************** *** 2501,2506 **** --- 2557,2571 ---- 0, /* tp_init */ 0, /* tp_alloc */ instancemethod_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + instancemethod_pythoncall, /* tp_pythoncall */ }; /* Clear out the free list */ Index: Objects/funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.63 diff -c -r2.63 funcobject.c *** Objects/funcobject.c 18 Jun 2003 01:13:41 -0000 2.63 --- Objects/funcobject.c 13 Jan 2004 16:30:12 -0000 *************** *** 5,10 **** --- 5,61 ---- #include "compile.h" #include "eval.h" #include "structmember.h" + #include "frameobject.h" + + static PyObject* + func_caller_nofrees(PyObject* func, PyObject*** pp_stack, 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; + int ac = co->co_argcount; + + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = ((PyTupleObject *)argdefs)->ob_size; + } + if (na <= ac && ac <= na + nd && nk == 0) { + PyFrameObject *f; + PyObject *retval = NULL; + PyThreadState *tstate = PyThreadState_GET(); + PyObject **fastlocals, **stack; + int i; + + assert(globals != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) + return NULL; + + fastlocals = f->f_localsplus; + stack = (*pp_stack) - na; + + for (i = 0; i < na; i++) { + Py_INCREF(*stack); + fastlocals[i] = *stack++; + } + for (; i < ac; i++) { + Py_INCREF(d[nd-(ac-i)]); + fastlocals[i] = d[nd-(ac-i)]; + } + retval = PyEval_RunFrame(f); + assert(tstate != NULL); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return retval; + } + return PyEval_EvalCodeEx(co, globals, + (PyObject *)NULL, (*pp_stack)-na-2*nk, na, + (*pp_stack)-2*nk, nk, d, nd, + NULL); + } PyObject * PyFunction_New(PyObject *code, PyObject *globals) *************** *** 36,41 **** --- 87,99 ---- op->func_doc = doc; op->func_dict = NULL; op->func_module = NULL; + if (((PyCodeObject *)code)->co_flags + == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + op->func_caller = func_caller_nofrees; + } + else { + op->func_caller = PyEval_DoCall; + } /* __module__: If module name is in globals, use it. Otherwise, use None. *************** *** 523,528 **** --- 581,592 ---- return PyMethod_New(func, obj, type); } + static PyObject* + func_pythoncall(PyObject *func, PyObject ***pp_stack, int na, int nk) + { + return ((PyFunctionObject*)func)->func_caller(func, pp_stack, na, nk); + } + PyTypeObject PyFunction_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, *************** *** 563,568 **** --- 627,641 ---- 0, /* tp_init */ 0, /* tp_alloc */ func_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + func_pythoncall, /* tp_pythoncall */ }; Index: Objects/methodobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/methodobject.c,v retrieving revision 2.48 diff -c -r2.48 methodobject.c *** Objects/methodobject.c 13 Dec 2003 11:26:11 -0000 2.48 --- Objects/methodobject.c 13 Jan 2004 16:30:12 -0000 *************** *** 6,11 **** --- 6,189 ---- static PyCFunctionObject *free_list = NULL; + 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 = *--*pp_stack; + PyTuple_SET_ITEM(args, na, w); + } + return args; + } + + static PyObject * + load_keyword_args(int nk, PyObject ***pp_stack, PyObject *func) + { + PyObject *kwdict = PyDict_New(); + + if (kwdict == NULL) + return NULL; + + while (--nk >= 0) { + int err; + PyObject *value = *--*pp_stack; + PyObject *key = *--*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* + meth_caller_varargs_kw(PyCFunctionObject* m, PyObject*** pp_stack, + int na, int nk) + { + PyObject *x; + PyObject *kw = NULL; + PyObject *callargs; + + if (nk != 0) { + kw = load_keyword_args(nk, pp_stack, (PyObject*)m); + if (kw == NULL) + return NULL; + } + + callargs = load_args(pp_stack, na); + if (callargs == NULL) { + Py_XDECREF(kw); + return NULL; + } + + x = ((PyCFunctionWithKeywords)m->m_ml->ml_meth)( + m->m_self, callargs, kw); + Py_DECREF(callargs); + + return x; + } + + static PyObject* + meth_caller_varargs(PyCFunctionObject* m, PyObject*** pp_stack, int na, int nk) + { + PyObject *x; + PyObject *callargs; + + if (nk == 0) { + callargs = load_args(pp_stack, na); + if (callargs == NULL) { + return NULL; + } + + x = m->m_ml->ml_meth(m->m_self, callargs); + + Py_DECREF(callargs); + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", + m->m_ml->ml_name); + return NULL; + } + + return x; + } + + static PyObject* + meth_caller_noargs(PyCFunctionObject* m, PyObject*** pp_stack, int na, int nk) + { + if (na == 0 && nk == 0) { + return m->m_ml->ml_meth(m->m_self, NULL); + } + else if (na != 0) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%d given)", + m->m_ml->ml_name, na); + return NULL; + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", + m->m_ml->ml_name); + return NULL; + } + } + + static PyObject* + meth_caller_o(PyCFunctionObject* m, PyObject*** pp_stack, int na, int nk) + { + if (na == 1 && nk == 0) { + PyObject *arg = *--*pp_stack; + PyObject *x; + x = m->m_ml->ml_meth(m->m_self, arg); + Py_DECREF(arg); + return x; + } + else if (na != 1) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%d given)", + m->m_ml->ml_name, na); + return NULL; + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", + m->m_ml->ml_name); + return NULL; + } + } + + PyObject* + meth_caller_oldargs(PyCFunctionObject* m, PyObject*** pp_stack, + int na, int nk) + { + if (nk == 0) { + PyObject *arg; + PyObject *x; + if (na == 0) { + arg = NULL; + } + if (na == 1) { + arg = *--*pp_stack; + } + else { + arg = load_args(pp_stack, na); + if (arg == NULL) + return NULL; + } + x = m->m_ml->ml_meth(m->m_self, arg); + Py_XDECREF(arg); + return x; + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no keyword arguments", + m->m_ml->ml_name); + return NULL; + } + } + PyObject * PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) { *************** *** 25,30 **** --- 203,232 ---- op->m_self = self; Py_XINCREF(module); op->m_module = module; + + switch (PyCFunction_GET_FLAGS(op) + & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) { + case METH_VARARGS: + op->m_caller = (pythoncallfunc)meth_caller_varargs; + break; + case METH_VARARGS | METH_KEYWORDS: + case METH_OLDARGS | METH_KEYWORDS: + op->m_caller = (pythoncallfunc)meth_caller_varargs_kw; + break; + case METH_NOARGS: + op->m_caller = (pythoncallfunc)meth_caller_noargs; + break; + case METH_O: + op->m_caller = (pythoncallfunc)meth_caller_o; + break; + case METH_OLDARGS: + op->m_caller = (pythoncallfunc)meth_caller_oldargs; + break; + default: + PyErr_BadInternalCall(); + return NULL; + } + _PyObject_GC_TRACK(op); return (PyObject *)op; } *************** *** 239,244 **** --- 441,452 ---- } + static PyObject* + meth_pythoncall(PyCFunctionObject* m, PyObject*** pp_stack, int na, int nk) + { + return m->m_caller((PyObject*)m, pp_stack, na, nk); + } + PyTypeObject PyCFunction_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, *************** *** 273,278 **** --- 481,501 ---- meth_getsets, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ + 0, /* tp_del */ + (pythoncallfunc)meth_pythoncall, /* tp_pythoncall */ }; /* List all methods in a chain -- helper for findmethodinchain */ Index: Objects/typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.255 diff -c -r2.255 typeobject.c *** Objects/typeobject.c 13 Dec 2003 15:21:55 -0000 2.255 --- Objects/typeobject.c 13 Jan 2004 16:30:13 -0000 *************** *** 3223,3228 **** --- 3223,3232 ---- goto error; } + if (type->tp_pythoncall == NULL) { + type->tp_pythoncall = PyEval_DoCall; + } + /* if the type dictionary doesn't contain a __doc__, set it from the tp_doc slot. */ Index: Python/ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.373 diff -c -r2.373 ceval.c *** Python/ceval.c 20 Nov 2003 01:44:58 -0000 2.373 --- Python/ceval.c 13 Jan 2004 16:30:14 -0000 *************** *** 28,37 **** typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *); /* Forward declarations */ - static PyObject *eval_frame(PyFrameObject *); - static PyObject *call_function(PyObject ***, int); - static PyObject *fast_function(PyObject *, PyObject ***, int, int, int); - static PyObject *do_call(PyObject *, PyObject ***, int, int); static PyObject *ext_do_call(PyObject *, PyObject ***, int, int, int); static PyObject *update_keyword_args(PyObject *, int, PyObject ***,PyObject *); static PyObject *update_star_args(int, int, PyObject *, PyObject ***); --- 28,33 ---- *************** *** 207,213 **** f->f_back = tstate->frame; gen->gi_running = 1; ! result = eval_frame(f); gen->gi_running = 0; /* Don't keep the reference to f_back any longer than necessary. It --- 203,209 ---- f->f_back = tstate->frame; gen->gi_running = 1; ! result = PyEval_RunFrame(f); gen->gi_running = 0; /* Don't keep the reference to f_back any longer than necessary. It *************** *** 572,579 **** /* Interpreter main loop */ ! static PyObject * ! eval_frame(PyFrameObject *f) { #ifdef DXPAIRS int lastopcode = 0; --- 568,575 ---- /* Interpreter main loop */ ! PyObject * ! PyEval_RunFrame(PyFrameObject *f) { #ifdef DXPAIRS int lastopcode = 0; *************** *** 745,751 **** consts = co->co_consts; fastlocals = f->f_localsplus; freevars = f->f_localsplus + f->f_nlocals; ! _PyCode_GETCODEPTR(co, &first_instr); /* An explanation is in order for the next line. f->f_lasti now refers to the index of the last instruction --- 741,748 ---- consts = co->co_consts; fastlocals = f->f_localsplus; freevars = f->f_localsplus + f->f_nlocals; ! /*_PyCode_GETCODEPTR(co, &first_instr);*/ ! first_instr = PyString_AS_STRING(co->co_code); /* An explanation is in order for the next line. f->f_lasti now refers to the index of the last instruction *************** *** 2124,2130 **** case CALL_FUNCTION: PCALL(PCALL_ALL); ! x = call_function(&stack_pointer, oparg); PUSH(x); if (x != NULL) continue; --- 2121,2146 ---- case CALL_FUNCTION: PCALL(PCALL_ALL); ! { ! int na = oparg & 0xff; ! int nk = (oparg>>8) & 0xff; ! PyObject **pfunc = stack_pointer - na - 2*nk - 1; ! PyObject *func = *pfunc; ! pythoncall f; ! ! if ((f = func->ob_type->tp_pythoncall)) { ! x = f(func, &stack_pointer, na, nk); ! } ! else { ! PyEval_DoCall(func, &stack_pointer, na, nk); ! } ! ! while (stack_pointer > pfunc) { ! w = POP(); ! Py_DECREF(w); ! } ! } ! PUSH(x); if (x != NULL) continue; *************** *** 2672,2678 **** return gen_new(f); } ! retval = eval_frame(f); fail: /* Jump here from prelude on failure */ --- 2688,2694 ---- return gen_new(f); } ! retval = PyEval_RunFrame(f); fail: /* Jump here from prelude on failure */ *************** *** 3414,3548 **** nargs); } - static PyObject * - call_function(PyObject ***pp_stack, int oparg) - { - 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); - 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) - x = (*meth)(self, NULL); - else if (flags & METH_O && na == 1) { - PyObject *arg = EXT_POP(*pp_stack); - x = (*meth)(self, arg); - Py_DECREF(arg); - } - else { - err_args(func, flags, na); - x = NULL; - } - } - else { - PyObject *callargs; - callargs = load_args(pp_stack, na); - x = PyCFunction_Call(func, callargs, NULL); - 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); - if (PyFunction_Check(func)) - x = fast_function(func, pp_stack, n, na, nk); - else - x = do_call(func, pp_stack, na, nk); - Py_DECREF(func); - } - - /* What does this do? */ - 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. - */ - 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 = eval_frame(f); - assert(tstate != NULL); - ++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, --- 3430,3435 ---- *************** *** 3624,3631 **** return args; } ! static PyObject * ! do_call(PyObject *func, PyObject ***pp_stack, int na, int nk) { PyObject *callargs = NULL; PyObject *kwdict = NULL; --- 3511,3518 ---- return args; } ! PyObject * ! PyEval_DoCall(PyObject *func, PyObject ***pp_stack, int na, int nk) { PyObject *callargs = NULL; PyObject *kwdict = NULL;