summaryrefslogtreecommitdiff
path: root/py/nlrx86.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/nlrx86.c')
-rw-r--r--py/nlrx86.c63
1 files changed, 50 insertions, 13 deletions
diff --git a/py/nlrx86.c b/py/nlrx86.c
index cc37f72af..3a27460eb 100644
--- a/py/nlrx86.c
+++ b/py/nlrx86.c
@@ -26,13 +26,25 @@
#include "py/mpstate.h"
-#if MICROPY_NLR_X86
+#if !MICROPY_NLR_SETJMP && defined(__i386__)
#undef nlr_push
// For reference, x86 callee save regs are:
// ebx, esi, edi, ebp, esp, eip
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define NLR_OS_WINDOWS 1
+#else
+#define NLR_OS_WINDOWS 0
+#endif
+
+#if NLR_OS_WINDOWS
+unsigned int nlr_push_tail(nlr_buf_t *nlr) asm("nlr_push_tail");
+#else
+__attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr);
+#endif
+
unsigned int nlr_push(nlr_buf_t *nlr) {
(void)nlr;
@@ -58,23 +70,48 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
return 0; // needed to silence compiler warning
}
-NORETURN void nlr_jump_tail(nlr_buf_t *top) {
- (void)top;
+__attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr) {
+ nlr_buf_t **top = &MP_STATE_THREAD(nlr_top);
+ nlr->prev = *top;
+ MP_NLR_SAVE_PYSTACK(nlr);
+ *top = nlr;
+ return 0; // normal return
+}
+
+void nlr_pop(void) {
+ nlr_buf_t **top = &MP_STATE_THREAD(nlr_top);
+ *top = (*top)->prev;
+}
+
+NORETURN void nlr_jump(void *val) {
+ nlr_buf_t **top_ptr = &MP_STATE_THREAD(nlr_top);
+ nlr_buf_t *top = *top_ptr;
+ if (top == NULL) {
+ nlr_jump_fail(val);
+ }
+
+ top->ret_val = val;
+ MP_NLR_RESTORE_PYSTACK(top);
+ *top_ptr = top->prev;
__asm volatile (
- "mov 28(%edx), %esi \n" // load saved %esi
- "mov 24(%edx), %edi \n" // load saved %edi
- "mov 20(%edx), %ebx \n" // load saved %ebx
- "mov 16(%edx), %esp \n" // load saved %esp
- "mov 12(%edx), %ebp \n" // load saved %ebp
- "mov 8(%edx), %eax \n" // load saved %eip
- "mov %eax, (%esp) \n" // store saved %eip to stack
- "xor %eax, %eax \n" // clear return register
- "inc %al \n" // increase to make 1, non-local return
+ "mov %0, %%edx \n" // %edx points to nlr_buf
+ "mov 28(%%edx), %%esi \n" // load saved %esi
+ "mov 24(%%edx), %%edi \n" // load saved %edi
+ "mov 20(%%edx), %%ebx \n" // load saved %ebx
+ "mov 16(%%edx), %%esp \n" // load saved %esp
+ "mov 12(%%edx), %%ebp \n" // load saved %ebp
+ "mov 8(%%edx), %%eax \n" // load saved %eip
+ "mov %%eax, (%%esp) \n" // store saved %eip to stack
+ "xor %%eax, %%eax \n" // clear return register
+ "inc %%al \n" // increase to make 1, non-local return
"ret \n" // return
+ : // output operands
+ : "r"(top) // input operands
+ : // clobbered registers
);
for (;;); // needed to silence compiler warning
}
-#endif // MICROPY_NLR_X86
+#endif // !MICROPY_NLR_SETJMP && defined(__i386__)