blob: cccfa822b59d866a73e18edcca47dba608e739d9 [file] [log] [blame]
Vladimir Marangozov58e64a82000-09-03 23:47:08 +00001/* Parse tree node implementation */
2
Tim Peters1d6a7292000-09-26 06:11:54 +00003#include "Python.h"
Vladimir Marangozov58e64a82000-09-03 23:47:08 +00004#include "node.h"
5#include "errcode.h"
6
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007node *
Thomas Wouters23c9e002000-07-22 19:20:54 +00008PyNode_New(int type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009{
Guido van Rossum86bea461997-04-29 21:03:06 +000010 node *n = PyMem_NEW(node, 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011 if (n == NULL)
12 return NULL;
13 n->n_type = type;
14 n->n_str = NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000015 n->n_lineno = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000016 n->n_nchildren = 0;
17 n->n_child = NULL;
18 return n;
19}
20
Tim Peters755ebea2002-07-08 06:32:09 +000021/* See comments at XXXROUNDUP below. */
22static int
23fancy_roundup(int n)
24{
25 /* Round up to the closest power of 2 >= n. */
26 int result = 256;
27 assert(n > 128);
28 while (result < n)
29 result <<= 1;
30 return result;
31}
32
33/* A gimmick to make massive numbers of reallocs quicker. The result is
34 * a number >= the input. For n=0 we must return 0.
35 * For n=1, we return 1, to avoid wasting memory in common 1-child nodes
36 * (XXX are those actually common?).
37 * Else for n <= 128, round up to the closest multiple of 4. Why 4?
38 * Rounding up to a multiple of an exact power of 2 is very efficient.
39 * Else call fancy_roundup() to grow proportionately to n. We've got an
40 * extreme case then (like test_longexp.py), and on many platforms doing
41 * anything less than proportional growth leads to exorbitant runtime
42 * (e.g., MacPython), or extreme fragmentation of user address space (e.g.,
43 * Win98).
44 * This would be straightforward if a node stored its current capacity. The
45 * code is tricky to avoid that.
46 */
47#define XXXROUNDUP(n) ((n) == 1 ? 1 : \
48 (n) <= 128 ? (((n) + 3) & ~3) : \
49 fancy_roundup(n))
50
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000051
Jeremy Hylton94988062000-06-20 19:10:44 +000052int
Thomas Wouters23c9e002000-07-22 19:20:54 +000053PyNode_AddChild(register node *n1, int type, char *str, int lineno)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054{
Tim Peters755ebea2002-07-08 06:32:09 +000055 const int nch = n1->n_nchildren;
56 int current_capacity;
57 int required_capacity;
58 node *n;
59
Fred Drakeef8ace32000-08-24 00:32:09 +000060 if (nch == INT_MAX || nch < 0)
Jeremy Hylton94988062000-06-20 19:10:44 +000061 return E_OVERFLOW;
Tim Peters755ebea2002-07-08 06:32:09 +000062
63 current_capacity = XXXROUNDUP(nch);
64 required_capacity = XXXROUNDUP(nch + 1);
65 if (current_capacity < required_capacity) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066 n = n1->n_child;
Tim Peters755ebea2002-07-08 06:32:09 +000067 PyMem_RESIZE(n, node, required_capacity);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000068 if (n == NULL)
Jeremy Hylton94988062000-06-20 19:10:44 +000069 return E_NOMEM;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070 n1->n_child = n;
71 }
Tim Peters755ebea2002-07-08 06:32:09 +000072
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073 n = &n1->n_child[n1->n_nchildren++];
74 n->n_type = type;
75 n->n_str = str;
Guido van Rossum3f5da241990-12-20 15:06:42 +000076 n->n_lineno = lineno;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000077 n->n_nchildren = 0;
78 n->n_child = NULL;
Jeremy Hylton94988062000-06-20 19:10:44 +000079 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080}
Guido van Rossum03a24cd1990-11-18 17:37:06 +000081
Guido van Rossum3f5da241990-12-20 15:06:42 +000082/* Forward */
Tim Petersdbd9ba62000-07-09 03:09:57 +000083static void freechildren(node *);
Guido van Rossum3f5da241990-12-20 15:06:42 +000084
85
86void
Thomas Wouters23c9e002000-07-22 19:20:54 +000087PyNode_Free(node *n)
Guido van Rossum3f5da241990-12-20 15:06:42 +000088{
89 if (n != NULL) {
90 freechildren(n);
Guido van Rossum86bea461997-04-29 21:03:06 +000091 PyMem_DEL(n);
Guido van Rossum3f5da241990-12-20 15:06:42 +000092 }
93}
94
Guido van Rossum03a24cd1990-11-18 17:37:06 +000095static void
Thomas Wouters23c9e002000-07-22 19:20:54 +000096freechildren(node *n)
Guido van Rossum03a24cd1990-11-18 17:37:06 +000097{
98 int i;
99 for (i = NCH(n); --i >= 0; )
100 freechildren(CHILD(n, i));
101 if (n->n_child != NULL)
Guido van Rossum86bea461997-04-29 21:03:06 +0000102 PyMem_DEL(n->n_child);
Guido van Rossum03a24cd1990-11-18 17:37:06 +0000103 if (STR(n) != NULL)
Guido van Rossum86bea461997-04-29 21:03:06 +0000104 PyMem_DEL(STR(n));
Guido van Rossum03a24cd1990-11-18 17:37:06 +0000105}