From 30cc6998de698eb63d995c5956d3eec620c80e29 Mon Sep 17 00:00:00 2001 From: koba-e964 Date: Sun, 23 Mar 2014 20:58:28 +0900 Subject: [PATCH] [bugfix] macroexpand macroexpand restores pic->lib in the case of an error --- src/macro.c | 59 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/src/macro.c b/src/macro.c index 33e194cc..5157265c 100644 --- a/src/macro.c +++ b/src/macro.c @@ -213,32 +213,47 @@ macroexpand(pic_state *pic, pic_value expr, struct pic_senv *senv) if (tag == pic->sDEFINE_LIBRARY) { struct pic_lib *prev = pic->lib; + jmp_buf jmp, *prevjmp = pic->jmp; + bool name_restored = false; - if (pic_length(pic, expr) < 2) { - pic_error(pic, "syntax error"); + /* restores pic->lib even if an error occurs */ + if (setjmp(jmp) == 0) { + pic->jmp = &jmp; + if (pic_length(pic, expr) < 2) { + pic_error(pic, "syntax error"); + } + pic_make_library(pic, pic_cadr(pic, expr)); + + /* proceed expressions in new library */ + pic_in_library(pic, pic_cadr(pic, expr)); + { + int ai = pic_gc_arena_preserve(pic); + struct pic_proc *proc; + + pic_for_each (v, pic_cddr(pic, expr)) { + proc = pic_compile(pic, v); + if (proc == NULL) { + abort(); + } + pic_apply_argv(pic, proc, 0); + if (pic_undef_p(v)) { + abort(); + } + pic_gc_arena_restore(pic, ai); + } + } + pic_in_library(pic, prev->name); + name_restored = true; } - pic_make_library(pic, pic_cadr(pic, expr)); - - /* proceed expressions in new library */ - pic_in_library(pic, pic_cadr(pic, expr)); - { - int ai = pic_gc_arena_preserve(pic); - struct pic_proc *proc; - - pic_for_each (v, pic_cddr(pic, expr)) { - proc = pic_compile(pic, v); - if (proc == NULL) { - abort(); - } - pic_apply_argv(pic, proc, 0); - if (pic_undef_p(v)) { - abort(); - } - pic_gc_arena_restore(pic, ai); + else { + if (! name_restored) { + pic_in_library(pic, prev->name); } } - pic_in_library(pic, prev->name); - + pic->jmp = prevjmp; + if (pic->err) { + longjmp(*pic->jmp, 1); + } return pic_none_value(); }