tupleobject.c 12.7 KB
Newer Older
1
/***********************************************************
2 3
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.
4 5 6

                        All Rights Reserved

7 8
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
9
provided that the above copyright notice appear in all copies and that
10
both that copyright notice and this permission notice appear in
11
supporting documentation, and that the names of Stichting Mathematisch
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
Centrum or CWI or Corporation for National Research Initiatives or
CNRI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

While CWI is the initial source for this software, a modified version
is made available by the Corporation for National Research Initiatives
(CNRI) at the Internet address ftp://ftp.python.org.

STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
29 30 31

******************************************************************/

Guido van Rossum's avatar
Guido van Rossum committed
32 33
/* Tuple object implementation */

34
#include "Python.h"
Guido van Rossum's avatar
Guido van Rossum committed
35

36
/* Speed optimization to avoid frequent malloc/free of small tuples */
37
#ifndef MAXSAVESIZE
38 39 40 41
#define MAXSAVESIZE	20  /* Largest tuple to save on free list */
#endif
#ifndef MAXSAVEDTUPLES 
#define MAXSAVEDTUPLES  2000  /* Maximum number of tuples of each size to save */
42 43 44
#endif

#if MAXSAVESIZE > 0
45
/* Entries 1 up to MAXSAVESIZE are free lists, entry 0 is the empty
46 47
   tuple () of which at most one instance will be allocated.
*/
48
static PyTupleObject *free_tuples[MAXSAVESIZE];
49
static int num_free_tuples[MAXSAVESIZE];
50 51 52 53 54 55
#endif
#ifdef COUNT_ALLOCS
int fast_tuple_allocs;
int tuple_zero_allocs;
#endif

56 57
PyObject *
PyTuple_New(size)
Guido van Rossum's avatar
Guido van Rossum committed
58 59 60
	register int size;
{
	register int i;
61
	register PyTupleObject *op;
Guido van Rossum's avatar
Guido van Rossum committed
62
	if (size < 0) {
63
		PyErr_BadInternalCall();
Guido van Rossum's avatar
Guido van Rossum committed
64 65
		return NULL;
	}
66
#if MAXSAVESIZE > 0
67 68
	if (size == 0 && free_tuples[0]) {
		op = free_tuples[0];
69
		Py_INCREF(op);
70 71 72
#ifdef COUNT_ALLOCS
		tuple_zero_allocs++;
#endif
73
		return (PyObject *) op;
74
	}
75 76 77 78
	if (0 < size && size < MAXSAVESIZE &&
	    (op = free_tuples[size]) != NULL)
	{
		free_tuples[size] = (PyTupleObject *) op->ob_item[0];
79
		num_free_tuples[size]--;
80 81
#ifdef COUNT_ALLOCS
		fast_tuple_allocs++;
82
#endif
83
		/* PyObject_InitVar is inlined */
84 85
#ifdef Py_TRACE_REFS
		op->ob_size = size;
86
		op->ob_type = &PyTuple_Type;
87
#endif
88
		_Py_NewReference((PyObject *)op);
89 90
	}
	else
91 92
#endif
	{
93 94 95 96 97 98 99 100
		int nbytes = size * sizeof(PyObject *);
		/* Check for overflow */
		if (nbytes / sizeof(PyObject *) != (size_t)size ||
		    (nbytes += sizeof(PyTupleObject) - sizeof(PyObject *))
		    <= 0)
		{
			return PyErr_NoMemory();
		}
101 102
		/* PyObject_NewVar is inlined */
		op = (PyTupleObject *) PyObject_MALLOC(nbytes);
103
		if (op == NULL)
104
			return PyErr_NoMemory();
105

106
		PyObject_INIT_VAR(op, &PyTuple_Type, size);
107
	}
Guido van Rossum's avatar
Guido van Rossum committed
108 109
	for (i = 0; i < size; i++)
		op->ob_item[i] = NULL;
110 111
#if MAXSAVESIZE > 0
	if (size == 0) {
112
		free_tuples[0] = op;
113
		++num_free_tuples[0];
114
		Py_INCREF(op);	/* extra INCREF so that this is never freed */
115 116
	}
#endif
117
	return (PyObject *) op;
Guido van Rossum's avatar
Guido van Rossum committed
118 119 120
}

int
121 122
PyTuple_Size(op)
	register PyObject *op;
Guido van Rossum's avatar
Guido van Rossum committed
123
{
124 125
	if (!PyTuple_Check(op)) {
		PyErr_BadInternalCall();
Guido van Rossum's avatar
Guido van Rossum committed
126 127 128
		return -1;
	}
	else
129
		return ((PyTupleObject *)op)->ob_size;
Guido van Rossum's avatar
Guido van Rossum committed
130 131
}

132 133 134
PyObject *
PyTuple_GetItem(op, i)
	register PyObject *op;
Guido van Rossum's avatar
Guido van Rossum committed
135 136
	register int i;
{
137 138
	if (!PyTuple_Check(op)) {
		PyErr_BadInternalCall();
Guido van Rossum's avatar
Guido van Rossum committed
139 140
		return NULL;
	}
141 142
	if (i < 0 || i >= ((PyTupleObject *)op) -> ob_size) {
		PyErr_SetString(PyExc_IndexError, "tuple index out of range");
Guido van Rossum's avatar
Guido van Rossum committed
143 144
		return NULL;
	}
145
	return ((PyTupleObject *)op) -> ob_item[i];
Guido van Rossum's avatar
Guido van Rossum committed
146 147 148
}

int
149 150
PyTuple_SetItem(op, i, newitem)
	register PyObject *op;
Guido van Rossum's avatar
Guido van Rossum committed
151
	register int i;
152
	PyObject *newitem;
Guido van Rossum's avatar
Guido van Rossum committed
153
{
154 155
	register PyObject *olditem;
	register PyObject **p;
156
	if (!PyTuple_Check(op) || op->ob_refcnt != 1) {
157 158
		Py_XDECREF(newitem);
		PyErr_BadInternalCall();
Guido van Rossum's avatar
Guido van Rossum committed
159
		return -1;
Guido van Rossum's avatar
Guido van Rossum committed
160
	}
161 162 163 164
	if (i < 0 || i >= ((PyTupleObject *)op) -> ob_size) {
		Py_XDECREF(newitem);
		PyErr_SetString(PyExc_IndexError,
				"tuple assignment index out of range");
Guido van Rossum's avatar
Guido van Rossum committed
165
		return -1;
Guido van Rossum's avatar
Guido van Rossum committed
166
	}
167
	p = ((PyTupleObject *)op) -> ob_item + i;
168 169
	olditem = *p;
	*p = newitem;
170
	Py_XDECREF(olditem);
Guido van Rossum's avatar
Guido van Rossum committed
171 172 173 174 175 176 177
	return 0;
}

/* Methods */

static void
tupledealloc(op)
178
	register PyTupleObject *op;
Guido van Rossum's avatar
Guido van Rossum committed
179 180
{
	register int i;
181
	register int len =  op->ob_size;
182
	Py_TRASHCAN_SAFE_BEGIN(op)
183 184
	if (len > 0) {
		i = len;
185 186
		while (--i >= 0)
			Py_XDECREF(op->ob_item[i]);
187
#if MAXSAVESIZE > 0
188 189 190 191
		if (len < MAXSAVESIZE && num_free_tuples[len] < MAXSAVEDTUPLES) {
			op->ob_item[0] = (PyObject *) free_tuples[len];
			num_free_tuples[len]++;
			free_tuples[len] = op;
192
			goto done; /* return */
193
		}
194
#endif
195
	}
196
	PyObject_DEL(op);
197 198
done:
	Py_TRASHCAN_SAFE_END(op)
Guido van Rossum's avatar
Guido van Rossum committed
199 200
}

201
static int
Guido van Rossum's avatar
Guido van Rossum committed
202
tupleprint(op, fp, flags)
203
	PyTupleObject *op;
Guido van Rossum's avatar
Guido van Rossum committed
204 205 206 207 208
	FILE *fp;
	int flags;
{
	int i;
	fprintf(fp, "(");
209 210
	for (i = 0; i < op->ob_size; i++) {
		if (i > 0)
Guido van Rossum's avatar
Guido van Rossum committed
211
			fprintf(fp, ", ");
212
		if (PyObject_Print(op->ob_item[i], fp, 0) != 0)
213
			return -1;
Guido van Rossum's avatar
Guido van Rossum committed
214 215 216 217
	}
	if (op->ob_size == 1)
		fprintf(fp, ",");
	fprintf(fp, ")");
218
	return 0;
Guido van Rossum's avatar
Guido van Rossum committed
219 220
}

221
static PyObject *
Guido van Rossum's avatar
Guido van Rossum committed
222
tuplerepr(v)
223
	PyTupleObject *v;
Guido van Rossum's avatar
Guido van Rossum committed
224
{
225
	PyObject *s, *comma;
Guido van Rossum's avatar
Guido van Rossum committed
226
	int i;
227 228
	s = PyString_FromString("(");
	comma = PyString_FromString(", ");
Guido van Rossum's avatar
Guido van Rossum committed
229 230
	for (i = 0; i < v->ob_size && s != NULL; i++) {
		if (i > 0)
231 232
			PyString_Concat(&s, comma);
		PyString_ConcatAndDel(&s, PyObject_Repr(v->ob_item[i]));
Guido van Rossum's avatar
Guido van Rossum committed
233
	}
234
	Py_DECREF(comma);
235
	if (v->ob_size == 1)
236 237
		PyString_ConcatAndDel(&s, PyString_FromString(","));
	PyString_ConcatAndDel(&s, PyString_FromString(")"));
Guido van Rossum's avatar
Guido van Rossum committed
238 239 240 241 242
	return s;
}

static int
tuplecompare(v, w)
243
	register PyTupleObject *v, *w;
Guido van Rossum's avatar
Guido van Rossum committed
244 245 246 247 248
{
	register int len =
		(v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
	register int i;
	for (i = 0; i < len; i++) {
249
		int cmp = PyObject_Compare(v->ob_item[i], w->ob_item[i]);
Guido van Rossum's avatar
Guido van Rossum committed
250 251 252 253 254 255
		if (cmp != 0)
			return cmp;
	}
	return v->ob_size - w->ob_size;
}

256 257
static long
tuplehash(v)
258
	PyTupleObject *v;
259 260 261
{
	register long x, y;
	register int len = v->ob_size;
262
	register PyObject **p;
263 264 265
	x = 0x345678L;
	p = v->ob_item;
	while (--len >= 0) {
266
		y = PyObject_Hash(*p++);
267 268
		if (y == -1)
			return -1;
269
		x = (1000003*x) ^ y;
270 271 272 273 274 275 276
	}
	x ^= v->ob_size;
	if (x == -1)
		x = -2;
	return x;
}

Guido van Rossum's avatar
Guido van Rossum committed
277 278
static int
tuplelength(a)
279
	PyTupleObject *a;
Guido van Rossum's avatar
Guido van Rossum committed
280 281 282 283
{
	return a->ob_size;
}

284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
static int
tuplecontains(a, el)
	PyTupleObject *a;
	PyObject *el;
{
	int i, cmp;

	for (i = 0; i < a->ob_size; ++i) {
		cmp = PyObject_Compare(el, PyTuple_GET_ITEM(a, i));
		if (cmp == 0)
			return 1;
		if (PyErr_Occurred())
			return -1;
	}
	return 0;
}

301
static PyObject *
Guido van Rossum's avatar
Guido van Rossum committed
302
tupleitem(a, i)
303
	register PyTupleObject *a;
Guido van Rossum's avatar
Guido van Rossum committed
304 305 306
	register int i;
{
	if (i < 0 || i >= a->ob_size) {
307
		PyErr_SetString(PyExc_IndexError, "tuple index out of range");
Guido van Rossum's avatar
Guido van Rossum committed
308 309
		return NULL;
	}
310
	Py_INCREF(a->ob_item[i]);
Guido van Rossum's avatar
Guido van Rossum committed
311 312 313
	return a->ob_item[i];
}

314
static PyObject *
Guido van Rossum's avatar
Guido van Rossum committed
315
tupleslice(a, ilow, ihigh)
316
	register PyTupleObject *a;
Guido van Rossum's avatar
Guido van Rossum committed
317 318
	register int ilow, ihigh;
{
319
	register PyTupleObject *np;
Guido van Rossum's avatar
Guido van Rossum committed
320 321 322 323 324 325 326 327 328
	register int i;
	if (ilow < 0)
		ilow = 0;
	if (ihigh > a->ob_size)
		ihigh = a->ob_size;
	if (ihigh < ilow)
		ihigh = ilow;
	if (ilow == 0 && ihigh == a->ob_size) {
		/* XXX can only do this if tuples are immutable! */
329 330
		Py_INCREF(a);
		return (PyObject *)a;
Guido van Rossum's avatar
Guido van Rossum committed
331
	}
332
	np = (PyTupleObject *)PyTuple_New(ihigh - ilow);
Guido van Rossum's avatar
Guido van Rossum committed
333 334 335
	if (np == NULL)
		return NULL;
	for (i = ilow; i < ihigh; i++) {
336 337
		PyObject *v = a->ob_item[i];
		Py_INCREF(v);
Guido van Rossum's avatar
Guido van Rossum committed
338 339
		np->ob_item[i - ilow] = v;
	}
340
	return (PyObject *)np;
Guido van Rossum's avatar
Guido van Rossum committed
341 342
}

343 344 345
PyObject *
PyTuple_GetSlice(op, i, j)
	PyObject *op;
346 347
	int i, j;
{
348 349
	if (op == NULL || !PyTuple_Check(op)) {
		PyErr_BadInternalCall();
350 351
		return NULL;
	}
352
	return tupleslice((PyTupleObject *)op, i, j);
353 354
}

355
static PyObject *
Guido van Rossum's avatar
Guido van Rossum committed
356
tupleconcat(a, bb)
357 358
	register PyTupleObject *a;
	register PyObject *bb;
Guido van Rossum's avatar
Guido van Rossum committed
359 360 361
{
	register int size;
	register int i;
362 363 364
	PyTupleObject *np;
	if (!PyTuple_Check(bb)) {
		PyErr_BadArgument();
Guido van Rossum's avatar
Guido van Rossum committed
365 366
		return NULL;
	}
367
#define b ((PyTupleObject *)bb)
Guido van Rossum's avatar
Guido van Rossum committed
368
	size = a->ob_size + b->ob_size;
369
	np = (PyTupleObject *) PyTuple_New(size);
Guido van Rossum's avatar
Guido van Rossum committed
370
	if (np == NULL) {
371
		return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
372 373
	}
	for (i = 0; i < a->ob_size; i++) {
374 375
		PyObject *v = a->ob_item[i];
		Py_INCREF(v);
Guido van Rossum's avatar
Guido van Rossum committed
376 377 378
		np->ob_item[i] = v;
	}
	for (i = 0; i < b->ob_size; i++) {
379 380
		PyObject *v = b->ob_item[i];
		Py_INCREF(v);
Guido van Rossum's avatar
Guido van Rossum committed
381 382
		np->ob_item[i + a->ob_size] = v;
	}
383
	return (PyObject *)np;
Guido van Rossum's avatar
Guido van Rossum committed
384 385 386
#undef b
}

387
static PyObject *
388
tuplerepeat(a, n)
389
	PyTupleObject *a;
390 391 392 393
	int n;
{
	int i, j;
	int size;
394 395
	PyTupleObject *np;
	PyObject **p;
396 397
	if (n < 0)
		n = 0;
398
	if (a->ob_size == 0 || n == 1) {
399 400
		/* Since tuples are immutable, we can return a shared
		   copy in this case */
401 402
		Py_INCREF(a);
		return (PyObject *)a;
403 404
	}
	size = a->ob_size * n;
405
	if (size/a->ob_size != n)
406
		return PyErr_NoMemory();
407
	np = (PyTupleObject *) PyTuple_New(size);
408 409 410 411 412 413
	if (np == NULL)
		return NULL;
	p = np->ob_item;
	for (i = 0; i < n; i++) {
		for (j = 0; j < a->ob_size; j++) {
			*p = a->ob_item[j];
414
			Py_INCREF(*p);
415 416 417
			p++;
		}
	}
418
	return (PyObject *) np;
419 420
}

421
static PySequenceMethods tuple_as_sequence = {
422 423 424 425 426
	(inquiry)tuplelength, /*sq_length*/
	(binaryfunc)tupleconcat, /*sq_concat*/
	(intargfunc)tuplerepeat, /*sq_repeat*/
	(intargfunc)tupleitem, /*sq_item*/
	(intintargfunc)tupleslice, /*sq_slice*/
Guido van Rossum's avatar
Guido van Rossum committed
427 428
	0,		/*sq_ass_item*/
	0,		/*sq_ass_slice*/
429
	(objobjproc)tuplecontains, /*sq_contains*/
Guido van Rossum's avatar
Guido van Rossum committed
430 431
};

432 433
PyTypeObject PyTuple_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum's avatar
Guido van Rossum committed
434 435
	0,
	"tuple",
436 437
	sizeof(PyTupleObject) - sizeof(PyObject *),
	sizeof(PyObject *),
438 439
	(destructor)tupledealloc, /*tp_dealloc*/
	(printfunc)tupleprint, /*tp_print*/
Guido van Rossum's avatar
Guido van Rossum committed
440 441
	0,		/*tp_getattr*/
	0,		/*tp_setattr*/
442 443
	(cmpfunc)tuplecompare, /*tp_compare*/
	(reprfunc)tuplerepr, /*tp_repr*/
Guido van Rossum's avatar
Guido van Rossum committed
444 445 446
	0,		/*tp_as_number*/
	&tuple_as_sequence,	/*tp_as_sequence*/
	0,		/*tp_as_mapping*/
447
	(hashfunc)tuplehash, /*tp_hash*/
Guido van Rossum's avatar
Guido van Rossum committed
448
};
449 450 451 452 453 454

/* The following function breaks the notion that tuples are immutable:
   it changes the size of a tuple.  We get away with this only if there
   is only one module referencing the object.  You can also think of it
   as creating a new tuple object and destroying the old one, only
   more efficiently.  In any case, don't use this if the tuple may
455 456 457
   already be known to some other part of the code...
   If last_is_sticky is set, the tuple will grow or shrink at the
   front, otherwise it will grow or shrink at the end. */
458 459

int
460 461
_PyTuple_Resize(pv, newsize, last_is_sticky)
	PyObject **pv;
462
	int newsize;
463
	int last_is_sticky;
464
{
465 466
	register PyTupleObject *v;
	register PyTupleObject *sv;
467 468 469
	int i;
	int sizediff;

470 471
	v = (PyTupleObject *) *pv;
	if (v == NULL || !PyTuple_Check(v) || v->ob_refcnt != 1) {
472
		*pv = 0;
473 474
		Py_DECREF(v);
		PyErr_BadInternalCall();
475 476
		return -1;
	}
477
	sizediff = newsize - v->ob_size;
478 479
	if (sizediff == 0)
		return 0;
480
	/* XXX UNREF/NEWREF interface should be more symmetrical */
481
#ifdef Py_REF_DEBUG
482
	--_Py_RefTotal;
483
#endif
484
	_Py_ForgetReference((PyObject *)v);
485
	if (last_is_sticky && sizediff < 0) {
486 487
		/* shrinking:
		   move entries to the front and zero moved entries */
488
		for (i = 0; i < newsize; i++) {
489
			Py_XDECREF(v->ob_item[i]);
490 491 492 493 494
			v->ob_item[i] = v->ob_item[i - sizediff];
			v->ob_item[i - sizediff] = NULL;
		}
	}
	for (i = newsize; i < v->ob_size; i++) {
495
		Py_XDECREF(v->ob_item[i]);
496 497
		v->ob_item[i] = NULL;
	}
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
#if MAXSAVESIZE > 0
	if (newsize == 0 && free_tuples[0]) {
		num_free_tuples[0]--;
		sv = free_tuples[0];
		sv->ob_size = 0;
		Py_INCREF(sv);
#ifdef COUNT_ALLOCS
		tuple_zero_allocs++;
#endif
		tupledealloc(v);
		*pv = (PyObject*) sv;
		return 0;
	}
	if (0 < newsize && newsize < MAXSAVESIZE &&
	    (sv = free_tuples[newsize]) != NULL)
	{
		free_tuples[newsize] = (PyTupleObject *) sv->ob_item[0];
		num_free_tuples[newsize]--;
#ifdef COUNT_ALLOCS
		fast_tuple_allocs++;
#endif
#ifdef Py_TRACE_REFS 
		sv->ob_type = &PyTuple_Type; 
#endif 
		for (i = 0; i < newsize; ++i){
			sv->ob_item[i] = v->ob_item[i];
			v->ob_item[i] = NULL;
		}
		sv->ob_size = v->ob_size;
		tupledealloc(v);
		*pv = (PyObject *) sv;
	} else 
#endif		
	{
		sv = (PyTupleObject *)
533
			PyObject_REALLOC((char *)v,
534 535 536
				sizeof(PyTupleObject) + newsize * sizeof(PyObject *));
		*pv = (PyObject *) sv;
		if (sv == NULL) {
537
			PyObject_DEL(v);
538 539 540
			PyErr_NoMemory();
			return -1;
		}
541
	}
542
	_Py_NewReference((PyObject *)sv);
543 544 545 546 547 548 549 550 551 552
	for (i = sv->ob_size; i < newsize; i++)
		sv->ob_item[i] = NULL;
	if (last_is_sticky && sizediff > 0) {
		/* growing: move entries to the end and zero moved entries */
		for (i = newsize - 1; i >= sizediff; i--) {
			sv->ob_item[i] = sv->ob_item[i - sizediff];
			sv->ob_item[i - sizediff] = NULL;
		}
	}
	sv->ob_size = newsize;
553 554
	return 0;
}
555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571

void
PyTuple_Fini()
{
#if MAXSAVESIZE > 0
	int i;

	Py_XDECREF(free_tuples[0]);
	free_tuples[0] = NULL;

	for (i = 1; i < MAXSAVESIZE; i++) {
		PyTupleObject *p, *q;
		p = free_tuples[i];
		free_tuples[i] = NULL;
		while (p) {
			q = p;
			p = (PyTupleObject *)(p->ob_item[0]);
572
			PyObject_DEL(q);
573 574 575 576
		}
	}
#endif
}