122122uint8_t value_out = 0 ;
123123#endif
124124
125- #if MICROPY_ENABLE_PYSTACK && CIRCUITPY_OS_GETENV
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
126129#include "shared-module/os/__init__.h"
127130#endif
131+ #endif
128132
129133static void reset_devices (void ) {
130134 #if CIRCUITPY_BLEIO_HCI
131135 bleio_reset ();
132136 #endif
133137}
134138
135- STATIC void start_mp (supervisor_allocation * heap , supervisor_allocation * pystack , int pystack_size ) {
139+ #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
144+ #if CIRCUITPY_OS_GETENV
145+ // Leaves size to build default on any failure
146+ (void )common_hal_os_getenv_int ("CIRCUITPY_PYSTACK_SIZE" , & pystack_size );
147+ // Check if value is valid
148+ 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
150+ // TODO: Find a way to inform the user about it.
151+ // Perhaps safemode? Or is it too much?
152+ }
153+ #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+ }
160+ }
161+ #endif
162+
163+ STATIC void start_mp (supervisor_allocation * heap ) {
136164 supervisor_workflow_reset ();
137165
138166 // Stack limit should be less than real stack size, so we have a chance
@@ -363,7 +391,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
363391 }
364392}
365393
366- STATIC bool run_code_py (safe_mode_t safe_mode , bool * simulate_reset , supervisor_allocation * pystack , int pystack_size ) {
394+ STATIC bool run_code_py (safe_mode_t safe_mode , bool * simulate_reset ) {
367395 bool serial_connected_at_start = serial_connected ();
368396 bool printed_safe_mode_message = false;
369397 #if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
@@ -399,13 +427,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset, supervisor_
399427 };
400428 #endif
401429
430+ #if MICROPY_ENABLE_PYSTACK
431+ alloc_pystack ();
432+ #endif
402433 supervisor_allocation * heap = allocate_remaining_memory ();
403-
404- // Prepare the VM state.
405- #pragma GCC diagnostic push
406- #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // stackless doesn't want allocations.
407- start_mp (heap , pystack , pystack_size );
408- #pragma GCC diagnostic pop
434+ start_mp (heap );
409435
410436 #if CIRCUITPY_USB
411437 usb_setup_with_vm ();
@@ -733,7 +759,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset, supervisor_
733759
734760vstr_t * boot_output ;
735761
736- STATIC void run_boot_py (safe_mode_t safe_mode , supervisor_allocation * pystack , int pystack_size ) {
762+ STATIC void run_boot_py (safe_mode_t safe_mode ) {
737763 if (safe_mode == NO_HEAP ) {
738764 return ;
739765 }
@@ -749,11 +775,11 @@ STATIC void run_boot_py(safe_mode_t safe_mode, supervisor_allocation *pystack, i
749775
750776 // Do USB setup even if boot.py is not run.
751777
778+ #if MICROPY_ENABLE_PYSTACK
779+ alloc_pystack ();
780+ #endif
752781 supervisor_allocation * heap = allocate_remaining_memory ();
753- #pragma GCC diagnostic push
754- #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // stackless doesn't want allocations.
755- start_mp (heap , pystack , pystack_size );
756- #pragma GCC diagnostic pop
782+ start_mp (heap );
757783
758784 #if CIRCUITPY_USB
759785 // Set up default USB values after boot.py VM starts but before running boot.py.
@@ -850,15 +876,15 @@ STATIC void run_boot_py(safe_mode_t safe_mode, supervisor_allocation *pystack, i
850876 #endif
851877}
852878
853- STATIC int run_repl (supervisor_allocation * pystack , int pystack_size ) {
879+ STATIC int run_repl (void ) {
854880 int exit_code = PYEXEC_FORCED_EXIT ;
855881 stack_resize ();
856882 filesystem_flush ();
883+ #if MICROPY_ENABLE_PYSTACK
884+ alloc_pystack ();
885+ #endif
857886 supervisor_allocation * heap = allocate_remaining_memory ();
858- #pragma GCC diagnostic push
859- #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // stackless doesn't want allocations.
860- start_mp (heap , pystack , pystack_size );
861- #pragma GCC diagnostic pop
887+ start_mp (heap );
862888
863889 #if CIRCUITPY_USB
864890 usb_setup_with_vm ();
@@ -978,38 +1004,6 @@ int __attribute__((used)) main(void) {
9781004 alarm_reset ();
9791005 #endif
9801006
981- // Pystack variables have to exist even in stackless for the function calls
982- supervisor_allocation * pystack ;
983- mp_int_t pystack_size = CIRCUITPY_PYSTACK_SIZE ; // Use build default for now.
984- #if MICROPY_ENABLE_PYSTACK
985- // Allocate default at least temporarily, needed for getenv
986- pystack = allocate_memory (CIRCUITPY_PYSTACK_SIZE , false, false);
987-
988- // Fetch value if exists from settings.toml
989- #if CIRCUITPY_OS_GETENV
990- // Init needed.
991- supervisor_allocation * heap = allocate_remaining_memory ();
992-
993- // Leaves size to build default on any failure
994- (void )common_hal_os_getenv_int ("CIRCUITPY_PYSTACK_SIZE" , & pystack_size );
995- free_memory (heap );
996- // Convert frame count to allocation size, 384 is the default for 1536 bytes
997- pystack_size = pystack_size * sizeof (size_t );
998-
999- // Check if value is valid
1000- if ((CIRCUITPY_PYSTACK_SIZE != pystack_size ) && (pystack_size < 1 )) {
1001- pystack_size = CIRCUITPY_PYSTACK_SIZE ; // Reset to build default
1002- // TODO: Find a way to inform the user about it.
1003- // Perhaps safemode?
1004- }
1005-
1006- if (CIRCUITPY_PYSTACK_SIZE != pystack_size ) {
1007- free_memory (pystack ); // Free the temporary
1008- pystack = allocate_memory (pystack_size , false, false); // Allocate new pystack
1009- }
1010- #endif
1011- #endif
1012-
10131007 // Reset everything and prep MicroPython to run boot.py.
10141008 reset_port ();
10151009 // Port-independent devices, like CIRCUITPY_BLEIO_HCI.
@@ -1032,7 +1026,7 @@ int __attribute__((used)) main(void) {
10321026 filesystem_set_internal_concurrent_write_protection (true);
10331027 filesystem_set_internal_writable_by_usb (CIRCUITPY_USB == 1 );
10341028
1035- run_boot_py (safe_mode , pystack , pystack_size );
1029+ run_boot_py (safe_mode );
10361030
10371031 supervisor_workflow_start ();
10381032
@@ -1046,7 +1040,7 @@ int __attribute__((used)) main(void) {
10461040 bool simulate_reset = true;
10471041 for (;;) {
10481042 if (!skip_repl ) {
1049- exit_code = run_repl (pystack , pystack_size );
1043+ exit_code = run_repl ();
10501044 supervisor_set_run_reason (RUN_REASON_REPL_RELOAD );
10511045 }
10521046 if (exit_code == PYEXEC_FORCED_EXIT ) {
@@ -1057,7 +1051,7 @@ int __attribute__((used)) main(void) {
10571051 // If code.py did a fake deep sleep, pretend that we
10581052 // are running code.py for the first time after a hard
10591053 // reset. This will preserve any alarm information.
1060- skip_repl = run_code_py (safe_mode , & simulate_reset , pystack , pystack_size );
1054+ skip_repl = run_code_py (safe_mode , & simulate_reset );
10611055 } else {
10621056 skip_repl = false;
10631057 }
0 commit comments