From b92cbe612913a7c9d066c34912a3f77fe6392b2b Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
Date: Mon, 15 Sep 2014 15:53:09 +0100
Subject: [PATCH] py: Move definition of mp_sys_exit to core.

sys.exit always raises SystemExit so doesn't need a special
implementation for each port.  If C exit() is really needed, use the
standard os._exit function.

Also initialise mp_sys_path and mp_sys_argv in teensy port.
---
 py/modsys.c   | 25 +++++++++++++++++--------
 py/objint.h   |  2 ++
 stmhal/main.c | 13 -------------
 teensy/main.c | 12 +++---------
 unix/main.c   | 16 ++++------------
 5 files changed, 26 insertions(+), 42 deletions(-)

diff --git a/py/modsys.c b/py/modsys.c
index 4ce20f5c5..8ef66af05 100644
--- a/py/modsys.c
+++ b/py/modsys.c
@@ -25,8 +25,9 @@
  */
 
 #include <stdint.h>
-#include <limits.h>
+
 #include "mpconfig.h"
+#include "nlr.h"
 #include "misc.h"
 #include "qstr.h"
 #include "obj.h"
@@ -42,13 +43,7 @@
 
 /// \module sys - system specific functions
 
-// These should be implemented by ports, specific types don't matter,
-// only addresses.
-struct _dummy_t;
-extern struct _dummy_t mp_sys_exit_obj;
-
-extern mp_obj_int_t mp_maxsize_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;
@@ -69,6 +64,20 @@ STATIC const mp_obj_tuple_t mp_sys_version_info_obj = {{&mp_type_tuple}, 3, {I(3
 STATIC const MP_DEFINE_STR_OBJ(platform_obj, MICROPY_PY_SYS_PLATFORM);
 #endif
 
+/// \function exit([retval])
+/// Raise a `SystemExit` exception.  If an argument is given, it is the
+/// value given to `SystemExit`.
+STATIC mp_obj_t mp_sys_exit(mp_uint_t n_args, const mp_obj_t *args) {
+    mp_obj_t exc;
+    if (n_args == 0) {
+        exc = mp_obj_new_exception(&mp_type_SystemExit);
+    } else {
+        exc = mp_obj_new_exception_arg1(&mp_type_SystemExit, args[0]);
+    }
+    nlr_raise(exc);
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit);
+
 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) },
 
diff --git a/py/objint.h b/py/objint.h
index 50f36df4d..638742a85 100644
--- a/py/objint.h
+++ b/py/objint.h
@@ -33,6 +33,8 @@ typedef struct _mp_obj_int_t {
 #endif
 } mp_obj_int_t;
 
+extern const mp_obj_int_t mp_maxsize_obj;
+
 void mp_obj_int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind);
 char *mp_obj_int_formatted(char **buf, int *buf_size, int *fmt_size, mp_const_obj_t self_in,
                            int base, const char *prefix, char base_char, char comma);
diff --git a/stmhal/main.c b/stmhal/main.c
index a34ffab32..6aa7b082d 100644
--- a/stmhal/main.c
+++ b/stmhal/main.c
@@ -550,16 +550,3 @@ soft_reset:
     first_soft_reset = false;
     goto soft_reset;
 }
-
-/// \moduleref sys
-/// \function exit([retval])
-/// Raise a `SystemExit` exception.  If an argument is given, it is the
-/// value given to `SystemExit`.
-STATIC NORETURN mp_obj_t mp_sys_exit(uint n_args, const mp_obj_t *args) {
-    int rc = 0;
-    if (n_args > 0) {
-        rc = mp_obj_get_int(args[0]);
-    }
-    nlr_raise(mp_obj_new_exception_arg1(&mp_type_SystemExit, mp_obj_new_int(rc)));
-}
-MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit);
diff --git a/teensy/main.c b/teensy/main.c
index 8de26f25e..3b2994c86 100644
--- a/teensy/main.c
+++ b/teensy/main.c
@@ -269,6 +269,9 @@ soft_reset:
 
     // Micro Python init
     mp_init();
+    mp_obj_list_init(mp_sys_path, 0);
+    mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script)
+    mp_obj_list_init(mp_sys_argv, 0);
 
     readline_init0();
 
@@ -369,12 +372,3 @@ char * ultoa(unsigned long val, char *buf, int radix)
 	}
 	return buf;
 }
-
-STATIC NORETURN mp_obj_t mp_sys_exit(uint n_args, const mp_obj_t *args) {
-    int rc = 0;
-    if (n_args > 0) {
-        rc = mp_obj_get_int(args[0]);
-    }
-    nlr_raise(mp_obj_new_exception_arg1(&mp_type_SystemExit, mp_obj_new_int(rc)));
-}
-MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit);
diff --git a/unix/main.c b/unix/main.c
index 177c76b53..f00bf3d33 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -130,10 +130,11 @@ STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind,
         // check for SystemExit
         mp_obj_t exc = (mp_obj_t)nlr.ret_val;
         if (mp_obj_is_subclass_fast(mp_obj_get_type(exc), &mp_type_SystemExit)) {
+            // None is an exit value of 0; an int is its value; anything else is 1
             mp_obj_t exit_val = mp_obj_exception_get_value(exc);
-            mp_int_t val;
-            if (!mp_obj_get_int_maybe(exit_val, &val)) {
-                val = 0;
+            mp_int_t val = 0;
+            if (exit_val != mp_const_none && !mp_obj_get_int_maybe(exit_val, &val)) {
+                val = 1;
             }
             exit(val);
         }
@@ -406,15 +407,6 @@ int main(int argc, char **argv) {
     return ret;
 }
 
-STATIC mp_obj_t mp_sys_exit(uint n_args, const mp_obj_t *args) {
-    int rc = 0;
-    if (n_args > 0) {
-        rc = mp_obj_get_int(args[0]);
-    }
-    nlr_raise(mp_obj_new_exception_arg1(&mp_type_SystemExit, mp_obj_new_int(rc)));
-}
-MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit);
-
 uint mp_import_stat(const char *path) {
     struct stat st;
     if (stat(path, &st) == 0) {
-- 
GitLab