[Python-checkins] CVS: python/dist/src/Python ceval.c,2.213,2.214

Jeremy Hylton python-dev@python.org
Wed, 03 Jan 2001 15:52:39 -0800


Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv9469/Python

Modified Files:
	ceval.c 
Log Message:
Revised implementation of CALL_FUNCTION and friends.
More revision still needed.

Much of the code that was in the mainloop was moved to a series of
helper functions.  PyEval_CallObjectWithKeywords was split into two
parts.  The first part now only does argument handling.  The second
part is now named call_object and delegates the call to a
call_(function,method,etc.) helper.

XXX The call_XXX helper functions should be replaced with tp_call
functions for the respective types.

The CALL_FUNCTION implementation contains three kinds of optimization:
1. fast_cfunction and fast_function are called when the arguments on
   the stack can be passed directly to eval_code2() without copying
   them into a tuple.
2. PyCFunction objects are dispatched immediately, because they are
   presumed to occur more often than anything else.
3. Bound methods are dispatched inline.  The method object contains a
   pointer to the function object that will be called.  The function
   is called from within the mainloop, which may allow optimization #1
   to be used, too.

The extened call implementation -- f(*args) and f(**kw) -- are
implemented as a separate case in the mainloop.  This allows the
common case of normal function calls to execute without wasting time
on checks for extended calls, although it does introduce a small
amount of code duplication.

Also, the unused final argument of eval_code2() was removed.  This is
probably the last trace of the access statement :-).



Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.213
retrieving revision 2.214
diff -C2 -r2.213 -r2.214
*** ceval.c	2000/10/30 17:15:19	2.213
--- ceval.c	2001/01/03 23:52:36	2.214
***************
*** 30,33 ****
--- 30,34 ----
  #endif
  
+ typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);
  
  /* Forward declarations */
***************
*** 37,42 ****
  			    PyObject **, int,
  			    PyObject **, int,
! 			    PyObject **, int,
! 			    PyObject *);
  #ifdef LLTRACE
  static int prtrace(PyObject *, char *);
--- 38,58 ----
  			    PyObject **, int,
  			    PyObject **, int,
! 			    PyObject **, int);
! 
! static PyObject *call_object(PyObject *, PyObject *, PyObject *);
! static PyObject *call_cfunction(PyObject *, PyObject *, PyObject *);
! static PyObject *call_instance(PyObject *, PyObject *, PyObject *);
! static PyObject *call_method(PyObject *, PyObject *, PyObject *);
! static PyObject *call_eval_code2(PyObject *, PyObject *, PyObject *);
! static PyObject *fast_function(PyObject *, PyObject ***, int, int, int);
! static PyObject *fast_cfunction(PyObject *, PyObject ***, 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 ***);
! static PyObject *update_star_args(int, int, PyObject *,	PyObject ***);
! static PyObject *load_args(PyObject ***, int);
! #define CALL_FLAG_VAR 1
! #define CALL_FLAG_KW 2
! 
  #ifdef LLTRACE
  static int prtrace(PyObject *, char *);
***************
*** 45,50 ****
  static int call_trace(PyObject **, PyObject **,
  		      PyFrameObject *, char *, PyObject *);
- static PyObject *call_builtin(PyObject *, PyObject *, PyObject *);
- static PyObject *call_function(PyObject *, PyObject *, PyObject *);
  static PyObject *loop_subscript(PyObject *, PyObject *);
  static PyObject *apply_slice(PyObject *, PyObject *, PyObject *);
--- 61,64 ----
***************
*** 76,80 ****
  #endif
  
- 
  #ifdef WITH_THREAD
  
--- 90,93 ----
***************
*** 321,326 ****
  			  (PyObject **)NULL, 0,
  			  (PyObject **)NULL, 0,
! 			  (PyObject **)NULL, 0,
! 			  (PyObject *)NULL);
  }
  
--- 334,338 ----
  			  (PyObject **)NULL, 0,
  			  (PyObject **)NULL, 0,
! 			  (PyObject **)NULL, 0);
  }
  
***************
*** 331,343 ****
  eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
  	   PyObject **args, int argcount, PyObject **kws, int kwcount,
! 	   PyObject **defs, int defcount, PyObject *owner)
  {
  #ifdef DXPAIRS
  	int lastopcode = 0;
  #endif
  	register unsigned char *next_instr;
  	register int opcode=0;	/* Current opcode */
  	register int oparg=0;	/* Current opcode argument, if any */
- 	register PyObject **stack_pointer;
  	register enum why_code why; /* Reason for block stack unwind */
  	register int err;	/* Error status -- nonzero if error */
--- 343,355 ----
  eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
  	   PyObject **args, int argcount, PyObject **kws, int kwcount,
! 	   PyObject **defs, int defcount)
  {
  #ifdef DXPAIRS
  	int lastopcode = 0;
  #endif
+ 	PyObject **stack_pointer;
  	register unsigned char *next_instr;
  	register int opcode=0;	/* Current opcode */
  	register int oparg=0;	/* Current opcode argument, if any */
  	register enum why_code why; /* Reason for block stack unwind */
  	register int err;	/* Error status -- nonzero if error */
***************
*** 669,673 ****
  #endif
  		/* Main switch on opcode */
! 		
  		switch (opcode) {
  		
--- 681,685 ----
  #endif
  		/* Main switch on opcode */
! 
  		switch (opcode) {
  		
***************
*** 1798,1801 ****
--- 1810,1867 ----
  
  		case CALL_FUNCTION:
+ 		{
+ 		    int na = oparg & 0xff;
+ 		    int nk = (oparg>>8) & 0xff;
+ 		    int n = na + 2 * nk;
+ 		    PyObject **pfunc = stack_pointer - n - 1;
+ 		    PyObject *func = *pfunc;
+ 		    f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */
+ 
+ 		    /* Always dispatch PyCFunction first, because
+ 		       these are presumed to be the most frequent
+ 		       callable object.
+ 		    */
+ 		    if (PyCFunction_Check(func)) {
+ 			    if (PyCFunction_GET_FLAGS(func) == 0) {
+ 				    x = fast_cfunction(func,
+ 						       &stack_pointer, na);  
+ 			    } else {
+ 				    x = do_call(func, &stack_pointer,
+ 						na, nk);
+ 			    }
+ 		    } else {
+ 			    if (PyMethod_Check(func) 
+ 				&& PyMethod_GET_SELF(func) != NULL) {
+ 				    /* optimize access to bound methods */
+ 				    PyObject *self = PyMethod_GET_SELF(func);
+ 				    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, &stack_pointer,
+ 						      n, na, nk); 
+ 			    } else {
+ 				    x = do_call(func, &stack_pointer,
+ 						na, nk);
+ 			    }
+ 			    Py_DECREF(func);
+ 		    }
+ 
+ 		    while (stack_pointer > pfunc) {
+ 			    w = POP();
+ 			    Py_DECREF(w);
+ 		    }
+ 		    PUSH(x);
+ 		    if (x != NULL) 
+ 			    continue;
+ 		    break;
+ 		}
+ 		
  		case CALL_FUNCTION_VAR:
  		case CALL_FUNCTION_KW:
***************
*** 1805,1989 ****
  		    int nk = (oparg>>8) & 0xff;
  		    int flags = (opcode - CALL_FUNCTION) & 3;
! 		    int n = na + 2*nk + (flags & 1) + ((flags >> 1) & 1);
! 		    PyObject **pfunc = stack_pointer - n - 1;
! 		    PyObject *func = *pfunc;
! 		    PyObject *self = NULL;
! 		    PyObject *class = NULL;
  		    f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */
! 		    if (PyMethod_Check(func)) {
! 			self = PyMethod_Self(func);
! 			class = PyMethod_Class(func);
! 			func = PyMethod_Function(func);
! 			Py_INCREF(func);
! 			if (self != NULL) {
  			    Py_INCREF(self);
  			    Py_DECREF(*pfunc);
  			    *pfunc = self;
  			    na++;
  			    n++;
! 			}
! 			else if (!((flags & 1) && na == 0)) {
! 			    /* Unbound methods must be called with an
! 			       instance of the class (or a derived
! 			       class) as first argument */ 
! 			    if (na > 0 && (self = stack_pointer[-n]) != NULL 
! 				&& PyInstance_Check(self) 
! 				&& PyClass_IsSubclass((PyObject *)
! 				    (((PyInstanceObject *)self)->in_class),
! 						      class))
!                                   /* Handy-dandy */ ;
! 			    else {
! 				PyErr_SetString(PyExc_TypeError,
! 	    "unbound method must be called with instance as first argument");
! 				x = NULL;
! 				break;
! 			    }
! 			}
! 		    }
! 		    else
! 			Py_INCREF(func);
! 		    if (PyFunction_Check(func) && flags == 0) {
! 			PyObject *co = PyFunction_GetCode(func);
! 			PyObject *globals = PyFunction_GetGlobals(func);
! 			PyObject *argdefs = PyFunction_GetDefaults(func);
! 			PyObject **d;
! 			int nd;
! 			if (argdefs != NULL) {
! 			    d = &PyTuple_GET_ITEM(argdefs, 0);
! 			    nd = ((PyTupleObject *)argdefs)->ob_size;
! 			}
! 			else {
! 			    d = NULL;
! 			    nd = 0;
! 			}
! 			x = eval_code2((PyCodeObject *)co, globals, 
! 				       (PyObject *)NULL, stack_pointer-n, na,
! 				       stack_pointer-2*nk, nk, d, nd,
! 				       class);
! 		    }
! 		    else {
! 			int nstar = 0;
! 			PyObject *callargs;
! 			PyObject *stararg = 0;
! 			PyObject *kwdict = NULL;
! 			if (flags & 2) {
! 			    kwdict = POP();
! 			    if (!PyDict_Check(kwdict)) {
! 				PyErr_SetString(PyExc_TypeError,
! 					"** argument must be a dictionary");
! 				goto extcall_fail;
! 			    }
! 			}
! 			if (flags & 1) {
! 			    stararg = POP();
! 			    if (!PySequence_Check(stararg)) {
! 				PyErr_SetString(PyExc_TypeError,
! 					"* argument must be a sequence");
! 				goto extcall_fail;
! 			    }
! 			    /* Convert abstract sequence to concrete tuple */
! 			    if (!PyTuple_Check(stararg)) {
! 				PyObject *t = NULL;
! 				t = PySequence_Tuple(stararg);
! 				if (t == NULL) {
! 				    goto extcall_fail;
! 				}
! 				Py_DECREF(stararg);
! 				stararg = t;
! 			    }
! 			    nstar = PyTuple_GET_SIZE(stararg);
! 			    if (nstar < 0) {
! 				goto extcall_fail;
! 			    }
! 			    if (class && self == NULL && na == 0) {
! 				/* * arg is first argument of method,
! 				   so check it is isinstance of class */
! 				self = PyTuple_GET_ITEM(stararg, 0);
! 				if (!(PyInstance_Check(self) &&
! 				      PyClass_IsSubclass((PyObject *)
! 				   (((PyInstanceObject *)self)->in_class),
! 							 class))) {
! 				    PyErr_SetString(PyExc_TypeError,
! 	    "unbound method must be called with instance as first argument");
! 				    x = NULL;
! 				    break;
! 				}
! 			    }
! 			}
! 			if (nk > 0) {
! 			    if (kwdict == NULL) {
! 				kwdict = PyDict_New();
! 				if (kwdict == NULL) {
!     				    goto extcall_fail;
! 				}
! 			    }
! 			    else {
! 				    PyObject *d = PyDict_Copy(kwdict);
! 				    if (d == NULL) {
! 					    goto extcall_fail;
! 				    }
! 				    Py_DECREF(kwdict);
! 				    kwdict = d;
! 			    }
! 			    err = 0;
! 			    while (--nk >= 0) {
! 				PyObject *value = POP();
! 				PyObject *key = POP();
! 				if (PyDict_GetItem(kwdict, key) != NULL) {
! 				    err = 1;
! 				    PyErr_Format(PyExc_TypeError, 
! 					 "keyword parameter '%.400s' "
! 					 "redefined in function call",
! 					 PyString_AsString(key));
! 				    Py_DECREF(key);
! 				    Py_DECREF(value);
! 				    goto extcall_fail;
! 				}
! 				err = PyDict_SetItem(kwdict, key, value);
! 				Py_DECREF(key);
! 				Py_DECREF(value);
! 				if (err)
! 				    break;
! 			    }
! 			    if (err) {
! 			      extcall_fail:
! 				Py_XDECREF(kwdict);
! 				Py_XDECREF(stararg);
! 				Py_DECREF(func);
! 				x=NULL;
! 				break;
! 			    }
! 			}
! 			callargs = PyTuple_New(na + nstar);
! 			if (callargs == NULL) {
! 			    x = NULL;
! 			    break;
! 			}
! 			if (stararg) {
! 			    int i;
! 			    for (i = 0; i < nstar; i++) {
! 				PyObject *a = PyTuple_GET_ITEM(stararg, i);
! 				Py_INCREF(a);
! 				PyTuple_SET_ITEM(callargs, na + i, a);
! 			    }
! 			    Py_DECREF(stararg);
! 			}
! 			while (--na >= 0) {
! 			    w = POP();
! 			    PyTuple_SET_ITEM(callargs, na, w);
! 			}
! 			x = PyEval_CallObjectWithKeywords(func,
! 							  callargs,
! 							  kwdict);  
! 			Py_DECREF(callargs);
! 			Py_XDECREF(kwdict);
! 		    }
  		    Py_DECREF(func);
  		    while (stack_pointer > pfunc) {
! 			w = POP();
! 			Py_DECREF(w);
  		    }
  		    PUSH(x);
! 		    if (x != NULL) continue;
  		    break;
  		}
--- 1871,1906 ----
  		    int nk = (oparg>>8) & 0xff;
  		    int flags = (opcode - CALL_FUNCTION) & 3;
! 		    int n = na + 2 * nk;
! 		    PyObject **pfunc, *func;
! 		    if (flags & CALL_FLAG_VAR)
! 			    n++;
! 		    if (flags & CALL_FLAG_KW)
! 			    n++;
! 		    pfunc = stack_pointer - n - 1;
! 		    func = *pfunc;
  		    f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */
! 
! 		    if (PyMethod_Check(func) 
! 			&& PyMethod_GET_SELF(func) != NULL) {
! 			    PyObject *self = PyMethod_GET_SELF(func);
  			    Py_INCREF(self);
+ 			    func = PyMethod_GET_FUNCTION(func);
+ 			    Py_INCREF(func);
  			    Py_DECREF(*pfunc);
  			    *pfunc = self;
  			    na++;
  			    n++;
! 		    } else 
! 			    Py_INCREF(func);
! 		    x = ext_do_call(func, &stack_pointer, flags, na, nk);
  		    Py_DECREF(func);
+ 
  		    while (stack_pointer > pfunc) {
! 			    w = POP();
! 			    Py_DECREF(w);
  		    }
  		    PUSH(x);
! 		    if (x != NULL) 
! 			    continue;
  		    break;
  		}
***************
*** 2615,2620 ****
  PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
  {
!         ternaryfunc call;
!         PyObject *result;
  
  	if (arg == NULL)
--- 2532,2536 ----
  PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
  {
! 	PyObject *result;
  
  	if (arg == NULL)
***************
*** 2634,2647 ****
  		return NULL;
  	}
- 
-         if ((call = func->ob_type->tp_call) != NULL)
-                 result = (*call)(func, arg, kw);
-         else if (PyMethod_Check(func) || PyFunction_Check(func))
- 		result = call_function(func, arg, kw);
- 	else
- 		result = call_builtin(func, arg, kw);
  
  	Py_DECREF(arg);
! 	
          if (result == NULL && !PyErr_Occurred())
  		PyErr_SetString(PyExc_SystemError,
--- 2550,2596 ----
  		return NULL;
  	}
  
+ 	result = call_object(func, arg, kw);
  	Py_DECREF(arg);
! 	return result;
! }
! 
! /* How often is each kind of object called?  The answer depends on the
!    program.  An instrumented call_object() was used to run the Python
!    regression test suite.  The results were:
!    4200000 PyCFunctions
!     390000 fast_function() calls
!      94000 other functions
!     480000 all functions (sum of prev two)
!     150000 methods
!     100000 classes
! 
!     Tests on other bodies of code show that PyCFunctions are still
!     most common, but not by such a large margin.
! */
! 
! static PyObject *
! call_object(PyObject *func, PyObject *arg, PyObject *kw)
! {
!         ternaryfunc call;
!         PyObject *result;
! 
! 	if (PyMethod_Check(func))
! 		result = call_method(func, arg, kw);
! 	else if (PyFunction_Check(func))
! 		result = call_eval_code2(func, arg, kw);
! 	else if (PyCFunction_Check(func))
! 		result = call_cfunction(func, arg, kw);
! 	else if (PyClass_Check(func))
! 		result = PyInstance_New(func, arg, kw);
! 	else if (PyInstance_Check(func))
! 		result = call_instance(func, arg, kw);
! 	else if ((call = func->ob_type->tp_call) != NULL)
! 		result = (*call)(func, arg, kw);
! 	else {
! 		PyErr_Format(PyExc_TypeError, "object is not callable: %s",
! 			     PyString_AS_STRING(PyObject_Repr(func)));
! 		return NULL;
! 	}
          if (result == NULL && !PyErr_Occurred())
  		PyErr_SetString(PyExc_SystemError,
***************
*** 2652,2772 ****
  
  static PyObject *
! call_builtin(PyObject *func, PyObject *arg, PyObject *kw)
  {
! 	if (PyCFunction_Check(func)) {
! 		PyCFunctionObject* f = (PyCFunctionObject*) func;
! 		PyCFunction meth = PyCFunction_GetFunction(func);
! 		PyObject *self = PyCFunction_GetSelf(func);
! 		int flags = PyCFunction_GetFlags(func);
! 		if (!(flags & METH_VARARGS)) {
! 			int size = PyTuple_Size(arg);
! 			if (size == 1)
! 				arg = PyTuple_GET_ITEM(arg, 0);
! 			else if (size == 0)
! 				arg = NULL;
! 		}
! 		if (flags & METH_KEYWORDS)
! 			return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
! 		if (kw != NULL && PyDict_Size(kw) != 0) {
! 			PyErr_Format(PyExc_TypeError,
! 				"%.200s() takes no keyword arguments",
! 				f->m_ml->ml_name);
! 			return NULL;
  		}
  		return (*meth)(self, arg);
  	}
! 	if (PyClass_Check(func)) {
! 		return PyInstance_New(func, arg, kw);
  	}
! 	if (PyInstance_Check(func)) {
! 	        PyObject *res, *call = PyObject_GetAttrString(func, "__call__");
! 		if (call == NULL) {
! 			PyInstanceObject *inst = (PyInstanceObject*) func;
! 			PyErr_Clear();
! 			PyErr_Format(PyExc_AttributeError,
! 				"%.200s instance has no __call__ method",
! 				PyString_AsString(inst->in_class->cl_name));
! 			return NULL;
! 		}
! 		res = PyEval_CallObjectWithKeywords(call, arg, kw);
! 		Py_DECREF(call);
! 		return res;
  	}
! 	PyErr_Format(PyExc_TypeError, "call of non-function (type %.400s)",
! 		     func->ob_type->tp_name);
  	return NULL;
  }
  
  static PyObject *
! call_function(PyObject *func, PyObject *arg, PyObject *kw)
  {
! 	PyObject *class = NULL; /* == owner */
! 	PyObject *argdefs;
! 	PyObject **d, **k;
! 	int nk, nd;
! 	PyObject *result;
! 	
! 	if (kw != NULL && !PyDict_Check(kw)) {
! 		PyErr_BadInternalCall();
  		return NULL;
- 	}
- 	
- 	if (PyMethod_Check(func)) {
- 		PyObject *self = PyMethod_Self(func);
- 		class = PyMethod_Class(func);
- 		func = PyMethod_Function(func);
- 		if (self == NULL) {
- 			/* Unbound methods must be called with an instance of
- 			   the class (or a derived class) as first argument */
- 			if (PyTuple_Size(arg) >= 1) {
- 				self = PyTuple_GET_ITEM(arg, 0);
- 				if (self != NULL &&
- 				    PyInstance_Check(self) &&
- 				    PyClass_IsSubclass((PyObject *)
- 				      (((PyInstanceObject *)self)->in_class),
- 					       class))
- 					/* Handy-dandy */ ;
- 				else
- 					self = NULL;
- 			}
- 			if (self == NULL) {
- 				PyErr_SetString(PyExc_TypeError,
- 	   "unbound method must be called with instance as first argument");
- 				return NULL;
- 			}
- 			Py_INCREF(arg);
- 		}
- 		else {
- 			int argcount = PyTuple_Size(arg);
- 			PyObject *newarg = PyTuple_New(argcount + 1);
- 			int i;
- 			if (newarg == NULL)
- 				return NULL;
- 			Py_INCREF(self);
- 			PyTuple_SET_ITEM(newarg, 0, self);
- 			for (i = 0; i < argcount; i++) {
- 				PyObject *v = PyTuple_GET_ITEM(arg, i);
- 				Py_XINCREF(v);
- 				PyTuple_SET_ITEM(newarg, i+1, v);
- 			}
- 			arg = newarg;
- 		}
- 		if (!PyFunction_Check(func)) {
- 			result = PyEval_CallObjectWithKeywords(func, arg, kw);
- 			Py_DECREF(arg);
- 			return result;
- 		}
  	}
! 	else {
! 		if (!PyFunction_Check(func)) {
! 			PyErr_Format(PyExc_TypeError,
! 				     "call of non-function (type %.200s)",
! 				     func->ob_type->tp_name);
  			return NULL;
  		}
  		Py_INCREF(arg);
  	}
! 	
! 	argdefs = PyFunction_GetDefaults(func);
  	if (argdefs != NULL && PyTuple_Check(argdefs)) {
  		d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0);
--- 2601,2714 ----
  
  static PyObject *
! call_cfunction(PyObject *func, PyObject *arg, PyObject *kw)
  {
! 	PyCFunctionObject* f = (PyCFunctionObject*)func;
! 	PyCFunction meth = PyCFunction_GET_FUNCTION(func);
! 	PyObject *self = PyCFunction_GET_SELF(func);
! 	int flags = PyCFunction_GET_FLAGS(func);
! 
! 	if (flags & METH_KEYWORDS && kw == NULL) {
! 		static PyObject *dict = NULL;
! 		if (dict == NULL) {
! 			dict = PyDict_New();
! 			if (dict == NULL)
! 				return NULL;
  		}
+ 		kw = dict;
+ 		Py_INCREF(dict);
+ 	}
+ 	if (flags & METH_VARARGS && kw == NULL) {
  		return (*meth)(self, arg);
  	}
! 	if (flags & METH_KEYWORDS) {
! 		return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
  	}
! 	if (!(flags & METH_VARARGS)) {
! 		int size = PyTuple_GET_SIZE(arg);
! 		if (size == 1)
! 			arg = PyTuple_GET_ITEM(arg, 0);
! 		else if (size == 0)
! 			arg = NULL;
! 		return (*meth)(self, arg);
  	}
! 	if (kw != NULL && PyDict_Size(kw) != 0) {
! 		PyErr_Format(PyExc_TypeError,
! 			     "%.200s() takes no keyword arguments",
! 			     f->m_ml->ml_name);
! 		return NULL;
! 	}
! 	/* should never get here ??? */
! 	PyErr_BadInternalCall();
  	return NULL;
  }
  
  static PyObject *
! call_instance(PyObject *func, PyObject *arg, PyObject *kw)
  {
! 	PyObject *res, *call = PyObject_GetAttrString(func, "__call__");
! 	if (call == NULL) {
! 		PyInstanceObject *inst = (PyInstanceObject*) func;
! 		PyErr_Clear();
! 		PyErr_Format(PyExc_AttributeError,
! 			     "%.200s instance has no __call__ method",
! 			     PyString_AsString(inst->in_class->cl_name));
  		return NULL;
  	}
! 	res = call_object(call, arg, kw);
! 	Py_DECREF(call);
! 	return res;
! }
! 
! static PyObject *
! call_method(PyObject *func, PyObject *arg, PyObject *kw)
! {
! 	PyObject *self = PyMethod_GET_SELF(func);
! 	PyObject *class = PyMethod_GET_CLASS(func);
! 	PyObject *result;
! 
! 	func = PyMethod_GET_FUNCTION(func);
! 	if (self == NULL) {
! 		/* Unbound methods must be called with an instance of
! 		   the class (or a derived class) as first argument */
! 		if (PyTuple_Size(arg) >= 1)
! 			self = PyTuple_GET_ITEM(arg, 0);
! 		if (!(self != NULL && PyInstance_Check(self)
! 		    && PyClass_IsSubclass((PyObject *)
! 				  (((PyInstanceObject *)self)->in_class),
! 					  class))) {
! 		PyErr_SetString(PyExc_TypeError,
! 	"unbound method must be called with instance as first argument");
  			return NULL;
  		}
  		Py_INCREF(arg);
+ 	} else {
+ 		int argcount = PyTuple_Size(arg);
+ 		PyObject *newarg = PyTuple_New(argcount + 1);
+ 		int i;
+ 		if (newarg == NULL)
+ 			return NULL;
+ 		Py_INCREF(self);
+ 		PyTuple_SET_ITEM(newarg, 0, self);
+ 		for (i = 0; i < argcount; i++) {
+ 			PyObject *v = PyTuple_GET_ITEM(arg, i);
+ 			Py_XINCREF(v);
+ 			PyTuple_SET_ITEM(newarg, i+1, v);
+ 		}
+ 		arg = newarg;
  	}
! 	result = call_object(func, arg, kw);
! 	Py_DECREF(arg);
! 	return result;
! }
! 
! static PyObject *
! call_eval_code2(PyObject *func, PyObject *arg, PyObject *kw)
! {
! 	PyObject *result;
! 	PyObject *argdefs;
! 	PyObject **d, **k;
! 	int nk, nd;
! 
! 	argdefs = PyFunction_GET_DEFAULTS(func);
  	if (argdefs != NULL && PyTuple_Check(argdefs)) {
  		d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0);
***************
*** 2799,2813 ****
  	
  	result = eval_code2(
! 		(PyCodeObject *)PyFunction_GetCode(func),
! 		PyFunction_GetGlobals(func), (PyObject *)NULL,
  		&PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg),
  		k, nk,
! 		d, nd,
! 		class);
  	
- 	Py_DECREF(arg);
  	if (k != NULL)
  		PyMem_DEL(k);
  	
  	return result;
  }
--- 2741,2946 ----
  	
  	result = eval_code2(
! 		(PyCodeObject *)PyFunction_GET_CODE(func),
! 		PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
  		&PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg),
  		k, nk,
! 		d, nd);
  	
  	if (k != NULL)
  		PyMem_DEL(k);
  	
+ 	return result;
+ }
+ 
+ #define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
+ 
+ /* The two fast_xxx() functions optimize calls for which no argument
+    tuple is necessary; the objects are passed directly from the stack.
+    fast_cfunction() is called for METH_OLDARGS functions.
+    fast_function() is for functions with no special argument handling.
+ */
+ 
+ static PyObject *
+ fast_cfunction(PyObject *func, PyObject ***pp_stack, int na)
+ {
+ 	PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+ 	PyObject *self = PyCFunction_GET_SELF(func);
+ 
+ 	if (na == 0)
+ 		return (*meth)(self, NULL);
+ 	else if (na == 1)
+ 		return (*meth)(self, EXT_POP(*pp_stack));
+ 	else {
+ 		PyObject *args = load_args(pp_stack, na);
+ 		PyObject *result = (*meth)(self, args);
+ 		Py_DECREF(args);
+ 		return result;
+ 	}
+ }
+ 
+ static PyObject *
+ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)  
+ {
+ 	PyObject *co = PyFunction_GET_CODE(func);
+ 	PyObject *globals = PyFunction_GET_GLOBALS(func);
+ 	PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
+ 	PyObject **d = NULL;
+ 	int nd = 0;
+ 
+ 	if (argdefs != NULL) {
+ 		d = &PyTuple_GET_ITEM(argdefs, 0);
+ 		nd = ((PyTupleObject *)argdefs)->ob_size;
+ 	}
+ 	return eval_code2((PyCodeObject *)co, globals, 
+ 			  (PyObject *)NULL, (*pp_stack)-n, na,
+ 			  (*pp_stack)-2*nk, nk, d, nd);
+ }
+ 
+ static PyObject *
+ update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack)
+ {
+ 	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, 
+ 				     "keyword parameter '%.400s' "
+ 				     "redefined in function call",
+ 				     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);
+ 		if (kwdict == NULL)
+ 			goto call_fail;
+ 	}
+ 	callargs = load_args(pp_stack, na);
+ 	if (callargs == NULL)
+ 		goto call_fail;
+ 	result = call_object(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_SetString(PyExc_TypeError,
+ 					"** argument must be a dictionary");
+ 			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_SetString(PyExc_TypeError,
+ 					"* argument must be a sequence");
+ 			    }
+ 				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);
+ 		if (kwdict == NULL)
+ 			goto ext_call_fail;
+ 	}
+ 	callargs = update_star_args(na, nstar, stararg, pp_stack);
+ 	if (callargs == NULL)
+ 		goto ext_call_fail;
+ 	result = call_object(func, callargs, kwdict);
+       ext_call_fail:
+ 	Py_XDECREF(callargs);
+ 	Py_XDECREF(kwdict);
+ 	Py_XDECREF(stararg);
  	return result;
  }