diff options
author | Damien George <damien.p.george@gmail.com> | 2014-04-17 17:26:19 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-04-17 17:26:19 +0100 |
commit | eeffbb694809d6ee1434842bc234eb44714c25ac (patch) | |
tree | 1cf175198f43d4f099a362a575e0b845b5c69dc7 | |
parent | 594d0ddbb2740996b460dd596f76fc21f092e9fc (diff) | |
parent | 3a83b805fcb759344ef7e4055f124d5eb989ac34 (diff) | |
download | micropython-eeffbb694809d6ee1434842bc234eb44714c25ac.tar.gz micropython-eeffbb694809d6ee1434842bc234eb44714c25ac.zip |
Merge pull request #507 from pfalcon/nlr-setjmp
nlr: Add implementation using setjmp/longjmp.
-rw-r--r-- | py/nlr.h | 20 | ||||
-rw-r--r-- | py/nlrsetjmp.c | 16 | ||||
-rw-r--r-- | py/py.mk | 1 |
3 files changed, 36 insertions, 1 deletions
@@ -2,12 +2,14 @@ // exception handling, basically a stack of setjmp/longjmp buffers #include <limits.h> +#include <setjmp.h> typedef struct _nlr_buf_t nlr_buf_t; struct _nlr_buf_t { // the entries here must all be machine word size nlr_buf_t *prev; void *ret_val; +#if !MICROPY_NLR_SETJMP #if defined(__i386__) void *regs[6]; #elif defined(__x86_64__) @@ -19,13 +21,29 @@ struct _nlr_buf_t { #elif defined(__thumb2__) void *regs[10]; #else -#error Unknown arch in nlr.h + #define MICROPY_NLR_SETJMP (1) + #warning "No native NLR support for this arch, using setjmp implementation" +#endif +#endif + +#if MICROPY_NLR_SETJMP + jmp_buf jmpbuf; #endif }; +#if MICROPY_NLR_SETJMP +extern nlr_buf_t *nlr_setjmp_top; +void nlr_setjmp_jump(void *val) __attribute__((noreturn)); +// nlr_push() must be defined as a macro, because "The stack context will be +// invalidated if the function which called setjmp() returns." +#define nlr_push(buf) ((buf)->prev = nlr_setjmp_top, nlr_setjmp_top = (buf), setjmp((buf)->jmpbuf)) +#define nlr_pop() { nlr_setjmp_top = nlr_setjmp_top->prev; } +#define nlr_jump(val) nlr_setjmp_jump(val) +#else unsigned int nlr_push(nlr_buf_t *); void nlr_pop(void); void nlr_jump(void *val) __attribute__((noreturn)); +#endif // This must be implemented by a port. It's called by nlr_jump // if no nlr buf has been pushed. It must not return, but rather diff --git a/py/nlrsetjmp.c b/py/nlrsetjmp.c new file mode 100644 index 0000000000..a97c8634b2 --- /dev/null +++ b/py/nlrsetjmp.c @@ -0,0 +1,16 @@ +#include <setjmp.h> +#include <stdio.h> +#include "nlr.h" + +#if MICROPY_NLR_SETJMP + +nlr_buf_t *nlr_setjmp_top; + +void nlr_setjmp_jump(void *val) { + nlr_buf_t *buf = nlr_setjmp_top; + nlr_setjmp_top = buf->prev; + buf->ret_val = val; + longjmp(buf->jmpbuf, 1); +} + +#endif @@ -10,6 +10,7 @@ PY_O_BASENAME = \ nlrx86.o \ nlrx64.o \ nlrthumb.o \ + nlrsetjmp.o \ malloc.o \ gc.o \ qstr.o \ |