From e1e359ff59d6bbf09441cc1f3965be63f1046182 Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
Date: Sat, 7 Feb 2015 17:24:10 +0000
Subject: [PATCH] py: Put mp_sys_path, mp_sys_argv and gc_collected in
 mp_state_ctx_t.

Without mp_sys_path and mp_sys_argv in the root pointer section of the
state, their memory was being incorrectly collected by GC.
---
 py/gc.c      |  8 ++------
 py/modgc.c   |  2 +-
 py/modsys.c  | 12 +++---------
 py/mpstate.h | 10 +++++++++-
 py/runtime.h |  6 ++----
 5 files changed, 17 insertions(+), 21 deletions(-)

diff --git a/py/gc.c b/py/gc.c
index 121e50b78..86db78f84 100644
--- a/py/gc.c
+++ b/py/gc.c
@@ -222,13 +222,9 @@ STATIC void gc_deal_with_stack_overflow(void) {
     }
 }
 
-#if MICROPY_PY_GC_COLLECT_RETVAL
-uint gc_collected;
-#endif
-
 STATIC void gc_sweep(void) {
     #if MICROPY_PY_GC_COLLECT_RETVAL
-    gc_collected = 0;
+    MP_STATE_MEM(gc_collected) = 0;
     #endif
     // free unmarked heads and their tails
     int free_tail = 0;
@@ -253,7 +249,7 @@ STATIC void gc_sweep(void) {
 #endif
                 free_tail = 1;
                 #if MICROPY_PY_GC_COLLECT_RETVAL
-                gc_collected++;
+                MP_STATE_MEM(gc_collected)++;
                 #endif
                 // fall through to free the head
 
diff --git a/py/modgc.c b/py/modgc.c
index 38f7c15fe..47980deca 100644
--- a/py/modgc.c
+++ b/py/modgc.c
@@ -39,7 +39,7 @@ extern uint gc_collected;
 STATIC mp_obj_t py_gc_collect(void) {
     gc_collect();
 #if MICROPY_PY_GC_COLLECT_RETVAL
-    return MP_OBJ_NEW_SMALL_INT(gc_collected);
+    return MP_OBJ_NEW_SMALL_INT(MP_STATE_MEM(gc_collected));
 #else
     return mp_const_none;
 #endif
diff --git a/py/modsys.c b/py/modsys.c
index 51e10dae5..4ea60a697 100644
--- a/py/modsys.c
+++ b/py/modsys.c
@@ -24,6 +24,7 @@
  * THE SOFTWARE.
  */
 
+#include "py/mpstate.h"
 #include "py/nlr.h"
 #include "py/builtin.h"
 #include "py/objlist.h"
@@ -42,13 +43,6 @@ extern mp_uint_t mp_sys_stdin_obj;
 extern mp_uint_t mp_sys_stdout_obj;
 extern mp_uint_t mp_sys_stderr_obj;
 
-// These two lists must be initialised per port (after the call to mp_init).
-// TODO document these properly, they aren't constants or functions...
-/// \constant path - a mutable list of directories to search for imported modules
-mp_obj_list_t mp_sys_path_obj;
-/// \constant argv - a mutable list of arguments this program started with
-mp_obj_list_t mp_sys_argv_obj;
-
 /// \constant version - Python language version that this implementation conforms to, as a string
 STATIC const MP_DEFINE_STR_OBJ(version_obj, "3.4.0");
 
@@ -99,8 +93,8 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_print_exception_obj, 1, 2, mp_sys_pri
 STATIC const mp_map_elem_t mp_module_sys_globals_table[] = {
     { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sys) },
 
-    { MP_OBJ_NEW_QSTR(MP_QSTR_path), (mp_obj_t)&mp_sys_path_obj },
-    { MP_OBJ_NEW_QSTR(MP_QSTR_argv), (mp_obj_t)&mp_sys_argv_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_path), (mp_obj_t)&MP_STATE_VM(mp_sys_path_obj) },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_argv), (mp_obj_t)&MP_STATE_VM(mp_sys_argv_obj) },
     { MP_OBJ_NEW_QSTR(MP_QSTR_version), (mp_obj_t)&version_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_version_info), (mp_obj_t)&mp_sys_version_info_obj },
 #ifdef MICROPY_PY_SYS_PLATFORM
diff --git a/py/mpstate.h b/py/mpstate.h
index 10a5db819..a2366df7f 100644
--- a/py/mpstate.h
+++ b/py/mpstate.h
@@ -32,7 +32,7 @@
 #include "py/misc.h"
 #include "py/nlr.h"
 #include "py/obj.h"
-#include "py/objlist.h" // in case port needs mp_obj_list_t in root pointers
+#include "py/objlist.h"
 #include "py/objexcept.h"
 
 // This file contains structures defining the state of the Micro Python
@@ -66,6 +66,10 @@ typedef struct _mp_state_mem_t {
     uint16_t gc_auto_collect_enabled;
 
     mp_uint_t gc_last_free_atb_index;
+
+    #if MICROPY_PY_GC_COLLECT_RETVAL
+    mp_uint_t gc_collected;
+    #endif
 } mp_state_mem_t;
 
 // This structure hold runtime and VM information.  It includes a section
@@ -106,6 +110,10 @@ typedef struct _mp_state_vm_t {
     // dictionary for the __main__ module
     mp_obj_dict_t dict_main;
 
+    // these two lists must be initialised per port, after the call to mp_init
+    mp_obj_list_t mp_sys_path_obj;
+    mp_obj_list_t mp_sys_argv_obj;
+
     // dictionary for overridden builtins
     #if MICROPY_CAN_OVERRIDE_BUILTINS
     mp_obj_dict_t *mp_module_builtins_override_dict;
diff --git a/py/runtime.h b/py/runtime.h
index a4386b4bb..e09162433 100644
--- a/py/runtime.h
+++ b/py/runtime.h
@@ -125,10 +125,8 @@ mp_obj_t mp_convert_native_to_obj(mp_uint_t val, mp_uint_t type);
 mp_obj_t mp_native_call_function_n_kw(mp_obj_t fun_in, mp_uint_t n_args_kw, const mp_obj_t *args);
 void mp_native_raise(mp_obj_t o);
 
-extern struct _mp_obj_list_t mp_sys_path_obj;
-extern struct _mp_obj_list_t mp_sys_argv_obj;
-#define mp_sys_path ((mp_obj_t)&mp_sys_path_obj)
-#define mp_sys_argv ((mp_obj_t)&mp_sys_argv_obj)
+#define mp_sys_path ((mp_obj_t)&MP_STATE_VM(mp_sys_path_obj))
+#define mp_sys_argv ((mp_obj_t)&MP_STATE_VM(mp_sys_argv_obj))
 
 #if MICROPY_WARNINGS
 void mp_warning(const char *msg, ...);
-- 
GitLab