summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/nlr.h5
-rw-r--r--py/nlrthumb.S2
-rw-r--r--py/nlrx64.S31
-rw-r--r--py/nlrx86.S3
-rw-r--r--stm/main.c5
-rw-r--r--stmhal/main.c5
-rw-r--r--unix-cpy/main.c12
-rw-r--r--unix/main.c6
8 files changed, 53 insertions, 16 deletions
diff --git a/py/nlr.h b/py/nlr.h
index ce62334fd4..4e931919db 100644
--- a/py/nlr.h
+++ b/py/nlr.h
@@ -27,6 +27,11 @@ unsigned int nlr_push(nlr_buf_t *);
void nlr_pop(void);
void nlr_jump(void *val) __attribute__((noreturn));
+// 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
+// should bail out with a fatal error.
+void nlr_jump_fail(void *val);
+
// use nlr_raise instead of nlr_jump so that debugging is easier
#ifndef DEBUG
#define nlr_raise(val) nlr_jump(val)
diff --git a/py/nlrthumb.S b/py/nlrthumb.S
index 8c6eb95522..6a0c7ee1e1 100644
--- a/py/nlrthumb.S
+++ b/py/nlrthumb.S
@@ -60,6 +60,8 @@ nlr_pop:
nlr_jump:
ldr r3, .L2 @ load addr of nlr_top
ldr r2, [r3] @ load nlr_top
+ cmp r2, #0 @ test if nlr_top is NULL
+ beq nlr_jump_fail @ if nlr_top is NULL, transfer control to nlr_jump_fail
str r0, [r2, #4] @ store return value
ldr r0, [r2] @ load prev nlr_buf
str r0, [r3] @ store prev nol_buf into nlr_top (to unlink list)
diff --git a/py/nlrx64.S b/py/nlrx64.S
index a4073981a5..929a348caf 100644
--- a/py/nlrx64.S
+++ b/py/nlrx64.S
@@ -61,6 +61,8 @@ nlr_jump:
#endif
movq %rdi, %rax # put return value in %rax
movq nlr_top(%rip), %rdi # get nlr_top into %rdi
+ test %rdi, %rdi # check for nlr_top being NULL
+ je .fail # fail if nlr_top is NULL
movq %rax, 8(%rdi) # store return value
movq (%rdi), %rax # load prev nlr_buf
movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
@@ -76,10 +78,14 @@ nlr_jump:
xorq %rax, %rax # clear return register
inc %al # increase to make 1, non-local return
ret # return
+.fail:
+ movq %rax, %rdi # put argument back in first-arg register
+ je nlr_jump_fail # transfer control to nlr_jump_fail
#if !(defined(__APPLE__) && defined(__MACH__))
.size nlr_jump, .-nlr_jump
#endif
+ .bss
#if !(defined(__APPLE__) && defined(__MACH__))
.local nlr_top
#endif
@@ -107,12 +113,21 @@ nlr_push:
xorq %rax, %rax # return 0, normal return
ret # return
-/* void nlr_jump(rcx=uint val) */
+/* void nlr_pop() */
+ .globl nlr_pop
+nlr_pop:
+ movq nlr_top(%rip), %rax # get nlr_top into %rax
+ movq (%rax), %rax # load prev nlr_buf
+ movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
+ ret # return
+/* void nlr_jump(rcx=uint val) */
.globl nlr_jump
nlr_jump:
movq %rcx, %rax # put return value in %rax
- movq nlr_top(%rip), %rcx # get nlr_top into %rsi
+ movq nlr_top(%rip), %rcx # get nlr_top into %rcx
+ test %rcx, %rcx # check for nlr_top being NULL
+ je .fail # fail if nlr_top is NULL
movq %rax, 8(%rcx) # store return value
movq (%rcx), %rax # load prev nlr_buf
movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
@@ -130,17 +145,13 @@ nlr_jump:
xorq %rax, %rax # clear return register
inc %al # increase to make 1, non-local return
ret # return
+.fail:
+ movq %rax, %rcx # put argument back in first-arg register
+ je nlr_jump_fail # transfer control to nlr_jump_fail
+ .bss
.comm nlr_top,8,8
- /* void nlr_pop() */
- .globl nlr_pop
-nlr_pop:
- movq nlr_top(%rip), %rax # get nlr_top into %rax
- movq (%rax), %rax # load prev nlr_buf
- movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
- ret # return
-
#endif // !defined(__CYGWIN__)
#endif // __x86_64__
diff --git a/py/nlrx86.S b/py/nlrx86.S
index 5cfd4a8cfc..003de5095f 100644
--- a/py/nlrx86.S
+++ b/py/nlrx86.S
@@ -60,6 +60,8 @@ _nlr_jump:
nlr_jump:
#endif
mov nlr_top, %edx # load nlr_top
+ test %edx, %edx # check for nlr_top being NULL
+ je nlr_jump_fail # fail if nlr_top is NULL
mov 4(%esp), %eax # load return value
mov %eax, 4(%edx) # store return value
mov (%edx), %eax # load prev nlr_top
@@ -78,6 +80,7 @@ nlr_jump:
.size nlr_jump, .-nlr_jump
#endif
+ .bss
#ifndef _WIN32
.local nlr_top
#endif
diff --git a/stm/main.c b/stm/main.c
index a11a813d2d..636f900212 100644
--- a/stm/main.c
+++ b/stm/main.c
@@ -79,6 +79,11 @@ void __fatal_error(const char *msg) {
}
}
+void nlr_jump_fail(void *val) {
+ printf("FATAL: uncaught exception %p\n", val);
+ __fatal_error("");
+}
+
STATIC mp_obj_t pyb_config_source_dir = MP_OBJ_NULL;
STATIC mp_obj_t pyb_config_main = MP_OBJ_NULL;
diff --git a/stmhal/main.c b/stmhal/main.c
index 897271d14a..e5ba67dc1d 100644
--- a/stmhal/main.c
+++ b/stmhal/main.c
@@ -73,6 +73,11 @@ void __fatal_error(const char *msg) {
}
}
+void nlr_jump_fail(void *val) {
+ printf("FATAL: uncaught exception %p\n", val);
+ __fatal_error("");
+}
+
STATIC mp_obj_t pyb_config_source_dir = MP_OBJ_NULL;
STATIC mp_obj_t pyb_config_main = MP_OBJ_NULL;
STATIC mp_obj_t pyb_config_usb_mode = MP_OBJ_NULL;
diff --git a/unix-cpy/main.c b/unix-cpy/main.c
index 944d26e9f3..6cdd72c5da 100644
--- a/unix-cpy/main.c
+++ b/unix-cpy/main.c
@@ -1,3 +1,4 @@
+#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
@@ -74,12 +75,11 @@ int main(int argc, char **argv) {
return 0;
}
-// for sqrt
-#include <math.h>
-machine_float_t machine_sqrt(machine_float_t x) {
- return sqrt(x);
-}
-
mp_import_stat_t mp_import_stat(const char *path) {
return MP_IMPORT_STAT_NO_EXIST;
}
+
+void nlr_jump_fail(void *val) {
+ printf("FATAL: uncaught NLR %p\n", val);
+ exit(1);
+}
diff --git a/unix/main.c b/unix/main.c
index 11df4cadf2..8065663011 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -293,6 +293,7 @@ void pre_process_options(int argc, char **argv) {
}
int main(int argc, char **argv) {
+ nlr_jump(0);
volatile int stack_dummy;
stack_top = (void*)&stack_dummy;
@@ -447,3 +448,8 @@ int DEBUG_printf(const char *fmt, ...) {
va_end(ap);
return ret;
}
+
+void nlr_jump_fail(void *val) {
+ printf("FATAL: uncaught NLR %p\n", val);
+ exit(1);
+}