Merge branch 'merge-micropython-v1.19.1' of https://github.com/dhalbert/circuitpython into merge-micropython-v1.19.1

This commit is contained in:
Dan Halbert 2023-08-18 22:53:24 -04:00
commit d35e4ffc39
18 changed files with 197 additions and 44 deletions

View File

@ -0,0 +1,34 @@
// Include MicroPython API.
#include "py/runtime.h"
// This is the function which will be called from Python as cexample.add_ints(a, b).
STATIC mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_t b_obj) {
// Extract the ints from the micropython input objects.
int a = mp_obj_get_int(a_obj);
int b = mp_obj_get_int(b_obj);
// Calculate the addition and convert to MicroPython object.
return mp_obj_new_int(a + b);
}
// Define a Python reference to the function above.
STATIC MP_DEFINE_CONST_FUN_OBJ_2(example_add_ints_obj, example_add_ints);
// Define all properties of the module.
// Table entries are key/value pairs of the attribute name (a string)
// and the MicroPython object reference.
// All identifiers and strings are written as MP_QSTR_xxx and will be
// optimized to word-sized integers by the build system (interned strings).
STATIC const mp_rom_map_elem_t example_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cexample) },
{ MP_ROM_QSTR(MP_QSTR_add_ints), MP_ROM_PTR(&example_add_ints_obj) },
};
STATIC MP_DEFINE_CONST_DICT(example_module_globals, example_module_globals_table);
// Define module object.
const mp_obj_module_t example_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&example_module_globals,
};
// Register the module to make it available in Python.
MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule);

View File

@ -0,0 +1,15 @@
# Create an INTERFACE library for our C module.
add_library(usermod_cexample INTERFACE)
# Add our source files to the lib
target_sources(usermod_cexample INTERFACE
${CMAKE_CURRENT_LIST_DIR}/examplemodule.c
)
# Add the current directory as an include directory.
target_include_directories(usermod_cexample INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)
# Link our INTERFACE library to the usermod target.
target_link_libraries(usermod INTERFACE usermod_cexample)

View File

@ -0,0 +1,9 @@
EXAMPLE_MOD_DIR := $(USERMOD_DIR)
# Add all C files to SRC_USERMOD.
SRC_USERMOD += $(EXAMPLE_MOD_DIR)/examplemodule.c
# We can add our module folder to include paths if needed
# This is not actually needed in this example.
CFLAGS_USERMOD += -I$(EXAMPLE_MOD_DIR)
CEXAMPLE_MOD_DIR := $(USERMOD_DIR)

View File

@ -0,0 +1,17 @@
extern "C" {
#include <examplemodule.h>
// Here we implement the function using C++ code, but since it's
// declaration has to be compatible with C everything goes in extern "C" scope.
mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj) {
// Prove we have (at least) C++11 features.
const auto a = mp_obj_get_int(a_obj);
const auto b = mp_obj_get_int(b_obj);
const auto sum = [&]() {
return mp_obj_new_int(a + b);
} ();
// Prove we're being scanned for QSTRs.
mp_obj_t tup[] = {sum, MP_ROM_QSTR(MP_QSTR_hellocpp)};
return mp_obj_new_tuple(2, tup);
}
}

View File

@ -0,0 +1,25 @@
#include <examplemodule.h>
// Define a Python reference to the function we'll make available.
// See example.cpp for the definition.
STATIC MP_DEFINE_CONST_FUN_OBJ_2(cppfunc_obj, cppfunc);
// Define all properties of the module.
// Table entries are key/value pairs of the attribute name (a string)
// and the MicroPython object reference.
// All identifiers and strings are written as MP_QSTR_xxx and will be
// optimized to word-sized integers by the build system (interned strings).
STATIC const mp_rom_map_elem_t cppexample_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cppexample) },
{ MP_ROM_QSTR(MP_QSTR_cppfunc), MP_ROM_PTR(&cppfunc_obj) },
};
STATIC MP_DEFINE_CONST_DICT(cppexample_module_globals, cppexample_module_globals_table);
// Define module object.
const mp_obj_module_t cppexample_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&cppexample_module_globals,
};
// Register the module to make it available in Python.
MP_REGISTER_MODULE(MP_QSTR_cppexample, cppexample_user_cmodule);

View File

@ -0,0 +1,5 @@
// Include MicroPython API.
#include "py/runtime.h"
// Declare the function we'll make available in Python as cppexample.cppfunc().
extern mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj);

View File

@ -0,0 +1,16 @@
# Create an INTERFACE library for our CPP module.
add_library(usermod_cppexample INTERFACE)
# Add our source files to the library.
target_sources(usermod_cppexample INTERFACE
${CMAKE_CURRENT_LIST_DIR}/example.cpp
${CMAKE_CURRENT_LIST_DIR}/examplemodule.c
)
# Add the current directory as an include directory.
target_include_directories(usermod_cppexample INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)
# Link our INTERFACE library to the usermod target.
target_link_libraries(usermod INTERFACE usermod_cppexample)

View File

@ -0,0 +1,12 @@
CPPEXAMPLE_MOD_DIR := $(USERMOD_DIR)
# Add our source files to the respective variables.
SRC_USERMOD += $(CPPEXAMPLE_MOD_DIR)/examplemodule.c
SRC_USERMOD_CXX += $(CPPEXAMPLE_MOD_DIR)/example.cpp
# Add our module directory to the include path.
CFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR)
CXXFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR) -std=c++11
# We use C++ features so have to link against the standard library.
LDFLAGS_USERMOD += -lstdc++

View File

@ -0,0 +1,10 @@
# This top-level micropython.cmake is responsible for listing
# the individual modules we want to include.
# Paths are absolute, and ${CMAKE_CURRENT_LIST_DIR} can be
# used to prefix subdirectories.
# Add the C example.
include(${CMAKE_CURRENT_LIST_DIR}/cexample/micropython.cmake)
# Add the CPP example.
include(${CMAKE_CURRENT_LIST_DIR}/cppexample/micropython.cmake)

View File

@ -33,9 +33,7 @@
#include "supervisor/shared/translate/compressed_string.h" #include "supervisor/shared/translate/compressed_string.h"
// Map MicroPython's error messages to our translations. // Map MicroPython's error messages to our translations.
#if defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME #if !defined(MICROPY_ENABLE_DYNRUNTIME) || !MICROPY_ENABLE_DYNRUNTIME
#define MP_ERROR_TEXT(x) (x)
#else
#define MP_ERROR_TEXT(x) translate(x) #define MP_ERROR_TEXT(x) translate(x)
#endif #endif

15
tests/endorse.py Executable file
View File

@ -0,0 +1,15 @@
#!/usr/bin/env python3
import os
import sys
import pathlib
for f in sys.argv[1:]:
if not f.endswith(".out"):
print(f"{f}:0: Not a .out file")
continue
p = pathlib.Path(f).stem
a, _, b = p.partition("_")
print(a, b)
p = pathlib.Path(a) / (b + ".exp")
print(f"{p}: Updating expected result from {f}")
os.rename(f, p)

View File

@ -1,4 +1,3 @@
mod0 RuntimeError Corrupt .mpy file mod0 ValueError incompatible .mpy file
mod1 RuntimeError Corrupt .mpy file mod1 ValueError incompatible .mpy file
mod2 ValueError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info. mod2 ValueError incompatible .mpy file
mod3 ValueError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info.

View File

@ -109,7 +109,7 @@ user_files = {
# create and mount a user filesystem # create and mount a user filesystem
uos.mount(UserFS(user_files), "/userfs") uos.mount(UserFS(user_files), "/userfs")
usys.path.append("/userfs") sys.path.append("/userfs")
# import .mpy files from the user filesystem # import .mpy files from the user filesystem
for i in range(len(user_files)): for i in range(len(user_files)):
@ -122,4 +122,4 @@ for i in range(len(user_files)):
# unmount and undo path addition # unmount and undo path addition
uos.umount("/userfs") uos.umount("/userfs")
usys.path.pop() sys.path.pop()

View File

@ -1,3 +1,3 @@
mod0 ValueError incompatible native .mpy architecture mod0 ValueError incompatible .mpy arch
mod1 OK mod1 OK
mod2 OK mod2 OK

View File

@ -1,5 +1,9 @@
# Test that native code loaded from a .mpy file is retained after a GC. # Test that native code loaded from a .mpy file is retained after a GC.
# This is known not to work in CircuitPython. Fixes welcome.
print("SKIP")
raise SystemExit
try: try:
import gc, sys, uio, uos import gc, sys, uio, uos

View File

@ -18,7 +18,7 @@ abc
0x0 0x0
0x0 0x0
# tracked allocation # tracked allocation
m_tracked_head = 0 m_tracked_head = 0x0
0 1 0 1
1 1 1 1
2 1 2 1
@ -35,7 +35,7 @@ m_tracked_head = 0
5 1 5 1
6 1 6 1
7 1 7 1
m_tracked_head = 0 m_tracked_head = 0x0
# vstr # vstr
tests tests
sts sts
@ -48,30 +48,29 @@ RuntimeError:
ame__ ame__
mport mport
builtins micropython __future__ _asyncio builtins micropython __future__ _thread
_thread _uasyncio aesio array _uasyncio aesio array audiocore
audiocore audiomixer binascii bitmaptools audiomixer bitmaptools cexample cmath
btree cexample cmath collections collections cppexample displayio gc
cppexample displayio errno ffi math qrio rainbowio struct
framebuf gc hashlib json synthio termios traceback ubinascii
math qrio rainbowio re uctypes uerrno uhashlib uheapq
struct synthio sys termios uio ujson ulab ulab.numpy
traceback ubinascii uctypes uerrno ulab.numpy.fft ulab.numpy.linalg ulab.scipy
uheapq uio ujson ulab ulab.scipy.linalg ulab.scipy.optimize
ulab.numpy ulab.numpy.fft ulab.numpy.linalg ulab.scipy.signal ulab.scipy.special
ulab.scipy ulab.scipy.linalg ulab.utils uos urandom ure
ulab.scipy.optimize ulab.scipy.signal uselect usys utime utimeq
ulab.scipy.special ulab.utils uos uzlib zlib
urandom ure uselect utime
utimeq uzlib zlib
ime ime
utime utimeq utime utimeq
argv atexit byteorder exc_info argv atexit byteorder exc_info
exit getsizeof implementation maxsize exit getsizeof implementation maxsize
modules path platform stderr modules path platform print_exception
stdin stdout version version_info ps1 ps2 stderr stdin
stdout tracebacklimit version version_info
ementation ementation
# attrtuple # attrtuple
(start=1, stop=2, step=3) (start=1, stop=2, step=3)
@ -199,4 +198,9 @@ frzstr_pkg2.mod
frzmpy_pkg2.mod frzmpy_pkg2.mod
1 1
ZeroDivisionError ZeroDivisionError
\
X
'\x1b'
b'\x00\xff'
NULL NULL

View File

@ -79,6 +79,10 @@ def main():
submodules = ["extmod/ulab", "lib/", "tools/"] submodules = ["extmod/ulab", "lib/", "tools/"]
elif TARGET == "tests": elif TARGET == "tests":
submodules = ["extmod/ulab", "lib/", "tools/"] submodules = ["extmod/ulab", "lib/", "tools/"]
submodules_tags = [
"frozen/Adafruit_CircuitPython_asyncio",
"frozen/Adafruit_CircuitPython_Ticks",
]
elif TARGET == "docs": elif TARGET == "docs":
# used in .readthedocs.yml to generate RTD # used in .readthedocs.yml to generate RTD
submodules = ["extmod/ulab"] submodules = ["extmod/ulab"]

View File

@ -757,7 +757,6 @@ def link_objects(env, native_qstr_vals_len, native_qstr_objs_len):
bytearray(native_qstr_vals_len * env.arch.qstr_entry_size), bytearray(native_qstr_vals_len * env.arch.qstr_entry_size),
env.arch.qstr_entry_size, env.arch.qstr_entry_size,
) )
env.sections.append(env.qstr_val_section)
# Create section to contain mp_native_obj_table # Create section to contain mp_native_obj_table
env.obj_table_section = Section( env.obj_table_section = Section(
@ -765,7 +764,6 @@ def link_objects(env, native_qstr_vals_len, native_qstr_objs_len):
bytearray(native_qstr_objs_len * env.arch.word_size), bytearray(native_qstr_objs_len * env.arch.word_size),
env.arch.word_size, env.arch.word_size,
) )
env.sections.append(env.qstr_obj_section)
# Resolve unknown symbols # Resolve unknown symbols
mp_fun_table_sec = Section(".external.mp_fun_table", b"", 0) mp_fun_table_sec = Section(".external.mp_fun_table", b"", 0)
@ -944,17 +942,6 @@ def build_mpy(env, entry_offset, fmpy, native_qstr_vals, native_qstr_objs):
# MPY: machine code # MPY: machine code
out.write_bytes(env.full_text) out.write_bytes(env.full_text)
# MPY: n_qstr_link (assumes little endian)
out.write_uint(len(native_qstr_vals) + len(native_qstr_objs))
for q in range(len(native_qstr_vals)):
off = env.qstr_val_section.addr + q * env.arch.qstr_entry_size
out.write_uint(off << 2)
out.write_qstr(native_qstr_vals[q])
for q in range(len(native_qstr_objs)):
off = env.qstr_obj_section.addr + q * env.arch.word_size
out.write_uint(off << 2 | 3)
out.write_qstr(native_qstr_objs[q])
# MPY: scope_flags # MPY: scope_flags
scope_flags = MP_SCOPE_FLAG_VIPERRELOC scope_flags = MP_SCOPE_FLAG_VIPERRELOC
if len(env.full_rodata): if len(env.full_rodata):
@ -967,7 +954,6 @@ def build_mpy(env, entry_offset, fmpy, native_qstr_vals, native_qstr_objs):
if len(env.full_rodata): if len(env.full_rodata):
rodata_const_table_idx = 1 rodata_const_table_idx = 1
out.write_uint(len(env.full_rodata)) out.write_uint(len(env.full_rodata))
out.write_bytes(env.full_rodata)
if len(env.full_bss): if len(env.full_bss):
bss_const_table_idx = 2 bss_const_table_idx = 2
out.write_uint(len(env.full_bss)) out.write_uint(len(env.full_bss))