Remove much dead code from ceval.c

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.)
This commit is contained in:
Jeremy Hylton 2001-08-12 21:52:24 +00:00
parent f65b1a175f
commit 910d7d46dc
3 changed files with 58 additions and 255 deletions

View 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 */

View 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 */

View 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;
}
}