static void unwind_exception(jit_int32_t regval, obool_t unsafe) { jit_int32_t frame; jit_int32_t stack; jit_node_t *equal; /* Need to restore and resync thread state */ frame = GPR[FRAME] != JIT_NOREG ? GPR[FRAME] : JIT_R0; stack = GPR[STACK] != JIT_NOREG ? GPR[STACK] : JIT_R0; /* Restore fp */ jit_ldxi(frame, regval, offsetof(oexception_t, fp)); jit_stxi(offsetof(othread_t, fp), JIT_V0, frame); /* Restore sp */ if (unsafe) { /* If throw may be from another vm stack frame, need to * zero memory, or it may later be cast to the wrong object; * the logic is somewhat optimized, to zero memory before * function return instead of function call, but exceptions * break all rules. */ if (GPR[STACK] != JIT_NOREG) { jit_ldxi(GPR[STACK], regval, offsetof(oexception_t, sp)); jit_ldxi(JIT_R1, JIT_V0, offsetof(othread_t, sp)); equal = jit_beqr(GPR[STACK], JIT_R1); jit_subr(JIT_R0, GPR[STACK], JIT_R1); jit_prepare(); jit_pushargr(JIT_R1); jit_pushargi(0); jit_pushargr(JIT_R0); jit_finishi(memset); jit_patch(equal); jit_stxi(offsetof(othread_t, sp), JIT_V0, GPR[STACK]); } else { jit_ldxi(JIT_R0, regval, offsetof(oexception_t, sp)); jit_ldxi(JIT_R1, JIT_V0, offsetof(othread_t, sp)); equal = jit_beqr(JIT_R0, JIT_R1); jit_subr(JIT_R0, JIT_R0, JIT_R1); jit_prepare(); jit_pushargr(JIT_R1); jit_pushargi(0); jit_pushargr(JIT_R0); jit_finishi(memset); jit_ldxi(JIT_R0, regval, offsetof(oexception_t, sp)); jit_patch(equal); jit_stxi(offsetof(othread_t, sp), JIT_V0, JIT_R0); } } else { jit_ldxi(stack, regval, offsetof(oexception_t, sp)); jit_stxi(offsetof(othread_t, sp), JIT_V0, stack); } /* Restore this (if there is a this register) */ if (GPR[THIS] != JIT_NOREG) jit_ldxi(GPR[THIS], regval, offsetof(oexception_t, th)); /* Restore exception frame */ jit_ldxi(JIT_R0, regval, offsetof(oexception_t, ex)); jit_stxi(offsetof(othread_t, ex), JIT_V0, JIT_R0); }
jit_node_t *compile_rpn(char *expr) { jit_node_t *in, *fn; int stack_base, stack_ptr; fn = jit_note(NULL, 0); jit_prolog(); in = jit_arg(); stack_ptr = stack_base = jit_allocai (32 * sizeof (int)); jit_getarg_i(JIT_R2, in); while (*expr) { char buf[32]; int n; if (sscanf(expr, "%[0-9]%n", buf, &n)) { expr += n - 1; stack_push(JIT_R0, &stack_ptr); jit_movi(JIT_R0, atoi(buf)); } else if (*expr == 'x') { stack_push(JIT_R0, &stack_ptr); jit_movr(JIT_R0, JIT_R2); } else if (*expr == '+') { stack_pop(JIT_R1, &stack_ptr); jit_addr(JIT_R0, JIT_R1, JIT_R0); } else if (*expr == '-') { stack_pop(JIT_R1, &stack_ptr); jit_subr(JIT_R0, JIT_R1, JIT_R0); } else if (*expr == '*') { stack_pop(JIT_R1, &stack_ptr); jit_mulr(JIT_R0, JIT_R1, JIT_R0); } else if (*expr == '/') { stack_pop(JIT_R1, &stack_ptr); jit_divr(JIT_R0, JIT_R1, JIT_R0); } else { fprintf(stderr, "cannot compile: %s\n", expr); abort(); } ++expr; } jit_retr(JIT_R0); jit_epilog(); return fn; }