Remove much dead code from ceval.c
authorJeremy Hylton <jeremy@alum.mit.edu>
Sun, 12 Aug 2001 21:52:24 +0000 (21:52 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Sun, 12 Aug 2001 21:52:24 +0000 (21:52 +0000)
The descr changes moved the dispatch for calling objects from
call_object() in ceval.c to PyObject_Call() in abstract.c.
call_object() and the many functions it used in ceval.c were no longer
used, but were not removed.

Rename meth_call() as PyCFunction_Call() so that it can be called by
the CALL_FUNCTION opcode in ceval.c.

Also, fix error message that referred to PyEval_EvalCodeEx() by its
old name eval_code2().  (I'll probably refer to it by its old name,
too.)

Include/methodobject.h
Objects/methodobject.c
Python/ceval.c

index a205011e696726c7f9c75bbcc9135b3ad7d1066b..e47ebea76935b542b01141001b2120f7e5d5a0b8 100644 (file)
@@ -14,6 +14,7 @@ extern DL_IMPORT(PyTypeObject) PyCFunction_Type;
 typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
 typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *,
                                             PyObject *);
+typedef PyObject *(*PyNoArgsFunction)(PyObject *);
 
 extern DL_IMPORT(PyCFunction) PyCFunction_GetFunction(PyObject *);
 extern DL_IMPORT(PyObject *) PyCFunction_GetSelf(PyObject *);
@@ -27,6 +28,7 @@ extern DL_IMPORT(int) PyCFunction_GetFlags(PyObject *);
        (((PyCFunctionObject *)func) -> m_self)
 #define PyCFunction_GET_FLAGS(func) \
        (((PyCFunctionObject *)func) -> m_ml -> ml_flags)
+extern DL_IMPORT(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *);
 
 struct PyMethodDef {
     char       *ml_name;
@@ -44,6 +46,9 @@ extern DL_IMPORT(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *);
 #define METH_OLDARGS  0x0000
 #define METH_VARARGS  0x0001
 #define METH_KEYWORDS 0x0002
+/* METH_NOARGS and METH_O must not be combined with any other flag. */
+#define METH_NOARGS   0x0004
+#define METH_O        0x0008
 
 typedef struct PyMethodChain {
     PyMethodDef *methods;              /* Methods of this type */
index 56fbcc22fd9a05b6046effc5caa10c14cd54e905..9d430445c8e9132f2839b88716fcedd76220eb1e 100644 (file)
@@ -56,6 +56,40 @@ PyCFunction_GetFlags(PyObject *op)
        return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
 }
 
+PyObject *
+PyCFunction_Call(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) {
+               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;
+       }
+       if (flags & METH_VARARGS) {
+               return (*meth)(self, arg);
+       }
+       if (!(flags & METH_VARARGS)) {
+               /* the really old style */
+               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);
+       }
+       /* should never get here ??? */
+       PyErr_BadInternalCall();
+       return NULL;
+}
+
 /* Methods (the standard built-in methods, that is) */
 
 static void
@@ -163,40 +197,6 @@ meth_hash(PyCFunctionObject *a)
        return x;
 }
 
-static PyObject *
-meth_call(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) {
-               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;
-       }
-       if (flags & METH_VARARGS) {
-               return (*meth)(self, arg);
-       }
-       if (!(flags & METH_VARARGS)) {
-               /* the really old style */
-               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);
-       }
-       /* should never get here ??? */
-       PyErr_BadInternalCall();
-       return NULL;
-}
-
 
 PyTypeObject PyCFunction_Type = {
        PyObject_HEAD_INIT(&PyType_Type)
@@ -214,7 +214,7 @@ PyTypeObject PyCFunction_Type = {
        0,                                      /* tp_as_sequence */
        0,                                      /* tp_as_mapping */
        (hashfunc)meth_hash,                    /* tp_hash */
-       meth_call,                              /* tp_call */
+       PyCFunction_Call,                       /* tp_call */
        0,                                      /* tp_str */
        PyObject_GenericGetAttr,                /* tp_getattro */
        0,                                      /* tp_setattro */
index bf85f1112375a22be5a057203524ffaa253000e7..7e98a250405a9452b393ce8f0906bb3c81c2ef59 100644 (file)
@@ -34,11 +34,6 @@ typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);
 
 /* Forward declarations */
 static PyObject *eval_frame(PyFrameObject *);
-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);
@@ -1949,11 +1944,11 @@ eval_frame(PyFrameObject *f)
                            else if (flags == METH_VARARGS) {
                                    PyObject *callargs;
                                    callargs = load_args(&stack_pointer, na);
-                                   x = call_cfunction(func, callargs, NULL);
+                                   x = PyCFunction_Call(func, callargs, NULL);
                                    Py_XDECREF(callargs); 
-                           } else if (flags == 0) 
-                                   x = fast_cfunction(func,
-                                                      &stack_pointer, na);
+                           } else if (!(flags & METH_KEYWORDS))
+                                      x = fast_cfunction(func,
+                                                         &stack_pointer, na);
                    } else {
                            if (PyMethod_Check(func)
                                && PyMethod_GET_SELF(func) != NULL) {
@@ -2307,7 +2302,8 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
        PyObject *x, *u;
 
        if (globals == NULL) {
-               PyErr_SetString(PyExc_SystemError, "eval_code2: NULL globals");
+               PyErr_SetString(PyExc_SystemError, 
+                               "PyEval_EvalCodeEx: NULL globals");
                return NULL;
        }
 
@@ -3000,20 +2996,6 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
        return result;
 }
 
-/* How often is each kind of object called?  The answer depends on the
-   program.  An instrumented PyObject_Call() 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.
-*/
-
 char *
 PyEval_GetFuncName(PyObject *func)
 {
@@ -3051,190 +3033,6 @@ PyEval_GetFuncDesc(PyObject *func)
        }
 }
 
-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 of type '%.100s' is not callable",
-                            func->ob_type->tp_name);
-               return NULL;
-       }
-        if (result == NULL && !PyErr_Occurred())
-               PyErr_SetString(PyExc_SystemError,
-                          "NULL result without error in call_object");
-
-        return result;
-}
-
-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) {
-               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;
-       }
-       if (flags & METH_VARARGS) {
-               return (*meth)(self, arg);
-       }
-       if (!(flags & METH_VARARGS)) {
-               /* the really old style */
-               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);
-       }
-       /* 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 */
-               int ok;
-               if (PyTuple_Size(arg) >= 1)
-                       self = PyTuple_GET_ITEM(arg, 0);
-               if (self == NULL)
-                       ok = 0;
-               else {
-                       ok = PyObject_IsInstance(self, class);
-                       if (ok < 0)
-                               return NULL;
-               }
-               if (!ok) {
-                       PyErr_Format(PyExc_TypeError,
-                                    "unbound method %s%s must be "
-                                    "called with instance as first argument",
-                                    PyEval_GetFuncName(func),
-                                    PyEval_GetFuncDesc(func));
-                       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);
-               nd = PyTuple_Size(argdefs);
-       }
-       else {
-               d = NULL;
-               nd = 0;
-       }
-
-       if (kw != NULL) {
-               int pos, i;
-               nk = PyDict_Size(kw);
-               k = PyMem_NEW(PyObject *, 2*nk);
-               if (k == NULL) {
-                       PyErr_NoMemory();
-                       Py_DECREF(arg);
-                       return NULL;
-               }
-               pos = i = 0;
-               while (PyDict_Next(kw, &pos, &k[i], &k[i+1]))
-                       i += 2;
-               nk = i/2;
-               /* XXX This is broken if the caller deletes dict items! */
-       }
-       else {
-               k = NULL;
-               nk = 0;
-       }
-
-       result = PyEval_EvalCodeEx(
-               (PyCodeObject *)PyFunction_GET_CODE(func),
-               PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
-               &PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg),
-               k, nk, d, nd,
-               PyFunction_GET_CLOSURE(func));
-
-       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
@@ -3249,18 +3047,18 @@ 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) {
-               PyObject *arg = EXT_POP(*pp_stack);
-               PyObject *result =  (*meth)(self, arg);
-               Py_DECREF(arg);
-               return result;
-       } else {
-               PyObject *args = load_args(pp_stack, na);
-               PyObject *result = (*meth)(self, args);
-               Py_DECREF(args);
-               return result;
+       if (na == 0)
+               return (*meth)(self, NULL);
+       else if (na == 1) {
+               PyObject *arg = EXT_POP(*pp_stack);
+               PyObject *result =  (*meth)(self, arg);
+               Py_DECREF(arg);
+               return result;
+       } else {
+               PyObject *args = load_args(pp_stack, na);
+               PyObject *result = (*meth)(self, args);
+               Py_DECREF(args);
+               return result;
        }
 }