mirror of
https://github.com/janet-lang/janet
synced 2024-12-27 00:40:26 +00:00
janet_try macro and janet_restore function.
This allows catching panics without using pcall.
This commit is contained in:
parent
c455bdad11
commit
d1f0a13ddc
@ -1315,8 +1315,25 @@ static JanetSignal janet_check_can_resume(JanetFiber *fiber, Janet *out) {
|
|||||||
return JANET_SIGNAL_OK;
|
return JANET_SIGNAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void janet_try_init(JanetTryState *state) {
|
||||||
|
state->stackn = janet_vm_stackn++;
|
||||||
|
state->gc_handle = janet_vm_gc_suspend;
|
||||||
|
state->vm_fiber = janet_vm_fiber;
|
||||||
|
state->vm_jmp_buf = janet_vm_jmp_buf;
|
||||||
|
state->vm_return_reg = janet_vm_return_reg;
|
||||||
|
janet_vm_return_reg = &(state->payload);
|
||||||
|
janet_vm_jmp_buf = &(state->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void janet_restore(JanetTryState *state) {
|
||||||
|
janet_vm_stackn = state->stackn;
|
||||||
|
janet_vm_gc_suspend = state->gc_handle;
|
||||||
|
janet_vm_fiber = state->vm_fiber;
|
||||||
|
janet_vm_jmp_buf = state->vm_jmp_buf;
|
||||||
|
janet_vm_return_reg = state->vm_return_reg;
|
||||||
|
}
|
||||||
|
|
||||||
static JanetSignal janet_continue_no_check(JanetFiber *fiber, Janet in, Janet *out) {
|
static JanetSignal janet_continue_no_check(JanetFiber *fiber, Janet in, Janet *out) {
|
||||||
jmp_buf buf;
|
|
||||||
|
|
||||||
JanetFiberStatus old_status = janet_fiber_status(fiber);
|
JanetFiberStatus old_status = janet_fiber_status(fiber);
|
||||||
|
|
||||||
@ -1349,45 +1366,23 @@ static JanetSignal janet_continue_no_check(JanetFiber *fiber, Janet in, Janet *o
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Save global state */
|
/* Save global state */
|
||||||
int32_t oldn = janet_vm_stackn++;
|
JanetTryState tstate;
|
||||||
int handle = janet_vm_gc_suspend;
|
JanetSignal signal = janet_try(&tstate);
|
||||||
JanetFiber *old_vm_fiber = janet_vm_fiber;
|
if (!signal) {
|
||||||
jmp_buf *old_vm_jmp_buf = janet_vm_jmp_buf;
|
/* Normal setup */
|
||||||
Janet *old_vm_return_reg = janet_vm_return_reg;
|
|
||||||
|
|
||||||
/* Setup fiber */
|
|
||||||
if (janet_vm_root_fiber == NULL) janet_vm_root_fiber = fiber;
|
if (janet_vm_root_fiber == NULL) janet_vm_root_fiber = fiber;
|
||||||
janet_vm_fiber = fiber;
|
janet_vm_fiber = fiber;
|
||||||
janet_gcroot(janet_wrap_fiber(fiber));
|
janet_gcroot(janet_wrap_fiber(fiber));
|
||||||
janet_fiber_set_status(fiber, JANET_STATUS_ALIVE);
|
janet_fiber_set_status(fiber, JANET_STATUS_ALIVE);
|
||||||
janet_vm_return_reg = out;
|
|
||||||
janet_vm_jmp_buf = &buf;
|
|
||||||
|
|
||||||
/* Run loop */
|
|
||||||
JanetSignal signal;
|
|
||||||
int jmpsig;
|
|
||||||
#if defined(JANET_BSD) || defined(JANET_APPLE)
|
|
||||||
jmpsig = _setjmp(buf);
|
|
||||||
#else
|
|
||||||
jmpsig = setjmp(buf);
|
|
||||||
#endif
|
|
||||||
if (jmpsig) {
|
|
||||||
signal = (JanetSignal) jmpsig;
|
|
||||||
} else {
|
|
||||||
signal = run_vm(fiber, in);
|
signal = run_vm(fiber, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tear down fiber */
|
/* Restore */
|
||||||
|
if (janet_vm_root_fiber == fiber) janet_vm_root_fiber = NULL;
|
||||||
janet_fiber_set_status(fiber, signal);
|
janet_fiber_set_status(fiber, signal);
|
||||||
janet_gcunroot(janet_wrap_fiber(fiber));
|
janet_gcunroot(janet_wrap_fiber(fiber));
|
||||||
|
janet_restore(&tstate);
|
||||||
/* Restore global state */
|
*out = tstate.payload;
|
||||||
if (janet_vm_root_fiber == fiber) janet_vm_root_fiber = NULL;
|
|
||||||
janet_vm_gc_suspend = handle;
|
|
||||||
janet_vm_fiber = old_vm_fiber;
|
|
||||||
janet_vm_stackn = oldn;
|
|
||||||
janet_vm_return_reg = old_vm_return_reg;
|
|
||||||
janet_vm_jmp_buf = old_vm_jmp_buf;
|
|
||||||
|
|
||||||
return signal;
|
return signal;
|
||||||
}
|
}
|
||||||
|
@ -1030,6 +1030,19 @@ struct JanetFile {
|
|||||||
int32_t flags;
|
int32_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* For janet_try and janet_restore */
|
||||||
|
typedef struct {
|
||||||
|
/* old state */
|
||||||
|
int32_t stackn;
|
||||||
|
int gc_handle;
|
||||||
|
JanetFiber *vm_fiber;
|
||||||
|
jmp_buf *vm_jmp_buf;
|
||||||
|
Janet *vm_return_reg;
|
||||||
|
/* new state */
|
||||||
|
jmp_buf buf;
|
||||||
|
Janet payload;
|
||||||
|
} JanetTryState;
|
||||||
|
|
||||||
/* Thread types */
|
/* Thread types */
|
||||||
#ifdef JANET_THREADS
|
#ifdef JANET_THREADS
|
||||||
typedef struct JanetThread JanetThread;
|
typedef struct JanetThread JanetThread;
|
||||||
@ -1411,6 +1424,13 @@ JANET_API JanetBuffer *janet_pretty(JanetBuffer *buffer, int depth, int flags, J
|
|||||||
#define JANET_HASH_KEY_SIZE 16
|
#define JANET_HASH_KEY_SIZE 16
|
||||||
JANET_API void janet_init_hash_key(uint8_t key[JANET_HASH_KEY_SIZE]);
|
JANET_API void janet_init_hash_key(uint8_t key[JANET_HASH_KEY_SIZE]);
|
||||||
#endif
|
#endif
|
||||||
|
JANET_API void janet_try_init(JanetTryState *state);
|
||||||
|
#if defined(JANET_BSD) || defined(JANET_APPLE)
|
||||||
|
#define janet_try(state) (janet_try_init(state), (JanetSignal) _setjmp((state)->buf))
|
||||||
|
#else
|
||||||
|
#define janet_try(state) (janet_try_init(state), (JanetSignal) setjmp((state)->buf))
|
||||||
|
#endif
|
||||||
|
JANET_API void janet_restore(JanetTryState *state);
|
||||||
JANET_API int janet_equals(Janet x, Janet y);
|
JANET_API int janet_equals(Janet x, Janet y);
|
||||||
JANET_API int32_t janet_hash(Janet x);
|
JANET_API int32_t janet_hash(Janet x);
|
||||||
JANET_API int janet_compare(Janet x, Janet y);
|
JANET_API int janet_compare(Janet x, Janet y);
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
(var num-tests-passed 0)
|
(var num-tests-passed 0)
|
||||||
(var num-tests-run 0)
|
(var num-tests-run 0)
|
||||||
(var suite-num 0)
|
(var suite-num 0)
|
||||||
(var numchecks 0)
|
|
||||||
(var start-time 0)
|
(var start-time 0)
|
||||||
|
|
||||||
(defn assert
|
(defn assert
|
||||||
@ -13,16 +12,8 @@
|
|||||||
(++ num-tests-run)
|
(++ num-tests-run)
|
||||||
(when x (++ num-tests-passed))
|
(when x (++ num-tests-passed))
|
||||||
(if x
|
(if x
|
||||||
(do
|
(xprintf stdout "\e[32m✔\e[0m %s: %v" (string e) x)
|
||||||
(when (= numchecks 25)
|
(xprintf stdout "\n\e[31m✘\e[0m %s: %v" (string e) x))
|
||||||
(set numchecks 0)
|
|
||||||
(print))
|
|
||||||
(++ numchecks)
|
|
||||||
(file/write stdout "\e[32m✔\e[0m"))
|
|
||||||
(do
|
|
||||||
(file/write stdout "\n\e[31m✘\e[0m ")
|
|
||||||
(set numchecks 0)
|
|
||||||
(print e)))
|
|
||||||
x)
|
x)
|
||||||
|
|
||||||
(defmacro assert-error
|
(defmacro assert-error
|
||||||
|
Loading…
Reference in New Issue
Block a user