int exectry(Estate state, int do_exec) { Wordcode end, always; int endval; int save_retflag, save_breaks, save_contflag; zlong save_try_errflag, save_try_tryflag; end = state->pc + WC_TRY_SKIP(state->pc[-1]); always = state->pc + 1 + WC_TRY_SKIP(*state->pc); state->pc++; pushheap(); cmdpush(CS_CURSH); /* The :try clause */ save_try_tryflag = try_tryflag; try_tryflag = 1; execlist(state, 1, do_exec); try_tryflag = save_try_tryflag; /* Don't record errflag here, may be reset. */ endval = lastval; freeheap(); cmdpop(); cmdpush(CS_ALWAYS); /* The always clause. */ save_try_errflag = try_errflag; try_errflag = (zlong)errflag; errflag = 0; save_retflag = retflag; retflag = 0; save_breaks = breaks; breaks = 0; save_contflag = contflag; contflag = 0; state->pc = always; execlist(state, 1, do_exec); errflag = try_errflag ? 1 : 0; try_errflag = save_try_errflag; if (!retflag) retflag = save_retflag; if (!breaks) breaks = save_breaks; if (!contflag) contflag = save_contflag; cmdpop(); popheap(); state->pc = end; return endval; }
int exectry(Estate state, int do_exec) { Wordcode end, always; int endval; int save_retflag, save_breaks, save_contflag; zlong save_try_errflag, save_try_tryflag, save_try_interrupt; end = state->pc + WC_TRY_SKIP(state->pc[-1]); always = state->pc + 1 + WC_TRY_SKIP(*state->pc); state->pc++; pushheap(); cmdpush(CS_CURSH); /* The :try clause */ save_try_tryflag = try_tryflag; try_tryflag = 1; execlist(state, 1, do_exec); try_tryflag = save_try_tryflag; /* Don't record errflag here, may be reset. However, */ /* endval should show failure when there is an error. */ endval = lastval ? lastval : errflag; freeheap(); cmdpop(); cmdpush(CS_ALWAYS); /* The always clause. */ save_try_errflag = try_errflag; save_try_interrupt = try_interrupt; try_errflag = (zlong)(errflag & ERRFLAG_ERROR); try_interrupt = (zlong)((errflag & ERRFLAG_INT) ? 1 : 0); /* We need to reset all errors to allow the block to execute */ errflag = 0; save_retflag = retflag; retflag = 0; save_breaks = breaks; breaks = 0; save_contflag = contflag; contflag = 0; state->pc = always; execlist(state, 1, do_exec); if (try_errflag) errflag |= ERRFLAG_ERROR; else errflag &= ~ERRFLAG_ERROR; if (try_interrupt) errflag |= ERRFLAG_INT; else errflag &= ~ERRFLAG_INT; try_errflag = save_try_errflag; try_interrupt = save_try_interrupt; if (!retflag) retflag = save_retflag; if (!breaks) breaks = save_breaks; if (!contflag) contflag = save_contflag; cmdpop(); popheap(); state->pc = end; return endval; }