122122uint8_t value_out = 0 ;
123123#endif
124124
125- #if MICROPY_ENABLE_PYSTACK
126- supervisor_allocation * pystack ;
127- mp_int_t pystack_size = 0 ; // 0 indicated 'not allocated'
128- #if CIRCUITPY_OS_GETENV
125+ #if MICROPY_ENABLE_PYSTACK && CIRCUITPY_OS_GETENV
129126#include "shared-module/os/__init__.h"
130127#endif
131- #endif
132128
133129static void reset_devices (void ) {
134130 #if CIRCUITPY_BLEIO_HCI
@@ -137,30 +133,24 @@ static void reset_devices(void) {
137133}
138134
139135#if MICROPY_ENABLE_PYSTACK
140- STATIC void alloc_pystack (void ) {
141- mp_int_t old_pystack_size = pystack_size ;
142- pystack_size = CIRCUITPY_PYSTACK_SIZE ; // Use build default for now.
143- // Fetch value if exists from settings.toml
136+ STATIC mp_int_t fetch_pystack_size (void ) {
137+ mp_int_t pystack_size = CIRCUITPY_PYSTACK_SIZE ;
144138 #if CIRCUITPY_OS_GETENV
139+ // Fetch value if exists from settings.toml
145140 // Leaves size to build default on any failure
146141 (void )common_hal_os_getenv_int ("CIRCUITPY_PYSTACK_SIZE" , & pystack_size );
147142 // Check if value is valid
148143 if ((CIRCUITPY_PYSTACK_SIZE != pystack_size ) && ((pystack_size < 1 ) || (pystack_size % sizeof (size_t ) != 0 ))) {
149- pystack_size = CIRCUITPY_PYSTACK_SIZE ; // Reset to build default
144+ pystack_size = CIRCUITPY_PYSTACK_SIZE ; // Reset
150145 // TODO: Find a way to inform the user about it.
151146 // Perhaps safemode? Or is it too much?
152147 }
153148 #endif
154- if (old_pystack_size != pystack_size ) {
155- if (old_pystack_size != 0 ) {
156- free_memory (pystack );
157- }
158- pystack = allocate_memory (pystack_size , false, false);
159- }
149+ return pystack_size ;
160150}
161151#endif
162152
163- STATIC void start_mp (supervisor_allocation * heap ) {
153+ STATIC void start_mp (supervisor_allocation * heap , supervisor_allocation * pystack , mp_int_t pystack_size ) {
164154 supervisor_workflow_reset ();
165155
166156 // Stack limit should be less than real stack size, so we have a chance
@@ -292,7 +282,7 @@ STATIC void count_strn(void *data, const char *str, size_t len) {
292282 * (size_t * )data += len ;
293283}
294284
295- STATIC void cleanup_after_vm (supervisor_allocation * heap , mp_obj_t exception ) {
285+ STATIC void cleanup_after_vm (supervisor_allocation * heap , supervisor_allocation * pystack , mp_obj_t exception ) {
296286 // Get the traceback of any exception from this run off the heap.
297287 // MP_OBJ_SENTINEL means "this run does not contribute to traceback storage, don't touch it"
298288 // MP_OBJ_NULL (=0) means "this run completed successfully, clear any stored traceback"
@@ -373,6 +363,7 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) {
373363 filesystem_flush ();
374364 stop_mp ();
375365 free_memory (heap );
366+ free_memory (pystack );
376367 supervisor_move_memory ();
377368
378369 // Let the workflows know we've reset in case they want to restart.
@@ -428,10 +419,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) {
428419 #endif
429420
430421 #if MICROPY_ENABLE_PYSTACK
431- alloc_pystack ();
422+ mp_int_t pystack_size = fetch_pystack_size ();
423+ supervisor_allocation * pystack = allocate_memory (pystack_size , false, false);
432424 #endif
433425 supervisor_allocation * heap = allocate_remaining_memory ();
434- start_mp (heap );
426+ start_mp (heap , pystack , pystack_size );
435427
436428 #if CIRCUITPY_USB
437429 usb_setup_with_vm ();
@@ -479,7 +471,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) {
479471
480472
481473 // Finished executing python code. Cleanup includes filesystem flush and a board reset.
482- cleanup_after_vm (heap , _exec_result .exception );
474+ cleanup_after_vm (heap , pystack , _exec_result .exception );
483475 _exec_result .exception = NULL ;
484476
485477 // If a new next code file was set, that is a reason to keep it (obviously). Stuff this into
@@ -776,10 +768,11 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
776768 // Do USB setup even if boot.py is not run.
777769
778770 #if MICROPY_ENABLE_PYSTACK
779- alloc_pystack ();
771+ mp_int_t pystack_size = fetch_pystack_size ();
772+ supervisor_allocation * pystack = allocate_memory (pystack_size , false, false);
780773 #endif
781774 supervisor_allocation * heap = allocate_remaining_memory ();
782- start_mp (heap );
775+ start_mp (heap , pystack , pystack_size );
783776
784777 #if CIRCUITPY_USB
785778 // Set up default USB values after boot.py VM starts but before running boot.py.
@@ -865,7 +858,7 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
865858
866859 port_post_boot_py (true);
867860
868- cleanup_after_vm (heap , _exec_result .exception );
861+ cleanup_after_vm (heap , pystack , _exec_result .exception );
869862 _exec_result .exception = NULL ;
870863
871864 port_post_boot_py (false);
@@ -881,10 +874,11 @@ STATIC int run_repl(void) {
881874 stack_resize ();
882875 filesystem_flush ();
883876 #if MICROPY_ENABLE_PYSTACK
884- alloc_pystack ();
877+ mp_int_t pystack_size = fetch_pystack_size ();
878+ supervisor_allocation * pystack = allocate_memory (pystack_size , false, false);
885879 #endif
886880 supervisor_allocation * heap = allocate_remaining_memory ();
887- start_mp (heap );
881+ start_mp (heap , pystack , pystack_size );
888882
889883 #if CIRCUITPY_USB
890884 usb_setup_with_vm ();
@@ -927,7 +921,7 @@ STATIC int run_repl(void) {
927921 exit_code = PYEXEC_DEEP_SLEEP ;
928922 }
929923 #endif
930- cleanup_after_vm (heap , MP_OBJ_SENTINEL );
924+ cleanup_after_vm (heap , pystack , MP_OBJ_SENTINEL );
931925
932926 // Also reset bleio. The above call omits it in case workflows should continue. In this case,
933927 // we're switching straight to another VM so we want to reset.
0 commit comments