symbian-qemu-0.9.1-12/python-2.6.1/Objects/methodobject.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 
       
     2 /* Method object implementation */
       
     3 
       
     4 #include "Python.h"
       
     5 #include "structmember.h"
       
     6 
       
     7 /* Free list for method objects to safe malloc/free overhead
       
     8  * The m_self element is used to chain the objects.
       
     9  */
       
    10 static PyCFunctionObject *free_list = NULL;
       
    11 static int numfree = 0;
       
    12 #ifndef PyCFunction_MAXFREELIST
       
    13 #define PyCFunction_MAXFREELIST 256
       
    14 #endif
       
    15 
       
    16 PyObject *
       
    17 PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
       
    18 {
       
    19 	PyCFunctionObject *op;
       
    20 	op = free_list;
       
    21 	if (op != NULL) {
       
    22 		free_list = (PyCFunctionObject *)(op->m_self);
       
    23 		PyObject_INIT(op, &PyCFunction_Type);
       
    24 		numfree--;
       
    25 	}
       
    26 	else {
       
    27 		op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
       
    28 		if (op == NULL)
       
    29 			return NULL;
       
    30 	}
       
    31 	op->m_ml = ml;
       
    32 	Py_XINCREF(self);
       
    33 	op->m_self = self;
       
    34 	Py_XINCREF(module);
       
    35 	op->m_module = module;
       
    36 	_PyObject_GC_TRACK(op);
       
    37 	return (PyObject *)op;
       
    38 }
       
    39 
       
    40 PyCFunction
       
    41 PyCFunction_GetFunction(PyObject *op)
       
    42 {
       
    43 	if (!PyCFunction_Check(op)) {
       
    44 		PyErr_BadInternalCall();
       
    45 		return NULL;
       
    46 	}
       
    47 	return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
       
    48 }
       
    49 
       
    50 PyObject *
       
    51 PyCFunction_GetSelf(PyObject *op)
       
    52 {
       
    53 	if (!PyCFunction_Check(op)) {
       
    54 		PyErr_BadInternalCall();
       
    55 		return NULL;
       
    56 	}
       
    57 	return ((PyCFunctionObject *)op) -> m_self;
       
    58 }
       
    59 
       
    60 int
       
    61 PyCFunction_GetFlags(PyObject *op)
       
    62 {
       
    63 	if (!PyCFunction_Check(op)) {
       
    64 		PyErr_BadInternalCall();
       
    65 		return -1;
       
    66 	}
       
    67 	return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
       
    68 }
       
    69 
       
    70 PyObject *
       
    71 PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
       
    72 {
       
    73 	PyCFunctionObject* f = (PyCFunctionObject*)func;
       
    74 	PyCFunction meth = PyCFunction_GET_FUNCTION(func);
       
    75 	PyObject *self = PyCFunction_GET_SELF(func);
       
    76 	Py_ssize_t size;
       
    77 
       
    78 	switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
       
    79 	case METH_VARARGS:
       
    80 		if (kw == NULL || PyDict_Size(kw) == 0)
       
    81 			return (*meth)(self, arg);
       
    82 		break;
       
    83 	case METH_VARARGS | METH_KEYWORDS:
       
    84 	case METH_OLDARGS | METH_KEYWORDS:
       
    85 		return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
       
    86 	case METH_NOARGS:
       
    87 		if (kw == NULL || PyDict_Size(kw) == 0) {
       
    88 			size = PyTuple_GET_SIZE(arg);
       
    89 			if (size == 0)
       
    90 				return (*meth)(self, NULL);
       
    91 			PyErr_Format(PyExc_TypeError,
       
    92 			    "%.200s() takes no arguments (%zd given)",
       
    93 			    f->m_ml->ml_name, size);
       
    94 			return NULL;
       
    95 		}
       
    96 		break;
       
    97 	case METH_O:
       
    98 		if (kw == NULL || PyDict_Size(kw) == 0) {
       
    99 			size = PyTuple_GET_SIZE(arg);
       
   100 			if (size == 1)
       
   101 				return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
       
   102 			PyErr_Format(PyExc_TypeError,
       
   103 			    "%.200s() takes exactly one argument (%zd given)",
       
   104 			    f->m_ml->ml_name, size);
       
   105 			return NULL;
       
   106 		}
       
   107 		break;
       
   108 	case METH_OLDARGS:
       
   109 		/* the really old style */
       
   110 		if (kw == NULL || PyDict_Size(kw) == 0) {
       
   111 			size = PyTuple_GET_SIZE(arg);
       
   112 			if (size == 1)
       
   113 				arg = PyTuple_GET_ITEM(arg, 0);
       
   114 			else if (size == 0)
       
   115 				arg = NULL;
       
   116 			return (*meth)(self, arg);
       
   117 		}
       
   118 		break;
       
   119 	default:
       
   120 		PyErr_BadInternalCall();
       
   121 		return NULL;
       
   122 	}
       
   123 	PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
       
   124 		     f->m_ml->ml_name);
       
   125 	return NULL;
       
   126 }
       
   127 
       
   128 /* Methods (the standard built-in methods, that is) */
       
   129 
       
   130 static void
       
   131 meth_dealloc(PyCFunctionObject *m)
       
   132 {
       
   133 	_PyObject_GC_UNTRACK(m);
       
   134 	Py_XDECREF(m->m_self);
       
   135 	Py_XDECREF(m->m_module);
       
   136 	if (numfree < PyCFunction_MAXFREELIST) {
       
   137 		m->m_self = (PyObject *)free_list;
       
   138 		free_list = m;
       
   139 		numfree++;
       
   140 	}
       
   141 	else {
       
   142 		PyObject_GC_Del(m);
       
   143 	}
       
   144 }
       
   145 
       
   146 static PyObject *
       
   147 meth_get__doc__(PyCFunctionObject *m, void *closure)
       
   148 {
       
   149 	const char *doc = m->m_ml->ml_doc;
       
   150 
       
   151 	if (doc != NULL)
       
   152 		return PyString_FromString(doc);
       
   153 	Py_INCREF(Py_None);
       
   154 	return Py_None;
       
   155 }
       
   156 
       
   157 static PyObject *
       
   158 meth_get__name__(PyCFunctionObject *m, void *closure)
       
   159 {
       
   160 	return PyString_FromString(m->m_ml->ml_name);
       
   161 }
       
   162 
       
   163 static int
       
   164 meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
       
   165 {
       
   166 	Py_VISIT(m->m_self);
       
   167 	Py_VISIT(m->m_module);
       
   168 	return 0;
       
   169 }
       
   170 
       
   171 static PyObject *
       
   172 meth_get__self__(PyCFunctionObject *m, void *closure)
       
   173 {
       
   174 	PyObject *self;
       
   175 	if (PyEval_GetRestricted()) {
       
   176 		PyErr_SetString(PyExc_RuntimeError,
       
   177 			"method.__self__ not accessible in restricted mode");
       
   178 		return NULL;
       
   179 	}
       
   180 	self = m->m_self;
       
   181 	if (self == NULL)
       
   182 		self = Py_None;
       
   183 	Py_INCREF(self);
       
   184 	return self;
       
   185 }
       
   186 
       
   187 static PyGetSetDef meth_getsets [] = {
       
   188 	{"__doc__",  (getter)meth_get__doc__,  NULL, NULL},
       
   189 	{"__name__", (getter)meth_get__name__, NULL, NULL},
       
   190 	{"__self__", (getter)meth_get__self__, NULL, NULL},
       
   191 	{0}
       
   192 };
       
   193 
       
   194 #define OFF(x) offsetof(PyCFunctionObject, x)
       
   195 
       
   196 static PyMemberDef meth_members[] = {
       
   197 	{"__module__",    T_OBJECT,     OFF(m_module), PY_WRITE_RESTRICTED},
       
   198 	{NULL}
       
   199 };
       
   200 
       
   201 static PyObject *
       
   202 meth_repr(PyCFunctionObject *m)
       
   203 {
       
   204 	if (m->m_self == NULL)
       
   205 		return PyString_FromFormat("<built-in function %s>",
       
   206 					   m->m_ml->ml_name);
       
   207 	return PyString_FromFormat("<built-in method %s of %s object at %p>",
       
   208 				   m->m_ml->ml_name,
       
   209 				   m->m_self->ob_type->tp_name,
       
   210 				   m->m_self);
       
   211 }
       
   212 
       
   213 static int
       
   214 meth_compare(PyCFunctionObject *a, PyCFunctionObject *b)
       
   215 {
       
   216 	if (a->m_self != b->m_self)
       
   217 		return (a->m_self < b->m_self) ? -1 : 1;
       
   218 	if (a->m_ml->ml_meth == b->m_ml->ml_meth)
       
   219 		return 0;
       
   220 	if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
       
   221 		return -1;
       
   222 	else
       
   223 		return 1;
       
   224 }
       
   225 
       
   226 static PyObject *
       
   227 meth_richcompare(PyObject *self, PyObject *other, int op)
       
   228 {
       
   229 	PyCFunctionObject *a, *b;
       
   230 	PyObject *res;
       
   231 	int eq;
       
   232 
       
   233 	if ((op != Py_EQ && op != Py_NE) ||
       
   234 	    !PyCFunction_Check(self) ||
       
   235 	    !PyCFunction_Check(other))
       
   236 	{
       
   237 		/* Py3K warning if types are not equal and comparison isn't == or !=  */
       
   238 		if (PyErr_WarnPy3k("builtin_function_or_method inequality "
       
   239 				   "comparisons not supported in 3.x", 1) < 0) {
       
   240 			return NULL;
       
   241 		}
       
   242 
       
   243 		Py_INCREF(Py_NotImplemented);
       
   244 		return Py_NotImplemented;
       
   245 	}
       
   246 	a = (PyCFunctionObject *)self;
       
   247 	b = (PyCFunctionObject *)other;
       
   248 	eq = a->m_self == b->m_self;
       
   249 	if (eq)
       
   250 		eq = a->m_ml->ml_meth == b->m_ml->ml_meth;
       
   251 	if (op == Py_EQ)
       
   252 		res = eq ? Py_True : Py_False;
       
   253 	else
       
   254 		res = eq ? Py_False : Py_True;
       
   255 	Py_INCREF(res);
       
   256 	return res;
       
   257 }
       
   258 
       
   259 static long
       
   260 meth_hash(PyCFunctionObject *a)
       
   261 {
       
   262 	long x,y;
       
   263 	if (a->m_self == NULL)
       
   264 		x = 0;
       
   265 	else {
       
   266 		x = PyObject_Hash(a->m_self);
       
   267 		if (x == -1)
       
   268 			return -1;
       
   269 	}
       
   270 	y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
       
   271 	if (y == -1)
       
   272 		return -1;
       
   273 	x ^= y;
       
   274 	if (x == -1)
       
   275 		x = -2;
       
   276 	return x;
       
   277 }
       
   278 
       
   279 
       
   280 PyTypeObject PyCFunction_Type = {
       
   281 	PyVarObject_HEAD_INIT(&PyType_Type, 0)
       
   282 	"builtin_function_or_method",
       
   283 	sizeof(PyCFunctionObject),
       
   284 	0,
       
   285 	(destructor)meth_dealloc, 		/* tp_dealloc */
       
   286 	0,					/* tp_print */
       
   287 	0,					/* tp_getattr */
       
   288 	0,					/* tp_setattr */
       
   289 	(cmpfunc)meth_compare,			/* tp_compare */
       
   290 	(reprfunc)meth_repr,			/* tp_repr */
       
   291 	0,					/* tp_as_number */
       
   292 	0,					/* tp_as_sequence */
       
   293 	0,					/* tp_as_mapping */
       
   294 	(hashfunc)meth_hash,			/* tp_hash */
       
   295 	PyCFunction_Call,			/* tp_call */
       
   296 	0,					/* tp_str */
       
   297 	PyObject_GenericGetAttr,		/* tp_getattro */
       
   298 	0,					/* tp_setattro */
       
   299 	0,					/* tp_as_buffer */
       
   300 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
       
   301  	0,					/* tp_doc */
       
   302  	(traverseproc)meth_traverse,		/* tp_traverse */
       
   303 	0,					/* tp_clear */
       
   304 	meth_richcompare,					/* tp_richcompare */
       
   305 	0,					/* tp_weaklistoffset */
       
   306 	0,					/* tp_iter */
       
   307 	0,					/* tp_iternext */
       
   308 	0,					/* tp_methods */
       
   309 	meth_members,				/* tp_members */
       
   310 	meth_getsets,				/* tp_getset */
       
   311 	0,					/* tp_base */
       
   312 	0,					/* tp_dict */
       
   313 };
       
   314 
       
   315 /* List all methods in a chain -- helper for findmethodinchain */
       
   316 
       
   317 static PyObject *
       
   318 listmethodchain(PyMethodChain *chain)
       
   319 {
       
   320 	PyMethodChain *c;
       
   321 	PyMethodDef *ml;
       
   322 	int i, n;
       
   323 	PyObject *v;
       
   324 
       
   325 	n = 0;
       
   326 	for (c = chain; c != NULL; c = c->link) {
       
   327 		for (ml = c->methods; ml->ml_name != NULL; ml++)
       
   328 			n++;
       
   329 	}
       
   330 	v = PyList_New(n);
       
   331 	if (v == NULL)
       
   332 		return NULL;
       
   333 	i = 0;
       
   334 	for (c = chain; c != NULL; c = c->link) {
       
   335 		for (ml = c->methods; ml->ml_name != NULL; ml++) {
       
   336 			PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
       
   337 			i++;
       
   338 		}
       
   339 	}
       
   340 	if (PyErr_Occurred()) {
       
   341 		Py_DECREF(v);
       
   342 		return NULL;
       
   343 	}
       
   344 	PyList_Sort(v);
       
   345 	return v;
       
   346 }
       
   347 
       
   348 /* Find a method in a method chain */
       
   349 
       
   350 PyObject *
       
   351 Py_FindMethodInChain(PyMethodChain *chain, PyObject *self, const char *name)
       
   352 {
       
   353 	if (name[0] == '_' && name[1] == '_') {
       
   354 		if (strcmp(name, "__methods__") == 0) {
       
   355 			if (PyErr_WarnPy3k("__methods__ not supported in 3.x",
       
   356 					   1) < 0)
       
   357 				return NULL;
       
   358 			return listmethodchain(chain);
       
   359 		}
       
   360 		if (strcmp(name, "__doc__") == 0) {
       
   361 			const char *doc = self->ob_type->tp_doc;
       
   362 			if (doc != NULL)
       
   363 				return PyString_FromString(doc);
       
   364 		}
       
   365 	}
       
   366 	while (chain != NULL) {
       
   367 		PyMethodDef *ml = chain->methods;
       
   368 		for (; ml->ml_name != NULL; ml++) {
       
   369 			if (name[0] == ml->ml_name[0] &&
       
   370 			    strcmp(name+1, ml->ml_name+1) == 0)
       
   371 				/* XXX */
       
   372 				return PyCFunction_New(ml, self);
       
   373 		}
       
   374 		chain = chain->link;
       
   375 	}
       
   376 	PyErr_SetString(PyExc_AttributeError, name);
       
   377 	return NULL;
       
   378 }
       
   379 
       
   380 /* Find a method in a single method list */
       
   381 
       
   382 PyObject *
       
   383 Py_FindMethod(PyMethodDef *methods, PyObject *self, const char *name)
       
   384 {
       
   385 	PyMethodChain chain;
       
   386 	chain.methods = methods;
       
   387 	chain.link = NULL;
       
   388 	return Py_FindMethodInChain(&chain, self, name);
       
   389 }
       
   390 
       
   391 /* Clear out the free list */
       
   392 
       
   393 int
       
   394 PyCFunction_ClearFreeList(void)
       
   395 {
       
   396 	int freelist_size = numfree;
       
   397 	
       
   398 	while (free_list) {
       
   399 		PyCFunctionObject *v = free_list;
       
   400 		free_list = (PyCFunctionObject *)(v->m_self);
       
   401 		PyObject_GC_Del(v);
       
   402 		numfree--;
       
   403 	}
       
   404 	assert(numfree == 0);
       
   405 	return freelist_size;
       
   406 }
       
   407 
       
   408 void
       
   409 PyCFunction_Fini(void)
       
   410 {
       
   411 	(void)PyCFunction_ClearFreeList();
       
   412 }
       
   413 
       
   414 /* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
       
   415    but it's part of the API so we need to keep a function around that
       
   416    existing C extensions can call.
       
   417 */
       
   418 
       
   419 #undef PyCFunction_New
       
   420 PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *);
       
   421 
       
   422 PyObject *
       
   423 PyCFunction_New(PyMethodDef *ml, PyObject *self)
       
   424 {
       
   425 	return PyCFunction_NewEx(ml, self, NULL);
       
   426 }