diff --git a/py/builtin.h b/py/builtin.h index 2159b718cc..743f748da0 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -45,3 +45,4 @@ extern const mp_obj_module_t mp_module_io; extern const mp_obj_module_t mp_module_math; extern const mp_obj_module_t mp_module_micropython; extern const mp_obj_module_t mp_module_struct; +extern const mp_obj_module_t mp_module_sys; diff --git a/py/builtinimport.c b/py/builtinimport.c index 3fb658c272..4af7dd7ed3 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -28,8 +28,6 @@ #define PATH_SEP_CHAR '/' -mp_obj_t mp_sys_path; - mp_import_stat_t stat_dir_or_file(vstr_t *path) { //printf("stat %s\n", vstr_str(path)); mp_import_stat_t stat = mp_import_stat(vstr_str(path)); @@ -48,9 +46,7 @@ mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *dest) { // extract the list of paths uint path_num = 0; mp_obj_t *path_items; - if (mp_sys_path != MP_OBJ_NULL) { - mp_obj_list_get(mp_sys_path, &path_num, &path_items); - } + mp_obj_list_get(mp_sys_path, &path_num, &path_items); if (path_num == 0) { // mp_sys_path is empty, so just use the given file name diff --git a/py/builtintables.c b/py/builtintables.c index 4b865e142c..0115ea04b5 100644 --- a/py/builtintables.c +++ b/py/builtintables.c @@ -134,6 +134,7 @@ STATIC const mp_map_elem_t mp_builtin_module_table[] = { #if MICROPY_ENABLE_FLOAT { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&mp_module_math }, #endif + { MP_OBJ_NEW_QSTR(MP_QSTR_sys), (mp_obj_t)&mp_module_sys }, // extra builtin modules as defined by a port MICROPY_EXTRA_BUILTIN_MODULES diff --git a/py/modsys.c b/py/modsys.c new file mode 100644 index 0000000000..59539b3b90 --- /dev/null +++ b/py/modsys.c @@ -0,0 +1,50 @@ +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "builtin.h" +#include "runtime.h" +#include "objlist.h" + +#if MICROPY_ENABLE_MOD_SYS + +// These should be implemented by ports, specific types don't matter, +// only addresses. +struct _dummy_t; +extern struct _dummy_t mp_sys_stdin_obj; +extern struct _dummy_t mp_sys_stdout_obj; +extern struct _dummy_t mp_sys_stderr_obj; + +mp_obj_list_t mp_sys_path_obj; +mp_obj_list_t mp_sys_argv_obj; + +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 }, + +#if MICROPY_MOD_SYS_STDFILES + { MP_OBJ_NEW_QSTR(MP_QSTR_stdin), (mp_obj_t)&mp_sys_stdin_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_stdout), (mp_obj_t)&mp_sys_stdout_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_stderr), (mp_obj_t)&mp_sys_stderr_obj }, +#endif +}; + +STATIC const mp_obj_dict_t mp_module_sys_globals = { + .base = {&mp_type_dict}, + .map = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(mp_module_sys_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(mp_module_sys_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)mp_module_sys_globals_table, + }, +}; + +const mp_obj_module_t mp_module_sys = { + .base = { &mp_type_module }, + .name = MP_QSTR_sys, + .globals = (mp_obj_dict_t*)&mp_module_sys_globals, +}; + +#endif diff --git a/py/mpconfig.h b/py/mpconfig.h index 2c118b4bba..cbe18b409b 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -120,6 +120,15 @@ typedef double mp_float_t; #define MICROPY_ENABLE_MOD_STRUCT (1) #endif +// Whether to provide "sys" module +#ifndef MICROPY_ENABLE_MOD_SYS +#define MICROPY_ENABLE_MOD_SYS (1) +#endif + +#ifndef MICROPY_MOD_SYS_STDFILES +#define MICROPY_MOD_SYS_STDFILES (0) +#endif + // Whether to support slice object and correspondingly // slice subscript operators #ifndef MICROPY_ENABLE_SLICE diff --git a/py/obj.h b/py/obj.h index 356e722dcb..6e5796668d 100644 --- a/py/obj.h +++ b/py/obj.h @@ -454,6 +454,8 @@ machine_int_t mp_obj_tuple_hash(mp_obj_t self_in); mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args); // list +struct _mp_obj_list_t; +void mp_obj_list_init(struct _mp_obj_list_t *o, uint n); mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg); void mp_obj_list_get(mp_obj_t self_in, uint *len, mp_obj_t **items); void mp_obj_list_set_len(mp_obj_t self_in, uint len); diff --git a/py/objlist.c b/py/objlist.c index 7c29867332..fa7d2bc1c7 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -8,13 +8,7 @@ #include "obj.h" #include "runtime0.h" #include "runtime.h" - -typedef struct _mp_obj_list_t { - mp_obj_base_t base; - machine_uint_t alloc; - machine_uint_t len; - mp_obj_t *items; -} mp_obj_list_t; +#include "objlist.h" STATIC mp_obj_t mp_obj_new_list_iterator(mp_obj_list_t *list, int cur); STATIC mp_obj_list_t *list_new(uint n); @@ -371,12 +365,16 @@ const mp_obj_type_t mp_type_list = { .locals_dict = (mp_obj_t)&list_locals_dict, }; -STATIC mp_obj_list_t *list_new(uint n) { - mp_obj_list_t *o = m_new_obj(mp_obj_list_t); +void mp_obj_list_init(mp_obj_list_t *o, uint n) { o->base.type = &mp_type_list; o->alloc = n < LIST_MIN_ALLOC ? LIST_MIN_ALLOC : n; o->len = n; o->items = m_new(mp_obj_t, o->alloc); +} + +STATIC mp_obj_list_t *list_new(uint n) { + mp_obj_list_t *o = m_new_obj(mp_obj_list_t); + mp_obj_list_init(o, n); return o; } diff --git a/py/objlist.h b/py/objlist.h new file mode 100644 index 0000000000..cc8d7de26e --- /dev/null +++ b/py/objlist.h @@ -0,0 +1,6 @@ +typedef struct _mp_obj_list_t { + mp_obj_base_t base; + machine_uint_t alloc; + machine_uint_t len; + mp_obj_t *items; +} mp_obj_list_t; diff --git a/py/py.mk b/py/py.mk index 388e70a767..741d4438f8 100644 --- a/py/py.mk +++ b/py/py.mk @@ -83,6 +83,7 @@ PY_O_BASENAME = \ modmath.o \ modmicropython.o \ modstruct.o \ + modsys.o \ vm.o \ showbc.o \ repl.o \ diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 27a48af589..b332e22fa2 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -270,3 +270,10 @@ Q(encode) Q(decode) Q(utf-8) #endif + +#if MICROPY_ENABLE_MOD_SYS +Q(argv) +Q(stdin) +Q(stdout) +Q(stderr) +#endif diff --git a/py/runtime.c b/py/runtime.c index 51190f233c..a507f97f36 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -53,17 +53,6 @@ void mp_init(void) { // locals = globals for outer module (see Objects/frameobject.c/PyFrame_New()) dict_locals = dict_globals = &dict_main; - -#if MICROPY_CPYTHON_COMPAT - // Precreate sys module, so "import sys" didn't throw exceptions. - mp_obj_t m_sys = mp_obj_new_module(MP_QSTR_sys); - // Avoid warning of unused var - (void)m_sys; -#endif - // init sys.path - // for efficiency, left to platform-specific startup code - //mp_sys_path = mp_obj_new_list(0, NULL); - //mp_store_attr(m_sys, MP_QSTR_path, mp_sys_path); } void mp_deinit(void) { diff --git a/py/runtime.h b/py/runtime.h index a3c6119838..1d60181e7f 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -57,8 +57,12 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th mp_obj_t mp_make_raise_obj(mp_obj_t o); -extern mp_obj_t mp_sys_path; mp_map_t *mp_loaded_modules_get(void); mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level); mp_obj_t mp_import_from(mp_obj_t module, qstr name); void mp_import_all(mp_obj_t module); + +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) diff --git a/stmhal/main.c b/stmhal/main.c index 29c704b10e..efaf7caf9d 100644 --- a/stmhal/main.c +++ b/stmhal/main.c @@ -263,10 +263,9 @@ soft_reset: // Micro Python init qstr_init(); mp_init(); - mp_obj_t def_path[2]; - def_path[0] = MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_); - def_path[1] = MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_lib); - mp_sys_path = mp_obj_new_list(2, def_path); + mp_obj_list_init(mp_sys_path, 0); + mp_obj_list_append(mp_sys_argv, MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_)); + mp_obj_list_append(mp_sys_argv, MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_lib)); readline_init(); diff --git a/unix/file.c b/unix/file.c index fa7be791a4..a0a865a263 100644 --- a/unix/file.c +++ b/unix/file.c @@ -146,9 +146,6 @@ mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_open_obj, 1, 2, mp_builtin_open); -void file_init() { - mp_obj_t m_sys = mp_obj_new_module(MP_QSTR_sys); - mp_store_attr(m_sys, MP_QSTR_stdin, fdfile_new(STDIN_FILENO)); - mp_store_attr(m_sys, MP_QSTR_stdout, fdfile_new(STDOUT_FILENO)); - mp_store_attr(m_sys, MP_QSTR_stderr, fdfile_new(STDERR_FILENO)); -} +const mp_obj_fdfile_t mp_sys_stdin_obj = { .base = {&rawfile_type}, .fd = STDIN_FILENO }; +const mp_obj_fdfile_t mp_sys_stdout_obj = { .base = {&rawfile_type}, .fd = STDOUT_FILENO }; +const mp_obj_fdfile_t mp_sys_stderr_obj = { .base = {&rawfile_type}, .fd = STDERR_FILENO }; diff --git a/unix/main.c b/unix/main.c index f18e40a7fa..e582244b39 100644 --- a/unix/main.c +++ b/unix/main.c @@ -42,7 +42,6 @@ long heap_size = 128*1024 * (sizeof(machine_uint_t) / 4); // Stack top at the start of program void *stack_top; -void file_init(); void microsocket_init(); void time_init(); void ffi_init(); @@ -326,7 +325,7 @@ int main(int argc, char **argv) { p++; } } - mp_sys_path = mp_obj_new_list(path_num, NULL); + mp_obj_list_init(mp_sys_path, path_num); mp_obj_t *path_items; mp_obj_list_get(mp_sys_path, &path_num, &path_items); path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_); @@ -348,10 +347,7 @@ int main(int argc, char **argv) { p = p1 + 1; } - mp_obj_t m_sys = mp_obj_new_module(MP_QSTR_sys); - mp_store_attr(m_sys, MP_QSTR_path, mp_sys_path); - mp_obj_t py_argv = mp_obj_new_list(0, NULL); - mp_store_attr(m_sys, MP_QSTR_argv, py_argv); + mp_obj_list_init(mp_sys_argv, 0); mp_store_name(qstr_from_str("test"), test_obj_new(42)); mp_store_name(qstr_from_str("mem_info"), mp_make_function_n(0, mem_info)); @@ -360,7 +356,6 @@ int main(int argc, char **argv) { mp_store_name(qstr_from_str("gc"), (mp_obj_t)&pyb_gc_obj); #endif - file_init(); microsocket_init(); #if MICROPY_MOD_TIME time_init(); @@ -418,7 +413,7 @@ int main(int argc, char **argv) { free(basedir); for (int i = a; i < argc; i++) { - mp_obj_list_append(py_argv, MP_OBJ_NEW_QSTR(qstr_from_str(argv[i]))); + mp_obj_list_append(mp_sys_argv, MP_OBJ_NEW_QSTR(qstr_from_str(argv[i]))); } do_file(argv[a]); executed = true; diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h index e2f2a69e11..832bdb05fb 100644 --- a/unix/mpconfigport.h +++ b/unix/mpconfigport.h @@ -13,6 +13,7 @@ #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) #define MICROPY_PATH_MAX (PATH_MAX) +#define MICROPY_MOD_SYS_STDFILES (1) // type definitions for the specific machine diff --git a/unix/qstrdefsport.h b/unix/qstrdefsport.h index a4772a2be9..42f20d2657 100644 --- a/unix/qstrdefsport.h +++ b/unix/qstrdefsport.h @@ -2,10 +2,6 @@ Q(Test) -Q(argv) -Q(stdin) -Q(stdout) -Q(stderr) Q(rawsocket) Q(socket) Q(sockaddr_in)