diff --git a/src/backends/glr.c b/src/backends/glr.c index e753ea55d938cc07582ceed83db92354cbacf68f..535dc2860c59018324893da1450cfc4ff4fadf8b 100644 --- a/src/backends/glr.c +++ b/src/backends/glr.c @@ -198,6 +198,16 @@ HParseResult *h_glr_parse(HAllocator* mm__, const HParser* parser, HInputStream* HArena *arena = h_new_arena(mm__, 0); // will hold the results HArena *tarena = h_new_arena(mm__, 0); // tmp, deleted after parse + // out-of-memory handling + jmp_buf except; + h_arena_set_except(arena, &except); + h_arena_set_except(tarena, &except); + if(setjmp(except)) { + h_delete_arena(arena); + h_delete_arena(tarena); + return NULL; + } + // allocate engine lists (will hold one engine per state) // these are swapped each iteration HSlist *engines = h_slist_new(tarena); diff --git a/src/backends/llk.c b/src/backends/llk.c index 0ab4610a29a1fcdefd1ca163ea2be8785b3ed0e6..2f41f9122c8ed76fe414c7ece16523cea87cd9fb 100644 --- a/src/backends/llk.c +++ b/src/backends/llk.c @@ -561,6 +561,17 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream* { HLLkState *s = llk_parse_start_(mm__, parser); + // out-of-memory handling + jmp_buf except; + h_arena_set_except(s->arena, &except); + h_arena_set_except(s->tarena, &except); + if(setjmp(except)) { + h_delete_arena(s->arena); + h_delete_arena(s->tarena); + h_free(s); + return NULL; + } + assert(stream->last_chunk); s->seq = llk_parse_chunk_(s, parser, stream); diff --git a/src/backends/lr.c b/src/backends/lr.c index fb256c0bfafa0b6c53b32307bea64f61d4885919..8f2a0ea41c139fc5fedb1580b246fb88a3cc8d5d 100644 --- a/src/backends/lr.c +++ b/src/backends/lr.c @@ -388,6 +388,16 @@ HParseResult *h_lr_parse(HAllocator* mm__, const HParser* parser, HInputStream* HArena *tarena = h_new_arena(mm__, 0); // tmp, deleted after parse HLREngine *engine = h_lrengine_new(arena, tarena, table, stream); + // out-of-memory handling + jmp_buf except; + h_arena_set_except(arena, &except); + h_arena_set_except(tarena, &except); + if(setjmp(except)) { + h_delete_arena(arena); + h_delete_arena(tarena); + return NULL; + } + // iterate engine to completion while(h_lrengine_step(engine, h_lrengine_action(engine)));