Skip to content

Commit 26cf55a

Browse files
committed
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).
1 parent 094ebef commit 26cf55a

8 files changed

Lines changed: 53 additions & 16 deletions

File tree

py/nlr.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ unsigned int nlr_push(nlr_buf_t *);
2727
void nlr_pop(void);
2828
void nlr_jump(void *val) __attribute__((noreturn));
2929

30+
// This must be implemented by a port. It's called by nlr_jump
31+
// if no nlr buf has been pushed. It must not return, but rather
32+
// should bail out with a fatal error.
33+
void nlr_jump_fail(void *val);
34+
3035
// use nlr_raise instead of nlr_jump so that debugging is easier
3136
#ifndef DEBUG
3237
#define nlr_raise(val) nlr_jump(val)

py/nlrthumb.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ nlr_pop:
6060
nlr_jump:
6161
ldr r3, .L2 @ load addr of nlr_top
6262
ldr r2, [r3] @ load nlr_top
63+
cmp r2, #0 @ test if nlr_top is NULL
64+
beq nlr_jump_fail @ if nlr_top is NULL, transfer control to nlr_jump_fail
6365
str r0, [r2, #4] @ store return value
6466
ldr r0, [r2] @ load prev nlr_buf
6567
str r0, [r3] @ store prev nol_buf into nlr_top (to unlink list)

py/nlrx64.S

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ nlr_jump:
6161
#endif
6262
movq %rdi, %rax # put return value in %rax
6363
movq nlr_top(%rip), %rdi # get nlr_top into %rdi
64+
test %rdi, %rdi # check for nlr_top being NULL
65+
je .fail # fail if nlr_top is NULL
6466
movq %rax, 8(%rdi) # store return value
6567
movq (%rdi), %rax # load prev nlr_buf
6668
movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
@@ -76,10 +78,14 @@ nlr_jump:
7678
xorq %rax, %rax # clear return register
7779
inc %al # increase to make 1, non-local return
7880
ret # return
81+
.fail:
82+
movq %rax, %rdi # put argument back in first-arg register
83+
je nlr_jump_fail # transfer control to nlr_jump_fail
7984
#if !(defined(__APPLE__) && defined(__MACH__))
8085
.size nlr_jump, .-nlr_jump
8186
#endif
8287

88+
.bss
8389
#if !(defined(__APPLE__) && defined(__MACH__))
8490
.local nlr_top
8591
#endif
@@ -107,12 +113,21 @@ nlr_push:
107113
xorq %rax, %rax # return 0, normal return
108114
ret # return
109115

110-
/* void nlr_jump(rcx=uint val) */
116+
/* void nlr_pop() */
117+
.globl nlr_pop
118+
nlr_pop:
119+
movq nlr_top(%rip), %rax # get nlr_top into %rax
120+
movq (%rax), %rax # load prev nlr_buf
121+
movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
122+
ret # return
111123

124+
/* void nlr_jump(rcx=uint val) */
112125
.globl nlr_jump
113126
nlr_jump:
114127
movq %rcx, %rax # put return value in %rax
115-
movq nlr_top(%rip), %rcx # get nlr_top into %rsi
128+
movq nlr_top(%rip), %rcx # get nlr_top into %rcx
129+
test %rcx, %rcx # check for nlr_top being NULL
130+
je .fail # fail if nlr_top is NULL
116131
movq %rax, 8(%rcx) # store return value
117132
movq (%rcx), %rax # load prev nlr_buf
118133
movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
@@ -130,17 +145,13 @@ nlr_jump:
130145
xorq %rax, %rax # clear return register
131146
inc %al # increase to make 1, non-local return
132147
ret # return
148+
.fail:
149+
movq %rax, %rcx # put argument back in first-arg register
150+
je nlr_jump_fail # transfer control to nlr_jump_fail
133151

152+
.bss
134153
.comm nlr_top,8,8
135154

136-
/* void nlr_pop() */
137-
.globl nlr_pop
138-
nlr_pop:
139-
movq nlr_top(%rip), %rax # get nlr_top into %rax
140-
movq (%rax), %rax # load prev nlr_buf
141-
movq %rax, nlr_top(%rip) # store prev nlr_buf (to unlink list)
142-
ret # return
143-
144155
#endif // !defined(__CYGWIN__)
145156

146157
#endif // __x86_64__

py/nlrx86.S

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ _nlr_jump:
6060
nlr_jump:
6161
#endif
6262
mov nlr_top, %edx # load nlr_top
63+
test %edx, %edx # check for nlr_top being NULL
64+
je nlr_jump_fail # fail if nlr_top is NULL
6365
mov 4(%esp), %eax # load return value
6466
mov %eax, 4(%edx) # store return value
6567
mov (%edx), %eax # load prev nlr_top
@@ -78,6 +80,7 @@ nlr_jump:
7880
.size nlr_jump, .-nlr_jump
7981
#endif
8082

83+
.bss
8184
#ifndef _WIN32
8285
.local nlr_top
8386
#endif

stm/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ void __fatal_error(const char *msg) {
7979
}
8080
}
8181

82+
void nlr_jump_fail(void *val) {
83+
printf("FATAL: uncaught exception %p\n", val);
84+
__fatal_error("");
85+
}
86+
8287
STATIC mp_obj_t pyb_config_source_dir = MP_OBJ_NULL;
8388
STATIC mp_obj_t pyb_config_main = MP_OBJ_NULL;
8489

stmhal/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ void __fatal_error(const char *msg) {
7373
}
7474
}
7575

76+
void nlr_jump_fail(void *val) {
77+
printf("FATAL: uncaught exception %p\n", val);
78+
__fatal_error("");
79+
}
80+
7681
STATIC mp_obj_t pyb_config_source_dir = MP_OBJ_NULL;
7782
STATIC mp_obj_t pyb_config_main = MP_OBJ_NULL;
7883
STATIC mp_obj_t pyb_config_usb_mode = MP_OBJ_NULL;

unix-cpy/main.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <stdlib.h>
12
#include <stdint.h>
23
#include <stdio.h>
34
#include <string.h>
@@ -74,12 +75,11 @@ int main(int argc, char **argv) {
7475
return 0;
7576
}
7677

77-
// for sqrt
78-
#include <math.h>
79-
machine_float_t machine_sqrt(machine_float_t x) {
80-
return sqrt(x);
81-
}
82-
8378
mp_import_stat_t mp_import_stat(const char *path) {
8479
return MP_IMPORT_STAT_NO_EXIST;
8580
}
81+
82+
void nlr_jump_fail(void *val) {
83+
printf("FATAL: uncaught NLR %p\n", val);
84+
exit(1);
85+
}

unix/main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ void pre_process_options(int argc, char **argv) {
293293
}
294294

295295
int main(int argc, char **argv) {
296+
nlr_jump(0);
296297
volatile int stack_dummy;
297298
stack_top = (void*)&stack_dummy;
298299

@@ -447,3 +448,8 @@ int DEBUG_printf(const char *fmt, ...) {
447448
va_end(ap);
448449
return ret;
449450
}
451+
452+
void nlr_jump_fail(void *val) {
453+
printf("FATAL: uncaught NLR %p\n", val);
454+
exit(1);
455+
}

0 commit comments

Comments
 (0)