77#include < cstdarg>
88#include < iostream>
99#include < stdexcept>
10+ #include < vector>
1011
1112void
1213amrexpr_parsererror (char const *s, ...)
@@ -23,6 +24,7 @@ namespace amrexpr {
2324
2425namespace {
2526 struct parser_node * parser_root = nullptr ;
27+ std::vector<void *> parser_ptrs;
2628}
2729
2830// This is called by a bison rule to store the original AST in a static variable.
@@ -37,17 +39,20 @@ parser_makesymbol (char* name)
3739{
3840 // We allocate more than enough space so that late we can turn parser_symbol
3941 // into into parser_node if necessary.
40- auto *symbol = (struct parser_symbol *) std::malloc (sizeof (struct parser_node )); // NOLINT
42+ parser_ptrs.push_back (std::malloc (sizeof (struct parser_node )));
43+ auto *symbol = (struct parser_symbol *) parser_ptrs.back (); // NOLINT
4144 symbol->type = PARSER_SYMBOL;
4245 symbol->name = strdup (name);
46+ parser_ptrs.push_back (symbol->name );
4347 symbol->ip = -1 ;
4448 return symbol;
4549}
4650
4751struct parser_node *
4852parser_newnode (enum parser_node_t type, struct parser_node * l, struct parser_node * r)
4953{
50- auto *tmp = (struct parser_node *) std::malloc (sizeof (struct parser_node ));
54+ parser_ptrs.push_back (std::malloc (sizeof (struct parser_node )));
55+ auto *tmp = (struct parser_node *) parser_ptrs.back ();
5156 if (type == PARSER_SUB) {
5257 tmp->type = PARSER_ADD;
5358 tmp->l = l;
@@ -63,7 +68,8 @@ parser_newnode (enum parser_node_t type, struct parser_node* l, struct parser_no
6368struct parser_node *
6469parser_newneg (struct parser_node * n)
6570{
66- auto *tmp = (struct parser_node *) std::malloc (sizeof (struct parser_node ));
71+ parser_ptrs.push_back (std::malloc (sizeof (struct parser_node )));
72+ auto *tmp = (struct parser_node *) parser_ptrs.back ();
6773 tmp->type = PARSER_MUL;
6874 tmp->l = parser_newnumber (-1.0 );
6975 tmp->r = n;
@@ -75,7 +81,8 @@ parser_newnumber (double d)
7581{
7682 // We allocate more than enough space so that late we can turn parser_number
7783 // into into parser_node if necessary.
78- auto *r = (struct parser_number *) std::malloc (sizeof (struct parser_node )); // NOLINT
84+ parser_ptrs.push_back (std::malloc (sizeof (struct parser_node )));
85+ auto *r = (struct parser_number *) parser_ptrs.back (); // NOLINT
7986 r->type = PARSER_NUMBER;
8087 r->value = d;
8188 return (struct parser_node *) r;
@@ -90,7 +97,8 @@ parser_newsymbol (struct parser_symbol* symbol)
9097struct parser_node *
9198parser_newf1 (enum parser_f1_t ftype, struct parser_node * l)
9299{
93- auto *tmp = (struct parser_f1 *) std::malloc (sizeof (struct parser_node )); // NOLINT
100+ parser_ptrs.push_back (std::malloc (sizeof (struct parser_node )));
101+ auto *tmp = (struct parser_f1 *) parser_ptrs.back (); // NOLINT
94102 tmp->type = PARSER_F1;
95103 tmp->l = l;
96104 tmp->ftype = ftype;
@@ -100,7 +108,8 @@ parser_newf1 (enum parser_f1_t ftype, struct parser_node* l)
100108struct parser_node *
101109parser_newf2 (enum parser_f2_t ftype, struct parser_node * l, struct parser_node * r)
102110{
103- auto *tmp = (struct parser_f2 *) std::malloc (sizeof (struct parser_node )); // NOLINT
111+ parser_ptrs.push_back (std::malloc (sizeof (struct parser_node )));
112+ auto *tmp = (struct parser_f2 *) parser_ptrs.back (); // NOLINT
104113 tmp->type = PARSER_F2;
105114 tmp->l = l;
106115 tmp->r = r;
@@ -112,7 +121,8 @@ struct parser_node*
112121parser_newf3 (enum parser_f3_t ftype, struct parser_node * n1, struct parser_node * n2,
113122 struct parser_node * n3)
114123{
115- auto *tmp = (struct parser_f3 *) std::malloc (sizeof (struct parser_node )); // NOLINT
124+ parser_ptrs.push_back (std::malloc (sizeof (struct parser_node )));
125+ auto *tmp = (struct parser_f3 *) parser_ptrs.back (); // NOLINT
116126 tmp->type = PARSER_F3;
117127 tmp->n1 = n1;
118128 tmp->n2 = n2;
@@ -124,7 +134,8 @@ parser_newf3 (enum parser_f3_t ftype, struct parser_node* n1, struct parser_node
124134struct parser_node *
125135parser_newassign (struct parser_symbol * sym, struct parser_node * v)
126136{
127- auto *r = (struct parser_assign *) std::malloc (sizeof (struct parser_node )); // NOLINT
137+ parser_ptrs.push_back (std::malloc (sizeof (struct parser_node )));
138+ auto *r = (struct parser_assign *) parser_ptrs.back (); // NOLINT
128139 r->type = PARSER_ASSIGN;
129140 r->s = sym;
130141 r->v = v;
@@ -137,7 +148,8 @@ parser_newlist (struct parser_node* nl, struct parser_node* nr)
137148 if (nr == nullptr ) {
138149 return nl;
139150 } else {
140- auto *r = (struct parser_node *) std::malloc (sizeof (struct parser_node ));
151+ parser_ptrs.push_back (std::malloc (sizeof (struct parser_node )));
152+ auto *r = (struct parser_node *) parser_ptrs.back ();
141153 r->type = PARSER_LIST;
142154 r->l = nl;
143155 r->r = nr;
@@ -156,7 +168,9 @@ amrexpr_parser_new ()
156168 my_parser->p_root = std::malloc (my_parser->sz_mempool );
157169 my_parser->p_free = my_parser->p_root ;
158170
159- my_parser->ast = parser_ast_dup (my_parser, parser_root, 1 ); /* 1: free the source parser_root */
171+ my_parser->ast = parser_ast_dup (my_parser, parser_root);
172+
173+ amrexpr_parser_delete_ptrs ();
160174
161175 if ((char *)my_parser->p_root + my_parser->sz_mempool != (char *)my_parser->p_free ) {
162176 throw std::runtime_error (" amrexpr_parser_new: error in memory size" );
@@ -176,6 +190,15 @@ amrexpr_parser_delete (struct amrexpr_parser* parser)
176190 std::free (parser);
177191}
178192
193+ void
194+ amrexpr_parser_delete_ptrs ()
195+ {
196+ for (auto * p : parser_ptrs) {
197+ std::free (p);
198+ }
199+ parser_ptrs.clear ();
200+ }
201+
179202namespace {
180203
181204std::size_t
@@ -197,19 +220,6 @@ parser_allocate (struct amrexpr_parser* my_parser, std::size_t N)
197220
198221}
199222
200- struct amrexpr_parser *
201- parser_dup (struct amrexpr_parser * source)
202- {
203- auto *dest = (struct amrexpr_parser *) std::malloc (sizeof (struct amrexpr_parser ));
204- dest->sz_mempool = source->sz_mempool ;
205- dest->p_root = std::malloc (dest->sz_mempool );
206- dest->p_free = dest->p_root ;
207-
208- dest->ast = parser_ast_dup (dest, source->ast , 0 ); /* 0: don't free the source */
209-
210- return dest;
211- }
212-
213223std::size_t
214224parser_ast_size (struct parser_node * node)
215225{
@@ -260,7 +270,7 @@ parser_ast_size (struct parser_node* node)
260270}
261271
262272struct parser_node *
263- parser_ast_dup (struct amrexpr_parser * my_parser, struct parser_node * node, int move )
273+ parser_ast_dup (struct amrexpr_parser * my_parser, struct parser_node * node)
264274{
265275 void * result = nullptr ;
266276
@@ -288,55 +298,45 @@ parser_ast_dup (struct amrexpr_parser* my_parser, struct parser_node* node, int
288298 case PARSER_LIST:
289299 result = parser_allocate (my_parser, sizeof (struct parser_node ));
290300 std::memcpy (result, node , sizeof (struct parser_node ));
291- ((struct parser_node *)result)->l = parser_ast_dup (my_parser, node->l , move );
292- ((struct parser_node *)result)->r = parser_ast_dup (my_parser, node->r , move );
301+ ((struct parser_node *)result)->l = parser_ast_dup (my_parser, node->l );
302+ ((struct parser_node *)result)->r = parser_ast_dup (my_parser, node->r );
293303 break ;
294304 case PARSER_F1:
295305 result = parser_allocate (my_parser, sizeof (struct parser_node ));
296306 std::memcpy (result, node , sizeof (struct parser_f1 ));
297307 ((struct parser_f1 *)result)->l = parser_ast_dup (my_parser,
298- ((struct parser_f1 *)node)->l , move );
308+ ((struct parser_f1 *)node)->l );
299309 break ;
300310 case PARSER_F2:
301311 result = parser_allocate (my_parser, sizeof (struct parser_node ));
302312 std::memcpy (result, node , sizeof (struct parser_f2 ));
303313 ((struct parser_f2 *)result)->l = parser_ast_dup (my_parser,
304- ((struct parser_f2 *)node)->l , move );
314+ ((struct parser_f2 *)node)->l );
305315 ((struct parser_f2 *)result)->r = parser_ast_dup (my_parser,
306- ((struct parser_f2 *)node)->r , move );
316+ ((struct parser_f2 *)node)->r );
307317 break ;
308318 case PARSER_F3:
309319 result = parser_allocate (my_parser, sizeof (struct parser_node ));
310320 std::memcpy (result, node , sizeof (struct parser_f3 ));
311321 ((struct parser_f3 *)result)->n1 = parser_ast_dup (my_parser,
312- ((struct parser_f3 *)node)->n1 , move );
322+ ((struct parser_f3 *)node)->n1 );
313323 ((struct parser_f3 *)result)->n2 = parser_ast_dup (my_parser,
314- ((struct parser_f3 *)node)->n2 , move );
324+ ((struct parser_f3 *)node)->n2 );
315325 ((struct parser_f3 *)result)->n3 = parser_ast_dup (my_parser,
316- ((struct parser_f3 *)node)->n3 , move );
326+ ((struct parser_f3 *)node)->n3 );
317327 break ;
318328 case PARSER_ASSIGN:
319329 result = parser_allocate (my_parser, sizeof (struct parser_node ));
320330 std::memcpy (result, node , sizeof (struct parser_assign ));
321331 ((struct parser_assign *)result)->s = (struct parser_symbol *)
322332 parser_ast_dup (my_parser, (struct parser_node *)
323- (((struct parser_assign *)node)->s ), move );
333+ (((struct parser_assign *)node)->s ));
324334 ((struct parser_assign *)result)->v = parser_ast_dup (my_parser,
325- ((struct parser_assign *)node)->v , move );
335+ ((struct parser_assign *)node)->v );
326336 break ;
327337 default :
328338 throw std::runtime_error (" parser_ast_dup: unknown node type " + std::to_string (node->type ));
329339 }
330- if (move) {
331- /* Note that we only do this on the original AST. We do not
332- * need to call free for AST stored in amrexpr_parser because the
333- * memory is not allocated with std::malloc directly.
334- */
335- if (node->type == PARSER_SYMBOL) {
336- std::free (((struct parser_symbol *)node)->name );
337- }
338- std::free ((void *)node);
339- }
340340 return (struct parser_node *)result;
341341}
342342
@@ -347,14 +347,6 @@ namespace {
347347 return ((struct parser_symbol *)node)->name ;
348348 }
349349
350- bool parser_same_symbol (struct parser_node * a, struct parser_node * b)
351- {
352- return (a->type == PARSER_SYMBOL)
353- && (b->type == PARSER_SYMBOL)
354- && (std::strcmp (((struct parser_symbol *)a)->name ,
355- ((struct parser_symbol *)b)->name ) == 0 );
356- }
357-
358350 bool is_add_combinable (struct parser_node * a, struct parser_node *b)
359351 {
360352 if ((a->type == PARSER_NUMBER) &&
@@ -608,6 +600,14 @@ namespace {
608600 }
609601}
610602
603+ bool parser_same_symbol (struct parser_node * a, struct parser_node * b)
604+ {
605+ return (a->type == PARSER_SYMBOL)
606+ && (b->type == PARSER_SYMBOL)
607+ && (std::strcmp (((struct parser_symbol *)a)->name ,
608+ ((struct parser_symbol *)b)->name ) == 0 );
609+ }
610+
611611bool parser_node_equal (struct parser_node * a, struct parser_node * b)
612612{
613613 if (a->type != b->type ) { return false ; }
@@ -650,7 +650,7 @@ bool parser_node_equal (struct parser_node* a, struct parser_node* b)
650650}
651651
652652void
653- parser_ast_optimize (struct parser_node * node, std::map<std::string,double >& local_consts)
653+ parser_ast_optimize (struct parser_node *& node, std::map<std::string,double >& local_consts)
654654{
655655 // No need to free memory because we only call this on ASTs in
656656 // amrexpr_parser that are allocated from the memory pool.
0 commit comments