extern obj_t core_eval_cont(volatile obj_t cont, volatile obj_t values, obj_t handler) { eval_dyn_env = MAKE_RECORD(dyn_env, EMPTY_LIST, handler); if (sigsetjmp(eval_sigrestart, 1)) { /* On Linux, siglongjmp is 30X slower than longjmp. */ /* push exception... */ } else { switch (setjmp(eval_restart)) { case LT_THROWN: { cv_t ret = push_exception(cont, values); cont = ret.cv_cont; values = ret.cv_values; } break; case LT_HEAP_FULL: cont_root = cont; values_root = values; collect_garbage(); cont = cont_root; values = values_root; cont_root = make_uninitialized(); values_root = make_uninitialized(); break; case LT_NO_EXCEPTION: register_lowex_handler(handle_lowex); break; default: assert(false); } } while (!is_null(cont)) { cv_t ret = cont_proc(cont)(cont, values); cont = ret.cv_cont; values = ret.cv_values; COMMIT(); #if DEBUG_EVAL int n = 0; obj_t p; for (p = cont; !is_null(p); p = cont_cont(p)) n++; EVAL_LOG("values=%O cont depth=%d", values, n); #endif } deregister_lowex_handler(handle_lowex); eval_dyn_env = make_uninitialized(); EVAL_LOG("END values=%O", values); assert(is_null(CDR(values))); return CAR(values); }
/** \brief Wrapper for "customers" that are only using a subset of Lean libraries. */ int safe_function_wrapper(lua_State * L, lua_CFunction f) { try { return f(L); } catch (exception & e) { lua_Debug ar; lua_getstack(L, 1, &ar); lua_getinfo(L, "Sl", &ar); if (ar.source && *(ar.source) == '@') push_exception(L, script_nested_exception(true, ar.source+1, ar.currentline, std::shared_ptr<exception>(e.clone()))); else if (ar.source) push_exception(L, script_nested_exception(false, ar.source, ar.currentline, std::shared_ptr<exception>(e.clone()))); else push_exception(L, e); } catch (std::bad_alloc &) { lua_pushstring(L, "out of memory"); } catch (std::exception & e) { lua_pushstring(L, e.what()); } catch(...) { lua_pushstring(L, "unknown error"); } return lua_error(L); }
Object call_function(Object func) { Object ret; if (IS_FUNC(func)) { resolve_method_self(func); /* call native */ if (GET_FUNCTION(func)->native != NULL) { return GET_FUNCTION(func)->native(); } else { TmFrame* f = push_frame(func); /* if (GET_FUNCTION(func)->modifier == 0) { return tm_eval(f); }*/ L_recall: if (setjmp(f->buf)==0) { return tm_eval(f); } else { f = tm->frame; /* handle exception in this frame */ if (f->jmp != NULL) { f->pc = f->jmp; f->jmp = NULL; goto L_recall; /* there is no handler, throw to last frame */ } else { push_exception(f); tm->frame--; longjmp(tm->frame->buf, 1); } } } } else if (IS_DICT(func)) { ret = class_new(func); Object *_fnc = dict_get_by_str(ret, "__init__"); if (_fnc != NULL) { call_function(*_fnc); } return ret; } tm_raise("File %o, line=%d: call_function:invalid object %o", GET_FUNCTION_FILE(tm->frame->fnc), tm->frame->lineno, func); return NONE_OBJECT; }
static void exception_migrate(lua_State * src, int i, lua_State * tgt) { push_exception(tgt, to_exception(src, i)); }