Changeset 388 for python/vendor/current/Parser/node.c
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Parser/node.c
r2 r388 8 8 PyNode_New(int type) 9 9 { 10 11 12 13 14 15 16 17 18 10 node *n = (node *) PyObject_MALLOC(1 * sizeof(node)); 11 if (n == NULL) 12 return NULL; 13 n->n_type = type; 14 n->n_str = NULL; 15 n->n_lineno = 0; 16 n->n_nchildren = 0; 17 n->n_child = NULL; 18 return n; 19 19 } 20 20 … … 23 23 fancy_roundup(int n) 24 24 { 25 26 27 28 29 30 31 32 33 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 if (result <= 0) 31 return -1; 32 } 33 return result; 34 34 } 35 35 … … 71 71 * capacity. The code is tricky to avoid that. 72 72 */ 73 #define XXXROUNDUP(n) ((n) <= 1 ? (n) : 74 (n) <= 128 ? (((n) + 3) & ~3) :\75 73 #define XXXROUNDUP(n) ((n) <= 1 ? (n) : \ 74 (n) <= 128 ? (((n) + 3) & ~3) : \ 75 fancy_roundup(n)) 76 76 77 77 … … 79 79 PyNode_AddChild(register node *n1, int type, char *str, int lineno, int col_offset) 80 80 { 81 82 83 84 81 const int nch = n1->n_nchildren; 82 int current_capacity; 83 int required_capacity; 84 node *n; 85 85 86 87 86 if (nch == INT_MAX || nch < 0) 87 return E_OVERFLOW; 88 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 89 current_capacity = XXXROUNDUP(nch); 90 required_capacity = XXXROUNDUP(nch + 1); 91 if (current_capacity < 0 || required_capacity < 0) 92 return E_OVERFLOW; 93 if (current_capacity < required_capacity) { 94 if (required_capacity > PY_SIZE_MAX / sizeof(node)) { 95 return E_NOMEM; 96 } 97 n = n1->n_child; 98 n = (node *) PyObject_REALLOC(n, 99 required_capacity * sizeof(node)); 100 if (n == NULL) 101 return E_NOMEM; 102 n1->n_child = n; 103 } 104 104 105 106 107 108 109 110 111 112 105 n = &n1->n_child[n1->n_nchildren++]; 106 n->n_type = type; 107 n->n_str = str; 108 n->n_lineno = lineno; 109 n->n_col_offset = col_offset; 110 n->n_nchildren = 0; 111 n->n_child = NULL; 112 return 0; 113 113 } 114 114 115 115 /* Forward */ 116 116 static void freechildren(node *); 117 static Py_ssize_t sizeofchildren(node *n); 117 118 118 119 … … 120 121 PyNode_Free(node *n) 121 122 { 122 if (n != NULL) { 123 freechildren(n); 124 PyObject_FREE(n); 125 } 123 if (n != NULL) { 124 freechildren(n); 125 PyObject_FREE(n); 126 } 127 } 128 129 Py_ssize_t 130 _PyNode_SizeOf(node *n) 131 { 132 Py_ssize_t res = 0; 133 134 if (n != NULL) 135 res = sizeof(node) + sizeofchildren(n); 136 return res; 126 137 } 127 138 … … 129 140 freechildren(node *n) 130 141 { 131 132 133 134 135 136 137 142 int i; 143 for (i = NCH(n); --i >= 0; ) 144 freechildren(CHILD(n, i)); 145 if (n->n_child != NULL) 146 PyObject_FREE(n->n_child); 147 if (STR(n) != NULL) 148 PyObject_FREE(STR(n)); 138 149 } 150 151 static Py_ssize_t 152 sizeofchildren(node *n) 153 { 154 Py_ssize_t res = 0; 155 int i; 156 for (i = NCH(n); --i >= 0; ) 157 res += sizeofchildren(CHILD(n, i)); 158 if (n->n_child != NULL) 159 /* allocated size of n->n_child array */ 160 res += XXXROUNDUP(NCH(n)) * sizeof(node); 161 if (STR(n) != NULL) 162 res += strlen(STR(n)) + 1; 163 return res; 164 }
Note:
See TracChangeset
for help on using the changeset viewer.