diff --git a/src/Init/Util.lean b/src/Init/Util.lean index 158fef2ab7..e14bdd272b 100644 --- a/src/Init/Util.lean +++ b/src/Init/Util.lean @@ -25,7 +25,7 @@ f () @[extern c inline "#4"] unsafe def unsafeCast {α : Type u} {β : Type v} [Inhabited β] (a : α) : β := arbitrary _ -@[neverExtract, extern c inline "lean_panic_fn(#3)"] +@[neverExtract, extern "lean_panic_fn"] constant panic {α : Type u} [Inhabited α] (msg : String) : α := arbitrary _ @[noinline] private def mkPanicMessage (modName : String) (line col : Nat) (msg : String) : String := diff --git a/src/runtime/lean.h b/src/runtime/lean.h index b1e657b0fa..c8f0c1b76f 100644 --- a/src/runtime/lean.h +++ b/src/runtime/lean.h @@ -242,11 +242,13 @@ static inline bool lean_is_scalar(lean_object * o) { return ((size_t)(o) & 1) == static inline lean_object * lean_box(size_t n) { return (lean_object*)(((size_t)(n) << 1) | 1); } static inline size_t lean_unbox(lean_object * o) { return (size_t)(o) >> 1; } +void lean_set_exit_on_panic(bool flag); +lean_object * lean_panic_fn(lean_object * default_val, lean_object * msg); + __attribute__((noreturn)) void lean_panic(char const * msg); __attribute__((noreturn)) void lean_panic_out_of_memory(); __attribute__((noreturn)) void lean_panic_unreachable(); __attribute__((noreturn)) void lean_panic_rc_overflow(); -lean_object * lean_panic_fn(lean_object * msg); static inline size_t lean_align(size_t v, size_t a) { return (v / a)*a + a * (v % a != 0); diff --git a/src/runtime/object.cpp b/src/runtime/object.cpp index 1b0322ed3d..f85793875d 100644 --- a/src/runtime/object.cpp +++ b/src/runtime/object.cpp @@ -39,8 +39,20 @@ extern "C" void lean_panic_rc_overflow() { lean_panic("reference counter overflowed"); } -extern "C" object * lean_panic_fn(object * msg) { - lean_panic(lean_string_cstr(msg)); +bool g_exit_on_panic = false; + +extern "C" void lean_set_exit_on_panic(bool flag) { + g_exit_on_panic = flag; +} + +extern "C" object * lean_panic_fn(object * default_val, object * msg) { + // TODO(Leo, Kha): add thread local buffer for interpreter. + std::cerr << lean_string_cstr(msg) << "\n"; + if (g_exit_on_panic) { + std::exit(1); + } + lean_dec(msg); + return default_val; } extern "C" size_t lean_object_byte_size(lean_object * o) { diff --git a/src/shell/lean.cpp b/src/shell/lean.cpp index f2127f37ee..55df07277b 100644 --- a/src/shell/lean.cpp +++ b/src/shell/lean.cpp @@ -241,6 +241,7 @@ static struct option g_long_options[] = { {"timeout", optional_argument, 0, 'T'}, {"cpp", optional_argument, 0, 'c'}, {"c", optional_argument, 0, 'C'}, + {"exitOnPanic", no_argument, 0, 'e'}, #if defined(LEAN_JSON) {"json", no_argument, 0, 'J'}, {"server", optional_argument, 0, 'S'}, @@ -257,7 +258,7 @@ static struct option g_long_options[] = { }; static char const * g_opt_str = - "PdD:m::c:C:qgvht:012j:012rM:012T:012ap:" + "PdD:m::c:C:qgvht:012j:012rM:012T:012ap:e" #if defined(LEAN_MULTI_THREAD) "s:012" #endif @@ -436,6 +437,9 @@ int main(int argc, char ** argv) { if (c == -1) break; // end of command line switch (c) { + case 'e': + lean_set_exit_on_panic(true); + break; case 'j': // num_threads = static_cast(atoi(optarg)); break;