Skip to content
Snippets Groups Projects
Commit 26cf55ae authored by Damien George's avatar Damien George
Browse files

Add a check for NULL nlr_top in nlr_jump.

If no nlr_buf has been pushed, and an nlr_jump is called, then control
is transferred to nlr_jump_fail (which should bail out with a fatal
error).
parent 094ebef2
Branches
No related tags found
No related merge requests found
...@@ -27,6 +27,11 @@ unsigned int nlr_push(nlr_buf_t *); ...@@ -27,6 +27,11 @@ unsigned int nlr_push(nlr_buf_t *);
void nlr_pop(void); void nlr_pop(void);
void nlr_jump(void *val) __attribute__((noreturn)); 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 // use nlr_raise instead of nlr_jump so that debugging is easier
#ifndef DEBUG #ifndef DEBUG
#define nlr_raise(val) nlr_jump(val) #define nlr_raise(val) nlr_jump(val)
......
...@@ -60,6 +60,8 @@ nlr_pop: ...@@ -60,6 +60,8 @@ nlr_pop:
nlr_jump: nlr_jump:
ldr r3, .L2 @ load addr of nlr_top ldr r3, .L2 @ load addr of nlr_top
ldr r2, [r3] @ load 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 str r0, [r2, #4] @ store return value
ldr r0, [r2] @ load prev nlr_buf ldr r0, [r2] @ load prev nlr_buf
str r0, [r3] @ store prev nol_buf into nlr_top (to unlink list) str r0, [r3] @ store prev nol_buf into nlr_top (to unlink list)
......
...@@ -61,6 +61,8 @@ nlr_jump: ...@@ -61,6 +61,8 @@ nlr_jump:
#endif #endif
movq %rdi, %rax # put return value in %rax movq %rdi, %rax # put return value in %rax
movq nlr_top(%rip), %rdi # get nlr_top into %rdi 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 %rax, 8(%rdi) # store return value
movq (%rdi), %rax # load prev nlr_buf movq (%rdi), %rax # load prev nlr_buf
movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list) movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
...@@ -76,10 +78,14 @@ nlr_jump: ...@@ -76,10 +78,14 @@ nlr_jump:
xorq %rax, %rax # clear return register xorq %rax, %rax # clear return register
inc %al # increase to make 1, non-local return inc %al # increase to make 1, non-local return
ret # 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__)) #if !(defined(__APPLE__) && defined(__MACH__))
.size nlr_jump, .-nlr_jump .size nlr_jump, .-nlr_jump
#endif #endif
.bss
#if !(defined(__APPLE__) && defined(__MACH__)) #if !(defined(__APPLE__) && defined(__MACH__))
.local nlr_top .local nlr_top
#endif #endif
...@@ -107,12 +113,21 @@ nlr_push: ...@@ -107,12 +113,21 @@ nlr_push:
xorq %rax, %rax # return 0, normal return xorq %rax, %rax # return 0, normal return
ret # 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 .globl nlr_jump
nlr_jump: nlr_jump:
movq %rcx, %rax # put return value in %rax 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 %rax, 8(%rcx) # store return value
movq (%rcx), %rax # load prev nlr_buf movq (%rcx), %rax # load prev nlr_buf
movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list) movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
...@@ -130,17 +145,13 @@ nlr_jump: ...@@ -130,17 +145,13 @@ nlr_jump:
xorq %rax, %rax # clear return register xorq %rax, %rax # clear return register
inc %al # increase to make 1, non-local return inc %al # increase to make 1, non-local return
ret # 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 .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 // !defined(__CYGWIN__)
#endif // __x86_64__ #endif // __x86_64__
...@@ -60,6 +60,8 @@ _nlr_jump: ...@@ -60,6 +60,8 @@ _nlr_jump:
nlr_jump: nlr_jump:
#endif #endif
mov nlr_top, %edx # load nlr_top 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 4(%esp), %eax # load return value
mov %eax, 4(%edx) # store return value mov %eax, 4(%edx) # store return value
mov (%edx), %eax # load prev nlr_top mov (%edx), %eax # load prev nlr_top
...@@ -78,6 +80,7 @@ nlr_jump: ...@@ -78,6 +80,7 @@ nlr_jump:
.size nlr_jump, .-nlr_jump .size nlr_jump, .-nlr_jump
#endif #endif
.bss
#ifndef _WIN32 #ifndef _WIN32
.local nlr_top .local nlr_top
#endif #endif
......
...@@ -79,6 +79,11 @@ void __fatal_error(const char *msg) { ...@@ -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_source_dir = MP_OBJ_NULL;
STATIC mp_obj_t pyb_config_main = MP_OBJ_NULL; STATIC mp_obj_t pyb_config_main = MP_OBJ_NULL;
......
...@@ -73,6 +73,11 @@ void __fatal_error(const char *msg) { ...@@ -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_source_dir = MP_OBJ_NULL;
STATIC mp_obj_t pyb_config_main = MP_OBJ_NULL; STATIC mp_obj_t pyb_config_main = MP_OBJ_NULL;
STATIC mp_obj_t pyb_config_usb_mode = MP_OBJ_NULL; STATIC mp_obj_t pyb_config_usb_mode = MP_OBJ_NULL;
......
#include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
...@@ -74,12 +75,11 @@ int main(int argc, char **argv) { ...@@ -74,12 +75,11 @@ int main(int argc, char **argv) {
return 0; 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) { mp_import_stat_t mp_import_stat(const char *path) {
return MP_IMPORT_STAT_NO_EXIST; return MP_IMPORT_STAT_NO_EXIST;
} }
void nlr_jump_fail(void *val) {
printf("FATAL: uncaught NLR %p\n", val);
exit(1);
}
...@@ -293,6 +293,7 @@ void pre_process_options(int argc, char **argv) { ...@@ -293,6 +293,7 @@ void pre_process_options(int argc, char **argv) {
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
nlr_jump(0);
volatile int stack_dummy; volatile int stack_dummy;
stack_top = (void*)&stack_dummy; stack_top = (void*)&stack_dummy;
...@@ -447,3 +448,8 @@ int DEBUG_printf(const char *fmt, ...) { ...@@ -447,3 +448,8 @@ int DEBUG_printf(const char *fmt, ...) {
va_end(ap); va_end(ap);
return ret; return ret;
} }
void nlr_jump_fail(void *val) {
printf("FATAL: uncaught NLR %p\n", val);
exit(1);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment