From 92d63b40cc807cb03124019e34f391d8d0a62cc7 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 08:46:37 -0500 Subject: [PATCH 01/16] tests: Restore memoryview1 test to micropython version we changed this way back at fab634e3eeb4 for Rosie Pi and the merge mangled it. I think at this point it makes sense just to take upstream's version again. --- tests/basics/memoryview1.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/tests/basics/memoryview1.py b/tests/basics/memoryview1.py index bcf1b68b00..4c20c91f49 100644 --- a/tests/basics/memoryview1.py +++ b/tests/basics/memoryview1.py @@ -54,23 +54,6 @@ print(list(m[1:-1])) m[2] = 6 print(a) -# invalid attribute -try: - memoryview(b'a').noexist -except AttributeError: - print('AttributeError') - -try: - m4[1:3] = m2[1:3] -except ValueError: - print("ValueError") - -# invalid assignment on RHS -try: - memoryview(array.array('i'))[0:2] = b'1234' -except ValueError: - print('ValueError') - # invalid attribute try: memoryview(b'a').noexist From 2c0664ea3f8a6ab720558e12024dfe9e69911a2f Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 08:47:15 -0500 Subject: [PATCH 02/16] slice: restore ability to construct a slice --- locale/circuitpython.pot | 10 +++++++++- py/objslice.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 2db71c8c47..0955d389c4 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -663,6 +663,10 @@ msgstr "" msgid "Cannot specify RTS or CTS in RS485 mode" msgstr "" +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "Cannot transfer without MOSI and MISO pins." msgstr "" @@ -3886,10 +3890,14 @@ msgstr "" msgid "sleep length must be non-negative" msgstr "" -#: extmod/ulab/code/ndarray.c py/objslice.c +#: extmod/ulab/code/ndarray.c msgid "slice step can't be zero" msgstr "" +#: py/objslice.c +msgid "slice step cannot be zero" +msgstr "" + #: py/nativeglue.c msgid "slice unsupported" msgstr "" diff --git a/py/objslice.c b/py/objslice.c index 2201e01751..230125a8c3 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -88,6 +88,33 @@ STATIC void slice_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } #endif +#if MICROPY_PY_BUILTINS_SLICE_ATTRS +STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type, + size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + if (type != &mp_type_slice) { + mp_raise_NotImplementedError(translate("Cannot subclass slice")); + } + // check number of arguments + mp_arg_check_num(n_args, kw_args, 1, 3, false); + + // 1st argument is the pin + mp_obj_t start = mp_const_none; + mp_obj_t stop = mp_const_none; + mp_obj_t step = mp_const_none; + if (n_args == 1) { + stop = args[0]; + } else { + start = args[0]; + stop = args[1]; + if (n_args == 3) { + step = args[2]; + } + } + + return mp_obj_new_slice(start, stop, step); +} +#endif + #if MICROPY_PY_BUILTINS_SLICE_INDICES && !MICROPY_PY_BUILTINS_SLICE_ATTRS STATIC const mp_rom_map_elem_t slice_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_indices), MP_ROM_PTR(&slice_indices_obj) }, @@ -99,6 +126,9 @@ const mp_obj_type_t mp_type_slice = { { &mp_type_type }, .name = MP_QSTR_slice, .print = slice_print, + #if MICROPY_PY_BUILTINS_SLICE_INDICES + .make_new = slice_make_new, + #endif #if MICROPY_PY_BUILTINS_SLICE_ATTRS .attr = slice_attr, #elif MICROPY_PY_BUILTINS_SLICE_INDICES @@ -127,7 +157,7 @@ void mp_obj_slice_indices(mp_obj_t self_in, mp_int_t length, mp_bound_slice_t *r } else { step = mp_obj_get_int(self->step); if (step == 0) { - mp_raise_ValueError(MP_ERROR_TEXT("slice step can't be zero")); + mp_raise_ValueError(MP_ERROR_TEXT("slice step cannot be zero")); } } From 0bef554fae2f9c2d84ec1a3a4971e044034f72b7 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 08:59:27 -0500 Subject: [PATCH 03/16] Fix framebuf_subclass test --- extmod/modframebuf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index 2524e21541..8b9eec4fc9 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -294,6 +294,9 @@ STATIC const mp_obj_type_t mp_type_framebuf; static mp_obj_framebuf_t *native_framebuf(mp_obj_t framebuf_obj) { mp_obj_t native_framebuf = mp_obj_cast_to_native_base(framebuf_obj, &mp_type_framebuf); mp_obj_assert_native_inited(native_framebuf); + if (native_framebuf == MP_OBJ_NULL) { + mp_raise_TypeError(NULL); + } return MP_OBJ_TO_PTR(native_framebuf); } From d0f6b323bba21f3aba529ce3c3b9f121472c2ddb Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 09:05:44 -0500 Subject: [PATCH 04/16] Update bytecode --- tests/micropython/import_mpy_native_x64.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/micropython/import_mpy_native_x64.py b/tests/micropython/import_mpy_native_x64.py index d0de507d44..cec06a8f05 100644 --- a/tests/micropython/import_mpy_native_x64.py +++ b/tests/micropython/import_mpy_native_x64.py @@ -90,7 +90,7 @@ user_files = { b'\x12' # n bytes(=4), viper code b'\x00\x00\x00\x00' # dummy machine code b'\x00' # n_qstr - b'\x70' # scope_flags: VIPERBSS | VIPERRODATA | VIPERRELOC + b'\x81\x60' # scope_flags: VIPERBSS | VIPERRODATA | VIPERRELOC b'\x00\x00' # n_obj, n_raw_code b'\x06rodata' # rodata, 6 bytes b'\x04' # bss, 4 bytes From c174bc42fa45956f1cff923457917fe9eb08a30c Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 09:21:42 -0500 Subject: [PATCH 05/16] Update to match our bytecode style --- tests/micropython/import_mpy_native_gc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/micropython/import_mpy_native_gc.py b/tests/micropython/import_mpy_native_gc.py index e8fac8f179..cd19bb035c 100644 --- a/tests/micropython/import_mpy_native_gc.py +++ b/tests/micropython/import_mpy_native_gc.py @@ -49,9 +49,9 @@ class UserFS: # by the required value of sys.implementation.mpy. features0_file_contents = { # -march=x64 -mcache-lookup-bc - 0xB05: b'M\x05\x0b\x1f \x84b\xe9/\x00\x00\x00SH\x8b\x1ds\x00\x00\x00\xbe\x02\x00\x00\x00\xffS\x18\xbf\x01\x00\x00\x00H\x85\xc0u\x0cH\x8bC \xbe\x02\x00\x00\x00[\xff\xe0H\x0f\xaf\xf8H\xff\xc8\xeb\xe6ATUSH\x8b\x1dA\x00\x00\x00H\x8b\x7f\x08L\x8bc(A\xff\xd4H\x8d5\x1f\x00\x00\x00H\x89\xc5H\x8b\x05-\x00\x00\x00\x0f\xb78\xffShH\x89\xefA\xff\xd4H\x8b\x03[]A\\\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x84@\x12factorial\x10\x00\x00\r \x01"\x9f\x1c\x01\x1e\xff', + 0xB05: b'M\x05\x0b\x1f \x84b\xe9/\x00\x00\x00SH\x8b\x1ds\x00\x00\x00\xbe\x02\x00\x00\x00\xffS\x18\xbf\x01\x00\x00\x00H\x85\xc0u\x0cH\x8bC \xbe\x02\x00\x00\x00[\xff\xe0H\x0f\xaf\xf8H\xff\xc8\xeb\xe6ATUSH\x8b\x1dA\x00\x00\x00H\x8b\x7f\x08H\x8bk(\xff\xd5H\x8d5 \x00\x00\x00I\x89\xc4H\x8b\x05.\x00\x00\x00\x0f\xb78\xffShL\x89\xe7\xff\xd5H\x8b\x03[]A\\\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x84@\x12factorial \x00\x00\r \x01"\x9f\x1c\x01\x1e\xff', # -march=armv7m - 0x1605: b"M\x05\x16\x1f \x84\x12\x1a\xe0\x00\x00\x13\xb5\nK\nJ{D\x9cX\x02!\xe3h\x98G\x03F\x01 3\xb9\x02!#i\x01\x93\x02\xb0\xbd\xe8\x10@\x18GXC\x01;\xf4\xe7\x00\xbfj\x00\x00\x00\x00\x00\x00\x00\xf8\xb5\tN\tK~D\xf4X@hgi\xb8G\x05F\x07K\x07I\xf2XyD\x10\x88ck\x98G(F\xb8G h\xf8\xbd6\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x01\x84\x00\x12factorial\x10\x00\x00\r<\x01>\x9f8\x01:\xff", + 0x1605: b"M\x05\x16\x1f \x84\x12\x1a\xe0\x00\x00\x13\xb5\nK\nJ{D\x9cX\x02!\xe3h\x98G\x03F\x01 3\xb9\x02!#i\x01\x93\x02\xb0\xbd\xe8\x10@\x18GXC\x01;\xf4\xe7\x00\xbfj\x00\x00\x00\x00\x00\x00\x00\xf8\xb5\tN\tK~D\xf4X@hgi\xb8G\x05F\x07K\x07I\xf2XyD\x10\x88ck\x98G(F\xb8G h\xf8\xbd6\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x01\x84\x00\x12factorial \x00\x00\r<\x01>\x9f8\x01:\xff", } # Populate other armv7m-derived archs based on armv7m. From 14e0bdbae38136912c7cb1d2b3930272b7aaf696 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 09:31:16 -0500 Subject: [PATCH 06/16] Move mp_get_stream non-inline This caused a build error with external native code, as MP_QSTR_protocol_stream was not available. --- py/stream.c | 3 +++ py/stream.h | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/py/stream.c b/py/stream.c index bf3bf07fcb..b0038bba18 100644 --- a/py/stream.c +++ b/py/stream.c @@ -576,4 +576,7 @@ int mp_stream_posix_fsync(mp_obj_t stream) { return res; } +const mp_stream_p_t *mp_get_stream(mp_const_obj_t self) { + return mp_proto_get(MP_QSTR_protocol_stream, self); +} #endif diff --git a/py/stream.h b/py/stream.h index 7b392a3558..4283e685c8 100644 --- a/py/stream.h +++ b/py/stream.h @@ -99,9 +99,7 @@ MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_ioctl_obj); #define MP_STREAM_OP_IOCTL (4) // Object is assumed to have a non-NULL stream protocol with valid r/w/ioctl methods -static inline const mp_stream_p_t *mp_get_stream(mp_const_obj_t self) { - return mp_proto_get(MP_QSTR_protocol_stream, self); -} +const mp_stream_p_t *mp_get_stream(mp_const_obj_t self); const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags); mp_obj_t mp_stream_close(mp_obj_t stream); From c3ce2bacdee205e046487427bdd2088c4f8bcd16 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 09:31:34 -0500 Subject: [PATCH 07/16] runtime: Remove unneeded includes objtype.h got included twice, and vfs.h is unneeded. --- py/runtime.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/py/runtime.c b/py/runtime.c index 8a60b90713..740457c462 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -30,15 +30,11 @@ #include #include - -#include "extmod/vfs.h" - #include "py/parsenum.h" #include "py/compile.h" #include "py/mperrno.h" #include "py/objstr.h" #include "py/objtuple.h" -#include "py/objtype.h" #include "py/objlist.h" #include "py/objtype.h" #include "py/objmodule.h" From 8fae7d2e3024de6336affc4b2a8fa992c946e017 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 09:37:41 -0500 Subject: [PATCH 08/16] runtime.c: Fix reading properties .. this fixes the vfs_fat_ramdisk failure. --- py/runtime.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/py/runtime.c b/py/runtime.c index 740457c462..9791379d79 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1062,27 +1062,27 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t } dest[0] = ((mp_obj_static_class_method_t *)MP_OBJ_TO_PTR(member))->fun; dest[1] = MP_OBJ_FROM_PTR(type); + #if MICROPY_PY_BUILTINS_PROPERTY + // If self is MP_OBJ_NULL, we looking at the class itself, not an instance. + } else if (mp_obj_is_type(member, &mp_type_property) && mp_obj_is_native_type(type) && self != MP_OBJ_NULL) { + // object member is a property; delegate the load to the property + // Note: This is an optimisation for code size and execution time. + // The proper way to do it is have the functionality just below + // in a __get__ method of the property object, and then it would + // be called by the descriptor code down below. But that way + // requires overhead for the nested mp_call's and overhead for + // the code. + const mp_obj_t *proxy = mp_obj_property_get(member); + if (proxy[0] == mp_const_none) { + mp_raise_AttributeError(translate("unreadable attribute")); + } else { + dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self); + } + #endif } else { // `member` is a value, so just return that value. dest[0] = member; } - #if MICROPY_PY_BUILTINS_PROPERTY - // If self is MP_OBJ_NULL, we looking at the class itself, not an instance. - } else if (mp_obj_is_type(member, &mp_type_property) && mp_obj_is_native_type(type) && self != MP_OBJ_NULL) { - // object member is a property; delegate the load to the property - // Note: This is an optimisation for code size and execution time. - // The proper way to do it is have the functionality just below - // in a __get__ method of the property object, and then it would - // be called by the descriptor code down below. But that way - // requires overhead for the nested mp_call's and overhead for - // the code. - const mp_obj_t *proxy = mp_obj_property_get(member); - if (proxy[0] == mp_const_none) { - mp_raise_AttributeError(translate("unreadable attribute")); - } else { - dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self); - } - #endif } else { // `member` is a value, so just return that value. dest[0] = member; From cdf220bcb4e8f83228a3b9350f3fe7a29d054c49 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 09:52:48 -0500 Subject: [PATCH 09/16] Fix ure tests --- extmod/modure.c | 47 +++++++++----------------------------- extmod/re1.5/compilecode.c | 3 --- 2 files changed, 11 insertions(+), 39 deletions(-) diff --git a/extmod/modure.c b/extmod/modure.c index dead69586c..7836140778 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -272,8 +272,13 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_split_obj, 2, 3, re_split); #if MICROPY_PY_URE_SUB -STATIC mp_obj_t re_sub_helper(mp_obj_t self_in, size_t n_args, const mp_obj_t *args) { - mp_obj_re_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) { + mp_obj_re_t *self; + if (mp_obj_is_type(args[0], &re_type)) { + self = MP_OBJ_TO_PTR(args[0]); + } else { + self = MP_OBJ_TO_PTR(mod_re_compile(1, args)); + } mp_obj_t replace = args[1]; mp_obj_t where = args[2]; mp_int_t count = 0; @@ -377,10 +382,7 @@ STATIC mp_obj_t re_sub_helper(mp_obj_t self_in, size_t n_args, const mp_obj_t *a return mp_obj_new_str_from_vstr(mp_obj_get_type(where), &vstr_return); } -STATIC mp_obj_t re_sub(size_t n_args, const mp_obj_t *args) { - return re_sub_helper(args[0], n_args, args); -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_sub_obj, 3, 5, re_sub); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_sub_obj, 3, 5, re_sub_helper); #endif @@ -439,33 +441,6 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_compile_obj, 1, 2, mod_re_compile); -STATIC mp_obj_t mod_re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) { - (void)n_args; - mp_obj_t self = mod_re_compile(1, args); - - const mp_obj_t args2[] = {self, args[1]}; - mp_obj_t match = ure_exec(is_anchored, 2, args2); - return match; -} - -STATIC mp_obj_t mod_re_match(size_t n_args, const mp_obj_t *args) { - return mod_re_exec(true, n_args, args); -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_match_obj, 2, 4, mod_re_match); - -STATIC mp_obj_t mod_re_search(size_t n_args, const mp_obj_t *args) { - return mod_re_exec(false, n_args, args); -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_search_obj, 2, 4, mod_re_search); - -#if MICROPY_PY_URE_SUB -STATIC mp_obj_t mod_re_sub(size_t n_args, const mp_obj_t *args) { - mp_obj_t self = mod_re_compile(1, args); - return re_sub_helper(MP_OBJ_TO_PTR(self), n_args, args); -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_sub_obj, 3, 5, mod_re_sub); -#endif - #if !MICROPY_ENABLE_DYNRUNTIME STATIC const mp_rom_map_elem_t mp_module_re_globals_table[] = { #if CIRCUITPY @@ -474,10 +449,10 @@ STATIC const mp_rom_map_elem_t mp_module_re_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ure) }, #endif { MP_ROM_QSTR(MP_QSTR_compile), MP_ROM_PTR(&mod_re_compile_obj) }, - { MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&mod_re_match_obj) }, - { MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&mod_re_search_obj) }, + { MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&re_match_obj) }, + { MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&re_search_obj) }, #if MICROPY_PY_URE_SUB - { MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&mod_re_sub_obj) }, + { MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&re_sub_obj) }, #endif #if MICROPY_PY_URE_DEBUG { MP_ROM_QSTR(MP_QSTR_DEBUG), MP_ROM_INT(FLAG_DEBUG) }, diff --git a/extmod/re1.5/compilecode.c b/extmod/re1.5/compilecode.c index 811742eea1..936f6ed28a 100644 --- a/extmod/re1.5/compilecode.c +++ b/extmod/re1.5/compilecode.c @@ -87,9 +87,6 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode) PC++; // Skip # of pair byte prog->len++; for (cnt = 0; *re != ']'; re++, cnt++) { - if (*re == '\\') { - ++re; - } if (!*re) return NULL; const char *b = re; if (*re == '\\') { From f21c2bd25a8ad81adda69f68570fa20d01b35e52 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 10:51:26 -0500 Subject: [PATCH 10/16] Update native skips to match micropython --- tests/run-tests | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/run-tests b/tests/run-tests index c1a2780dad..22d854c72f 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -448,7 +448,8 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): # Remove them from the below when they work if args.emit == 'native': skip_tests.update({'basics/%s.py' % t for t in 'gen_yield_from_close generator_name'.split()}) # require raise_varargs, generator name - skip_tests.update({'basics/async_%s.py' % t for t in 'with with2 with_break with_return'.split()}) # require yield + skip_tests.update({'basics/async_%s.py' % t for t in 'with with2 with_break with_return'.split()}) # require async_with + skip_tests.update({'basics/%s.py' % t for t in 'try_reraise try_reraise2'.split()}) # require raise_varargs skip_tests.add('basics/annotate_var.py') # requires checking for unbound local skip_tests.add('basics/del_deref.py') # requires checking for unbound local skip_tests.add('basics/del_local.py') # requires checking for unbound local @@ -464,7 +465,6 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): skip_tests.add('micropython/heapalloc_traceback.py') # because native doesn't have proper traceback info skip_tests.add('micropython/opt_level_lineno.py') # native doesn't have proper traceback info skip_tests.add('micropython/schedule.py') # native code doesn't check pending events - # skip_tests.add('../extmod/ulab/tests/argminmax.py') # requires yield def run_one_test(test_file): test_file = test_file.replace('\\', '/') From 607148bb85f1b04fa714a3bda3d53776da7e5fe1 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 10:59:07 -0500 Subject: [PATCH 11/16] Add frzqstr to coverage build This fixes a fail in extra_coverage.py. --- ports/unix/variants/coverage/frzmpy/frzqstr.py | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ports/unix/variants/coverage/frzmpy/frzqstr.py diff --git a/ports/unix/variants/coverage/frzmpy/frzqstr.py b/ports/unix/variants/coverage/frzmpy/frzqstr.py new file mode 100644 index 0000000000..051f2a9c16 --- /dev/null +++ b/ports/unix/variants/coverage/frzmpy/frzqstr.py @@ -0,0 +1,3 @@ +# Checks for regression on MP_QSTR_NULL +def returns_NULL(): + return "NULL" From 4054860ff3dc3d19e7de9b5347900b1928437b69 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 10:59:16 -0500 Subject: [PATCH 12/16] Name the variant like micropython does --- ports/unix/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/unix/Makefile b/ports/unix/Makefile index b414377fa3..8f6a5eb63c 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -13,8 +13,8 @@ include ../../py/mkenv.mk -include mpconfigport.mk include $(VARIANT_DIR)/mpconfigvariant.mk -# define main target -PROG = micropython +# This should be configured by the mpconfigvariant.mk +PROG ?= micropython # qstr definitions (must come before including py.mk) QSTR_DEFS = qstrdefsport.h From 68d468229883417aef2a378e56e88a3291c6132e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 10:59:32 -0500 Subject: [PATCH 13/16] compile: Reserve labels for native await --- py/compile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/py/compile.c b/py/compile.c index 5f66557382..ae38624c78 100644 --- a/py/compile.c +++ b/py/compile.c @@ -2809,6 +2809,7 @@ STATIC void compile_atom_expr_await(compiler_t *comp, mp_parse_node_struct_t *pn EMIT_ARG(call_method, 0, 0, 0); EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); EMIT_ARG(yield, MP_EMIT_YIELD_FROM); + reserve_labels_for_native(comp, 3); } #endif From 2bcfe21916df94b20f276b30cc09e1c7871fb555 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 11:01:41 -0500 Subject: [PATCH 14/16] Add natmod examples At least features0 works, and was useful in fixing the related native test --- examples/natmod/.gitignore | 1 + examples/natmod/btree/Makefile | 37 +++++++ examples/natmod/btree/btree_c.c | 147 ++++++++++++++++++++++++++ examples/natmod/btree/btree_py.py | 3 + examples/natmod/features0/Makefile | 14 +++ examples/natmod/features0/features0.c | 40 +++++++ examples/natmod/features1/Makefile | 14 +++ examples/natmod/features1/features1.c | 106 +++++++++++++++++++ examples/natmod/features2/Makefile | 14 +++ examples/natmod/features2/main.c | 83 +++++++++++++++ examples/natmod/features2/prod.c | 9 ++ examples/natmod/features2/prod.h | 1 + examples/natmod/features2/test.py | 29 +++++ examples/natmod/framebuf/Makefile | 13 +++ examples/natmod/framebuf/framebuf.c | 49 +++++++++ examples/natmod/uheapq/Makefile | 13 +++ examples/natmod/uheapq/uheapq.c | 16 +++ examples/natmod/urandom/Makefile | 13 +++ examples/natmod/urandom/urandom.c | 33 ++++++ examples/natmod/ure/Makefile | 13 +++ examples/natmod/ure/ure.c | 78 ++++++++++++++ examples/natmod/uzlib/Makefile | 13 +++ examples/natmod/uzlib/uzlib.c | 35 ++++++ 23 files changed, 774 insertions(+) create mode 100644 examples/natmod/.gitignore create mode 100644 examples/natmod/btree/Makefile create mode 100644 examples/natmod/btree/btree_c.c create mode 100644 examples/natmod/btree/btree_py.py create mode 100644 examples/natmod/features0/Makefile create mode 100644 examples/natmod/features0/features0.c create mode 100644 examples/natmod/features1/Makefile create mode 100644 examples/natmod/features1/features1.c create mode 100644 examples/natmod/features2/Makefile create mode 100644 examples/natmod/features2/main.c create mode 100644 examples/natmod/features2/prod.c create mode 100644 examples/natmod/features2/prod.h create mode 100644 examples/natmod/features2/test.py create mode 100644 examples/natmod/framebuf/Makefile create mode 100644 examples/natmod/framebuf/framebuf.c create mode 100644 examples/natmod/uheapq/Makefile create mode 100644 examples/natmod/uheapq/uheapq.c create mode 100644 examples/natmod/urandom/Makefile create mode 100644 examples/natmod/urandom/urandom.c create mode 100644 examples/natmod/ure/Makefile create mode 100644 examples/natmod/ure/ure.c create mode 100644 examples/natmod/uzlib/Makefile create mode 100644 examples/natmod/uzlib/uzlib.c diff --git a/examples/natmod/.gitignore b/examples/natmod/.gitignore new file mode 100644 index 0000000000..4815d20f06 --- /dev/null +++ b/examples/natmod/.gitignore @@ -0,0 +1 @@ +*.mpy diff --git a/examples/natmod/btree/Makefile b/examples/natmod/btree/Makefile new file mode 100644 index 0000000000..d795102b4a --- /dev/null +++ b/examples/natmod/btree/Makefile @@ -0,0 +1,37 @@ +# Location of top-level MicroPython directory +MPY_DIR = ../../.. + +# Name of module (different to built-in btree so it can coexist) +MOD = btree_$(ARCH) + +# Source files (.c or .py) +SRC = btree_c.c btree_py.py + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +ARCH = x64 + +BTREE_DIR = $(MPY_DIR)/lib/berkeley-db-1.xx +BTREE_DEFS = -D__DBINTERFACE_PRIVATE=1 -Dmpool_error="(void)" -Dabort=abort_ "-Dvirt_fd_t=void*" $(BTREE_DEFS_EXTRA) +CFLAGS += -I$(BTREE_DIR)/PORT/include +CFLAGS += -Wno-old-style-definition -Wno-sign-compare -Wno-unused-parameter $(BTREE_DEFS) + +SRC += $(addprefix $(realpath $(BTREE_DIR))/,\ + btree/bt_close.c \ + btree/bt_conv.c \ + btree/bt_delete.c \ + btree/bt_get.c \ + btree/bt_open.c \ + btree/bt_overflow.c \ + btree/bt_page.c \ + btree/bt_put.c \ + btree/bt_search.c \ + btree/bt_seq.c \ + btree/bt_split.c \ + btree/bt_utils.c \ + mpool/mpool.c \ + ) + +include $(MPY_DIR)/py/dynruntime.mk + +# btree needs gnu99 defined +CFLAGS += -std=gnu99 diff --git a/examples/natmod/btree/btree_c.c b/examples/natmod/btree/btree_c.c new file mode 100644 index 0000000000..5e8a34ac40 --- /dev/null +++ b/examples/natmod/btree/btree_c.c @@ -0,0 +1,147 @@ +#define MICROPY_PY_BTREE (1) + +#include "py/dynruntime.h" + +#include + +#if !defined(__linux__) +void *memcpy(void *dst, const void *src, size_t n) { + return mp_fun_table.memmove_(dst, src, n); +} +void *memset(void *s, int c, size_t n) { + return mp_fun_table.memset_(s, c, n); +} +#endif + +void *memmove(void *dest, const void *src, size_t n) { + return mp_fun_table.memmove_(dest, src, n); +} + +void *malloc(size_t n) { + void *ptr = m_malloc(n); + return ptr; +} +void *realloc(void *ptr, size_t n) { + mp_printf(&mp_plat_print, "UNDEF %d\n", __LINE__); + return NULL; +} +void *calloc(size_t n, size_t m) { + void *ptr = m_malloc(n * m); + // memory already cleared by conservative GC + return ptr; +} + +void free(void *ptr) { + m_free(ptr); +} + +void abort_(void) { + nlr_raise(mp_obj_new_exception(mp_load_global(MP_QSTR_RuntimeError))); +} + +int native_errno; +#if defined(__linux__) +int *__errno_location (void) +#else +int *__errno (void) +#endif +{ + return &native_errno; +} + +ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) { + mp_obj_base_t* o = stream; + const mp_stream_p_t *stream_p = o->type->protocol; + mp_uint_t out_sz = stream_p->write(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno); + if (out_sz == MP_STREAM_ERROR) { + return -1; + } else { + return out_sz; + } +} + +ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) { + mp_obj_base_t* o = stream; + const mp_stream_p_t *stream_p = o->type->protocol; + mp_uint_t out_sz = stream_p->read(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno); + if (out_sz == MP_STREAM_ERROR) { + return -1; + } else { + return out_sz; + } +} + +off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) { + const mp_obj_base_t* o = stream; + const mp_stream_p_t *stream_p = o->type->protocol; + struct mp_stream_seek_t seek_s; + seek_s.offset = offset; + seek_s.whence = whence; + mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_SEEK, (mp_uint_t)(uintptr_t)&seek_s, &native_errno); + if (res == MP_STREAM_ERROR) { + return -1; + } + return seek_s.offset; +} + +int mp_stream_posix_fsync(void *stream) { + mp_obj_base_t* o = stream; + const mp_stream_p_t *stream_p = o->type->protocol; + mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_FLUSH, 0, &native_errno); + if (res == MP_STREAM_ERROR) { + return -1; + } + return res; +} + +mp_obj_type_t btree_type; + +#include "extmod/modbtree.c" + +mp_map_elem_t btree_locals_dict_table[8]; +STATIC MP_DEFINE_CONST_DICT(btree_locals_dict, btree_locals_dict_table); + +STATIC mp_obj_t btree_open(size_t n_args, const mp_obj_t *args) { + // Make sure we got a stream object + mp_get_stream_raise(args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); + + BTREEINFO openinfo = {0}; + openinfo.flags = mp_obj_get_int(args[1]); + openinfo.cachesize = mp_obj_get_int(args[2]); + openinfo.psize = mp_obj_get_int(args[3]); + openinfo.minkeypage = mp_obj_get_int(args[4]); + DB *db = __bt_open(MP_OBJ_TO_PTR(args[0]), &btree_stream_fvtable, &openinfo, 0); + if (db == NULL) { + mp_raise_OSError(native_errno); + } + + return MP_OBJ_FROM_PTR(btree_new(db, args[0])); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_open_obj, 5, 5, btree_open); + +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + MP_DYNRUNTIME_INIT_ENTRY + + btree_type.base.type = (void*)&mp_fun_table.type_type; + btree_type.name = MP_QSTR_btree; + btree_type.print = btree_print; + btree_type.getiter = btree_getiter; + btree_type.iternext = btree_iternext; + btree_type.binary_op = btree_binary_op; + btree_type.subscr = btree_subscr; + btree_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_close), MP_OBJ_FROM_PTR(&btree_close_obj) }; + btree_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_flush), MP_OBJ_FROM_PTR(&btree_flush_obj) }; + btree_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_get), MP_OBJ_FROM_PTR(&btree_get_obj) }; + btree_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_put), MP_OBJ_FROM_PTR(&btree_put_obj) }; + btree_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_seq), MP_OBJ_FROM_PTR(&btree_seq_obj) }; + btree_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_keys), MP_OBJ_FROM_PTR(&btree_keys_obj) }; + btree_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_values), MP_OBJ_FROM_PTR(&btree_values_obj) }; + btree_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_items), MP_OBJ_FROM_PTR(&btree_items_obj) }; + btree_type.locals_dict = (void*)&btree_locals_dict; + + mp_store_global(MP_QSTR__open, MP_OBJ_FROM_PTR(&btree_open_obj)); + mp_store_global(MP_QSTR_INCL, MP_OBJ_NEW_SMALL_INT(FLAG_END_KEY_INCL)); + mp_store_global(MP_QSTR_DESC, MP_OBJ_NEW_SMALL_INT(FLAG_DESC)); + + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/examples/natmod/btree/btree_py.py b/examples/natmod/btree/btree_py.py new file mode 100644 index 0000000000..bd53c084a1 --- /dev/null +++ b/examples/natmod/btree/btree_py.py @@ -0,0 +1,3 @@ +# Implemented in Python to support keyword arguments +def open(stream, *, flags=0, cachesize=0, pagesize=0, minkeypage=0): + return _open(stream, flags, cachesize, pagesize, minkeypage) diff --git a/examples/natmod/features0/Makefile b/examples/natmod/features0/Makefile new file mode 100644 index 0000000000..57490df90a --- /dev/null +++ b/examples/natmod/features0/Makefile @@ -0,0 +1,14 @@ +# Location of top-level MicroPython directory +MPY_DIR = ../../.. + +# Name of module +MOD = features0 + +# Source files (.c or .py) +SRC = features0.c + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +ARCH = x64 + +# Include to get the rules for compiling and linking the module +include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/features0/features0.c b/examples/natmod/features0/features0.c new file mode 100644 index 0000000000..1b1867a3bc --- /dev/null +++ b/examples/natmod/features0/features0.c @@ -0,0 +1,40 @@ +/* This example demonstrates the following features in a native module: + - defining a simple function exposed to Python + - defining a local, helper C function + - getting and creating integer objects +*/ + +// Include the header file to get access to the MicroPython API +#include "py/dynruntime.h" + +// Helper function to compute factorial +STATIC mp_int_t factorial_helper(mp_int_t x) { + if (x == 0) { + return 1; + } + return x * factorial_helper(x - 1); +} + +// This is the function which will be called from Python, as factorial(x) +STATIC mp_obj_t factorial(mp_obj_t x_obj) { + // Extract the integer from the MicroPython input object + mp_int_t x = mp_obj_get_int(x_obj); + // Calculate the factorial + mp_int_t result = factorial_helper(x); + // Convert the result to a MicroPython integer object and return it + return mp_obj_new_int(result); +} +// Define a Python reference to the function above +STATIC MP_DEFINE_CONST_FUN_OBJ_1(factorial_obj, factorial); + +// This is the entry point and is called when the module is imported +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + // This must be first, it sets up the globals dict and other things + MP_DYNRUNTIME_INIT_ENTRY + + // Make the function available in the module's namespace + mp_store_global(MP_QSTR_factorial, MP_OBJ_FROM_PTR(&factorial_obj)); + + // This must be last, it restores the globals dict + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/examples/natmod/features1/Makefile b/examples/natmod/features1/Makefile new file mode 100644 index 0000000000..010640daf9 --- /dev/null +++ b/examples/natmod/features1/Makefile @@ -0,0 +1,14 @@ +# Location of top-level MicroPython directory +MPY_DIR = ../../.. + +# Name of module +MOD = features1 + +# Source files (.c or .py) +SRC = features1.c + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +ARCH = x64 + +# Include to get the rules for compiling and linking the module +include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/features1/features1.c b/examples/natmod/features1/features1.c new file mode 100644 index 0000000000..f865f1887c --- /dev/null +++ b/examples/natmod/features1/features1.c @@ -0,0 +1,106 @@ +/* This example demonstrates the following features in a native module: + - defining simple functions exposed to Python + - defining local, helper C functions + - defining constant integers and strings exposed to Python + - getting and creating integer objects + - creating Python lists + - raising exceptions + - allocating memory + - BSS and constant data (rodata) + - relocated pointers in rodata +*/ + +// Include the header file to get access to the MicroPython API +#include "py/dynruntime.h" + +// BSS (zero) data +uint16_t data16[4]; + +// Constant data (rodata) +const uint8_t table8[] = { 0, 1, 1, 2, 3, 5, 8, 13 }; +const uint16_t table16[] = { 0x1000, 0x2000 }; + +// Constant data pointing to BSS/constant data +uint16_t *const table_ptr16a[] = { &data16[0], &data16[1], &data16[2], &data16[3] }; +const uint16_t *const table_ptr16b[] = { &table16[0], &table16[1] }; + +// A simple function that adds its 2 arguments (must be integers) +STATIC mp_obj_t add(mp_obj_t x_in, mp_obj_t y_in) { + mp_int_t x = mp_obj_get_int(x_in); + mp_int_t y = mp_obj_get_int(y_in); + return mp_obj_new_int(x + y); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_obj, add); + +// A local helper function (not exposed to Python) +STATIC mp_int_t fibonacci_helper(mp_int_t x) { + if (x < MP_ARRAY_SIZE(table8)) { + return table8[x]; + } else { + return fibonacci_helper(x - 1) + fibonacci_helper(x - 2); + } +} + +// A function which computes Fibonacci numbers +STATIC mp_obj_t fibonacci(mp_obj_t x_in) { + mp_int_t x = mp_obj_get_int(x_in); + if (x < 0) { + mp_raise_ValueError(MP_ERROR_TEXT("can't compute negative Fibonacci number")); + } + return mp_obj_new_int(fibonacci_helper(x)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(fibonacci_obj, fibonacci); + +// A function that accesses the BSS data +STATIC mp_obj_t access(size_t n_args, const mp_obj_t *args) { + if (n_args == 0) { + // Create a list holding all items from data16 + mp_obj_list_t *lst = MP_OBJ_TO_PTR(mp_obj_new_list(MP_ARRAY_SIZE(data16), NULL)); + for (int i = 0; i < MP_ARRAY_SIZE(data16); ++i) { + lst->items[i] = mp_obj_new_int(data16[i]); + } + return MP_OBJ_FROM_PTR(lst); + } else if (n_args == 1) { + // Get one item from data16 + mp_int_t idx = mp_obj_get_int(args[0]) & 3; + return mp_obj_new_int(data16[idx]); + } else { + // Set one item in data16 (via table_ptr16a) + mp_int_t idx = mp_obj_get_int(args[0]) & 3; + *table_ptr16a[idx] = mp_obj_get_int(args[1]); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(access_obj, 0, 2, access); + +// A function that allocates memory and creates a bytearray +STATIC mp_obj_t make_array(void) { + uint16_t *ptr = m_new(uint16_t, MP_ARRAY_SIZE(table_ptr16b)); + for (int i = 0; i < MP_ARRAY_SIZE(table_ptr16b); ++i) { + ptr[i] = *table_ptr16b[i]; + } + return mp_obj_new_bytearray_by_ref(sizeof(uint16_t) * MP_ARRAY_SIZE(table_ptr16b), ptr); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(make_array_obj, make_array); + +// This is the entry point and is called when the module is imported +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + // This must be first, it sets up the globals dict and other things + MP_DYNRUNTIME_INIT_ENTRY + + // Messages can be printed as usualy + mp_printf(&mp_plat_print, "initialising module self=%p\n", self); + + // Make the functions available in the module's namespace + mp_store_global(MP_QSTR_add, MP_OBJ_FROM_PTR(&add_obj)); + mp_store_global(MP_QSTR_fibonacci, MP_OBJ_FROM_PTR(&fibonacci_obj)); + mp_store_global(MP_QSTR_access, MP_OBJ_FROM_PTR(&access_obj)); + mp_store_global(MP_QSTR_make_array, MP_OBJ_FROM_PTR(&make_array_obj)); + + // Add some constants to the module's namespace + mp_store_global(MP_QSTR_VAL, MP_OBJ_NEW_SMALL_INT(42)); + mp_store_global(MP_QSTR_MSG, MP_OBJ_NEW_QSTR(MP_QSTR_HELLO_MICROPYTHON)); + + // This must be last, it restores the globals dict + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/examples/natmod/features2/Makefile b/examples/natmod/features2/Makefile new file mode 100644 index 0000000000..4fd23c6879 --- /dev/null +++ b/examples/natmod/features2/Makefile @@ -0,0 +1,14 @@ +# Location of top-level MicroPython directory +MPY_DIR = ../../.. + +# Name of module +MOD = features2 + +# Source files (.c or .py) +SRC = main.c prod.c test.py + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +ARCH = x64 + +# Include to get the rules for compiling and linking the module +include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/features2/main.c b/examples/natmod/features2/main.c new file mode 100644 index 0000000000..1a39700dc4 --- /dev/null +++ b/examples/natmod/features2/main.c @@ -0,0 +1,83 @@ +/* This example demonstrates the following features in a native module: + - using floats + - defining additional code in Python (see test.py) + - have extra C code in a separate file (see prod.c) +*/ + +// Include the header file to get access to the MicroPython API +#include "py/dynruntime.h" + +// Include the header for auxiliary C code for this module +#include "prod.h" + +// Automatically detect if this module should include double-precision code. +// If double precision is supported by the target architecture then it can +// be used in native module regardless of what float setting the target +// MicroPython runtime uses (being none, float or double). +#if defined(__i386__) || defined(__x86_64__) || (defined(__ARM_FP) && (__ARM_FP & 8)) +#define USE_DOUBLE 1 +#else +#define USE_DOUBLE 0 +#endif + +// A function that uses the default float type configured for the current target +// This default can be overridden by specifying MICROPY_FLOAT_IMPL at the make level +STATIC mp_obj_t add(mp_obj_t x, mp_obj_t y) { + return mp_obj_new_float(mp_obj_get_float(x) + mp_obj_get_float(y)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_obj, add); + +// A function that explicitly uses single precision floats +STATIC mp_obj_t add_f(mp_obj_t x, mp_obj_t y) { + return mp_obj_new_float_from_f(mp_obj_get_float_to_f(x) + mp_obj_get_float_to_f(y)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_f_obj, add_f); + +#if USE_DOUBLE +// A function that explicitly uses double precision floats +STATIC mp_obj_t add_d(mp_obj_t x, mp_obj_t y) { + return mp_obj_new_float_from_d(mp_obj_get_float_to_d(x) + mp_obj_get_float_to_d(y)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_d_obj, add_d); +#endif + +// A function that computes the product of floats in an array. +// This function uses the most general C argument interface, which is more difficult +// to use but has access to the globals dict of the module via self->globals. +STATIC mp_obj_t productf(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + // Check number of arguments is valid + mp_arg_check_num(n_args, n_kw, 1, 1, false); + + // Extract buffer pointer and verify typecode + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_RW); + if (bufinfo.typecode != 'f') { + mp_raise_ValueError(MP_ERROR_TEXT("expecting float array")); + } + + // Compute product, store result back in first element of array + float *ptr = bufinfo.buf; + float prod = prod_array(bufinfo.len / sizeof(*ptr), ptr); + ptr[0] = prod; + + return mp_const_none; +} + +// This is the entry point and is called when the module is imported +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + // This must be first, it sets up the globals dict and other things + MP_DYNRUNTIME_INIT_ENTRY + + // Make the functions available in the module's namespace + mp_store_global(MP_QSTR_add, MP_OBJ_FROM_PTR(&add_obj)); + mp_store_global(MP_QSTR_add_f, MP_OBJ_FROM_PTR(&add_f_obj)); + #if USE_DOUBLE + mp_store_global(MP_QSTR_add_d, MP_OBJ_FROM_PTR(&add_d_obj)); + #endif + + // The productf function uses the most general C argument interface + mp_store_global(MP_QSTR_productf, MP_DYNRUNTIME_MAKE_FUNCTION(productf)); + + // This must be last, it restores the globals dict + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/examples/natmod/features2/prod.c b/examples/natmod/features2/prod.c new file mode 100644 index 0000000000..7791dcad1d --- /dev/null +++ b/examples/natmod/features2/prod.c @@ -0,0 +1,9 @@ +#include "prod.h" + +float prod_array(int n, float *ar) { + float ans = 1; + for (int i = 0; i < n; ++i) { + ans *= ar[i]; + } + return ans; +} diff --git a/examples/natmod/features2/prod.h b/examples/natmod/features2/prod.h new file mode 100644 index 0000000000..f27dd8d033 --- /dev/null +++ b/examples/natmod/features2/prod.h @@ -0,0 +1 @@ +float prod_array(int n, float *ar); diff --git a/examples/natmod/features2/test.py b/examples/natmod/features2/test.py new file mode 100644 index 0000000000..5ac80120d7 --- /dev/null +++ b/examples/natmod/features2/test.py @@ -0,0 +1,29 @@ +# This Python code will be merged with the C code in main.c + +import array + + +def isclose(a, b): + return abs(a - b) < 1e-3 + + +def test(): + tests = [ + isclose(add(0.1, 0.2), 0.3), + isclose(add_f(0.1, 0.2), 0.3), + ] + + ar = array.array("f", [1, 2, 3.5]) + productf(ar) + tests.append(isclose(ar[0], 7)) + + if "add_d" in globals(): + tests.append(isclose(add_d(0.1, 0.2), 0.3)) + + print(tests) + + if not all(tests): + raise SystemExit(1) + + +test() diff --git a/examples/natmod/framebuf/Makefile b/examples/natmod/framebuf/Makefile new file mode 100644 index 0000000000..2e2b815975 --- /dev/null +++ b/examples/natmod/framebuf/Makefile @@ -0,0 +1,13 @@ +# Location of top-level MicroPython directory +MPY_DIR = ../../.. + +# Name of module (different to built-in framebuf so it can coexist) +MOD = framebuf_$(ARCH) + +# Source files (.c or .py) +SRC = framebuf.c + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +ARCH = x64 + +include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/framebuf/framebuf.c b/examples/natmod/framebuf/framebuf.c new file mode 100644 index 0000000000..8d488cffd6 --- /dev/null +++ b/examples/natmod/framebuf/framebuf.c @@ -0,0 +1,49 @@ +#define MICROPY_PY_FRAMEBUF (1) + +#include "py/dynruntime.h" + +#if !defined(__linux__) +void *memset(void *s, int c, size_t n) { + return mp_fun_table.memset_(s, c, n); +} +#endif + +mp_obj_type_t mp_type_framebuf; + +#include "extmod/modframebuf.c" + +mp_map_elem_t framebuf_locals_dict_table[10]; +STATIC MP_DEFINE_CONST_DICT(framebuf_locals_dict, framebuf_locals_dict_table); + +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + MP_DYNRUNTIME_INIT_ENTRY + + mp_type_framebuf.base.type = (void*)&mp_type_type; + mp_type_framebuf.name = MP_QSTR_FrameBuffer; + mp_type_framebuf.make_new = framebuf_make_new; + mp_type_framebuf.buffer_p.get_buffer = framebuf_get_buffer; + framebuf_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill), MP_OBJ_FROM_PTR(&framebuf_fill_obj) }; + framebuf_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill_rect), MP_OBJ_FROM_PTR(&framebuf_fill_rect_obj) }; + framebuf_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_pixel), MP_OBJ_FROM_PTR(&framebuf_pixel_obj) }; + framebuf_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_hline), MP_OBJ_FROM_PTR(&framebuf_hline_obj) }; + framebuf_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_vline), MP_OBJ_FROM_PTR(&framebuf_vline_obj) }; + framebuf_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_rect), MP_OBJ_FROM_PTR(&framebuf_rect_obj) }; + framebuf_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_line), MP_OBJ_FROM_PTR(&framebuf_line_obj) }; + framebuf_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_blit), MP_OBJ_FROM_PTR(&framebuf_blit_obj) }; + framebuf_locals_dict_table[8] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_scroll), MP_OBJ_FROM_PTR(&framebuf_scroll_obj) }; + framebuf_locals_dict_table[9] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_text), MP_OBJ_FROM_PTR(&framebuf_text_obj) }; + mp_type_framebuf.locals_dict = (void*)&framebuf_locals_dict; + + mp_store_global(MP_QSTR_FrameBuffer, MP_OBJ_FROM_PTR(&mp_type_framebuf)); + mp_store_global(MP_QSTR_FrameBuffer1, MP_OBJ_FROM_PTR(&legacy_framebuffer1_obj)); + mp_store_global(MP_QSTR_MVLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB)); + mp_store_global(MP_QSTR_MONO_VLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB)); + mp_store_global(MP_QSTR_RGB565, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565)); + mp_store_global(MP_QSTR_GS2_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS2_HMSB)); + mp_store_global(MP_QSTR_GS4_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS4_HMSB)); + mp_store_global(MP_QSTR_GS8, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS8)); + mp_store_global(MP_QSTR_MONO_HLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHLSB)); + mp_store_global(MP_QSTR_MONO_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHMSB)); + + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/examples/natmod/uheapq/Makefile b/examples/natmod/uheapq/Makefile new file mode 100644 index 0000000000..55de3cc081 --- /dev/null +++ b/examples/natmod/uheapq/Makefile @@ -0,0 +1,13 @@ +# Location of top-level MicroPython directory +MPY_DIR = ../../.. + +# Name of module (different to built-in uheapq so it can coexist) +MOD = uheapq_$(ARCH) + +# Source files (.c or .py) +SRC = uheapq.c + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +ARCH = x64 + +include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/uheapq/uheapq.c b/examples/natmod/uheapq/uheapq.c new file mode 100644 index 0000000000..9da6bb4ada --- /dev/null +++ b/examples/natmod/uheapq/uheapq.c @@ -0,0 +1,16 @@ +#define MICROPY_PY_UHEAPQ (1) + +#include "py/dynruntime.h" + +#include "extmod/moduheapq.c" + +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + MP_DYNRUNTIME_INIT_ENTRY + + mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uheapq)); + mp_store_global(MP_QSTR_heappush, MP_OBJ_FROM_PTR(&mod_uheapq_heappush_obj)); + mp_store_global(MP_QSTR_heappop, MP_OBJ_FROM_PTR(&mod_uheapq_heappop_obj)); + mp_store_global(MP_QSTR_heapify, MP_OBJ_FROM_PTR(&mod_uheapq_heapify_obj)); + + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/examples/natmod/urandom/Makefile b/examples/natmod/urandom/Makefile new file mode 100644 index 0000000000..3f018baaf7 --- /dev/null +++ b/examples/natmod/urandom/Makefile @@ -0,0 +1,13 @@ +# Location of top-level MicroPython directory +MPY_DIR = ../../.. + +# Name of module (different to built-in urandom so it can coexist) +MOD = urandom_$(ARCH) + +# Source files (.c or .py) +SRC = urandom.c + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +ARCH = x64 + +include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/urandom/urandom.c b/examples/natmod/urandom/urandom.c new file mode 100644 index 0000000000..e1fed6a554 --- /dev/null +++ b/examples/natmod/urandom/urandom.c @@ -0,0 +1,33 @@ +#define MICROPY_PY_URANDOM (1) +#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) + +#include "py/dynruntime.h" + +// Dynamic native modules don't support a data section so these must go in the BSS +uint32_t yasmarang_pad, yasmarang_n, yasmarang_d; +uint8_t yasmarang_dat; + +#include "extmod/modurandom.c" + +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + MP_DYNRUNTIME_INIT_ENTRY + + yasmarang_pad = 0xeda4baba; + yasmarang_n = 69; + yasmarang_d = 233; + + mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_urandom)); + mp_store_global(MP_QSTR_getrandbits, MP_OBJ_FROM_PTR(&mod_urandom_getrandbits_obj)); + mp_store_global(MP_QSTR_seed, MP_OBJ_FROM_PTR(&mod_urandom_seed_obj)); + #if MICROPY_PY_URANDOM_EXTRA_FUNCS + mp_store_global(MP_QSTR_randrange, MP_OBJ_FROM_PTR(&mod_urandom_randrange_obj)); + mp_store_global(MP_QSTR_randint, MP_OBJ_FROM_PTR(&mod_urandom_randint_obj)); + mp_store_global(MP_QSTR_choice, MP_OBJ_FROM_PTR(&mod_urandom_choice_obj)); + #if MICROPY_PY_BUILTINS_FLOAT + mp_store_global(MP_QSTR_random, MP_OBJ_FROM_PTR(&mod_urandom_random_obj)); + mp_store_global(MP_QSTR_uniform, MP_OBJ_FROM_PTR(&mod_urandom_uniform_obj)); + #endif + #endif + + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/examples/natmod/ure/Makefile b/examples/natmod/ure/Makefile new file mode 100644 index 0000000000..f5254298fd --- /dev/null +++ b/examples/natmod/ure/Makefile @@ -0,0 +1,13 @@ +# Location of top-level MicroPython directory +MPY_DIR = ../../.. + +# Name of module (different to built-in ure so it can coexist) +MOD = ure_$(ARCH) + +# Source files (.c or .py) +SRC = ure.c + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +ARCH = x64 + +include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/ure/ure.c b/examples/natmod/ure/ure.c new file mode 100644 index 0000000000..175b93e395 --- /dev/null +++ b/examples/natmod/ure/ure.c @@ -0,0 +1,78 @@ +#define MICROPY_STACK_CHECK (1) +#define MICROPY_PY_URE (1) +#define MICROPY_PY_URE_MATCH_GROUPS (1) +#define MICROPY_PY_URE_MATCH_SPAN_START_END (1) +#define MICROPY_PY_URE_SUB (0) // requires vstr interface + +#include +#include "py/dynruntime.h" + +#define STACK_LIMIT (2048) + +const char *stack_top; + +void mp_stack_check(void) { + // Assumes descending stack on target + volatile char dummy; + if (stack_top - &dummy >= STACK_LIMIT) { + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("maximum recursion depth exceeded")); + } +} + +#if !defined(__linux__) +void *memcpy(void *dst, const void *src, size_t n) { + return mp_fun_table.memmove_(dst, src, n); +} +void *memset(void *s, int c, size_t n) { + return mp_fun_table.memset_(s, c, n); +} +#endif + +void *memmove(void *dest, const void *src, size_t n) { + return mp_fun_table.memmove_(dest, src, n); +} + +mp_obj_type_t match_type; +mp_obj_type_t re_type; + +#include "extmod/modure.c" + +mp_map_elem_t match_locals_dict_table[5]; +STATIC MP_DEFINE_CONST_DICT(match_locals_dict, match_locals_dict_table); + +mp_map_elem_t re_locals_dict_table[3]; +STATIC MP_DEFINE_CONST_DICT(re_locals_dict, re_locals_dict_table); + +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + MP_DYNRUNTIME_INIT_ENTRY + + char dummy; + stack_top = &dummy; + + // Because MP_QSTR_start/end/split are static, xtensa and xtensawin will make a small data section + // to copy in this key/value pair if they are specified as a struct, so assign them separately. + + match_type.base.type = (void*)&mp_fun_table.type_type; + match_type.name = MP_QSTR_match; + match_type.print = match_print; + match_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_group), MP_OBJ_FROM_PTR(&match_group_obj) }; + match_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_groups), MP_OBJ_FROM_PTR(&match_groups_obj) }; + match_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_span), MP_OBJ_FROM_PTR(&match_span_obj) }; + match_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_start), MP_OBJ_FROM_PTR(&match_start_obj) }; + match_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_end), MP_OBJ_FROM_PTR(&match_end_obj) }; + match_type.locals_dict = (void*)&match_locals_dict; + + re_type.base.type = (void*)&mp_fun_table.type_type; + re_type.name = MP_QSTR_ure; + re_type.print = re_print; + re_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_match), MP_OBJ_FROM_PTR(&re_match_obj) }; + re_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_search), MP_OBJ_FROM_PTR(&re_search_obj) }; + re_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_split), MP_OBJ_FROM_PTR(&re_split_obj) }; + re_type.locals_dict = (void*)&re_locals_dict; + + mp_store_global(MP_QSTR_compile, MP_OBJ_FROM_PTR(&mod_re_compile_obj)); + mp_store_global(MP_QSTR_match, MP_OBJ_FROM_PTR(&re_match_obj)); + mp_store_global(MP_QSTR_search, MP_OBJ_FROM_PTR(&re_search_obj)); + + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/examples/natmod/uzlib/Makefile b/examples/natmod/uzlib/Makefile new file mode 100644 index 0000000000..8761caf2dd --- /dev/null +++ b/examples/natmod/uzlib/Makefile @@ -0,0 +1,13 @@ +# Location of top-level MicroPython directory +MPY_DIR = ../../.. + +# Name of module (different to built-in uzlib so it can coexist) +MOD = uzlib_$(ARCH) + +# Source files (.c or .py) +SRC = uzlib.c + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +ARCH = x64 + +include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/uzlib/uzlib.c b/examples/natmod/uzlib/uzlib.c new file mode 100644 index 0000000000..99b3691761 --- /dev/null +++ b/examples/natmod/uzlib/uzlib.c @@ -0,0 +1,35 @@ +#define MICROPY_PY_UZLIB (1) + +#include "py/dynruntime.h" + +#if !defined(__linux__) +void *memset(void *s, int c, size_t n) { + return mp_fun_table.memset_(s, c, n); +} +#endif + +mp_obj_type_t decompio_type; + +#include "extmod/moduzlib.c" + +mp_map_elem_t decompio_locals_dict_table[3]; +STATIC MP_DEFINE_CONST_DICT(decompio_locals_dict, decompio_locals_dict_table); + +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + MP_DYNRUNTIME_INIT_ENTRY + + decompio_type.base.type = mp_fun_table.type_type; + decompio_type.name = MP_QSTR_DecompIO; + decompio_type.make_new = decompio_make_new; + decompio_type.protocol = &decompio_stream_p; + decompio_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_OBJ_FROM_PTR(&mp_stream_read_obj) }; + decompio_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_OBJ_FROM_PTR(&mp_stream_readinto_obj) }; + decompio_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_OBJ_FROM_PTR(&mp_stream_unbuffered_readline_obj) }; + decompio_type.locals_dict = (void*)&decompio_locals_dict; + + mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uzlib)); + mp_store_global(MP_QSTR_decompress, MP_OBJ_FROM_PTR(&mod_uzlib_decompress_obj)); + mp_store_global(MP_QSTR_DecompIO, MP_OBJ_FROM_PTR(&decompio_type)); + + MP_DYNRUNTIME_INIT_EXIT +} From eb4cf7add35c2c45ccde81f1214456862fc212ef Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 11:35:28 -0500 Subject: [PATCH 15/16] Add natmod "features0" example This example works, and was useful when fixing a native code test. Most of the other natmod examples do not work, however. --- examples/natmod/.gitignore | 1 - examples/natmod/btree/Makefile | 37 ------- examples/natmod/btree/btree_c.c | 147 -------------------------- examples/natmod/btree/btree_py.py | 3 - examples/natmod/features1/Makefile | 14 --- examples/natmod/features1/features1.c | 106 ------------------- examples/natmod/features2/Makefile | 14 --- examples/natmod/features2/main.c | 83 --------------- examples/natmod/features2/prod.c | 9 -- examples/natmod/features2/prod.h | 1 - examples/natmod/features2/test.py | 29 ----- examples/natmod/framebuf/Makefile | 13 --- examples/natmod/framebuf/framebuf.c | 49 --------- examples/natmod/uheapq/Makefile | 13 --- examples/natmod/uheapq/uheapq.c | 16 --- examples/natmod/urandom/Makefile | 13 --- examples/natmod/urandom/urandom.c | 33 ------ examples/natmod/ure/Makefile | 13 --- examples/natmod/ure/ure.c | 78 -------------- examples/natmod/uzlib/Makefile | 13 --- examples/natmod/uzlib/uzlib.c | 35 ------ 21 files changed, 720 deletions(-) delete mode 100644 examples/natmod/.gitignore delete mode 100644 examples/natmod/btree/Makefile delete mode 100644 examples/natmod/btree/btree_c.c delete mode 100644 examples/natmod/btree/btree_py.py delete mode 100644 examples/natmod/features1/Makefile delete mode 100644 examples/natmod/features1/features1.c delete mode 100644 examples/natmod/features2/Makefile delete mode 100644 examples/natmod/features2/main.c delete mode 100644 examples/natmod/features2/prod.c delete mode 100644 examples/natmod/features2/prod.h delete mode 100644 examples/natmod/features2/test.py delete mode 100644 examples/natmod/framebuf/Makefile delete mode 100644 examples/natmod/framebuf/framebuf.c delete mode 100644 examples/natmod/uheapq/Makefile delete mode 100644 examples/natmod/uheapq/uheapq.c delete mode 100644 examples/natmod/urandom/Makefile delete mode 100644 examples/natmod/urandom/urandom.c delete mode 100644 examples/natmod/ure/Makefile delete mode 100644 examples/natmod/ure/ure.c delete mode 100644 examples/natmod/uzlib/Makefile delete mode 100644 examples/natmod/uzlib/uzlib.c diff --git a/examples/natmod/.gitignore b/examples/natmod/.gitignore deleted file mode 100644 index 4815d20f06..0000000000 --- a/examples/natmod/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.mpy diff --git a/examples/natmod/btree/Makefile b/examples/natmod/btree/Makefile deleted file mode 100644 index d795102b4a..0000000000 --- a/examples/natmod/btree/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# Location of top-level MicroPython directory -MPY_DIR = ../../.. - -# Name of module (different to built-in btree so it can coexist) -MOD = btree_$(ARCH) - -# Source files (.c or .py) -SRC = btree_c.c btree_py.py - -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) -ARCH = x64 - -BTREE_DIR = $(MPY_DIR)/lib/berkeley-db-1.xx -BTREE_DEFS = -D__DBINTERFACE_PRIVATE=1 -Dmpool_error="(void)" -Dabort=abort_ "-Dvirt_fd_t=void*" $(BTREE_DEFS_EXTRA) -CFLAGS += -I$(BTREE_DIR)/PORT/include -CFLAGS += -Wno-old-style-definition -Wno-sign-compare -Wno-unused-parameter $(BTREE_DEFS) - -SRC += $(addprefix $(realpath $(BTREE_DIR))/,\ - btree/bt_close.c \ - btree/bt_conv.c \ - btree/bt_delete.c \ - btree/bt_get.c \ - btree/bt_open.c \ - btree/bt_overflow.c \ - btree/bt_page.c \ - btree/bt_put.c \ - btree/bt_search.c \ - btree/bt_seq.c \ - btree/bt_split.c \ - btree/bt_utils.c \ - mpool/mpool.c \ - ) - -include $(MPY_DIR)/py/dynruntime.mk - -# btree needs gnu99 defined -CFLAGS += -std=gnu99 diff --git a/examples/natmod/btree/btree_c.c b/examples/natmod/btree/btree_c.c deleted file mode 100644 index 5e8a34ac40..0000000000 --- a/examples/natmod/btree/btree_c.c +++ /dev/null @@ -1,147 +0,0 @@ -#define MICROPY_PY_BTREE (1) - -#include "py/dynruntime.h" - -#include - -#if !defined(__linux__) -void *memcpy(void *dst, const void *src, size_t n) { - return mp_fun_table.memmove_(dst, src, n); -} -void *memset(void *s, int c, size_t n) { - return mp_fun_table.memset_(s, c, n); -} -#endif - -void *memmove(void *dest, const void *src, size_t n) { - return mp_fun_table.memmove_(dest, src, n); -} - -void *malloc(size_t n) { - void *ptr = m_malloc(n); - return ptr; -} -void *realloc(void *ptr, size_t n) { - mp_printf(&mp_plat_print, "UNDEF %d\n", __LINE__); - return NULL; -} -void *calloc(size_t n, size_t m) { - void *ptr = m_malloc(n * m); - // memory already cleared by conservative GC - return ptr; -} - -void free(void *ptr) { - m_free(ptr); -} - -void abort_(void) { - nlr_raise(mp_obj_new_exception(mp_load_global(MP_QSTR_RuntimeError))); -} - -int native_errno; -#if defined(__linux__) -int *__errno_location (void) -#else -int *__errno (void) -#endif -{ - return &native_errno; -} - -ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) { - mp_obj_base_t* o = stream; - const mp_stream_p_t *stream_p = o->type->protocol; - mp_uint_t out_sz = stream_p->write(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno); - if (out_sz == MP_STREAM_ERROR) { - return -1; - } else { - return out_sz; - } -} - -ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) { - mp_obj_base_t* o = stream; - const mp_stream_p_t *stream_p = o->type->protocol; - mp_uint_t out_sz = stream_p->read(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno); - if (out_sz == MP_STREAM_ERROR) { - return -1; - } else { - return out_sz; - } -} - -off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) { - const mp_obj_base_t* o = stream; - const mp_stream_p_t *stream_p = o->type->protocol; - struct mp_stream_seek_t seek_s; - seek_s.offset = offset; - seek_s.whence = whence; - mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_SEEK, (mp_uint_t)(uintptr_t)&seek_s, &native_errno); - if (res == MP_STREAM_ERROR) { - return -1; - } - return seek_s.offset; -} - -int mp_stream_posix_fsync(void *stream) { - mp_obj_base_t* o = stream; - const mp_stream_p_t *stream_p = o->type->protocol; - mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_FLUSH, 0, &native_errno); - if (res == MP_STREAM_ERROR) { - return -1; - } - return res; -} - -mp_obj_type_t btree_type; - -#include "extmod/modbtree.c" - -mp_map_elem_t btree_locals_dict_table[8]; -STATIC MP_DEFINE_CONST_DICT(btree_locals_dict, btree_locals_dict_table); - -STATIC mp_obj_t btree_open(size_t n_args, const mp_obj_t *args) { - // Make sure we got a stream object - mp_get_stream_raise(args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); - - BTREEINFO openinfo = {0}; - openinfo.flags = mp_obj_get_int(args[1]); - openinfo.cachesize = mp_obj_get_int(args[2]); - openinfo.psize = mp_obj_get_int(args[3]); - openinfo.minkeypage = mp_obj_get_int(args[4]); - DB *db = __bt_open(MP_OBJ_TO_PTR(args[0]), &btree_stream_fvtable, &openinfo, 0); - if (db == NULL) { - mp_raise_OSError(native_errno); - } - - return MP_OBJ_FROM_PTR(btree_new(db, args[0])); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_open_obj, 5, 5, btree_open); - -mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { - MP_DYNRUNTIME_INIT_ENTRY - - btree_type.base.type = (void*)&mp_fun_table.type_type; - btree_type.name = MP_QSTR_btree; - btree_type.print = btree_print; - btree_type.getiter = btree_getiter; - btree_type.iternext = btree_iternext; - btree_type.binary_op = btree_binary_op; - btree_type.subscr = btree_subscr; - btree_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_close), MP_OBJ_FROM_PTR(&btree_close_obj) }; - btree_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_flush), MP_OBJ_FROM_PTR(&btree_flush_obj) }; - btree_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_get), MP_OBJ_FROM_PTR(&btree_get_obj) }; - btree_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_put), MP_OBJ_FROM_PTR(&btree_put_obj) }; - btree_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_seq), MP_OBJ_FROM_PTR(&btree_seq_obj) }; - btree_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_keys), MP_OBJ_FROM_PTR(&btree_keys_obj) }; - btree_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_values), MP_OBJ_FROM_PTR(&btree_values_obj) }; - btree_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_items), MP_OBJ_FROM_PTR(&btree_items_obj) }; - btree_type.locals_dict = (void*)&btree_locals_dict; - - mp_store_global(MP_QSTR__open, MP_OBJ_FROM_PTR(&btree_open_obj)); - mp_store_global(MP_QSTR_INCL, MP_OBJ_NEW_SMALL_INT(FLAG_END_KEY_INCL)); - mp_store_global(MP_QSTR_DESC, MP_OBJ_NEW_SMALL_INT(FLAG_DESC)); - - MP_DYNRUNTIME_INIT_EXIT -} diff --git a/examples/natmod/btree/btree_py.py b/examples/natmod/btree/btree_py.py deleted file mode 100644 index bd53c084a1..0000000000 --- a/examples/natmod/btree/btree_py.py +++ /dev/null @@ -1,3 +0,0 @@ -# Implemented in Python to support keyword arguments -def open(stream, *, flags=0, cachesize=0, pagesize=0, minkeypage=0): - return _open(stream, flags, cachesize, pagesize, minkeypage) diff --git a/examples/natmod/features1/Makefile b/examples/natmod/features1/Makefile deleted file mode 100644 index 010640daf9..0000000000 --- a/examples/natmod/features1/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# Location of top-level MicroPython directory -MPY_DIR = ../../.. - -# Name of module -MOD = features1 - -# Source files (.c or .py) -SRC = features1.c - -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) -ARCH = x64 - -# Include to get the rules for compiling and linking the module -include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/features1/features1.c b/examples/natmod/features1/features1.c deleted file mode 100644 index f865f1887c..0000000000 --- a/examples/natmod/features1/features1.c +++ /dev/null @@ -1,106 +0,0 @@ -/* This example demonstrates the following features in a native module: - - defining simple functions exposed to Python - - defining local, helper C functions - - defining constant integers and strings exposed to Python - - getting and creating integer objects - - creating Python lists - - raising exceptions - - allocating memory - - BSS and constant data (rodata) - - relocated pointers in rodata -*/ - -// Include the header file to get access to the MicroPython API -#include "py/dynruntime.h" - -// BSS (zero) data -uint16_t data16[4]; - -// Constant data (rodata) -const uint8_t table8[] = { 0, 1, 1, 2, 3, 5, 8, 13 }; -const uint16_t table16[] = { 0x1000, 0x2000 }; - -// Constant data pointing to BSS/constant data -uint16_t *const table_ptr16a[] = { &data16[0], &data16[1], &data16[2], &data16[3] }; -const uint16_t *const table_ptr16b[] = { &table16[0], &table16[1] }; - -// A simple function that adds its 2 arguments (must be integers) -STATIC mp_obj_t add(mp_obj_t x_in, mp_obj_t y_in) { - mp_int_t x = mp_obj_get_int(x_in); - mp_int_t y = mp_obj_get_int(y_in); - return mp_obj_new_int(x + y); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_obj, add); - -// A local helper function (not exposed to Python) -STATIC mp_int_t fibonacci_helper(mp_int_t x) { - if (x < MP_ARRAY_SIZE(table8)) { - return table8[x]; - } else { - return fibonacci_helper(x - 1) + fibonacci_helper(x - 2); - } -} - -// A function which computes Fibonacci numbers -STATIC mp_obj_t fibonacci(mp_obj_t x_in) { - mp_int_t x = mp_obj_get_int(x_in); - if (x < 0) { - mp_raise_ValueError(MP_ERROR_TEXT("can't compute negative Fibonacci number")); - } - return mp_obj_new_int(fibonacci_helper(x)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(fibonacci_obj, fibonacci); - -// A function that accesses the BSS data -STATIC mp_obj_t access(size_t n_args, const mp_obj_t *args) { - if (n_args == 0) { - // Create a list holding all items from data16 - mp_obj_list_t *lst = MP_OBJ_TO_PTR(mp_obj_new_list(MP_ARRAY_SIZE(data16), NULL)); - for (int i = 0; i < MP_ARRAY_SIZE(data16); ++i) { - lst->items[i] = mp_obj_new_int(data16[i]); - } - return MP_OBJ_FROM_PTR(lst); - } else if (n_args == 1) { - // Get one item from data16 - mp_int_t idx = mp_obj_get_int(args[0]) & 3; - return mp_obj_new_int(data16[idx]); - } else { - // Set one item in data16 (via table_ptr16a) - mp_int_t idx = mp_obj_get_int(args[0]) & 3; - *table_ptr16a[idx] = mp_obj_get_int(args[1]); - return mp_const_none; - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(access_obj, 0, 2, access); - -// A function that allocates memory and creates a bytearray -STATIC mp_obj_t make_array(void) { - uint16_t *ptr = m_new(uint16_t, MP_ARRAY_SIZE(table_ptr16b)); - for (int i = 0; i < MP_ARRAY_SIZE(table_ptr16b); ++i) { - ptr[i] = *table_ptr16b[i]; - } - return mp_obj_new_bytearray_by_ref(sizeof(uint16_t) * MP_ARRAY_SIZE(table_ptr16b), ptr); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(make_array_obj, make_array); - -// This is the entry point and is called when the module is imported -mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { - // This must be first, it sets up the globals dict and other things - MP_DYNRUNTIME_INIT_ENTRY - - // Messages can be printed as usualy - mp_printf(&mp_plat_print, "initialising module self=%p\n", self); - - // Make the functions available in the module's namespace - mp_store_global(MP_QSTR_add, MP_OBJ_FROM_PTR(&add_obj)); - mp_store_global(MP_QSTR_fibonacci, MP_OBJ_FROM_PTR(&fibonacci_obj)); - mp_store_global(MP_QSTR_access, MP_OBJ_FROM_PTR(&access_obj)); - mp_store_global(MP_QSTR_make_array, MP_OBJ_FROM_PTR(&make_array_obj)); - - // Add some constants to the module's namespace - mp_store_global(MP_QSTR_VAL, MP_OBJ_NEW_SMALL_INT(42)); - mp_store_global(MP_QSTR_MSG, MP_OBJ_NEW_QSTR(MP_QSTR_HELLO_MICROPYTHON)); - - // This must be last, it restores the globals dict - MP_DYNRUNTIME_INIT_EXIT -} diff --git a/examples/natmod/features2/Makefile b/examples/natmod/features2/Makefile deleted file mode 100644 index 4fd23c6879..0000000000 --- a/examples/natmod/features2/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# Location of top-level MicroPython directory -MPY_DIR = ../../.. - -# Name of module -MOD = features2 - -# Source files (.c or .py) -SRC = main.c prod.c test.py - -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) -ARCH = x64 - -# Include to get the rules for compiling and linking the module -include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/features2/main.c b/examples/natmod/features2/main.c deleted file mode 100644 index 1a39700dc4..0000000000 --- a/examples/natmod/features2/main.c +++ /dev/null @@ -1,83 +0,0 @@ -/* This example demonstrates the following features in a native module: - - using floats - - defining additional code in Python (see test.py) - - have extra C code in a separate file (see prod.c) -*/ - -// Include the header file to get access to the MicroPython API -#include "py/dynruntime.h" - -// Include the header for auxiliary C code for this module -#include "prod.h" - -// Automatically detect if this module should include double-precision code. -// If double precision is supported by the target architecture then it can -// be used in native module regardless of what float setting the target -// MicroPython runtime uses (being none, float or double). -#if defined(__i386__) || defined(__x86_64__) || (defined(__ARM_FP) && (__ARM_FP & 8)) -#define USE_DOUBLE 1 -#else -#define USE_DOUBLE 0 -#endif - -// A function that uses the default float type configured for the current target -// This default can be overridden by specifying MICROPY_FLOAT_IMPL at the make level -STATIC mp_obj_t add(mp_obj_t x, mp_obj_t y) { - return mp_obj_new_float(mp_obj_get_float(x) + mp_obj_get_float(y)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_obj, add); - -// A function that explicitly uses single precision floats -STATIC mp_obj_t add_f(mp_obj_t x, mp_obj_t y) { - return mp_obj_new_float_from_f(mp_obj_get_float_to_f(x) + mp_obj_get_float_to_f(y)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_f_obj, add_f); - -#if USE_DOUBLE -// A function that explicitly uses double precision floats -STATIC mp_obj_t add_d(mp_obj_t x, mp_obj_t y) { - return mp_obj_new_float_from_d(mp_obj_get_float_to_d(x) + mp_obj_get_float_to_d(y)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_d_obj, add_d); -#endif - -// A function that computes the product of floats in an array. -// This function uses the most general C argument interface, which is more difficult -// to use but has access to the globals dict of the module via self->globals. -STATIC mp_obj_t productf(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { - // Check number of arguments is valid - mp_arg_check_num(n_args, n_kw, 1, 1, false); - - // Extract buffer pointer and verify typecode - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_RW); - if (bufinfo.typecode != 'f') { - mp_raise_ValueError(MP_ERROR_TEXT("expecting float array")); - } - - // Compute product, store result back in first element of array - float *ptr = bufinfo.buf; - float prod = prod_array(bufinfo.len / sizeof(*ptr), ptr); - ptr[0] = prod; - - return mp_const_none; -} - -// This is the entry point and is called when the module is imported -mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { - // This must be first, it sets up the globals dict and other things - MP_DYNRUNTIME_INIT_ENTRY - - // Make the functions available in the module's namespace - mp_store_global(MP_QSTR_add, MP_OBJ_FROM_PTR(&add_obj)); - mp_store_global(MP_QSTR_add_f, MP_OBJ_FROM_PTR(&add_f_obj)); - #if USE_DOUBLE - mp_store_global(MP_QSTR_add_d, MP_OBJ_FROM_PTR(&add_d_obj)); - #endif - - // The productf function uses the most general C argument interface - mp_store_global(MP_QSTR_productf, MP_DYNRUNTIME_MAKE_FUNCTION(productf)); - - // This must be last, it restores the globals dict - MP_DYNRUNTIME_INIT_EXIT -} diff --git a/examples/natmod/features2/prod.c b/examples/natmod/features2/prod.c deleted file mode 100644 index 7791dcad1d..0000000000 --- a/examples/natmod/features2/prod.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "prod.h" - -float prod_array(int n, float *ar) { - float ans = 1; - for (int i = 0; i < n; ++i) { - ans *= ar[i]; - } - return ans; -} diff --git a/examples/natmod/features2/prod.h b/examples/natmod/features2/prod.h deleted file mode 100644 index f27dd8d033..0000000000 --- a/examples/natmod/features2/prod.h +++ /dev/null @@ -1 +0,0 @@ -float prod_array(int n, float *ar); diff --git a/examples/natmod/features2/test.py b/examples/natmod/features2/test.py deleted file mode 100644 index 5ac80120d7..0000000000 --- a/examples/natmod/features2/test.py +++ /dev/null @@ -1,29 +0,0 @@ -# This Python code will be merged with the C code in main.c - -import array - - -def isclose(a, b): - return abs(a - b) < 1e-3 - - -def test(): - tests = [ - isclose(add(0.1, 0.2), 0.3), - isclose(add_f(0.1, 0.2), 0.3), - ] - - ar = array.array("f", [1, 2, 3.5]) - productf(ar) - tests.append(isclose(ar[0], 7)) - - if "add_d" in globals(): - tests.append(isclose(add_d(0.1, 0.2), 0.3)) - - print(tests) - - if not all(tests): - raise SystemExit(1) - - -test() diff --git a/examples/natmod/framebuf/Makefile b/examples/natmod/framebuf/Makefile deleted file mode 100644 index 2e2b815975..0000000000 --- a/examples/natmod/framebuf/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# Location of top-level MicroPython directory -MPY_DIR = ../../.. - -# Name of module (different to built-in framebuf so it can coexist) -MOD = framebuf_$(ARCH) - -# Source files (.c or .py) -SRC = framebuf.c - -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) -ARCH = x64 - -include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/framebuf/framebuf.c b/examples/natmod/framebuf/framebuf.c deleted file mode 100644 index 8d488cffd6..0000000000 --- a/examples/natmod/framebuf/framebuf.c +++ /dev/null @@ -1,49 +0,0 @@ -#define MICROPY_PY_FRAMEBUF (1) - -#include "py/dynruntime.h" - -#if !defined(__linux__) -void *memset(void *s, int c, size_t n) { - return mp_fun_table.memset_(s, c, n); -} -#endif - -mp_obj_type_t mp_type_framebuf; - -#include "extmod/modframebuf.c" - -mp_map_elem_t framebuf_locals_dict_table[10]; -STATIC MP_DEFINE_CONST_DICT(framebuf_locals_dict, framebuf_locals_dict_table); - -mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { - MP_DYNRUNTIME_INIT_ENTRY - - mp_type_framebuf.base.type = (void*)&mp_type_type; - mp_type_framebuf.name = MP_QSTR_FrameBuffer; - mp_type_framebuf.make_new = framebuf_make_new; - mp_type_framebuf.buffer_p.get_buffer = framebuf_get_buffer; - framebuf_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill), MP_OBJ_FROM_PTR(&framebuf_fill_obj) }; - framebuf_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill_rect), MP_OBJ_FROM_PTR(&framebuf_fill_rect_obj) }; - framebuf_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_pixel), MP_OBJ_FROM_PTR(&framebuf_pixel_obj) }; - framebuf_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_hline), MP_OBJ_FROM_PTR(&framebuf_hline_obj) }; - framebuf_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_vline), MP_OBJ_FROM_PTR(&framebuf_vline_obj) }; - framebuf_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_rect), MP_OBJ_FROM_PTR(&framebuf_rect_obj) }; - framebuf_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_line), MP_OBJ_FROM_PTR(&framebuf_line_obj) }; - framebuf_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_blit), MP_OBJ_FROM_PTR(&framebuf_blit_obj) }; - framebuf_locals_dict_table[8] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_scroll), MP_OBJ_FROM_PTR(&framebuf_scroll_obj) }; - framebuf_locals_dict_table[9] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_text), MP_OBJ_FROM_PTR(&framebuf_text_obj) }; - mp_type_framebuf.locals_dict = (void*)&framebuf_locals_dict; - - mp_store_global(MP_QSTR_FrameBuffer, MP_OBJ_FROM_PTR(&mp_type_framebuf)); - mp_store_global(MP_QSTR_FrameBuffer1, MP_OBJ_FROM_PTR(&legacy_framebuffer1_obj)); - mp_store_global(MP_QSTR_MVLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB)); - mp_store_global(MP_QSTR_MONO_VLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB)); - mp_store_global(MP_QSTR_RGB565, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565)); - mp_store_global(MP_QSTR_GS2_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS2_HMSB)); - mp_store_global(MP_QSTR_GS4_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS4_HMSB)); - mp_store_global(MP_QSTR_GS8, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS8)); - mp_store_global(MP_QSTR_MONO_HLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHLSB)); - mp_store_global(MP_QSTR_MONO_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHMSB)); - - MP_DYNRUNTIME_INIT_EXIT -} diff --git a/examples/natmod/uheapq/Makefile b/examples/natmod/uheapq/Makefile deleted file mode 100644 index 55de3cc081..0000000000 --- a/examples/natmod/uheapq/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# Location of top-level MicroPython directory -MPY_DIR = ../../.. - -# Name of module (different to built-in uheapq so it can coexist) -MOD = uheapq_$(ARCH) - -# Source files (.c or .py) -SRC = uheapq.c - -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) -ARCH = x64 - -include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/uheapq/uheapq.c b/examples/natmod/uheapq/uheapq.c deleted file mode 100644 index 9da6bb4ada..0000000000 --- a/examples/natmod/uheapq/uheapq.c +++ /dev/null @@ -1,16 +0,0 @@ -#define MICROPY_PY_UHEAPQ (1) - -#include "py/dynruntime.h" - -#include "extmod/moduheapq.c" - -mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { - MP_DYNRUNTIME_INIT_ENTRY - - mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uheapq)); - mp_store_global(MP_QSTR_heappush, MP_OBJ_FROM_PTR(&mod_uheapq_heappush_obj)); - mp_store_global(MP_QSTR_heappop, MP_OBJ_FROM_PTR(&mod_uheapq_heappop_obj)); - mp_store_global(MP_QSTR_heapify, MP_OBJ_FROM_PTR(&mod_uheapq_heapify_obj)); - - MP_DYNRUNTIME_INIT_EXIT -} diff --git a/examples/natmod/urandom/Makefile b/examples/natmod/urandom/Makefile deleted file mode 100644 index 3f018baaf7..0000000000 --- a/examples/natmod/urandom/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# Location of top-level MicroPython directory -MPY_DIR = ../../.. - -# Name of module (different to built-in urandom so it can coexist) -MOD = urandom_$(ARCH) - -# Source files (.c or .py) -SRC = urandom.c - -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) -ARCH = x64 - -include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/urandom/urandom.c b/examples/natmod/urandom/urandom.c deleted file mode 100644 index e1fed6a554..0000000000 --- a/examples/natmod/urandom/urandom.c +++ /dev/null @@ -1,33 +0,0 @@ -#define MICROPY_PY_URANDOM (1) -#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) - -#include "py/dynruntime.h" - -// Dynamic native modules don't support a data section so these must go in the BSS -uint32_t yasmarang_pad, yasmarang_n, yasmarang_d; -uint8_t yasmarang_dat; - -#include "extmod/modurandom.c" - -mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { - MP_DYNRUNTIME_INIT_ENTRY - - yasmarang_pad = 0xeda4baba; - yasmarang_n = 69; - yasmarang_d = 233; - - mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_urandom)); - mp_store_global(MP_QSTR_getrandbits, MP_OBJ_FROM_PTR(&mod_urandom_getrandbits_obj)); - mp_store_global(MP_QSTR_seed, MP_OBJ_FROM_PTR(&mod_urandom_seed_obj)); - #if MICROPY_PY_URANDOM_EXTRA_FUNCS - mp_store_global(MP_QSTR_randrange, MP_OBJ_FROM_PTR(&mod_urandom_randrange_obj)); - mp_store_global(MP_QSTR_randint, MP_OBJ_FROM_PTR(&mod_urandom_randint_obj)); - mp_store_global(MP_QSTR_choice, MP_OBJ_FROM_PTR(&mod_urandom_choice_obj)); - #if MICROPY_PY_BUILTINS_FLOAT - mp_store_global(MP_QSTR_random, MP_OBJ_FROM_PTR(&mod_urandom_random_obj)); - mp_store_global(MP_QSTR_uniform, MP_OBJ_FROM_PTR(&mod_urandom_uniform_obj)); - #endif - #endif - - MP_DYNRUNTIME_INIT_EXIT -} diff --git a/examples/natmod/ure/Makefile b/examples/natmod/ure/Makefile deleted file mode 100644 index f5254298fd..0000000000 --- a/examples/natmod/ure/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# Location of top-level MicroPython directory -MPY_DIR = ../../.. - -# Name of module (different to built-in ure so it can coexist) -MOD = ure_$(ARCH) - -# Source files (.c or .py) -SRC = ure.c - -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) -ARCH = x64 - -include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/ure/ure.c b/examples/natmod/ure/ure.c deleted file mode 100644 index 175b93e395..0000000000 --- a/examples/natmod/ure/ure.c +++ /dev/null @@ -1,78 +0,0 @@ -#define MICROPY_STACK_CHECK (1) -#define MICROPY_PY_URE (1) -#define MICROPY_PY_URE_MATCH_GROUPS (1) -#define MICROPY_PY_URE_MATCH_SPAN_START_END (1) -#define MICROPY_PY_URE_SUB (0) // requires vstr interface - -#include -#include "py/dynruntime.h" - -#define STACK_LIMIT (2048) - -const char *stack_top; - -void mp_stack_check(void) { - // Assumes descending stack on target - volatile char dummy; - if (stack_top - &dummy >= STACK_LIMIT) { - mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("maximum recursion depth exceeded")); - } -} - -#if !defined(__linux__) -void *memcpy(void *dst, const void *src, size_t n) { - return mp_fun_table.memmove_(dst, src, n); -} -void *memset(void *s, int c, size_t n) { - return mp_fun_table.memset_(s, c, n); -} -#endif - -void *memmove(void *dest, const void *src, size_t n) { - return mp_fun_table.memmove_(dest, src, n); -} - -mp_obj_type_t match_type; -mp_obj_type_t re_type; - -#include "extmod/modure.c" - -mp_map_elem_t match_locals_dict_table[5]; -STATIC MP_DEFINE_CONST_DICT(match_locals_dict, match_locals_dict_table); - -mp_map_elem_t re_locals_dict_table[3]; -STATIC MP_DEFINE_CONST_DICT(re_locals_dict, re_locals_dict_table); - -mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { - MP_DYNRUNTIME_INIT_ENTRY - - char dummy; - stack_top = &dummy; - - // Because MP_QSTR_start/end/split are static, xtensa and xtensawin will make a small data section - // to copy in this key/value pair if they are specified as a struct, so assign them separately. - - match_type.base.type = (void*)&mp_fun_table.type_type; - match_type.name = MP_QSTR_match; - match_type.print = match_print; - match_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_group), MP_OBJ_FROM_PTR(&match_group_obj) }; - match_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_groups), MP_OBJ_FROM_PTR(&match_groups_obj) }; - match_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_span), MP_OBJ_FROM_PTR(&match_span_obj) }; - match_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_start), MP_OBJ_FROM_PTR(&match_start_obj) }; - match_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_end), MP_OBJ_FROM_PTR(&match_end_obj) }; - match_type.locals_dict = (void*)&match_locals_dict; - - re_type.base.type = (void*)&mp_fun_table.type_type; - re_type.name = MP_QSTR_ure; - re_type.print = re_print; - re_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_match), MP_OBJ_FROM_PTR(&re_match_obj) }; - re_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_search), MP_OBJ_FROM_PTR(&re_search_obj) }; - re_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_split), MP_OBJ_FROM_PTR(&re_split_obj) }; - re_type.locals_dict = (void*)&re_locals_dict; - - mp_store_global(MP_QSTR_compile, MP_OBJ_FROM_PTR(&mod_re_compile_obj)); - mp_store_global(MP_QSTR_match, MP_OBJ_FROM_PTR(&re_match_obj)); - mp_store_global(MP_QSTR_search, MP_OBJ_FROM_PTR(&re_search_obj)); - - MP_DYNRUNTIME_INIT_EXIT -} diff --git a/examples/natmod/uzlib/Makefile b/examples/natmod/uzlib/Makefile deleted file mode 100644 index 8761caf2dd..0000000000 --- a/examples/natmod/uzlib/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# Location of top-level MicroPython directory -MPY_DIR = ../../.. - -# Name of module (different to built-in uzlib so it can coexist) -MOD = uzlib_$(ARCH) - -# Source files (.c or .py) -SRC = uzlib.c - -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) -ARCH = x64 - -include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/uzlib/uzlib.c b/examples/natmod/uzlib/uzlib.c deleted file mode 100644 index 99b3691761..0000000000 --- a/examples/natmod/uzlib/uzlib.c +++ /dev/null @@ -1,35 +0,0 @@ -#define MICROPY_PY_UZLIB (1) - -#include "py/dynruntime.h" - -#if !defined(__linux__) -void *memset(void *s, int c, size_t n) { - return mp_fun_table.memset_(s, c, n); -} -#endif - -mp_obj_type_t decompio_type; - -#include "extmod/moduzlib.c" - -mp_map_elem_t decompio_locals_dict_table[3]; -STATIC MP_DEFINE_CONST_DICT(decompio_locals_dict, decompio_locals_dict_table); - -mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { - MP_DYNRUNTIME_INIT_ENTRY - - decompio_type.base.type = mp_fun_table.type_type; - decompio_type.name = MP_QSTR_DecompIO; - decompio_type.make_new = decompio_make_new; - decompio_type.protocol = &decompio_stream_p; - decompio_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_OBJ_FROM_PTR(&mp_stream_read_obj) }; - decompio_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_OBJ_FROM_PTR(&mp_stream_readinto_obj) }; - decompio_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_OBJ_FROM_PTR(&mp_stream_unbuffered_readline_obj) }; - decompio_type.locals_dict = (void*)&decompio_locals_dict; - - mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uzlib)); - mp_store_global(MP_QSTR_decompress, MP_OBJ_FROM_PTR(&mod_uzlib_decompress_obj)); - mp_store_global(MP_QSTR_DecompIO, MP_OBJ_FROM_PTR(&decompio_type)); - - MP_DYNRUNTIME_INIT_EXIT -} From 716a82ba677070abe37f55e0851b1cb7b4cb7260 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 5 May 2021 11:02:15 -0500 Subject: [PATCH 16/16] set the coroutine generator for native generators --- py/objgenerator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/py/objgenerator.c b/py/objgenerator.c index 3871dc462c..690f08a889 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -90,6 +90,7 @@ STATIC mp_obj_t native_gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_k o->base.type = &mp_type_gen_instance; // Parse the input arguments and set up the code state + o->coroutine_generator = self->coroutine_generator; o->pend_exc = mp_const_none; o->code_state.fun_bc = self_fun; o->code_state.ip = (const byte *)prelude_offset;