diff --git a/src/parsers/choice.c b/src/parsers/choice.c index dd3908ce93168f468ba6e1ff531a59476e404411..90c3662b515babe4a69b0e24dc146ebe1d0a647d 100644 --- a/src/parsers/choice.c +++ b/src/parsers/choice.c @@ -1,6 +1,20 @@ #include <stdarg.h> #include "parser_internal.h" +#if defined(__STDC_VERSION__) && ( \ + (__STDC_VERSION__ >= 201112L && !defined(__STDC_NO_VLA__)) || \ + (__STDC_VERSION__ >= 199901L) \ + ) +# define STACK_VLA(type,name,size) type name[size] +#else +# if defined(_MSC_VER) +# include <malloc.h> // for _alloca +# define STACK_VLA(type,name,size) type* name = _alloca(size) +# else +# error "Missing VLA implementation for this compiler" +# endif +#endif + typedef struct { size_t len; HParser **p_array; @@ -53,11 +67,14 @@ static void desugar_choice(HAllocator *mm__, HCFStack *stk__, void *env) { static bool choice_ctrvm(HRVMProg *prog, void* env) { HSequence *s = (HSequence*)env; - uint16_t gotos[s->len]; + // NOTE(uucidl): stack allocation since this backend uses + // setjmp/longjmp for error handling. + STACK_VLA(uint16_t, gotos, s->len); for (size_t i=0; i<s->len; ++i) { uint16_t insn = h_rvm_insert_insn(prog, RVM_FORK, 0); - if (!h_compile_regex(prog, s->p_array[i])) + if (!h_compile_regex(prog, s->p_array[i])) { return false; + } gotos[i] = h_rvm_insert_insn(prog, RVM_GOTO, 65535); h_rvm_patch_arg(prog, insn, h_rvm_get_ip(prog)); }