From ca1d8df06cdead8f9de1ba81d1de8cda363c16b4 Mon Sep 17 00:00:00 2001 From: "Sven M. Hallberg" <pesco@khjk.org> Date: Mon, 30 Nov 2015 14:19:40 +0100 Subject: [PATCH] don't allocate a new arena in h_bind, use the existing one Rationale: If memory allocation fails in the inner parse and we longjump up the stack, the temporary arena will be missed and leak. NB: This change means that any allocations done by the continuation (in the form of new parsers, probably) will persist for the lifetime of the parse result. Beware of wasting too much memory this way! The bind continuation should generally keep dynamic allocations to a minimum. --- src/parsers/bind.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/parsers/bind.c b/src/parsers/bind.c index 7fa821dc..808df974 100644 --- a/src/parsers/bind.c +++ b/src/parsers/bind.c @@ -4,7 +4,6 @@ typedef struct { const HParser *p; HContinuation k; void *env; - HAllocator *mm__; } BindEnv; // an HAllocator backed by an HArena @@ -39,20 +38,15 @@ static HParseResult *parse_bind(void *be_, HParseState *state) { if(!res) return NULL; - // create a temporary arena allocator for the continuation - HArena *arena = h_new_arena(be->mm__, 0); - ArenaAllocator aa = {{aa_alloc, aa_realloc, aa_free}, arena}; + // create a wrapper arena allocator for the continuation + ArenaAllocator aa = {{aa_alloc, aa_realloc, aa_free}, state->arena}; HParser *kx = be->k((HAllocator *)&aa, res->ast, be->env); if(!kx) { - h_delete_arena(arena); return NULL; } - res = h_do_parse(kx, state); - - h_delete_arena(arena); - return res; + return h_do_parse(kx, state); } static const HParserVtable bind_vt = { @@ -76,7 +70,6 @@ HParser *h_bind__m(HAllocator *mm__, be->p = p; be->k = k; be->env = env; - be->mm__ = mm__; return h_new_parser(mm__, &bind_vt, be); } -- GitLab